martes, 13 de octubre de 2015

PROGRAMACION EN EL MODELO DE MEMORIA COMPARTIDA

TECNICAS DE SINCRONIZACION:
  • SEMAFOROS
  • BARRERAS

Sincronización de hilos en python

Mutex o locks o Candados
Realmente los mutex son la herramienta más fácil que hay de sintonización. Un mutex se usa en programación concurrente para que un solo procesos o hilo en nuestro caso pueda tomar un recurso compartido por otros. La parte de código que toma dicho recurso se llama sección crítica. El mutex solo puede tomar dos estados que son tomados y liberado. Miremos un ejemplo para aclarar las ideas.
En el archivo mutex.py y compare su salida con el de hilo.py de la entrada anterior


#!/usr/bin/python
# Nombre de Fichero : mutex.py

import threading
from time import sleep
mutex = threading.Lock()
class Hilo(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        mutex.acquire()
        sleep(3-self.id)
        print "Yo soy %s la variable d tiene el valor %s"%(self.id,d)
        mutex.release()

d=1;
hilos = [Hilo(1),
Hilo(2),
Hilo(3)]

for h in hilos:
    h.start()

 

 locks re-entrantes – Rlook
La clase RLock es similar a Lock, pero puede ser adquirido por el mismo thread varias veces, y no quedará liberado hasta que el thread lo libere tantas veces como llamó a acquire.



Los semáforos
Los semáforos son parecidos a los mutex pero en vez de tomar el valor 1 y 0, toman n valores que nos indicara la cantidad de hilos, que puede tomar el recurso concurrentemente. Para esto python nos facilita la clase Semaphore y BoundedSemaphore. La diferencia de Semaphore y BoundedSemaphore es que, cuando se libera el recurso más veces que el n inicial del semáforo en Semaphore cambia dicha cota, mientras que en BoundedSemaphore lo considera un error de ValueError
Miremos este ejemplo llamado semaphore.py
#!/usr/bin/python
# Nombre de Fichero : semaphore.py

import threading
from time import sleep
semaforo = threading.Semaphore(2)

n=0
class Hilo(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        semaforo.acquire()
        sleep(3-self.id)
        d.append(self.id)
        semaforo.release()

d=[];
hilos = [Hilo(1),
Hilo(2),
Hilo(3)]

for h in hilos:
    h.start()

sleep(4)
semaforo.acquire()
print d
semaforo.release()
fijese que si agrega justo antes del sleep(4) 3 release como estos
semaforo.release()
semaforo.release()
semaforo.release()
La salida cambia de orden ya que entra mas de uno hilo concurrente.
En cambio si después de agregar estas tres lineas, cambiamos la linea
semaforo = threading.Semaphore(2) por semaforo = threading.BoundedSemaphore(2)
dara error de tipo ValueError.
Las condiciones
Las condiciones son de utilidad para hacer que los threads sólo puedan entrar en la sección crítica de darse una cierta condición o evento.La clase condition tiene métodos wait, notify y notifyAll.
El método wait debe llamarse después de haber adquirido el objeto condiction con acquire. Este método libera el candado y bloquea al hilo hasta que una llamada a notify o notifyAll en otro hilo le indican que se ha cumplido la condición. El hilo que informa a los demás de que se ha producido la condición, también debe llamar a acquire antes de llamar a notify o notifyAll.
Espero que el ejemplo del archivo condition.py sea ilustrativo.
#!/usr/bin/python
# Nombre de Fichero : condition.py
import threading

cond = threading.Condition()

class Cliente (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        while True:
            cond.acquire()
            cond.wait()
            mesa.pop()
            cond.notify()
            cond.release()

class Cosinero(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        while True:
            cond.acquire()
            if len(mesa) != 0: cond.wait()
            mesa.append("Torta de frutillas")
            cond.notify()
            cond.release()

print "El bar"

mesa = []
cliente = Cliente()
cosinero = Cosinero()

cliente.start()
cosinero.start()

while True:
    print mesa
acquire no bloqueante
Para que acquire no bloque el hilo le tenemos que pasar (False) como parámetro. Dicha invocación nos dará el resultado de si obtuvo el hilo o no. Modificaremos el ejemplo del mutex para que se vea lo que pasa.
#!/usr/bin/python
# Nombre de Fichero : mutex2.py

import threading
from time import sleep
mutex = threading.Lock()
class Hilo(threading.Thread):
    def __init__(self, id):
        threading.Thread.__init__(self)
        self.id = id

    def run(self):
        b = mutex.acquire(False)
        print b
        sleep(3-self.id)
        print "Yo soy %s la variable d tiene el valor %s"%(self.id,d)
        if b :mutex.release()

d=1;
hilos = [Hilo(1),
Hilo(2),
Hilo(3)]

for h in hilos:
    h.start()
Los eventos
La clase Event es un wrapper por encima de Condition y sirven principalmente para coordinar threads mediante señales que indican los eventos que han ocurrido. Los no tienen los métodos acquire y release.
El hilo que debe esperar el evento se pondra en espera por medio de la llama al método wait y se bloquea, le podriamos pasar como parámetro un número en coma flotante indicando el número máximo de segundos a esperar. Otro hilo, cuando ocurre el evento, envía la señal a los hilos bloqueados a la espera de dicho evento utilizando el método set. Los hilos que estaban esperando se desbloquean una vez recibida la señal. La bandera que indica si se ha producido el evento se puede volver a setar a falso usando clear. Los eventos son similares a las condiciones.
Un ejemplo lo vemos en eventos.py que es una modificación de condition.py
#!/usr/bin/python
# Nombre de Fichero :  eventos.py
import threading

evento = threading.Event()

class Cliente (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        while True:
            self.evento.wait()
            mesa.pop()

class Cosinero(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        while True:
            if len(mesa) != 0: cond.wait()
            mesa.append("Torta de frutillas")
            evento.set()

print "El bar"

mesa = []
cliente = Cliente()
cosinero = Cosinero()

cliente.start()
cosinero.start()

while True:
    print mesa


 Barreras


Los locks, también llamados mutex son objetos con dos estados posibles: adquirido o libre. Cuando un thread adquiere la barrera, los demás threads que pidan adquirirlo se bloquearán hasta que el thread que lo ha adquirido libere la barrera, momento en el cual podrá entrar otro thread.

La barrera se representa mediante la clase Lock. Llamando a Lock.acquire() el hilo bloqueará el Lock, de forma que el siguiente hilo que llame a Lock.acquire() se quedará a la espera de que el Lock se desbloquee. La llamada a Lock.release() desbloquea el Lock, haciendo que el hilo que estaba en espera continúe. Un ejemplo se muestra a continuación:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from threading import Thread, Lock
import time
 
class MiHilo(Thread):
 
     
    def __init__ (self, inicio, fin, bloqueo):
        Thread.__init__(self)
        self.inicio = inicio
        self.fin = fin
        self.bloqueo = bloqueo
       
    def run (self):
        bloqueo.acquire()
        for i in range(self.inicio,self.fin):
           print ("contador = "+str(i))
           time.sleep(0.2)
        bloqueo.release()
             
if __name__ == '__main__':
    bloqueo = Lock()
    bloqueo.acquire()
    hilo = MiHilo(0,10, bloqueo)
    hilo.start()
    time.sleep(1)
    for i in range (10,20):
       print ("main = "+str(i))
       time.sleep(0.1)
        
    bloqueo.release()

Esta clase Lock es muy simple. Cualquier hilo, puede liberar a otro sin importar si lo haya bloquedado o no, además si un hilo llama él mismo dos veces a acquire(), se queda bloqueado en la segunda llamada. Una mejor opción es RLock. En esta barrera solo el que haya llamado al método acquire() puede liberarlo con el método release() y un mismo hilo puede llamar varias veces a acquire() sin quedarse bloqueado, pero tiene que hacer el mismo número de llamadas a release() para desbloquearlo. El ejemplo siguiente muestra su funcionamiento:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from threading import Thread, RLock
import time
 
class MiHilo(Thread):
    def __init__ (self, inicio, fin, bloqueo):
        Thread.__init__(self)
        self.inicio = inicio
        self.fin = fin
        self.bloqueo = bloqueo
 
    def run (self):
        bloqueo.acquire()
        for i in range(self.inicio,self.fin):
           print ("contador = "+str(i))
           time.sleep(0.2)
        bloqueo.release()
             
if __name__ == '__main__':
    bloqueo = RLock()
    bloqueo.acquire()
     
    hilo = MiHilo(0,10, bloqueo)
    hilo.start()
    time.sleep(1)
    for i in range (10,20):
       print ("main = "+str(i))
       bloqueo.acquire()
       time.sleep(0.1)
        
    bloqueo.release()
    print ("El hilo todavia no ha comenzado")
    for i in range(10,20):
       bloqueo.release()




 REFERENCIAS

  • https://pythonr2.wordpress.com/tag/semaforos-en-python/ 
  • http://www.solveet.com/barreras















miércoles, 16 de septiembre de 2015

PRACTICA 5 SUMA EREW


#CRISANTO TIBURCIO YOVANA
#PRACTICA 5
#SUMA EREW 
#DEFINICIÓN DE FUNCIONES
import threading
import math

def hilo(i,j):
    if ((2*j)%(2**i)==0):
        a[int(2*j)]=a[int(2*j)]+a[int((2*j)-2**(i-1))]

#PROGRAMA PRINCIPAL
a=[0,5,2,10,1,8,12,7,3]
print "¿Deseas modificar el vector original?"
print "Si= 1, No= 2"
b=int(raw_input("Ingresa opcion: "))
if(b==1):
    for i in range (1,9):
        a[i]=int(raw_input("Ingresa numero: "))
    print "El vector modificado es:"
    print a
else:
    print "El vector original es:"
    print a
n=len(a)
lg=int(math.log(n,2))
i=1
while(i<=lg):
    j=1
    while(j<=(n/2)):
        t=threading.Thread(target=hilo, args=(i,j, ))
        t.start()
        j=j+1
    i=i+1
print a

martes, 1 de septiembre de 2015

Programación orientada a objetos en Python



Introducción

Si bien Python es un lenguaje orientado a objetos (Programación Orientada a Objetos, POO), es posible utilizarlo sin tener en cuenta explicitamente este hecho. Por eso se dice que Python es un lenguaje "Multi paradigma". Los objetos ya han sido usados de manera implícita: Los tipos de datos (str, dict, listas) son
objetos. Cada uno tiene funciones asociadas (llamadas métodos en la jerga) y sus atributos. Por ejemplo str.lower() devuelve un str en minúscula, porque todos los objetos de esta clase (str) tienen el método lower() asociados.
Una clase se puede usar para definir un tipo de datos, y si bien los tipos de datos incluidos en Python son variados, su capacidad para hacer representaciones (modelos) del mundo real es limitada. Es por eso que hace falta poder definir nuestras propias clases. 

Jerga de POO 

Clases: Generadores de objetos

Es una estructura que se usa como plantilla para crear objetos (de una clase). Esta plantilla describen tanto el estado como el comportamiento de los objetos que se crean a partir de ella. El estado es mantenido via los atributos y el comportamiento via los métodos.

Instancia: Implementación particular de una clase 

Cada instancia es una implementación de una clase. Si tenemos la clase orca, una instancia puede ser Willy. Es posible crear varias instancias independientes una de otra (como Shamu que es independiente
de Willy). 

Atributos (o variables de instancia): Características de los objetos

Cada objeto tiene sus atributos, como por ejemplo peso. Willy tendrá un peso distinto de Shamu. Aunque ambas instancias pertenecen a la misma clase (orca). Comparten el tipo de atributo. Podriamos tener la clase perro con instancias Lassie y Laika con el atributo color_de_pelo que no será compartido con las instancias de la clase orca 

Métodos: Comportamiento de los objetos

Un método es una función que pertenece a una clase. Los métodos definen como se portan los objetos derivados de una clase. La clase perro puede tener el método ladrar. Algunos métodos pueden usar parámetros (como ladrar(enojado)).

Herencia: Las propiedades se trasmiten de clases relacionadas

Las clases pueden relacionarse entre ellas y no ser entidades aisladas. Es posible tener una clase mamífero con propiedades comunes a la case orca y la clase perro. Por ejemplo el método reproducción puede ser definido para la clase mamífero. No sera necesario crear para ellos el método reproducción ya que lo heredarán.

Variable de clases: caracteristicas de las clases.

Son variables asociadas a todos los objetos de una clase. Cuando un objeto es creado, el objeto hereda a variable de clase.

Polimorfismo

Es la habilidad para los distintos objetos de responder al mismo método de manera distinto. Es lo que permite por ejemplo al iterar sobre una lista, un set, diccionario, archivo, etc de la misma manera:

for nombre in secuencia:
# hacer algo



Encapsulación

Ocultar la operación interna de un objeto y dar acceso a los programadores por métodos públicos. La encapsulación en Python no es total, sino mas bien nominativa (también conocida como pseudo-encapsulación). Los métodos de uso interno se marcan como tales y los programadores eligen (o no) respetar.

Creando clases Modelo: 

class NOMBRE: [cuerpo]

 Una clase que hace algo: 

class Square: def __init__(self): self.side=1

 Uso: 


>>> Bob=Square() # Bob es una instancia de Square. 
>>> Bob.side # Veamos el valor de side. 1 
>>> Bob.side=5 # Asignar un valor nuevo a side.
 >>> Bob.side # Ver el valor de side.

Este cambio es específico para una instancia, al crearse una nueva, se ejecuta __initi__ de nuevo:

>>> Krusty=Square()
 >>> Krusty.side 
 Asignando una variable a la clase (y no solo a la instancia):

>>> class Square: side=1 
>>> Square.side 

Es posible usar las variables de clases para controlar cuantas instancias de una clase han sido creadas: 

class Square: 
   cuenta = 0 
   def __init__(self): Square.cuenta += 1 
    print "Objecto creado OK" 

Uso:

>>> Bob = Square() "Objecto creado OK" 
>>> Patricio = Square() "Objecto creado OK" 
>>> Square.cuenta 2 

Ejemplo con la clase Secuencia. En biología una secuencia nucleotídica es un fragmento de ADN. Por ejemplo: "ATGCA". Esto representa una secuencia de 5 nucleotidos (Adenina, Timina, Guanina, Citosina y nuevamente Adenina). Esta secuencia podria ser representada como un string:

secuencia = "ATGCA"

Esta representación no nos permite almacenar funciones asociadas a este tipo de datos (métodos). Una función propia de las secuencia es su transcripción, esto es: el proceso por el cual el ADN se convierte en ARN. En dicha transcripción los nucleotidos se convierten siguiendo la siguiente tabla:

ADN              ARN 
A                     U 
 T                    A 
C                     G 
G                      C

Con estos datos podemos hacer un programa que define una clase con el métdo transcripcion:

import string
       class Sequencia: tabla = string.maketrans('ACTG','UGAC') 
      def __init__(self, cadena): 
           self.cadena = cadena.upper()   
     def transcripcion(self): 
          tt = string.translate(self.cadena,self.tabla) 
      return tt 
miseq = Sequencia('ACAGTGTA') 
print miseq.transcripcion()


Esto permite definir instancias de secuencia y luego transcribirlas:

>>> virus_peligroso = Secuencia('atggagagccttgttcttggtgtcaa') 
>>> virus_peligroso.cadena 
'ATGGAGAGCCTTGTTCTTGGTGTCAA' 
>>> virus_peligroso.transcripcion() 
'UACCUCUCGGAACAAGAACCACAGUU' 

Podemos agregar entonces el método restriccion que requiere un parámetro:

def restriccion(self,enz):
     if enz in Secuencia.enz_d: 
           return self.cadena.count(Secuencia.enz_d[enz]) 
     else:
          return 0 


Herencia en acción 

La herencia de una clase implica que una clase hija hereda los métodos y atributos de la clase padre. Por ejemplo existe un tipo de secuencia de ADN denominada plásmido, que son independientes del ADN principal (cromosómico) de la célula. Esto puede ser modelado como una clase nueva (Plasmido) que tiene las mismas propiedades de Secuencia, mas métodos propios. En este caso se dice que la clase Plasmido hereda de Secuencia. Uno de los métodos que son propios de los plásmidos es la resistencia a antibioticos. El método ab_res verifica si un plasmido particular tiene o no resistencia a un antibiotico:

class Plasmido(Secuencia):
        ab_res_d = {"Tet":"CTAGCAT","Amp":"CACTACTG"}
        def __init__(self,cadena):
             Secuencia.__init__(self,cadena)
         def ab_res(self,ab):
            if ab in self.ab_res_d and self.ab_res_d[ab] in self.cadena:
                 return True
            else:
                return False


Resultado:

>>> x5 = Plasmido('TACGTCACTACTGAG') 
>>> x5.ab_res('Amp') 
True 



REFERENCIAS

 • Python Programming/OOP: en.wikibooks.org/wiki/Python_Programming/OOP.
 • Introduction to OOP with Python: www.voidspace.org.uk/python/articles/OOP.shtml.
 • Dive into Python. Capítulo 5. diveintopython.org/object_oriented_framework.




















 

sábado, 29 de agosto de 2015

PROGRAMACIÓN ANDROID CON PYTHON

¿Qué es Android?

Android es un sistema operativo inicialmente pensado para teléfonos móviles, al igual que iOS, Symbian y Blackberry OS. Lo que lo hace diferente es que está basado en Linux, un núcleo de sistema operativo libre, gratuito y multiplataforma.
El sistema permite programar aplicaciones en una variación de Java llamada Dalvik. El sistema operativo proporciona todas las interfaces necesarias para desarrollar aplicaciones que accedan a las funciones del teléfono (como el GPS, las llamadas, la agenda, etc.) de una forma muy sencilla en un lenguaje de programación muy conocido como es Java. 

Introducción a la programación en Python para Android

Nos llega este interesante proyecto de la mano de Kivy, un framework basado en OpenGL escrito en python que nos permite hacer aplicaciones desktop, IOS, Windows y tambien Android.
Hace poco vimos cómo compilar con el SDK de Android desde otro lenguaje que no sea Java, por ejemplo desde Scala.
Ahora con  Kivy, que es a la vez un framework y un toolkit como PythonQT o como el GTK+ toolkit de Gnome, podemos crear botones, animaciones, elementos visuales desde Python.
Mathieu Virbel, leader programmer de Kivy nos publica hace pocos días este script en Python que permite compilar desde python con el toolchain de Android y de esta forma  obtener un APK para Android.

Introducción: Instalación del Framework Kivy


En nuestro caso no es necesario instalar a kivy, el script de python-for-android nos descaraga directemente el framework de Kivy.
Solo instalamos Kivy para tener los ejemplo Demo a Compilar, no es necesario tenerlo instalado se puede saltar al siguiente paso.
En Mac os, es simple uno se puede bajar el archivo Kivy-1.5.0-osx.dmg para snow Leopard y lo instala como de costumbre, esto instalará todas las dependencias de Python OpenGL


PROGRAMACION ANDROID CON PYTHON




la forma de programa aplicaciones android desde su ordenador, con sl4a, pero mi propósito no es solo enseñarles simplemente como hacerlo desde el móvil o un emulador virtual de android con el SDK si no enseñarles como crear aplicaciones y desde nuestro IDLE de python de nuestro pc y ejecutarlo directamente en el SDK sin necesidad de transferir archivos, aunque hay ya documentación sobre esto, yo voy a crear uno propio con mas claridad y para que todos puedan verlo paso a paso.

primero tendremos que descargar el SDK de android en el siguiente link: http://developer.android.com/sdk/index.html


crear una carpeta en nuestra unidad C: que se llame android y dentro instalar nuestro SDK de tal manera que quedaría así:



una vez instalado vamos a crear nuestro android emulado, por lo que vamos a ejecutar nuestro SDK para poder instalar las APIS necesarias y ejecutamos sdk.exe y instalaremos por ejemplo las de la 3.0



le damos a install packages y después aceptamos la licencia y le damos a install.



una vez instaladas las apis nos vamos a crear nuestro emulador y ejecutamos avd.exe.
Le pulamos en new para crear un nuevo emulador y escogemos la versión que nos hemos descargado antes en este caso la 3.0 y lo demás lo podemos dejar así, creo que no es necesario decir nada mas en este punto, lo demás es intuitivo, como por ejemplo escoger el tipo de dispositivo que queremos utilizar...

device: tipo de dispositivo

target:versión del dispositivo

cpu/abi: tipo de cpu(la que mas les convenga)

memori ram: ram para el dispositvo (recomendaria entre 250 y 500)

internal storage: la memoria interna del dispositivo(se puede dejar así)

sd card: memoria de la sd(recomendaría entre 1000 y 1500 MIB)




una vez escogido como lo queremos pulsamos ok y esperamos que se cree, después lo seleccionamos y le damos a start y se nos abrirá otra ventana en la que seleccionamos scale display to real size para seleccionar el tamaño de nuestra pantalla del dispositivo y ponemos en screen size 7 que es un buen tamaño y pulsamos oky esperamos que se inicie



una vez arrancado nos dirigiremos a nuestro navegador y nos pondremos a instalar sl4a de android poniendo en google sl4a accediendo a la direccion que pone en la imagen



una vez dentro nos descargamos el archivo sl4a_r6 para la instalación del programa



cuando se descargue lo instalamos y procedemos a descargar python para android poniendo en google python for android y accediendo al siguiente enlace



y descargamos el archivo llamado pythonforandroid_r5 y lo instalamos
una vez instalado accedemos a el programa python for android y pulsamos en browse modules y nos llevara a una pagina web donde descargaremos el archivo pytbluez y seguidamente volveremos a entrar en python for android y le daremos a import modules e importaremos este modulo descargado, después pulsaremos en la parte de arriba install





en la imagen pone unistall por que yo ya lo tengo instalado pero vosotros tendréis que darle a install.

una vez hecho todo esto crearemos en nuestro escritorio una carpeta y la llamaremos android o python for android... como queráis.

Descargamos el archivo python_extra_r14 en nuestro pc desde la pagina de andtes de python for android y lo extraemos, después accedemos a la carpeta idlelib y todo lo que contenga lo copiamos a la carpeta de nuestro escritorio android, no copiaremos la carpeta si no todo lo de dentro, lo seleccionamos todo, copiamos y pegamos en la carpeta del escritorio, también el archivo android.py de la carpeta anterior.

Despues nos vamos a C:/WINDOWS/system32 y buscamos el archivo llamado cmd.exe y le damos a enviar a escritorio(acceso directo)



Cuando este en el escritorio lo cortamos y lo pegamos en nuestra carpeta android, una vez dentro pulsamos en nuestro acceso directo cmd.exe y le damos botón derecho y propiedades y modificamos donde dice iniciar en y ponemos la ruta de nuestra carpeta copiando la ruta de donde dice dirección en nuestra carpeta pegándola donde dice iniciar en



Despues copiamos el archivo adb.exe y adbwinapi.dll de la carpeta de donde instalamos el sdk en C:\Android\platform-tools copiamos estos dos archivos y los pegamos en C:\WINDOWS\system32 



Ya lo tenemos todo preparado para empezar y abrimos nuestro sl4a en el emulador, una vez dentro de sl4a pulsamos en el botón menú y después en VIEW el la ventana que se abre abajo




Despues en interpreters, y volvemos a darle en el botón menú y pulsamos start server



y pulsamos private y accedemos a ver que dirección va a usar para comunicarse con el pc





Ahora nos dirigimos a la carpeta que creamos en nuestro escritorio y ejecutamos el cmd.exe y ejecutamos lo siguiente:

1-adb forward tcp:9999 tcp:(direccion dispositivo android)
2-set AP_PORT=9999
3-idle.bat



se nos abrirá el idle de python y le damos a file y new windows



y ya podemos empezar a escribir en nuestro idle de python y  ver los resultados en nuestro emulador, por ejemplo veamos el típico mensaje de hola mundo poniendo lo siguiente:

import android
droid = android.Android()
droid.makeToast("hola mundo")




 REFERENCIAS
  •  
  • http://hackloper.blogspot.com.es/2013/11/programacion-android-con-python.html 
  • http://www.xatakandroid.com/sistema-operativo/que-es-android

 


PROGRAMACIÓN GOOGLE APLICACIONES ENGINE CON PYTHON

Historia

Google App Engine o también conocido más comúnmente como GAE o App Engine nos abre la infraestructura de producción de Google de forma gratuita como plataforma de desarrollo y hospedaje de aplicaciones web.

El servicio fue lanzado el 7 de abril del 2008 como un servicio de cloud pero a diferencia de otros servicios en la nube como Amazon Web Services o Azure Services Platform de Microsoft, el servicio ofrecido por Google es un servicio de Plataforma como Servicio y no de Infraestructura como Servicio.
El uso de la infraestructura de servicio de Google App Engine es completamente gratuita hasta un Gigabyte de almacenamiento y cinco millones de visitas mensuales. Si superamos esos límites entonces tendremos que pagar por más recursos a Google a unos precios bastante asequibles. Además podemos usar un dominio propio para la URL de nuestra aplicación o bien podemos usar un subdominio de appspot.com ofrecido de manera gratuita por Google al estilo de Heroku.
Recomiendo encarecidamente echarle un ojo a la página de cuotas para ver bien como va el tema de los servicios gratuitos y tal porque eso de los cinco millones de visitas es cuanto menos un número muy subjetivo.

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 si, con serias limitaciones. Entre dichos lenguajes se encuentran:
  • Groovy
  • JRuby
  • Scala
  • PHP
  • Clojure
  • Perl

En el siguiente enlace puedes encontrar un listado completo de implementaciones de diferentes lenguajes sobre JVM.
GAE soporta varios frameworks bajo Python como CherryPy, Pylons, Flask y Django 0.96 y 1.2. Además la misma Google ha desarrrollado un framework propio llamado —viva la originalidad que les caracteriza— webapp para aplicaciones web que van mejorando y actualizando. También existe un framework desarrollado específicamente para GAE y siguiendo —supuestamente— la filosofía de Django llamado GAE framework.
En cuanto a lo que respecta a Java, parece ser que es posible utilizar Grails de forma bastante sencilla y poco traumática utilizando para ello el Plugin para App Engine.

Restricciones

  • Las aplicaciones solo tienen permisos de lectura a los archivos del sistema de archivos. Para almacenar datos y archivos en modo lectura y escritura es necesario utilizar un sistema de archivos virtual sobre el DataStore.
  • Solo se puede ejecutar código a través de consultas HTTP
  • Las aplicaciones Java solo pueden usar el conjunto considerado seguro de clases del JRE estándar. ( Comprueba el Listado de clases)
  • Las aplicaciones no pueden crear nuevos hilos de ejecución
  • Los usuarios de Python pueden subir módulos para su uso en la plataforma pero no aquellos que están completamente desarrollados en C o Pyrex
  • El soporte para SSL solo está disponible par dominios *.appspot.com
  • Un proceso iniciado en el servicio para responder a una consulta no puede durar más de treinta segundos
  • No soporta sesiones persistentes, solo sesiones replicadas a las que además se les aplican ciertos límites.
  • No se pueden abrir sockets, por lo tanto, no se puede usar Twisted

El entorno de desarrollo

El SDK de Google App Engine viene con un entorno de desarrollo que puede ser ejecutado en local en nuestra máquina antes de subir los cambios a la nube y que simula completamente el entorno del App Engine. El SDK puede ser decargado de la página de descargas del proyecto.
Para ejecutar el servidor del entorno de desarrollo tan solo debemos ejecutar el script dev_appserver.py y como parámetro el path al directorio que contiene la aplicación. Por ejemplo en una consola de un sistema tipo UNIX:

genbeta@dev ~ $ python dev_appserver.py mi_app

El script dev_appserver.py admite numerosas opciones, mira la ayuda para verlas.

El entorno de ejecución de Python

App Engine ejecuta nuestras aplicaciones mediante un intérprete de Python 2.5.2 cargado en un entorno “sandboxed“. Toda aplicación programada para correr en la nube de Google debe incorporar un archivo de configuración llamado app.yaml donde se configuran diferentes aspectos de la aplicación y el entorno de ejecución.
El entorno de ejecución admite módulos de terceros programados íntegramente en Python y no deben incluir ninguna extensión C o cualquier otro código susceptible de ser compilado. El entorno incluye la librería estándar de Python a excepción de algunos módulos que han sido desactivados por seguridad como por ejemplo la escritura de disco o los sockets.
Otros módulos de Python han sido reemplazados o personalizados para hacerlos compatibles con App Engine. Un ejemplo de archivo de configuración app.yaml sería como el que sigue:
application: appdelaostia
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
  script: appdelaostia.py
El tema del entorno de ejecución de Python es bastante complejo y se escapa de la intención de esta introducción a Google App Engine, así que te recomiendo que revises la documentación del proyecto si estás interesado/a en saber más sobre él.

 

Introducción

Google App Engine es un servicio gratuito que ofrece Google desde el año 2008 para la producción y alojamiento de aplicaciones Web en lenguaje Python.
Este producto ofrece la posibilidad de añadir otros desarrolladores a la producción de nuestra aplicación, el único requisito es que los "Developers" sean usuarios registrados de Google para acceder al marco colaborativo.
La infraestructura "hard" de Google se dispone en una red no centralizada de estaciones con servidores menores que alojan y corren las distribuciones de todas sus aplicaciones, ya sea el buscador, su correo Gmail, los servicios de vídeo, Docs...
Desde mediados del 2008, Google permite utilizar esta infraestructura de manera gratuita para alojar nuestras propias aplicaciones, con las limitaciones lógicas de cualquier producto gratuito que pueden ser consultadas a la hora de registrarse y acceder al servicio, suficientes para exigencias de desarrollo en entornos educativos.
La escalabilidad y seguridad de los datos y aplicaciones están garantizados, tanto por las copias de seguridad residentes en stores lejanos como por la migración de servicio ante cualquier incidente como si de una red eléctrica de suministro en malla se tratara.

Lenguajes

Por el momento, las aplicaciones deben usar el lenguaje Python, no se descarta que en un futuro cercano aumente la disponibilidad a otros lenguajes conocidos.
Python es un lenguaje interpretado creado a principios de los 90 por Guido van Rossum, en la actualidad en nómina de Google y que está detrás de las herramientas de software el App Engine. Dispone de sitio oficial, http://www.python.org/, donde se puede encontrar todo acerca de sus características, versiones, descargas, documentación... está en inglés, también hay información interesante en castellano buscando con "Don Google" como http://pyspanishdoc.sourceforge.net/ y otros.

Versión

Google App Engine se basa en la versión Python 2.5., con un runtime limitado por cuestiones lógicas de seguridad, descartando así módulos de acceso al sistema de ficheros de bases de datos y servidor, prohibe conexiones TCP, llamadas de bajo nivel al sistema operativo, etc.

Framework

Todo proyecto de software en Internet necesita soporte de programas, bibliotecas y un lenguaje interpretado, esto es lo que se conoce como framework, el más popular open source en aplicaciones bajo Python es Django, su sitio oficial es www.djangoproject.com/, también encontramos en castellano http://django.es/. En el enlace “Documentación” del Google App Engine aparecen instrucciones de como usar Django específicamente para este servicio.
Google aporta su propio framework, sencillo y completamente integrado en el App Engine, es el framework "appweb".
Además de las APIs (interfaces de programación de aplicaciones) generales que trae la versión 2.5 de Python, webapp framework aporta 6 APIs específicas valiosas y útiles que permiten registrar y autenticar usuarios, acceder a la base de datos, enviar correos electrónicos, establecer comunicación entre aplicaciones mediante http, gestionar la caché de memoria y manipular y procesar imágenes.
El SDK (Kit de desarrollo de software) que proporciona Google acompaña un servidor para pruebas en local que imita a los servidores reales para testear las aplicaciones creadas antes de subirlas al remoto.
Este SDK incluye las librerías de las APIs disponibles y descritas anteriormente, el servidor local de pruebas y otras aplicaciones de gestión.

Manual

Presentamos a continuación, los pasos para trabajar con Google App Engine, la instalación de las herramientas necesarias, así como la creación y alojamiento en la "Cloud Google" de nuestras aplicaciones, este "how to" se ha realizado sobre XP.
1.        Descarga de Python 2.5 desde http://python.org, sección download. Hacemos click sobre la 2.5.4. que aparece al final de la lista

 2.        Instalación de Python siguiendo las instrucciones del instalador.


 .        Descarga el SDK de Google App Engine desde http://code.google.com/appengine/downloads.html

 




4. Durante al instalación, aceptamos las condiciones de la licencia y se elegirá el directorio de instalación y se seleccionará la casilla "Add product path to user PATH".





       
5.        Verificación de la instalación del SDK lanzando el servidor de pruebas con una aplicación de ejemplo que viene incluida.
Buscamos a través de nuestro explorador de archivos la carpeta guestbook y seleccionamos y copiamos la ruta completa desde la raíz (por ej: c:appenginedemosguestbook), abrimos una sesión en línea de comandos y tecleamos: dev_appserver.py c:appenginedemosguestbook.







Con esta instrucción lanzamos el servidor con la aplicación contenida en la carpeta que pasa como parámetro. Puede haber diferencias en la ruta y carpeta que contiene la aplicación de ejemplo guestbook según la subversión 2.5. de Python descargada.
Puede ser interesante descender en la consola de comandos por el árbol del directorio a través de instrucciones CHDIR hasta la carpeta inmediatamente superior a guestbook e invocarla desde ahí.
Ten en cuenta que el ejemplo también puede venir en ruta samplesguestbook o similar, según el paquete Python descargado, por eso lo conveniente de buscarla.
Otro aspecto que es importante para que funcione el servidor de pruebas es que cada uno sustituya c:appengine por la ruta de instalación propia del SDK. Si todo ha ido bien aparecerá la ventana siguiente.
Abriendo el navegador contra la dirección http://localhost:8080/ podremos ver la aplicación guestbook.







Siempre que queramos podremos cerrar el servidor pulsando Control + C en la consola, si vemos que tarda un poco podemos actualizar el navegador para el retorno del cursor al display de comandos. Puedes escribir algo en la caja y darle al botón Sign Guestbook apareciendo lo escrito en otra respuesta del Servidor.



6.        Vamos a programar ahora nuestra primera aplicación HelloWorld, para ello creamos una carpeta llamada engine que cuelgue directamente de C:/



7.        Creamos ahora nuestro primer script en Python, abrimos bloc de notas o wordpad (Inicio, Accesorios y Bloc de Notas) y picamos el siguiente código (nota: lo que está entre paréntesis y en cursiva son comentarios aclaratorios que no deben escribirse):



print 'Content-Type: text/html' (lo que viene es texto/html para la respuesta http)
print '' (espacio)
print '<HTML>'
print '<BODY>'
print '<MARQUEE><H1>Hola Mundo, Hello World!!!!</H1></MARQUEE>' (imprime Hola Mundo y Hello World con formato H1 y en movimiento por la etiqueta marquee)
print '</BODY>'
print '</HTML>'


Lo guardamos como hola.py en la carpeta engine.
El método print escribe la cadena de texto en la salida standar por lo que al ejecutarse en un servidor web se genera la escritura de un documento respuesta a una petición http.



8.        Lo siguiente es decirle al servidor cuando debe ejecutar este script, para ello abrimos un nuevo documento en bloc de notas y escribimos lo siguiente:

application: engine (id de la aplicación)
version: 1 (versión de la aplicación)
runtime: python (de momento Google solo deja Python)
api_version: 1 (versión API utilizada)
handlers: (manejadores o lista de URls aceptadas por nuestra aplicación con sus correspondientes scripts asociados)
- url: /.*
script: hola.py



Guardamos como app.yaml en la carpeta engine. Este archivo actúa como descriptor de despliegue asociando URl's con sus correspondientes scripts, como el fichero web.xml en desarrollos Java EE. El formato yaml es un formato de serialización de datos multilenguaje que pretende ser más sencillo y legible que el XML, puedes ampliar información en http://www.yaml.org.
Abrimos la consola de comandos, arrancamos el servidor de prueba y cargamos nuestra aplicación escribiendo desde C:> lo siguiente:
dev_appserver.py engine
A continuación abrimos el servidor de pruebas con el navegador y obtenemos lo siguiente.



9.        Activación del servicio.
Si es la primera vez que subimos una aplicación a Google, tendremos que activar el servicio, para ello accedemos a http://appengine.google.com/start.
Nos autenticamos con el usuario y contraseña de Google al igual que hacemos con Gmail, Docs...
Si aún no tienes una cuenta puedes crearla dando al enlace desde la página de login.

Pulsamos sobre crear una aplicación y después deberemos verificar la cuenta mediante el envío por parte de Google de un código por SMS a nuestro móvil sin coste alguno.
Como España no aparece en la lista de distribución, deberemos seleccionar Other (Not Listed) y poner el prefijo 34 delante del número de nuestro móvil.
Hacemos click en Send y al poco rato recibiremos un mensaje de texto en nuestro móvil con el código a introducir en la verificación de nuestra cuenta. Este proceso de verificación sólo hay que hacerlo al crear la primera aplicación de nuestra cuenta.


 













Si la verificación es correcta se nos pedirá el identificador y el título de la aplicación que vamos a crear, esto es importante porque el identificador definirá la URL con la que los usuarios accederán a nuestra aplicación. En nuestro caso engine, y al comprobar la disponibilidad nos encontramos con que ya está “cogida”, optamos entonces por una ID más exótica como “ajalospajaros”, procedemos a cambiar el nombre de la carpeta de trabajo engine por ajalospajaros y en el fichero app.yaml modificamos la id de la aplicación sustituyendo también engine por ajalospajaros. Finalmente la URL de acceso de los usuarios será http://ajalospajaros.appspot.com..


Hay que tener en cuenta que si no queremos este dominio genérico appspot.com y disponemos de cuenta en Google Apps (no confundir con Google App Engine, ver artículo del Observatorio Tecnológico:http://observatorio.cnice.mec.es/modules.php?op=modload&name=News&file=article&sid=653), podremos asociar a nuestras aplicaciones los dominios que gestionemos con dicha cuenta, cambiando las DNS y los registros que se te indiquen desde Google en tu panel de administración del dominio que tengas.

10.     Subida de la aplicación.

Abrimos la consola y escribimos lo siguiente desde C>: appcfg.py update ajalospajaros
Accedemos a la aplicación creada desde  http://ajalospajaros.appspot.com

 

 REFERENCIAS
  • http://recursostic.educacion.es/observatorio/web/eu/internet/recursos-online/735-google-app-engine
  • http://www.genbetadev.com/programacion-en-la-nube/introduccion-a-google-app-engine