9

    MAR 2017

    Escribi un programa para que me sume todos los numeros naturales menores a N, siendo N ingresado por teclado, por ejemplo si ingresamos 4 calcula la suma de (1 + 2 + 3 +4 = 10). Pero resulta que cometi un error por lo que el programa devuelve mal el resultado. El desafio consiste en encontrar el error en mi codigo para que el programa funcione correctamente. C++ #include <iostream> using namespace std; int sumatoria(int limite) { int suma = 0; for (int i = 1; i < limite; i++) { suma+=i; } return suma; } int main(int argc, const char *argv[]) { int tope; std::cout << "Ingrese tope: " << std::endl; std::cin >> tope; std::cout << sumatoria(tope) << std::endl; return 0; } 123456789101112131415161718192021 #include <iostream> using namespace std; int sumatoria(int limite){    int suma = 0;    for (int i = 1; i < limite; i++) {        suma+=i;    }    return suma;} int main(int argc, const char *argv[]){    int tope;    std::cout << "Ingrese tope: "  << std::endl;    std::cin >> tope;    std::cout << sumatoria(tope) << std::endl;    return 0;}  




    5

    NOV 2016

    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: ZSH apt-get install python python-wxaddons 1 apt-get install python python-wxaddons Veamos ahora el codigo fuente de nuestro primer programa: Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" 12345 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" 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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): 123456 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):  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__ ()). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) 12345678 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title) 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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent 123456789 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent  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). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): self.Show(True) 123456789101112 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        self.Show(True)  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». Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') 12345678910111213141516 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'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̶1;, 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). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 1234567891011121314151617 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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: C++ chmod u+x programa.py 1 chmod u+x programa.py Luego invoquelo de la siguiente manera: ZSH ./programa.py 1 ./programa.py 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)). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.SetSizerAndFit(grilla) self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 12345678910111213141516171819 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.SetSizerAndFit(grilla)        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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̶1;Enter text here.̶1;). 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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:") grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) self.SetSizerAndFit(grilla) self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 123456789101112131415161718192021 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        self.SetSizerAndFit(grilla)        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:") grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) self.SetSizerAndFit(grilla) self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 1234567891011121314151617181920212223 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython"class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):         wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))         self.SetSizerAndFit(grilla)        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:") grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) self.etiqueta = wx.StaticText(self,-1,label=u'Hola !') self.etiqueta.SetBackgroundColour(wx.BLUE) self.etiqueta.SetForegroundColour(wx.WHITE) grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND ) self.SetSizerAndFit(grilla) self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 123456789101112131415161718192021222324252627282930 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):        wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))        self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')        self.etiqueta.SetBackgroundColour(wx.BLUE)        self.etiqueta.SetForegroundColour(wx.WHITE)        grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )        self.SetSizerAndFit(grilla)        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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). Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:") grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) self.etiqueta = wx.StaticText(self,-1,label=u'Hola !') self.etiqueta.SetBackgroundColour(wx.BLUE) self.etiqueta.SetForegroundColour(wx.WHITE) grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND ) grilla.AddGrowableCol(0) self.SetSizerAndFit(grilla) self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 12345678910111213141516171819202122232425262728293031 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):        wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))        self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')        self.etiqueta.SetBackgroundColour(wx.BLUE)        self.etiqueta.SetForegroundColour(wx.WHITE)        grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )        grilla.AddGrowableCol(0)        self.SetSizerAndFit(grilla)        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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̶1;).   Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:") grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) self.etiqueta = wx.StaticText(self,-1,label=u'Hola !') self.etiqueta.SetBackgroundColour(wx.BLUE) self.etiqueta.SetForegroundColour(wx.WHITE) grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND ) grilla.AddGrowableCol(0) self.SetSizerAndFit(grilla) self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y ); self.Show(True) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 1234567891011121314151617181920212223242526272829303132 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):        wx.Frame.__init__(self,parent,id,title)        self.parent = parent        self.initialize()    def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))        self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')        self.etiqueta.SetBackgroundColour(wx.BLUE)        self.etiqueta.SetForegroundColour(wx.WHITE)        grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )        grilla.AddGrowableCol(0)        self.SetSizerAndFit(grilla)        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y );        self.Show(True) if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS_ENTER) grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton) self.etiqueta = wx.StaticText(self,-1,label=u'Hola !') self.etiqueta.SetBackgroundColour(wx.BLUE) self.etiqueta.SetForegroundColour(wx.WHITE) grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND ) grilla.AddGrowableCol(0) self.SetSizerAndFit(grilla) self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y ) self.Show(True) def SiCliqueaBoton(self,event): self.etiqueta.SetLabel(self.entrada.GetValue() + "Cliqueo el boton!") def SiPulsaEnter(self,event): self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!") if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 1234567891011121314151617181920212223242526272829303132333435363738 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):        wx.Frame.__init__(self,parent,id,title)        self.parent = parent         self.initialize()     def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS_ENTER)        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))        boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton)        self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')        self.etiqueta.SetBackgroundColour(wx.BLUE)        self.etiqueta.SetForegroundColour(wx.WHITE)        grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND )        grilla.AddGrowableCol(0)        self.SetSizerAndFit(grilla)        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )        self.Show(True)     def SiCliqueaBoton(self,event):        self.etiqueta.SetLabel(self.entrada.GetValue() +  "Cliqueo el boton!")     def SiPulsaEnter(self,event):        self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!") if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop()  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. Python #!/usr/bin/python try: import wx except ImportError: raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,id,title) self.parent = parent self.initialize() def initialize(self): grilla = wx.GridBagSizer() self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS_ENTER) grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND) self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter) boton = wx.Button(self,-1,label="Pulsame !") grilla.Add(boton, (0,1)) boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton) self.etiqueta = wx.StaticText(self,-1,label=u'Hola !') self.etiqueta.SetBackgroundColour(wx.BLUE) self.etiqueta.SetForegroundColour(wx.WHITE) grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND ) grilla.AddGrowableCol(0) self.SetSizerAndFit(grilla) self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y ) self.entrada.SetFocus() self.entrada.SetSelection(-1,-1) self.Show(True) def SiCliqueaBoton(self,event): self.etiqueta.SetLabel(self.entrada.GetValue() + "Cliqueo el boton!") self.entrada.SetFocus() self.entrada.SetSelection(-1,-1) def SiPulsaEnter(self,event): self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!") self.entrada.SetFocus() self.entrada.SetSelection(-1,-1) if __name__ == "__main__": app = wx.App() frame = simpleapp_wx(None,-1,'Mi aplicacion') app.MainLoop() 1234567891011121314151617181920212223242526272829303132333435363738394041424344 #!/usr/bin/pythontry:     import wx except ImportError:    raise ImportError,"Se requiere el modulo wxPython" class simpleapp_wx(wx.Frame):    def __init__(self,parent,id,title):        wx.Frame.__init__(self,parent,id,title)        self.parent = parent         self.initialize()     def initialize(self):        grilla = wx.GridBagSizer()        self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS_ENTER)        grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)        self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter)        boton = wx.Button(self,-1,label="Pulsame !")        grilla.Add(boton, (0,1))        boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton)        self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')        self.etiqueta.SetBackgroundColour(wx.BLUE)        self.etiqueta.SetForegroundColour(wx.WHITE)        grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND )        grilla.AddGrowableCol(0)        self.SetSizerAndFit(grilla)        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )        self.entrada.SetFocus()        self.entrada.SetSelection(-1,-1)         self.Show(True)     def SiCliqueaBoton(self,event):        self.etiqueta.SetLabel(self.entrada.GetValue() +  "Cliqueo el boton!")        self.entrada.SetFocus()        self.entrada.SetSelection(-1,-1)      def SiPulsaEnter(self,event):        self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!")        self.entrada.SetFocus()        self.entrada.SetSelection(-1,-1)  if __name__ == "__main__":    app = wx.App()    frame = simpleapp_wx(None,-1,'Mi aplicacion')    app.MainLoop() 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/




    12

    NOV 2015

    Charlando con un amigo en el IRC sobre la posibilidad del anonimato en la red no pudimos llegar a una conclusion aceptable, si recuerdan el año pasado  una charla de la universidad de  Carnegie Mellon sobre como descifrar el software de anonimato Tor fue abruptamente sacada de la agenda de la conferencia de “hackers̶1; Black Hat el año pasado, la comunidad de seguridad se preguntaba en ese entonces  si la investigación fue  entregada en secreto a agencias de la ley de los Estados Unidos quienes como sabemos buscan anular la ocultación de la los usuarios anónimos de Internet. Ahora la organización  Tor Proyect dice que cree que el FBI usó la tecnica de ataque de Carnegie Mellon  y les pagó generosamente por el privilegio. El Proyecto Tor en la tarde del miércoles envió a WIRED una declaración de su director Roger Dingledine acusando directamente Carnegie Mellon de proporcionar secretamente  sus investigaciones de como vulnerar TOR a el FBI a cambio de un pago de “por lo menos $ 1 millón de dolares.̶1;  




    30

    AGO 2014

    El 15 de agosto pasado se ha completado la nueva implementacion del lenguaje de programación C++y se publicará a finales de este año. Más allá de C ++ 14, el comité contempla producir otro C ++ estándar en aproximadamente 2017. Eso no quiere decir que no pasa nada en el ínterin, sin embargo, debido a que actualmente tiene ocho (8) Especificaciones técnicas separadas en marcha, varios de los cuales están en proyecto de publicar en 2014 y 2015. A partir de 2012, el comité ha hecho la transición a un modelo de “desacoplado̶1; donde las principales piezas de trabajo pueden progresar independientemente del estándar sí mismo y se entrega como del TS por separado. Los proveedores pueden optar por implementarlos, y la comunidad pueden adquirir experiencia con el std::experimental de cada función. Esto nos permite aprender y adaptarse diseño de cada característica basada en la experiencia antes de que se incluye formalmente en una versión futura de la actual estándar C++.




    28

    AGO 2014

    Las lecciones aprendidas a partir de la recuperación de datos y restauración de los sistemas después de eventos climáticos severos, nos ayudan a estar preparados para contar con estrategias de recuperación de desastres. Fuente: DiarioTI  




    18

    ABR 2017

    Equipo Organizador Usuarios de Software Libre de Jujuy (USL Jujuy) Lugar y Horario Lugar Biblioteca Pupular Bartolome Mitre R11; Tilcara R11; Rivadavia 388 Horarios Mañana: 09:30 a 13:15 hs. Tarde: 15:00 a 19:30 hs. Actividades y Conferencias En la mañana 9:30 Acreditaciones 10:00 a 10:30 ==> Introducción al Software Libre R11; Débora Analia Sudañez R11; Comunidad USLJujuy 10:30 R11; 11:15 ==> ¿Por qué programar con software libre? R11; David Rearte R11; Ricardo Vilte -Augusto Caligares 11:30 R11; 12:15 ==> Red Chaski en La Quiaca R11; Nicolás Pertierra R11; Atalaya Sur 12:30 R11; 13:15 ==> Arreglando el desorden con Git y GitFlow R11; Abel Antonio Cerda En la tarde Los stands estarán disponibles desde horas 15:00 a 19:30 de manera que todo el público pueda acceder a cada actividad cuando desee y el tiempo que requiera Prototipos rápidos con Arduino Desarrollo de aplicaciones mobile Radios Libres Install Fest Mini Stands Servidor owncloud para biblioteca Pc Programas Libres RetroPi Arcade




    12

    ABR 2017

    Les traigo acá un breve y practico tutorial de como funciona y como usar el bucle FOR en c++. Incluye dos alternativas usado con iteradores. Espero que le guste y hasta la próxima entrega.




    11

    ABR 2017

    Estamos cercanos a los dias de la celebración de Pascuas, leyendo sobre como se implementa la fecha en que cae, se me ocurrió escribir el siguiente desafío. El Computus es el cálculo de la fecha de Pascua. A principios del siglo IV había en la cristiandad una gran confusión sobre cuándo había de celebrarse la Pascua cristiana o de Pascua de Resurrección, con motivo del aniversario de la resurrección de Jesús de Nazaret. Habían surgido en aquel momento numerosas tendencias o grupos de practicantes que utilizaban cálculos propios. (Wikipedia: Calculo de Pascua) Escribí mi versión en C++ para que sirva de guía y se animen a escribirlo en otros lenguajes o a mejorar este codigo. C++ #include <iostream> using namespace std; const int M = 24; const int N = 5; void calcular_pascua(int); int main() { int anio; std::cout << "Año: " << std::endl; std::cin >> anio; calcular_pascua(anio); return 0; } void calcular_pascua(int anio) { int a,b,c,d,e,pascua; cout << "Ingrese año:"; cin >> anio; a = anio % 19; b = anio % 4; c = anio % 7; d = (19*a+M) % 30; e = (2*b+4*c+6*d+N) % 7; if (d+e < 10) { pascua = d+e+22; cout << "La pascua sera el " << pascua << " de marzo" << endl; } if (d+e > 9) { pascua = d+e-9; cout << "La pascua sera el " << pascua << " de abril" << endl; } } 123456789101112131415161718192021222324252627282930313233343536373839 #include <iostream> using namespace std; const int M = 24;const int N = 5; void calcular_pascua(int); int main(){    int anio;    std::cout << "Año: " << std::endl;    std::cin >> anio;    calcular_pascua(anio);    return 0;} void calcular_pascua(int anio){    int a,b,c,d,e,pascua;    cout << "Ingrese año:";    cin >> anio;    a = anio % 19;    b = anio % 4;    c = anio % 7;    d = (19*a+M) % 30;    e = (2*b+4*c+6*d+N) % 7;    if (d+e < 10)    {        pascua = d+e+22;        cout << "La pascua sera el " << pascua << " de marzo" << endl;    }    if (d+e > 9)    {        pascua = d+e-9;        cout << "La pascua sera el " << pascua << " de abril" << endl;    }}   :




    7

    ABR 2017

    Continuando con los tutoriales hoy le traigo un video de como usar la estructura de control de repetición por contador While. Espero les guste, a continuación el video y el código.   C++ #include <iostream> using namespace std; int main(int argc, const char *argv[]) { int contador = 0; while (contador <= 10) { std::cout << contador << std::endl; contador++; } return 0; } 12345678910111213 #include <iostream> using namespace std; int main(int argc, const char *argv[]){    int contador = 0;    while (contador <= 10) {        std::cout << contador << std::endl;        contador++;    }    return 0;}  




    30

    MAR 2017

    En este caso se trata de una utilidad on-line para la configuracion de los colores de las terminales Unix. Terminal Sexy Recomendable para crear archivos de configuracion tales como Xresourses.