domingo, 31 de enero de 2010

Crear una agenda en Python - Primera parte (diseño)

Vamos a crear una agenda de escritorio con Python y el framework de desarrollo gráfico wxPython. Este desarrollo lo vamos a hacer en varias fases. en este post detalla la primera, el diseño gráfico de la ventana que contendrá nuestra agenda. Para ello vamos a utilizar wxGlade, un diseñador (que no un IDE) de widgets para wxPython. La apariencia quedará mas menos parecida a la imagen que se presenta. Vemos que se trata de un frame al que le hemos variado la configuracion por defecto (no aparecen los botones de minimizar y maximizar). Dentro del frame hemos incluido un objeto contenedor, BoxSizer, de 2 espacios en horizontal. En el espacio de arriba se incluye el calendario, y en el de abajo una caja de texto multilínea, en donde anotaremos las notas que queramos para ese día.Hay que tener claro que en este primer post vamos a diseñar la pantalla. El cómo se van a guardar las notas por día, en qué sistema (que serán ficheros XML), la programación de los eventos, manejador de eventos, dónde y cómo se verá más adelante. Vamos a ver las cosas paso a paso. Aquí solo el diseño.

Como hemos dicho anteriormente, vamos a construir una agenda en Python, utilizando el framework gráfico wxPython. Para ello vamos a utilizar wxGlade, un diseñador (no un IDE) pra el framework wxPython.

Ejecutamos wxGlade. Seleccionamos la clase base wxFrame (nuestra apliación es solo una ventana, no está dentro de ningún MDI). Se le da el nombre que se quiera al frame.


A continuación hay que incluir un panel, para meter los widgets que queramos en la posición que más nos guste. En este caso añado un BoxSizer, en donde lo configuro con 2 slots (espacios) y horientación horizontal.

Nos tiene que quedar algo así:








Con wxGlade podemos movernos por todos los widgets de nuestro diseño, tanto en los contenedores BoxSizer como en el frame. En todos ellos podemos cambiar sus propiedades. En la siguiente captura de pantalla, mediante wxGlade: Tree, nos hemos ido a las propiedades de frame_1 (la ventana contenedora de todo), y hemos cambiado en sus propiedades, en la pestaña Common, ciertos valores, como los colores de fondo, el tooltip, tipo de letra, etc. Si hacemos click en Properties/Widget podemos configurar el estilo del frame (la ventana contenedora), cambiar nombre, icono, tal como se ve en la siguiente captura de pantalla:


(El icono que le se ha puesto ha sido uno que he encontrado en el Art Gallery de PowerBuilder 6.) Seguimos.

Ahora insertamos el objeto calendario en el slot de arriba del BoxSizer. Si nos vamos con el wxGlade: Tree hasta el objeto Calendar (haciendo Click), en Properties nos aparecen sus propiedades. Nos vamos a las pestaña Layout y cambiamos la alineación a wxEXPAND, para que se nos ajuste (queda mejor). En la pestaña Properties/Widget podemos indicar que la semana empiece por Lunes y no en Domingo.


En el slot de abajo del BoxSizer incluimos una caja de texto (TextCtrl). En las propiedades de este control, en la pestaña Widget, activamos la opción wxTE_MULTILINE, para escribir varias líneas. En la pestaña Layout activamos el alineamiento wx_EXPAND, y en el borde, activamos wxALL. Damos valores a Position, Proportion y Border, tal como se ve en la imagen.


Podemos guardar el diseño desde la ventana de wxGlade. En File / Save as podemos guardar el proyecto, como tipo de fichero wxg. También se nos da la posibilidad de guardarlo en XML. Siempre es bueno guardar el proyecto, para poder realizar cambios o mejoras.


Una vez salvado el proyecto podemos generar el código en Python. Para ello vamos a wxGlade: Tree, y haciendo click en Application aparecen las propiedades de la aplicación.


Como puede observarse, podemos generar de manera automática el código con la aplicación App, y la clase MyApp (evidentemente, podemos cambiar el nombre activando las casillas). Podemos generar el código en un solo fichero ó un fichero por cada clase (esto es interesante si lo que vamos a hacer es crear una librería de clases), y sobretodo el lenguaje al que queremos que se genere, en nuestro caso Python.
En Output path hay que indicar donde se genera el ó los ficheros .py del código. Una vez elegido, click en Generate Code, y ya lo tenemos.





Una vez generado el código podemos probarlo. Nos vamos al intéprete de comandos (CMD), y ejecutamos:
python nombre_proyecto.py. En nuestro caso:
python agenda_widget.py.

Como se muestra en la imagen, funcionar, funciona, pero no ha quedado muy estético que digamos. Lo bueno que tiene trabajar con diseñadores, es que te facilitan este tipo de contratiempos. Para solucionarlo, podemos volver a wxGlade, y cambiar en el proyecto, en las propiedades del frame, su propiedad de tamaño (size), y cambiarlo por 200, 300. El resultado de ese cambio se refleja en la siguiente imagen:



Como se observa, no es difícil, en absoluto, crear diseños de pantallas en Python, gracias a herramientas como wxGlade. Hay otras, como PythonCard, o incluso Boa Constructor (este ya no es un diseñador, es un IDE en toda regla, que permite diseño), pero para empezar, wxGlade es una herramienta más que válida.

Es muy importante que se mire con detenimiento el código que genera wxGlade en el fichero .py, para poder entender el framework de wxPython.

En siguientes posts veremos el funcionamiento del programa.

viernes, 29 de enero de 2010

Programa de loterías en Python


A continuación os presento un programa muy sencillo, escrito en Python, para la generación aleatoria de combinaciones para juegos de azar. Lo he probado en Windows, así que en Linux no creo que haya problemas. He utilizado el módulo random para crear los números pseudoaleatorios. Hay varias formas de hacerlo. Yo he utilizado el método uniform, que da entre el rango que especifiquemos un número real. Como se verá en el código lo que he hecho ha sido un casting con int(), para quedarme con la parte entera, que es la que me interesa. Por supuesto el código tiene muchas mejoras, pero lo importante es ver el funcionamiento, y sobretodo lo sencillo que es programar en Python. Si he escrito esta noche este programa es porque es Viernes, no me ha tocado el Euromillones.

# Progama para generar secuencias de loterías.
# Escrito por Ángel Luis García García en Python 2.5.4

import random, os

def combinacion(num_ele, total_num, repetir = False,
ordenar_resultado = True):

elementos = []
if num_ele > total_num and not repetir:
print "No puedes sacar más valores de los que ya tienes!"
return

aux = num_ele
while aux > 0:
numero = int(random.uniform(1,total_num))
if repetir:
elementos.append(numero)
aux = aux - 1
else:
if elementos.count(numero) == 0:
elementos.append(numero)
aux = aux - 1

if ordenar_resultado:
elementos.sort()
print elementos

def menu():
print '''

================================
MENU PRINCIPAL
================================

Este programa genera combinaciones
de juegos de azar. Elige el juego
que más te guste.

1) Lotería primitiva
2) Euromillones
9) Salir

'''

opcion = raw_input("")
return opcion

def aplicacion():
os.system('cls')
opcion = ""
while opcion != "9":
opcion = menu()
if opcion == "1":
print ""
print "Combinación para Lotería Primitiva: "
combinacion(6,49)
print ""

if opcion == "2":
print ""
print "Euromillones"
print "Combinación ganadora: "
combinacion(5,50)
print "Estrellas: "
combinacion(2,9)
print ""

# Ejecutamos el programa.
aplicacion()

Java - Clase String

Clase String

En java no existen primitivas que permitan almacenar una cadena de caracteres. Para ello se utilizan objetos de la clase String.

Las variables que almacenan las referencias a un objeto se denominan variables de referencia. Para definir una variable que se utilice como referencia a un objeto se pone a su izquierda el nombre de la clase a la que pertenecerá el objeto. Por Ejemplo: String nombre ;

Normalmente, en Java, para instanciar un objeto a partir de una clase se necesita el modificador new, pero no ocurre en los objetos de la clase String, y en algunas otras excepciones, las cuales se construyen automáticamente en el momento que toman el primer valor. Lo bueno de esto es que se aprovechan varios métodos de la clase String para realizar operaciones sobre cadenas de caracteres, como por ejemplo, extraer determinados caracteres, devolver su longitud, etc.

Veamos todo esto con el siguiente ejemplo.

class prueba3 {

public static void main(String arg[]) {

// Se instancia el objeto de la clase String de forma automática, y hacemos referencia a él a través de la variable frase.

String frase ;

// Damos valor a la variable frase.

frase = " En un lugar de la Mancha, etc. " ;

// Operamos sobre el objeto, a través de sus métodos.

// Mostramos contenido de frase.

System.out.println("Contenido de frase: " + frase) ;

// Vamos a quitar todos los espacios en blanco.

frase = frase.trim() ;

// Mostramos contenido de frase.

System.out.println("Contenido de frase sin espacios en blanco: " + frase) ;

// Mostramos contenido de frase.

System.out.println("Posición de la palabra Mancha: " + frase.indexOf("Mancha")) ;

// Ponemos la frase en mayúsculas.

frase = frase.toUpperCase() ;

// Mostramos contenido de frase.

System.out.println("Contenido de frase en mayúsculas: " + frase) ;

}

}

La clase String tiene muchos más métodos de los que hay aquí. Todo es cuestión de ir a investigar.

jueves, 28 de enero de 2010

Java - Variables primitivas

Variables en Java

Restricciones en los nombres de las variables

1) El primer carácter debe ser una letra, el carácter “_” ó el carácter “$”.

2) No se pueden utilizar palabras reservadas de Java.

3) No pueden contener espacios en blanco.

4) Hay CASE SENSITIVE, es decir, se distingue entre mayúsculas y minúsculas. Así la variable nombre es diferente a la variable NOMBRE.

Variables primitivas

· Tipo Entero:

byte (-128 a 127), byte

short (-32768 a 32767), entero corto

int (-2^31 a (2^31) – 1), entero

long (-2^63 a (2^63) – 1, entero largo

· Tipo Real:

float (±3.4x10^38 a ±3.4x10^-45), real simple precisión

double (±1.8x10^308 a ±4.9x10^-324), real doble precisión

· Tipo booleano:

true (verdadero)

false (falso)

· Tipo carácter:

char. Los caracteres se codifican según el formato UNICODE (16 bits, al contrario que ASCII, que solo usa 8 bits). A continuación se presentan los valores especiales del tipo char, esto es, los caracteres de control ó secuencias de escape:

‘\n’ Línea siguiente

‘\t’ Tabulador

‘\b’ Retroceso

‘\r’ Retorno de carro

‘\’’ Comillas simples

‘\\’ Contrabarra

‘\”’ Comillas dobles

‘\xxx’ Carácter en octal.

‘\0’ Carácter nulo (null)

‘\uxxxx’ Carácter en hexadecimal Unicode

Expresión de valores numéricos

Los valores numéricos pueden aparecer representados en base decimal, hexadecimal ú octal. En Java, cuando un valor de tipo entero aparece sin ninguna terminación especial, se trata de un int. Si un valor lleva decimales y sin terminación especial, se trata de un double. Las terminaciones especiales son las siguientes:

L ó l, entero largo. Ejemplo: long a = 400L

F ó f, flotante ó real de simple precisión. Ejemplo: float a = 5.443F

El casting es un procedimiento para transformar una variable primitiva de un tipo a otro, o transformar un objeto de una clase a otra clase siempre y cuando haya una relación de herencia entre ambas. Pasar de byte a short, de short a int, de byte a int, … es automático siempre y cuando el entero a convertir no supere el rango del tipo convertido; en definitiva, pasar de una variable primitiva de un tipo de la cadena de la siguiente línea a otra que se encuentre a su derecha es automático. Esto es:

byte-->short-->int-->long-->float-->double

Así, por ejemplo, si a una variable de tipo long se le asigna un valor entero perteneciente al rango de int, promociona automáticamente a long y no es necesario casting. En cambio, si se le pasa un entero que se sale fuera del rango de int, es necesario realizar un casting para que la llamada al método no provoque error al compilar. Veámoslo con el siguiente ejemplo. Si una variable de tipo short, llamada var_short queremos asignarle el valor de 30000, no se podría, ya que var_short tiene un rango de valores posibles de -32768 a 32767. Para ello habría que hacer un casting, del siguiente modo: var_short = (short)30000.

Ejemplo de variables primitivas:

class prueba2 {

public static void main(String arg[]) {

System.out.println("Ejemplo de variables primitivas") ;

// Declaramos variables

byte var_byte ;

short var_short ;

int var_int ;

long var_long ;

float var_float ;

double var_double ;

boolean var_true, var_false ;

char var_char ;

// Damos valores a las variables declaradas.

var_byte = 120 ;

var_short = 30000;

var_int = 50000 ;

var_long = 3000000000L ;

var_double = 4.56E+9D ;

var_float = 4.67F ;

var_true = true ;

var_false = false ;

var_char = 'h' ;

// Mostramos valores por pantalla.

System.out.println("Tipo byte. Valor de var_byte: " + var_byte) ;

System.out.println("Tipo short. Valor de var_short: " + var_short) ;

System.out.println("Tipo int. Valor de var_int: " + var_int) ;

System.out.println("Tipo long. Valor de var_long: " + var_long) ;

System.out.println("Tipo float. Valor de var_float: " + var_float) ;

System.out.println("Tipo double. Valor de var_double: " + var_double + " NOTA: 4.56E+9D equivale a 4.59 por 10^9") ;

System.out.println("Tipo boolean. Valor de var_true: " + var_true) ;

System.out.println("Tipo boolean. Valor de var_false: " + var_false) ;

System.out.println("Tipo char. Valor de var_char: " + var_char) ;

System.out.println("Incluimos 3 saltos de línea" + '\n' + '\n' + '\n') ;

}

}