Programación en PYTHON (PDF Download Available)

February 5, 2018 | Author: Anonymous | Category: Python
Share Embed


Short Description

Dec 2, 2017 - Full-text (PDF) | Programación en PYTHON | ResearchGate, the professional network for scientists. ... Ejer...

Description

Programación en P YTHON I. Arregui, A.M. Ferreiro & J. A. García Departamento de Matemáticas, Universidad de La Coruña

https://sites.google.com/site/lppython/

Abril, 2012 Aula de Formación Informática Universidad de A Coruña

Índice general

Introducción a P YTHON Programación en P YTHON Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

P YTHON

I

Es el lenguaje de programación más utilizado por la empresa Google

P YTHON

I

Es el lenguaje de programación más utilizado por la empresa Google

I

Declarado lenguaje del año 2007 por TIOBE: http://developpers.slashdot.org/article.pl?sid=08/01/09/1819221

P YTHON

I

Es el lenguaje de programación más utilizado por la empresa Google

I

Declarado lenguaje del año 2007 por TIOBE: http://developpers.slashdot.org/article.pl?sid=08/01/09/1819221

I

Séptimo lenguaje de programación más popular (julio de 2009): http://www.tiobe.com/

Índice general

Introducción a P YTHON Programación en P YTHON Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

Bibliografía I

M ARK L UTZ. Programming Python. O’Reilly, 2006

I

J. J. G ÓMEZ C ADENAS , J. B URGUET C ASTELL. Curso de cálculo numérico. U. de Valencia, 2004

I

N. R APPIN , R. D UNN. wxPython in Action. Manning, 2006

I

C. P RECORD. wxPython 2.8 Application Development Cookbook. Packt Publishing, 2010

I

R. C OPELAND. Essential SQLAlchemy. Mapping Python to Databases. O’Reilly Media, 2008

I

http://www.python.org/doc

I

http://docs.python.org/index.html

I

http://www.diveintopython.org/

I

http://docs.sqlalchemy.org/en/latest/index.html

I

http://www.wxpython.org/

I

http://wiki.wxpython.org/

Para realizar las prácticas de este curso necesitaremos instalar las siguientes librerías: 1. P YTHON (versiones recientes, 2.5.x ó 2.6.x ó 3.x) www.python.org 2. W X P YTHON (envoltura de WxWidgets para Python), para la parte de GUI’s, Interfaces gráficos www.wxpython.org 3. S QL A LCHEMY (Mapeo Objeto Relacional u “Object Relation Manager” (ORM)), ”permite representar en una clase u objeto una tabla de una base de datos” http://www.sqlalchemy.org/ 4. I-P YTHON∗ : consola avanzada de Python http://ipython.org/ En cada una de estas páginas se indica la forma de instalarlos desde cero y las dependencias que necesitaremos para compilarlos.

En general, cualquier paquete de P YTHON incluye un script de instalación y se instala sin más que teclear desde línea de comandos: $ python setup.py install La mayoría de los paquetes anteriores está disponible para las principales plataformas L INUX en .rpm (R ED H AT /F EDORA /M ANDRIVA /C ENT OS) ó .deb (D EBIAN / U BUNTU). La instalación es automática en Ubuntu (>= 7.10) con tan solo seleccionar estos paquetes en el Synaptic o mediante apt-get.

En general, cualquier paquete de P YTHON incluye un script de instalación y se instala sin más que teclear desde línea de comandos: $ python setup.py install La mayoría de los paquetes anteriores está disponible para las principales plataformas L INUX en .rpm (R ED H AT /F EDORA /M ANDRIVA /C ENT OS) ó .deb (D EBIAN / U BUNTU). La instalación es automática en Ubuntu (>= 7.10) con tan solo seleccionar estos paquetes en el Synaptic o mediante apt-get. También es posible instalar todos estos paquetes en W INDOWS y M AC OSX, para los que existen binarios ya compilados. I

E NTHOUGHT proporciona un instalador para W INDOWS y M AC OSX que instala todos los paquetes necesarios para realizar las prácticas de este curso. La versión proporcionada no siempre es la más reciente en todos los paquetes. Puede bajarse en la dirección: http://www.enthought.com/products/getepd.php

I

P YTHON XY: proporciona un instalador para W INDOWS y L INUX que instala todos los paquetes necesarios. Puede descargarse de, http://www.pythonxy.com/download.php

Introducción a P YTHON Generalidades Variables y espacio de trabajo Tuplas y listas Diccionarios Copia de objetos Programación en P YTHON Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

P YTHON Algunas características: I Python es un lenguaje de programación de propósito general (diseñado por el holandés Guido van Rossum, a finales de los 80). I Programación estructurada y clara (el tabulador es parte del propio lenguaje). I Alta productividad: gran velocidad de desarrollo. I Soporta múltiples paradigmas de programación: orientada a objetos, estructurada, funcional. I Portable (Linux, Windows, Mac OSX). I Interpretado, dinámico, fuertemente tipado, gestión de memoria automática. I Lenguaje sencillo de aprender. I Dispone de una amplia Biblioteca estándar (conjunto de módulos incluidos en la propia distribución de Python). http://docs.python.org/library/ I Fácil de extender; enlace con C/C++ (SWIG, Weave, CPython), .NET (IronPython), CORBA, Java (Jython), F ORTRAN (f2py)... I Disponibles un gran número de módulos.

E L Z EN DE P YTHON >>>import this I Bello mejor que feo. I Explícito es mejor que implícito. I Simple es mejor que complejo. I Complejo es mejor que complicado. I Plano es mejor que anidado. I Disperso es mejor que denso. I La legibilidad cuenta. I Los casos especiales no son tan especiales como para quebrantar las reglas. I Aunque lo práctico gana a la pureza. I Los errores no deberían dejarse pasar. I A menos que hayan sido silenciados explícitamente. I Frente a la ambigüedad, rechaza la tentación de adivinar. I Debería haber una -y preferiblemente sólo una- manera obvia de hacerlo. I Aunque esa manera pueda no ser obvia al principio a menos que usted sea holandés. I Ahora mejor que nunca. I Aunque nuca es a menudo mejor que ya mismo. I Si la implementación es difícil de explicar, es una mala idea. I Si la implementación es fácil de explicar, puede que sea una buena idea. I Los espacios de nombres (namespaces) son una gran idea. ÂaHagan ˛ esas cosas!

P YTHON Algunas aplicaciones:

I

desarrollo web (Zope, Plone, Django, webpy, TurboGears, Pylons, e-mail, RSS, etc.) acceso a bases de datos (pyodbc, mysqldb, etc.)

I

interfaces gráficas de usuario (Tk/Tcl, WxWidgets, Qt, FLTK, Gtk, ...)

I

juegos (PyGame, PyKyra)

I

aplicaciones de red: cliente–servidor (Twisted Python), ...

I

representación grÃafica: ˛ gráficos 2d (M AT P LOT L IB), C HACO), visualización 3d (VTK, MayaVi), etc.

I

cálculo científico (N UM P Y, S CI P Y).

I

procesamiento de XML, HTML,

I

Funciona sobre plataformas L INUX / U NIX, W INDOWS, Mac, JVM (J YTHON), ... y existen implementaciones sobre la serie 60 de Nokia!

>Dónde se usa P YTHON? I

en G OOGLE, donde es uno de los tres lenguajes oficiales de desarrollo, junto con C / C++ y JAVA. Desarrollo esponsorizado por G OOGLE.

I

en YOU T UBE

I

en B IT T ORRENT

I

en el mundo de la animación: D REAM W ORKS A NIMATION, P IXAR, I NDUSTRIAL L IGHT & M AGIC,

I

el instalador de R ED H AT / FE DORA (A NACONDA) está escrito en P YTHON

I

ROCKS C LUSTER es una distribución L INUX de clustering implementada sobre C ENT OSL INUX, que utiliza scripts en P YTHON para la gestión de nodos, de usuarios, ...

I

Los Alamos National Laboratory y Sandia National Laboratories han desarrollado P Y T RILINOS, PARAV IEW, ...

I

S ALOME y A BAQUS (códigos de CAD y CAE) utilizan P YTHON como lenguaje de script estándar

I

la Universidad de Washington ha desarrollado SAGE, una herramienta para la docencia de las matemáticas

I

Casos de éxito: http://www.python.org/about/success/

>Por qué está P YTHON tan extendido? I

Facilidad para desarrollar envolturas que permitan manejar desde P YTHON prácticamente cualquier software escrito en C / C++ y F ORTRAN I I

de forma manual, utilizando la P YTHON C API mediante generadores automáticos: SWIG, SIP, Weave, f2py

I

Casi cualquier librería de software libre tiene su correspondiente envoltura que permite accederla desde P YTHON.

I

Hay una documentación muy completa I I

I

en la ventana de comandos, mendiante la función help en las webs de los distintos proyectos

La comunidad de P YTHON es muy activa I I I

S CI P Y Conference, anual en EEUU y Europa P Y C ON (en EEUU) y E URO P YTHON, conferencias anuales en el SIAM Anual Meeting 2008 hubo una sesión especial sobre el uso de P YTHON en el ámbito científico http://meetings.siam.org/sess/dsp_programsess.cfm?SESSIONCODE=7369

Editores y ventanas de comandos Editores: I spe (http://pythonide.blogspot.com/) I eric (http://www.die-offenbachs.de/eric/index.html) ambos disponen de gestor de directorios, gestor de ayudas, debugger I I

I

gedit, vi, emacs, . . . Eclipse+plugin para Python (http://www.eclipse.org/ y http://pydev.org/) Lista completa de editores, GUIs e IDEs: wiki.python.org/moin/PythonEditors

CUIDADO con los tabuladores ! (por convenio un tabulador debe ser de 4 espacios) El tabulador forma parte de la sintaxis del lenguaje; en lugar de delimitar los bloques de código mediante llaves, P YTHON utiliza la indentación Ventanas de comandos: $ python $ ipython [-pylab] [-wthread] La segunda permite los comandos ls, pwd, cd .., . . .

Inicio de P YTHON En L INUX, al escribir $ python se muestra el intérprete de Python:

>>>

Algunas utilidades: ↑ ó ↓: recupera comando(s) anterior(es) Inicio: se coloca en principio de línea Fin: se coloca en final de línea Ctrl-D ó quit(): sale del entorno P YTHON También puede ejecutarse un programa ya editado mediante: $ python nomprog.py

Un primer ejemplo Editemos un fichero ejemplo.py con el siguiente contenido: n = 100 b = range (n+1) s = sum (b) print print ’La suma de los ’, n, ’ primeros numeros naturales es:’, s print

Para ejecutarlo, hacemos: $ python ejemplo.py y nos dará como resultado: La suma de los 100 primeros numeros naturales es:

5050

Nota: P YTHON es un lenguaje dinámicamente tipado, i.e., una misma variable puede tomar valores distintos en distintos momentos. a=5 a="hola" Las variables no hay que declararlas.

Un primer ejemplo

En el ejemplo anterior, hemos escrito “numeros” en lugar de “números”. P YTHON no admite —por sí solo— tildes, ni eñes, ... Si queremos utilizar otros caracteres, debemos incluir las siguientes líneas en cabeza del fichero: #! /usr/bin/env python # -*- encoding: utf-8 -*-

Ayuda en P YTHON Ayuda en línea de comandos: >>> help ()

In [1]:

help ()

help>

In [2]:

help (math)

help> modules

In [3]:

help (pylab)

help> keywords

In [4]:

help (plot)

help> topics

Pulsando la tecla Return o haciendo CTRL-D volvemos al prompt de P YTHON. Observación: Si usamos la consola I-P YTHON y tecleamos help(pylab), debemos haber importado previamente el paquete mediante import pylab; sin embargo, si hacemos help() y en la ayuda escribimos help> pylab no es necesario importar previamente el paquete. En la ventana I-P YTHON, podemos hacer: In[1]: In[2]:

import numpy c = numpy.[ TABULADOR ]

dir (obj): devuelve una lista de los atributos y métodos de cualquier objeto: módulos, funciones, cadenas, listas, diccionarios, etc.

PYTHONPATH El lugar donde P YTHON guarda el camino de los módulos que se pueden importar es la variable de entorno PYTHONPATH Es posible modificarla de formas distintas: I

Como variable de entorno podemos cambiarla de la forma habitual con las variables de entorno. En bash, por ejemplo, basta con añadir estas líneas a nuestro fichero .bashrc: export PYTHONPATH=$PYTHONPATH:/midir1:/midir2

I

También es posible modificarlo desde P YTHON o desde la consola tecleando: import sys; sys.path.append ("/home/me/mypy") esto añade nuestro directorio de trabajo "/home/me/mypy" a la variable path de P YTHON

La librería estándar de Python Algunos módulos incluidos en la distribución de Python. The Python Standard Library http://docs.python.org/library/ I sys: módulo que proporciona acceso a algunas variables usadas o mantenidas por el

intérprete (en el entorno de ejecución) y las funciones que interactúan con el intérprete. I os: paquete que tiene numerosas funciones para manipular ficheros y procesos. I time: módulo que proporciona funciones relacionadas con la medida del tiempo. I datatime: manejo de tipos de datos date (fechas) y time (mediciones de tiempo). I math: funciones matemáticas básicas. I random: generador de números pseudo-aleatorios. I string: manejo de cadenas de texto. I zlib, gzib, zipfile, tarfile: comprensión de ficheros. I email, mailbox, ssl, socket, webbrowser, smtpd, etc. : herramientas de e-mail, red,

protocolo de internet. I audioop, imageop, wave, etc. : servicios multimedia. I xml.dom, xml.sax, etc.: parses de XML y HTML.

Algunas librerías de cálculo científico I

numpy: paquete útil para cálculo científico. Contiene: I I I I I

poderoso manejo de arrays n-dimensionales, funciones básicas de álgebra lineal, transformadas de Fourier, capacidades sofisticadas de generación de números aleatorios, herramientas para integrar código Fortran y C/C++.

I

scipy: librería para matemáticas, ciencia e ingeniería, que depende de N UM P Y. Proporciona métodos eficientes de cálculo numérico, como por ejemplo, integración numérica y optimización.

I

MatPlotLib: librería de representación gráfica 2D que proporciona imágenes de gran calidad y diversos formatos.

I

tvtk: envoltura de VTK que soporta arrays de N UMPY /S CIPY de un modo transparente.

I

enthought: E NTHOUGHT P YTHON D ISTRIBUTION (EPD) es una distribución de programación P YTHON que incluye en torno a 60 librerías y herramientas adicionales.

I

mayavi2: herramienta de visualización científica para datos 2D y 3D. I

mlab: proporciona un modo sencillo y rápido de visualizar datos 3D.

Otros ejemplos sencillos Editemos un fichero a00.py con el siguiente contenido: import math a = input (’ Introduzca un angulo: ’) x = math.cos (a) print ’Coseno de un angulo:’ print ’ cos (’ + str (a) + ’) = ’ + str (x) Para ejecutarlo, hacemos: $ python a00.py nos aparecerá en pantalla: Introduzca un angulo: y si proporcionamos, por ejemplo, 3.141592654, nos dará como resultado: Coseno de un angulo: cos (3.141592654) = -1.0

Otros ejemplos sencillos Otra forma de hacer el programa es la siguiente: import sys, math import math a = float (sys.argv [1]) x = math.cos (a) print ’Coseno de un angulo:’ print ’ cos (’ + str (a) + ’) = ’ + str (x) Para ejecutarlo, hacemos: $ python a00.py

(que nos dará un error)

$ python a00.py 3.141592654 y nos dará como resultado: Coseno de un angulo: cos (3.141592654) = -1.0

Otros ejemplos sencillos

Y otra forma de mostrar el resultado es: salida = ’ cos (%g) = %12.5e’ % (a,x) print salida lo que nos da como resultado: cos (3.14159) = -1.00000e+00 También puede ejecutarse, en la ventana I–P YTHON, de la siguiente manera: In [1]:

run a00.py 3.141592654

Otros ejemplos sencillos Producto de dos matrices: >>> from numpy import array, dot >>> a = array ([[1, 3],[2, -1]]) >>> b = array ([[4, -1],[0, 2]]) >>> c = a * b; d = dot (a,b) Ejemplo de gráfico 2-D: >>> from pylab import * >>> plot (range (10)) >>> xlabel (r’Abscisas’, fontsize=12) >>> ylabel (r"Ordenadas", fontsize=12) >>> title (r"Grafica de una recta", fontsize=14) >>> show () >>> title ("""Grafica ...de una recta""")

Variables Variable es un nombre que se da a una entidad (escalar, lista, array, diccionario, cadena de caracteres, ...) P YTHON es un lenguaje dinámicamente tipado: las variables pueden tomar distintos valores, de distinto tipo, en distintos momentos I

el resultado de una expresión se asigna a otra variable mediante el operador de asignación (=); p. ej.: >>> 5 + 2; b = 3 * 4 calcula la suma (no la asigna a ninguna variable) y hace que b tome el valor 12

I

para continuar expresión en la línea siguiente se utiliza la barra invertida (\)

I

no es necesario declarar inicialmente las variables

I

P YTHON distingue entre mayúsculas y minúsculas

I

los nombres de variables empiezan por letra.

Variables y espacio de trabajo Una variable puede “destruirse”: >>> del x El comando type permite conocer el tipo de una variable: >>> type (a) El espacio de trabajo (workspace) es el conjunto de variables y funciones de usuario en la memoria del programa >>> dir (obj): lista los atributos y métodos del objeto obj En la ventana I–P YTHON, el comando who permite examinar todas las variables activas en un instante dado, así como los paquetes importados. whos proporciona algunos detalles sobre cada variable

Tipos de datos en P YTHON: variables lógicas Toman los valores True o False. >>> m = True # a y b son variables enteras >>> a = 0; b = -4; >>> type (a); type (b) # a y b son variables reales >>> a = 0.; b = -4.; >>> type (a); type (b) >>> xa = bool (a) >>> xb = bool (b) >>> c1 = (b == True) >>> c2 = (xb == False) >>> c3 = (xb = False)

# xa es una variable lógica, cuyo valor es False # xb es una variable lógica, cuyo valor es True # El resultado es False porque b no es una variable lógica # El resultado es False porque xb tiene el valor True # Nos da un error de ejecución

Tipos de datos en P YTHON: la variable None Designa un objeto “vacío”. Haciendo: >>> a = None creamos la variable a, que no contiene nada y podrá ser de cualquier tipo (numérica, carácter, clase ...); para comprobarlo, podemos hacer: >>> a is None También podemos crear una lista, diccionario o tupla vacíos mediante: >>> a1 = []; a2 = { }; a3 = () # Consultamos el valor de a. # No muestra nada porque a=None >>> a = 4.5; # Asignamos a la variable a el valor 4.5 >>> a

Tipos de datos en P YTHON: variables numéricas Pueden ser: I

enteras (entre −2147483648 y 2147483647): 0, 283, -5

I

de tipo long:

I

reales de doble precisión: 0., -2.45, 1.084E+14

>>> i = 22L; i

complejas de doble precisión: a = 1.-4j, b = complex(7,-2) √ donde j designa la unidad imaginaria (j = −1). I

Las partes real e imaginaria de un complejo pueden recuperarse mediante: >>> b.real >>> b.imag Al operar dos variables numéricas, el resultado coge el tipo del operando “de mayor categoría”

Tipos de datos en P YTHON: cadenas de caracteres Van entre comillas simples o dobles >>> s = ’Hola, como estais?’ >>> s >>> print s Un ejemplo de programa, con funciones específicas: from string import *

s01 = s1 + s2 + s3; print s01

s1 = ’Primera cadena’

s02 = s1 + ’ ’ + s2 + ’ ’ + s3

s2 = ’Segunda cadena’

print s02

s3 = ’Tercera cadena’

print split (s01, sep=’ ’)

print ’ s1 = ’, s1

print count (s01,’cad’)

print ’ s2 = ’, s2

print capitalize (s02)

print ’ s3 = ’, s3

print lower (s01) print replace (s02,’den’,’sit’)

Tipos de datos en P YTHON >>> a = ’Mensaje de bienvenida’ >>> b = 4; c = 130L; d = 4.56789; m = 4.2-8.424j >>> cs = str (c) >>> ds = str (d) >>> ms = str (m)

# ’130’ # ’4.56789’ # ’(4.2-8.424j)’

>>> bd = float (b) # 4.0 # puede aplicarse a cadenas de caracteres numéricos, # a enteros y a complejos sin parte imaginaria >>> di = int (d) # # # >>> bc = complex >>> dc = complex

# 4 devuelve el entero más cercano hacia el cero puede aplicarse a cadenas de caracteres numéricos y a complejos sin parte imaginaria (b) # 4+0j (d) # 4.56789+0j

Tuplas y Listas

Las tuplas y las listas permiten almacenar una secuencia arbitraria de objetos Los objetos almacenados no tienen por qué ser del mismo tipo: pueden ser cadenas de texto, números, otras listas o tuplas, etc. Se accede a los elementos mediante un índice que especifica la posición del objeto en la lista o tupla. Diferencia principal entre tuplas y listas: I

La lista es modificable, la tupla no: en una lista se pueden modificar, añadir y borrar elementos.

Tuplas Una tupla es una secuencia arbitraria de objetos separados por comas y encerrados entre paréntesis, ( ) La numeración de los índices comienza en cero >>> x = () # Tupla vacía >>> x = (2,) # Tupla de un elemento >>> x = (1, 4.3, ’hola’, (-1,-2)) >>> x[0] # Recuperamos la primera componente 1 >>> x[3] (-1, -2) >>> x[-2] # Empieza a contar por el final ’hola’ >>> y = 2,3,4 # Se pueden omitir los paréntesis >>> z = 2, # Tupla de un solo elemento

len (x): longitud de una tupla max (x), min (x): máximo/mínimo de una tupla tuple (seq): convierte seq en una tupla >>> tuple (’hola’) (’h’,’o’,’l’,’a’)

Listas Una lista es una secuencia arbitraria de objetos separados por comas y encerrados entre corchetes, [ ]. La numeración de los índices comienza en cero. >>> x = [] # Lista vacía >>> x = [1,4.3,’hola’,[-1,-2],’dedo’,math.sin,[-0.4,-23.,45]] >>> x[0] 1 >>> x [3] [-1, -2] >>> x[-3] # Empieza a contar por el final ’dedo’ >>> x [2:4] # Devuelve una lista formada por [x[2], x[3]] [’hola’, [-1,-2]] >>> x[4:] [’dedo’, , [-0.4,-23,45]] >>> x[7] Traceback (most recent call last): File "", line 1, in ? IndexError:

list index out of range

Funciones útiles de las listas range ((inicio,)fin(,step)): crea una lista de enteros, desde inicio hasta fin (excluido!) con paso step. I si no se indica inicio, empieza en cero I si no se especifica step, el paso es uno >>> range (-1, 5, 1) [-1, 0, 1, 2, 3, 4] >>> range (-10, 10, 2) [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8]

len(x), max(x), min(x), siendo x una lista >>> x = [-120, 34, 1, 0, -3] >>> len (x) 5 >>> max (x) 34 >>> min (x) -120

# Número de elementos de x

Manejo de listas map(func,xlist): aplica la función func a todos los elementos de la lista xlist >>> x = [’Andres’,’FernAndo’,’MARIA’,’ANTOnio’] >>> map (string.lower,x)

# escribe todas las cadenas en minúsculas

[’andres’,’fernando’,’maria’,antonio’]

Los siguientes métodos pueden aplicarse a cualquier objeto de tipo list: I

append(obj): añade un elemento (obj) al final de la lista

I

extend(obj): añade a la lista los elementos de la lista obj

>>> z = [1,2]

>>> z.extend ([20,’hola’,-40])

>>> z.append ([’perro’,’gato’])

>>> z

>>> z

[1,2,[’perro’,’gato’],20,’hola’,-40]

[1,2,[’perro’,’gato’]]

>>> z + [20,’hola’,-40]

Manejo de listas x.insert(j,obj): inserta un elemento obj en la posición j de la lista x.remove(obj): localiza el primer elemento que coincide con (obj) y lo elimina da la lista x.pop(j): si se especifica un índice, se elimina el elemento de la posición correspondiente al índice; si no, elimina el último x.reverse(): escribe la lista en orden contrario x.sort(): ordena la lista >>> x = [1,’hola’,[2,3.4],’good’,[-1,0,1],’bye’] >>> x.remove (’hola’) >>> x >>> x.insert (2,’texto’) [1,[2,3.4],’good’,[-1,0,1],’bye’] >>> x >>> x.pop (1) [1,’good’,’texto’,[-1,0,1],’bye’] [2,3.4] >>> x.pop () >>> x ’bye’ [1,’good’,[-1,0,1],’bye’] >>> x [1,’good’,’texto’,[-1,0,1]]

Manejo de listas Podemos generar una lista con todos sus elementos iguales: >>> n = 5 >>> x = 0.25 >>> a = [x]*n >>> a [0.25, 0.25, 0.25, 0.25, 0.25] Una cadena de caracteres puede ser interpretada como una lista: >>> s = ’Hola, mundo’ >>> s[0] ’H’ >>> s[1] ’o’ >>> s[9] ’d’ Se puede convertir un objeto en una lista: >>> x=(1,2,3); y=list(x)

>>> list(obj)

Ejercicio I

I

I

Creamos dos listas vacías para almacenar nombres y dnis: >>> nombres=[] >>> dni=[] Añadimos datos a cada una de las listas >>> dni.append (’33807659D’); dni.append (’32233322K’) >>> nombres.append (’Felipe Fdez’) >>> nombres.append (r’Carlos Suarez’) Creamos una lista con las dos listas: >>> datos = [dni,nombres]

I

Accedemos a los datos >>> datos[0] >>> datos[1] >>> datos[0][1]

Ejercicio Dado un mallado 2–D, queremos crear: I

una lista de nodos, con sus dos coordenadas

I

una lista de elementos, con los índices de sus vértices

I

Coordenadas: >>> nodos 0.], [2., >>> nodos >>> nodos >>> nodos

= [[0., 0.], [1., 0.], [1., 1.], [0., 1.], [2., 1.]] [0] [2] [5]

La lista de los nodos es, simplemente, I

range (len (nodos))

Elementos: >>> conec = [[0, 1, 2], [0, 2, 3], [1, 4, 5], [1, 5, 2]] >>> conec [2] >>> conec [3] La lista de los elementos es:

range (len (conec))

Diccionarios Permiten almacenar una secuencia arbitraria de objetos I Se accede a sus elementos a partir de claves principales (keys). I

La ordenación de sus elementos se realiza por orden alfabético de las claves.

Ejemplo: >>> x = { ’clave01’:

’primer elemento’ }

o bien: >>> x = { }

# diccionario vacío

>>> x [’clave01’] = ’primer elemento’ >>> x [’clave02’] = 25.50 >>> x ’clave01’:

’primer elemento’, ’clave02’:

25.5

Diccionarios Otro ejemplo: >>> x = { }

# diccionario vacío

>>> clientes = {’C01’:[’Juan Fernandez’,38,’44000111D’], ’C02’:[’Maria Gonzalez’,17,’33221998L’]} >>> clientes[’C02’]

# datos del cliente C02

[’Maria Gonzalez’,17,’33221998L’]

¿Cómo añadir, modificar y borrar elementos? >>> clientes [’C03’] = [’Carlos Blanco’,23,’44555111L’] # añadir >>> clientes [’C01’] = [’Juan Fernandez’,29,’44000112D’] # modificar >>> del clientes [’C02’] # borrar >>> clientes

>>> namedict.has_key (namekey): devuelve True si el diccionario namedict tiene la clave namekey; en caso contrario devuelve False.

Diccionarios I I I I I I

len (ndic): número de elementos del diccionario ndic ndic.keys (): devuelve una lista de las claves del diccionario ndic ndic.values (): devuelve una lista con todos los valores del dicc. ndic.items (): devuelve en tuplas el contenido del diccionario ndic.update (ndic2): añade los elementos de un dicc. a otro ndic.clear (): borra todos los elementos del diccionario ndic.

Por ejemplo, >>> clients = {’C01’:[’F. Gutierrez’,19], ’C02’:[’A. Ferro’,45], ’C03’:[’C. Blanco’,23]} >>> clients.keys() [’C01’,’C02’,’C03’] >>> len (clients) 3 >>> clients.clear() >>> clients { }

Ejercicio

En el mallado anterior, crea un diccionario con los elementos. >>> >>> >>> >>> >>>

elem = { elem[0] = elem[1] = elem[2] = elem[3] =

>>> elem

} [0, [0, [1, [1,

1, 2, 4, 5,

2] 3] 5] 2]

Copia de objetos por valor Crear una copia por valor de una lista/tupla/diccionario consiste en crear un objeto con el mismo contenido; el nuevo objeto apunta a otra posición de memoria. >>> L1 = [1,

5.5,

4] # Crea una copia del contenido

>>> L2 = L1[:] >>> L2 is L1 False

# Si modificamos L2 no se modifica L1

>>> L2.append (100)

Otro modo es hacerlo es mediante la función copy(obj): >>> import copy >>> L1 = {’a’:1,

’b’:22,

’c’:4}

>>> L2 = copy.copy (L1) >>> L2 is L1 False >>> L1[’d’] = 88

# Si modificamos L1 no afecta a L2

Copia de objetos por referencia Crear una copia por referencia de un objeto consiste en crear un nuevo objeto, que apunta a la misma dirección de memoria que el objeto original. >>> L1 = [1, 5.5, 4] # Crea una nueva variable, que apunta a L1

>>> L3 = L1 >>> L3 is L1 True

Si modificamos L3, también modificamos L1: >>> L3.append (100) >>> L1 [1,

5.5,

4,

100]

Si eliminamos L1, no se elimina la copia L3: >>> del L1; L1 Traceback (most recent call last): File "", line 1, in ? NameError: name ’L1’ is not defined >>> L3 [1, 5.5, 4, 100]

Introducción a P YTHON Programación en P YTHON Bifurcaciones Bucles Funciones Módulos Os y Sys Lectura y escritura Excepciones Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

Programación en Python Nombre de los ficheros: nomfich.py Contienen secuencias de comandos Programas de comandos (script) I

se ejecutan tecleando:

Funciones I

$ python nomfich.py

def nomfunc (x1,x2,...): .. .

o bien In[1] run nomfich.py

su estructura es:

return [a,b,c] I

se ejecutan mediante una llamada desde un script, otra función, o desde la ventana de comandos

Son recursivos No es necesaria una compilación previa a la ejecución

Bifurcaciones if condicion: sentencia(s)

if condicion1: sentencia(s) elif condicion2: sentencia(s)

if condicion1: sentencia(s) elif condicion2: sentencia(s) elif . . . : ... else: sentencia(s)

I

Las condiciones pueden ser booleanas, escalares, vectoriales o matriciales; en este caso, los vectores y matrices deben ser de iguales dimensiones

I

Pueden anidarse

I

Solamente se ejecuta un bloque de sentencias

I

Operadores:

I

IMPORTANTE: Los sangrados deben realizarse con el tabulador !!!

<



>=

==

!=

or

and

not

Bifurcaciones

El resultado de cada condición será True o False. En particular, si hacemos if var donde var contiene a una variable, el resultado será: I

False, si var es: I I I I

I

la variable None una variable númerica con el valor cero una variable lógica con el valor False una tupla, lista o diccionario vacíos

True, en otro caso

Bucles for i in range (i1,i2,inc): sentencia(s) I

si i1 es cero y el paso es uno, puede omitirse

I

si inc es uno, puede omitirse

while (condicion): sentencia(s)

for item in ObjIterable: sentencia(s) I

1 2 3 4

donde ObjIterable es un objeto iterable El sangrado debe realizarse con el tabulador ! i m p o r t math m e t o d o s = [ math . s i n , math . cos , math . t a n , math . exp ] f o r k i n metodos : p r i n t k . __name__ , ’ ( p i ) = ’ , k ( math . p i )

Bucles Pueden utilizarse varias listas a la vez: for x, y, z in zip (xlist,ylist,zlist): print x, y, z En este caso, el número de iteraciones será la dimensión de la lista más pequeña. Los bucles pueden anidarse: for i in range (i1,i2,inc): for j in range (j1,j2,jinc): print a[i][j] Dos instrucciones importantes: break: sale del bucle más interior continue: comienza una nueva iteración del mismo bucle

Emular Switch

Python no dispone de la sentencia Switch, pero esta puede emularse empleando un diccionario. 1

from math i m p o r t *

2 3 4 5 6 7

num= p i menu = { ’ 1 ’ : cos , ’ 2 ’ : s i n , ’ 3 ’ : exp } c h o i c e = r a w _ i n p u t ( " E l i j a una o p c i o n 1 , 2 , 3 " ) v a l =menu [ c h o i c e ] ( num ) p r i n t ’%s ( p i ) = %f ’ %(menu [ c h o i c e ] . __name__ , v a l )

Ejercicios Escribe un programa P YTHON (“dias.py”) que lea una fecha (día, mes y año), compruebe si es correcta y la escriba en pantalla. import types a = input (’Introduce el anho:

’)

if (a > eval (f,x)

Funciones Podemos pasar, como argumento a una función, el nombre de otra función import numpy as np import pylab as pl def f (x): return x**2

from numpy import linspace x = linspace (-5.0,5.0,101) if opt == 1:

def g (x): return x**3

pinta (x,f) elif opt == 2: pinta (x,g)

def h (x): return np.sqrt(np.abs(x)) def pinta (x,f): pl.plot(x,f(x)) pl.show()

else: pinta (x,h)

Funciones

Recursividad: una función puede llamarse a sí misma 1 2 3 4 5 6 7 8 9

import types def f a c t ( n ) : i f t y p e ( n ) != t y p e s . IntType : r e t u r n −1 else : i f n ==0: return 1 else : r e t u r n n * f a c t ( n −1)

Funciones lambda I

La expresión lambda permite definir funciones simples inline.

I

Al igual que def la expresión lambda crean una función que puede llamarse a posteriori, pero que devuelve la función en vez de asignarle un nombre

1

lambda a r g 1 , a r g 2 ,

1

>>> f = lambda x , y : x * y >>> f ( 2 , 3 ) 6 >>> i m p o r t math >>> g= lambda x , k = 1 . 0 , a = 1 . : k * math . exp ( a * x ) >>> g ( 2 , k =1 , a =−1) 0.1353352832366127

2 3 4 5 6 7

. . . , argN : e x p r e s i o n

Funciones lambda I

1 2 3 4 5

Las funciones lambda se usan habitualmente para codificar tablas de salto o jump tables, que son acciones almacenadas en listas o diccionarios, para ser ejecutadas cuando se requiera.

i m p o r t math # incluye la LF = [ lambda lambda x lambda x

d e f i n i c i o n de x : math . s i n : math . c o s ( : math . exp (

las funciones ( x ) , x ) , x / math . p i ) ]

6 7 8

f o r f i n LF : p r i n t ( f ( math . p i ) ) # i m p r i m e 1 . 2 2 4 e −160 , −1.0 , e =2.718..

9 10

p r i n t ( LF [ 1 ] ( 2 . * math . p i ) ) # i m p r i m e 1 . 0

Herramientas de programación funcional: lambda, map, filter, reduce. I 1 2 3

I 1 2 3

I

1 2

3 4

5

map(func, sec):Aplicar una función sobre una secuencia de datos >>> map ( lambda x : x ** 2 , [ 1 , 2 , 3 ] ) map ( lambda x : x ** 2 , [ 1 , 2 , 3 ] ) # en P y t h o n 3 . 0 : l i s t ( map ( lambda x : x ** 2 , [ 1 , 2

,3]) )

filter(func, sec): filtra los elementos de un objeto iterable, >>> f i l t e r ( lambda x : x >0 , [ −1 , 3 , −4 , 5 ] ) [3 , 5] # en P y t h o n 3 . x : l i s t ( f i l t e r ( lambda x : x >0 , [ −1 , 3 , −4 , 5 ] ) )

reduce(func,sec): aplica la función de dos argumentos, func(x,y), de forma acumulativa a los puntos del objeto iterable, sec, de izquierda a derecha, con el fin de reducir el objeto iterable en un único valor. >>> from f u n c t o o l s i m p o r t r e d u c e # En >>> r e d u c e ( lambda x , y : x +y , [ c a l c u l a : ( ( −2+( −3) ) + ( −4) ) + ( −14 >>> r e d u c e ( lambda x , y : x * y , [ c a l c u l a : ( ( −2 * ( −3) ) * ( −4) ) * ( 120

P y t h o n 3 . x en 2 . 6 no −2 , −3 , −4 , −5]) # −5) −2 , −3 , −4 , −5]) # −5)

Trabajar con nuestros propios módulos En el fichero normas.py implementamos tres funciones que calculen las normas uno, infinito y dos de una lista de números, L = [x0 , . . . , xn ]: s n

||L||1 = ∑ |xi |, i=1 1 2 3 4

n

||L||∞ = max {|xi |}, i=1,...,n

||L||2 =

∑ (xi )2 i=1

# −* − c o d i n g : u t f −8 −* − # normas . py d e f n1 ( L ) : # L e s una l i s t a r e t u r n r e d u c e ( lambda x , y : a b s ( x ) + a b s ( y ) , L )

5 6 7

def ninf ( L ) : r e t u r n max ( map ( a b s , L ) )

8 9 10 11

i m p o r t math d e f n2 ( L ) : r e t u r n math . s q r t ( sum ( map ( lambda x : x ** 2 , L ) ) )

Trabajar con nuestros propios módulos I

1

Para poder instanciar los m´todos del módulo normas.py en el fichero main.py (ambos guardados en el mismo directorio), hay que importar el módulo, import normas # F i c h e r o : main . py

2 3

i m p o r t normas

4 5 6 7 8 9

I

1 2 3

1 2 3

L = [ −1 print ’ print ’ print ’ print ’

, 2 , 3 , −5] L = ’ ,L norma1 ( L ) = ’ , normas . n1 ( L ) norma2 ( L ) = ’ , normas . n2 ( L ) n o r m a I n f ( L ) = ’ , normas . n i n f ( L )

Mediante la sentencia from NombreModulo import AtributoModulo permite importar la función (o funciones) que indiquemos. from normas i m p o r t n i n f p r i n t n i n f ( [ −2 , −20 , 1 0 , 5 0 ] ) # m u e s t r a 50 p r i n t n1 ( [ −2 , −20 , 1 0 , 5 0 ] ) # e r r o r from normas i m p o r t n i n f , n1 , n2 p r i n t n i n f ( [ −2 , −20 , 1 0 , 5 0 ] ) # i m p r i m e 50 p r i n t n1 ( [ −2 , −20 , 1 0 , 5 0 ] ) # i m p r i m e 82

Shell I–Python

La shell I–P YTHON admite, entre otros, los comandos usuales de una shell de linux: pwd cd path, cd .. ls, ls -al cat a00.py cp a00.py

copia_a00.py

mv copia_a00.py rm a00_copia.py

a00_copia.py

El paquete Os

El paquete os tiene numerosas funciones para manipular ficheros y procesos. os.path: funciones para la gestión de rutas y archivos. os.mkdir (’subdir44’) os.getcwd ()

# devuelve el directorio en que nos encontramos

os.chdir (’subdir44’) os.chdir (os.environ[’HOME’]) os.rename (’fic01.py’,’fic02.c’) os.remove (’fic02.c’) Llamadas al sistema operativo: os.kill, os.execv, etc.

El paquete Os

Podemos consultar los ficheros de un directorio mediante: >>> os.listdir (os.curdir) >>> os.listdir (’/home/arregui/python/’) o bien mediante >>> import glob >>> glob.glob (’*’) + glob.glob (’.*’)

El paquete Sys

El módulo sys que proporciona acceso a algunas variables usadas o mantenidas por el intérprete (en el entorno de ejecución) y las funciones que interactúan con el intérprete. I

sys.argv: lista de los argumentos pasados a un script en la línea de comandos.

I

sys.exit: salida de P YTHON.

I

sys.stdin, sys.stdout, sys.dtderr: ficheros de acceso a la entrada, salida y errores estándar del intérprete.

El paquete Sys

1

import sys

2 3 4

# datos i n t r o d u c i d o s por t e c l a d o datos =sys . argv [ : ]

5 6

print ’ datos= ’ , datos

7 8

9 10

p r i n t " Al p r o g r a m a %s s e l e p a s a r o n %d a r g u m e n t o s de e n t r a d a : " % ( sys . argv [ 0 ] , len ( sys . argv ) − 1) for arg in sys . argv [ 1 : ] : p r i n t " %s " % a r g

Medida de tiempos La librería time incluye algunas funciones relacionadas con la medida del tiempo P YTHON proporciona la fecha y hora de tres formas distintas: I como tupla: año-mes-día-hora-min-seg-diasem-diaaño-x (tup) I como cadena de caracteres (str) I como número total de segundos transcurridos desde un origen (sec) time (): instante actual clock (): tiempo transcurrido desde el comienzo de la ejecución sleep (n): pausa de n segundos gmtime (): hora GMT localtime (): hora local asctime (tup): convierte la tupla en cadena de caracteres strftime (tup): convierte la tupla en cadena mktime (tup): convierte la tupla en segundos ctime (sec): convierte los segundos en cadena strptime (str): convierte la cadena en tupla tzset ():

Lectura y escritura interactiva Introducción de datos por teclado: x = raw_input (’mensaje’) Imprime ’mensaje’ en la pantalla; espera a que se le introduzca cualquier tipo de dato; lo almacena en la variable x como una cadena de caracteres. No es posible operar con la variable x >>> x = raw_input (’Introduzca un numero: ’) 124.5 No es posible hacer y = x**2, porque x=’124.5’ Tendríamos que hacer: y = float(x)**2

x = input (’mensaje’) Imprime ’mensaje’ en la pantalla; espera a que se le introduzca cualquier tipo de dato y lo almacena en la variable x; intenta evaluarlo para convertirlo en el tipo de dato correcto. Es posible operar con la variable x: >>> x = input (’Introduzca un numero: ’) 124.5 Es posible hacer: y=x**2, porque x=124.5

Lectura y escritura interactiva

Impresión de datos, no formateados, por pantalla: >>> print ’mensaje’, var1, var2, ..., vark Imprime en pantalla: mensaje var1 var2 vark Las variables aparecen separadas por un espacio: >>> nm = ’Andres’ >>> edad = 45 >>> print ’Nombre, edad = ’ , nm, edad Nombre, edad = Andres 45 >>> print ’Nombre= ’, nm, ’ edad = ’, edad Nombre = Andres edad = 45

Lectura y escritura interactiva Impresión de datos formateados por pantalla: print ’Msj1 = %tipo, Msj2 = %tipo’ % (var1,var2) donde tipo indica la forma en que vamos a representar cada variable: %i ó %d: número entero %f: número real en forma decimal %e: número real en formato exponencial %g: elimina los ceros no significativos %s: cadena de caracteres >>> name = ’Pepe’ >>> sdia = 50.5 >>> print ’%s gana al mes %7.2f euros’ % (name,sdia*30.) Pepe gana al mes 1515.00 euros

Lectura y escritura de ficheros de texto: Path I

En L INUX, el path se denota por:

I

En W INDOWS, el path

path = ’/tmp/sample.txt’

C:\Windows\Temp se representa en P YTHON por: path = ’C:\\Windows\\Temp’ En vez de tratar de modo especial los backslashes (\) en un string, podemos situar una ‘r’ antes de las comillas: path = r’C:\Windows\Temp’ Así, hemos convertido la cadena de caracteres en una raw string. Las raw string, o cadenas literales, se usan para que la cadena de texto interprete correctamente los backslashes.

Lectura de ficheros de texto I

Identificación del fichero: idf = file (pathfich,’r’) Si el fichero no existe, P YTHON devuelve un error. >>> idf1 = file (’fich1.txt’,’r’) >>> idf2 = file (’/home/arregui/python/fich2.dat’, ’r’)

I

Lectura de una línea: >>> texto = idf.readline ()

y en la variable texto se almacenará la primera línea del fichero ’fich1.txt’, más el salto de línea (\n) >>> idf.readline () ’1 2 3.456 8.001 -99.01\n’ I

Lectura de todo el fichero, desde el punto donde esté situado el puntero del mismo: >>> texto = idf.read ()

Devuelve una cadena de texto con todo el contenido del fichero; por ejemplo >>> idf.read () ’F1 F3 F5\nLeyendo un fichero\n’

Lectura de ficheros de texto

I

Para situar el puntero al inicio del fichero, hacemos: >>> idf.seek (0)

I

Lectura de todas las líneas del fichero: >>> idf.readlines() Devuelve una lista de strings >>> lineas = idf.readlines() >>> lineas[1] ’F1 F3 F5\n’

I

Para cerrar el fichero, hacemos: >>> idf.close() y para borrar el objeto idf, hacemos: >>> del idf

Escritura de ficheros de texto Creación del objeto file: idf = file (pathfich,’w’) Si el fichero no existe, lo crea. Para añadir texto, hacemos: idf.write (string) >>> idf.write (’Primera linea del fichero \n’) Si escribimos de nuevo, añade el texto a partir de lo último que se escribió >>> idf.write (""" Estoy escribiendo una multilinea.

Esto es una prueba

Fin """) El fichero se cierra mediante: idf.close () Si abrimos el fichero antes de cerrarlo, todavía no contiene el texto escrito.

Lectura y escritura de ficheros numéricos Si todas las líneas tienen el mismo número de columnas, podemos emplear el comando load de la librería M AT P LOT L IB. devuelve un array de dimensiones m×n (donde m y n son los números de filas y columnas, respectivamente) A = load (path(,delimiter=’type’)) Por ejemplo, from pylab import * fich = ’matriz.txt’ A = load (fich)

Si el número de columnas no es el mismo para todas las filas, leemos línea a from string import split línea: k = 1 while (k>0): cadena = split (f.readline()) if (cadena): a = map (float,cadena) else: k = -1

Lectura y escritura de ficheros numéricos I

split(cadena(,’;’)): método de string que divide una cadena en las diferentes palabras separadas por espacios, o por el símbolo que se indique

I

map: función especial para los casos en que se necesita una acción específica sobre todos los elementos de una lista.

Podemos guardar en un fichero una matriz A de tamaño m×n: save (fich, A (,fmt=’%tipo’, delimiter=’simb’)) donde: tipo indica el formato en que vamos a representar la variable: %i, %d, %f, %e, %g simb indica el carácter que separa los dígitos de las filas; si no se especifica, por defecto el separador es un espacio en blanco A = array([[2.3, -4.4, 0],[-20,4.4,-1]]) save(’matriz2.txt’, A, fmt=’%7.2f’, delimiter=’,’)

Excepciones Hay que distinguir dos tipos de errores: I syntax errors (errores de sintaxis) >>> while True print ’hola’ File "", line 1 while True print ’hola’ ^ SyntaxError: invalid syntax En este caso faltan los dos puntos (“:”). I

exceptions (excepciones) >>> 5/0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: integer division or modulo by zero

Se pueden capturar las excepciones mediante el comando: try: sentencias except TipoExcepcion: sentencias

Excepciones. División por cero. Ejemplo: >>> 3.

/ 0.

Traceback (most recent call last): File "", line 1, in ZeroDivisionError:

float division

Excepciones. División por cero. Ejemplo: >>> 3.

/ 0.

Traceback (most recent call last): File "", line 1, in ZeroDivisionError:

float division

Control del error: a = 5.0 b = 0.0 try: res = a / b except ZeroDivisionError: print ’Division por cero’

Excepciones. Manejo de ficheros Ejemplo: >>> f = open (’mifichero.txt’) Traceback (most recent call last): File "", line 1, in IOError: [Errno 2] No such file or directory:

’mifichero.txt’

Excepciones. Manejo de ficheros Ejemplo: >>> f = open (’mifichero.txt’) Traceback (most recent call last): File "", line 1, in IOError: [Errno 2] No such file or directory:

’mifichero.txt’

Control del error: import sys try: f = open (’mifichero.txt’) s = f.readline () i = int (s.strip ()) except IOError,(errno,strerror): print "I/O error (%s): %s" % (errno,strerror) except ValueError: print "No se puede convertir el dato en entero" except: print "Error inexperado:", sys.exc_info()[0]

Ejercicios 1. Escribe un programa P YTHON que: (a) lea las componentes de un vector I I

por pantalla desde un fichero

(b) calcule su media armónica α: α −1 =

1 n 1 ∑ ai n i=1

(c) calcule sus normas: n

kak2 =

!1/2 2

∑ |ai | i=1

kak∞ = max |ai | i=1,...,n

Ejercicios 2. Resuelve la ecuación: f (x) = x5 − 3.8x3 − 4 = 0

x ∈ (−2, 2.5)

mediante el método de bisección: dados a0 , b0 1 xk = (ak + bk ) 2 si f (xk )f (ak ) < 0

=⇒

si f (xk )f (bk ) < 0

=⇒

( ak+1 = ak bk+1 = xk ( ak+1 = xk bk+1 = bk

Ejercicios

3. Escribe un programa en P YTHON que lea una fecha (día, mes y año) y calcule los días transcurridos desde el 1 de enero del mismo año, comprobando previamente si la fecha es correcta

Ejercicios

3. Escribe un programa en P YTHON que lea una fecha (día, mes y año) y calcule los días transcurridos desde el 1 de enero del mismo año, comprobando previamente si la fecha es correcta 4. Calcula la edad de una persona en días Son años bisiestos los múltiplos de 4, excepto los múltiplos de 100 que no sean múltiplos de 400

Ejercicios

3. Escribe un programa en P YTHON que lea una fecha (día, mes y año) y calcule los días transcurridos desde el 1 de enero del mismo año, comprobando previamente si la fecha es correcta 4. Calcula la edad de una persona en días Son años bisiestos los múltiplos de 4, excepto los múltiplos de 100 que no sean múltiplos de 400 ∞ (−1)n+1 5. Sea la serie numérica (convergente) dada por: S = ∑ √ . n=1 1 + 4n Escribe un programa en P YTHON que calcule la suma de la serie con un error inferior a un parámetro dado.

Ejercicios

6. Escribe un programa en P YTHON que genere un diccionario con: I I I

títulos de películas y años en que se estrenaron nombres de directores nombres de actores

y muestre la información de las películas ordenadas por: I I I

clave fecha nombre del director

Introducción a P YTHON Programación en P YTHON Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

Programación orientada a objetos I

La Programación orientada a objetos (POO) es un paradigma de programación que busca representar entidades u objetos agrupando datos y métodos que puedan describir sus características y comportamiento.

I

En la POO los programas se organizan como la “vida real”, modelándolos a través de clases y objetos, que interaccionan entres sí. I I I I

Pensemos en puntos (1, 2), (3, 4), (5, 7) Todos ellos son distintos A cada uno de ellos le puedo aplicar los mismos métodos Todos ellos tienes las mismas propiedades, pero con valores distintos

Ventajas de la POO I

El código es más fácil de escribir, mantener, reutilizar y extender

I

Permite crear programas más complejos

I

La implementación de los programas está relacionado con la organización del mundo real

Programación orientada a objetos Algunos conceptos relacionados con la POO: I

Una Clase es como una plantilla, donde se definen propiedades y métodos

I

Las clases no se manipulan directamente, sino que se utilizan para definir nuevos tipos, denominados instancias de la clase u objetos Ej: Una clase sería como el plano de una casa, por tanto, es algo genérico. Las instancias de clase serían las distintas casas que se pueden construir a partir del plano.

I

Un método de la clase es una función de la misma. Un atributo de la clase es una variable.

I

Un método y atributo se dice público si es visible en cualquier punto del programa que maneja una instancia de la clase, mientras que se dice privado si sólo es accesible por los métodos de la propia clase.

Programación orientada a objetos I

Python permite la Programación Orientada a Objetos (POO)

I

Una clase se crea mediante: class nombreClase: Una clase suele tiene un método de inicialización (el inicializador de la clase) (__init__), que no puede devolver ningún argumento y que se llama al instanciar la clase:

I

class nombreClase: def __init__(self,args): ... I

I I

I

__init__ se llama inmediatamente después de crear una instancia de la clase. El método __init__ no es el constructor de la clase, sino el inicializador. El constructor de la clase es el método __new__, que se ejecuta antes de instanciar al método __init__.

Por convección, el primer argumento de un método de la clase es self, que es el puntero de la clase (equivalente al this de C++ o Java). No es una palabra reservada, sino que se emplea por convección.

Programación orientada a objetos

I

Aunque es necesario que self sea el primer argumento de un método de una clase, no se especifica al invocar el método, pues Python lo añade de forma automática.

I

Cualquier variable de la forma self.var es pública y accesible desde cualquier método de la clase, y también desde el programa donde use una instancia de la clase

I

Anteponiendo __, se crea una variable o función pseudo-privada: self.__varpriv

I

La sentencia pass puede usarse cuando se requiere una sentencia sintácticamente pero el programa no requiere acción.

Instancias de una clase I

I 1 2 3 4 5

Para crear un objeto o instancia de una clase, basta invocar la clase como si fuera una función, pasando los argumentos del método __init__. El valor de retorno es la instancia creada.

c l a s s Punto : # F i c h e r o : e j 1 _ c l a s s _ p t o s . py """ Clase Punto """ d e f _ _ i n i t _ _ ( s e l f , x =0 , y = 0 ) : s e l f . x=x # a t r i b u t o de l a i n s t a n c i a , s e l f . y=y # i . e . , v a r i a b l e que p e r t e n e c e a l a instancia

6 7 8 9

i f __name__== ’ __main__ ’ : pto1=Punto ( )

10 11 12

pto2=Punto ( 3 , 5 ) p r i n t ’ pto1 i s pto2 = ’ , pto1 i s pto2

Atributos de una instancia y de una clase

I

Los atributos de datos (llamados variables de instancia en Java , y variables miembro en C++), son las variables que pertenecen a una instancia específica de una clase.

I

Python también admite atributos de clase, que son variables que pertenecen a la clase en sí.

I

Desde fuera de la clase, mediante obj.nombre accedemos al atributo nombre del objeto obj.

I

Para hacer referencia a los atributos de datos, desde dentro de la clase, empleamos self: self.nombre.

I

Un atributo comienza a existir en el momento en que se le asigna un valor.

Atributos de una instancia y de una clase 1 2 3

c l a s s Punto : # F i c h e r o : e j 1 _ c l a s s _ p t o s . py """ Clase Punto """ numptos =0

4 5 6

7 8

d e f _ _ i n i t _ _ ( s e l f , x =0 , y = 0 ) : P u n t o . numptos +=1 # v a r i a b l e de l a c l a s e ( t o d a s l a s i n s t a n c i a s l a comparten ) s e l f . x=x # v a r i a b l e de l a i n s t a n c i a , s e l f . y=y # i . e . , v a r i a b l e que p e r t e n e c e a l a instancia

9 10 11

def p r i n t _ p t o ( s e l f ) : p r i n t ’ Punto= ( ’ , s e l f . x , ’ ,

12 13 14

i f __name__== ’ __main__ ’ : pto1=Punto ( )

15 16

pto2=Punto ( 3 , 5 )

17 18 19 20

pto1 . p r i n t _ p t o ( ) p r i n t ’ p2=(% f , %f ) ’%p t o 2 . x , p t o 2 . y p r i n t ’ T o t a l p u n t o s = ’ , p t o 1 . numPtos

’ , self .y, ’ ) ’

Sobrecarga de métodos

I

C++ y Java admiten la sobrecarga de funciones por lista de argumentos, i.e., una clase puede tener varios métodos con el mismo nombre, pero con diferentes argumentos, o de distinto tipo.

I

Python no admite sobrecarga de funciones.

I

Los métodos se definen solamente por su nombre y hay un único método por clase con un nombre dado.

Sobrecarga de operadores I

La sobrecarga de operadores permite redefinir ciertos operadores, como +, −, ∗, /, print, etc.

M´todo __init__ __del__ __str__ __call__ __add__ __sub__ __mul__ __div__ __pow__ __eq__ __lt__ __comp__ __or__ __getitem__ __setitem__ __getattr__ __setattr__

Sobrecarga Inicializador Destructor Impresiøsn (print) Evalua el objeto en los argumentos Operador + Operador Operador * Operador \ Operador ** Operador == Operador < Comparación Operador | (OR) Acceder al valor del índice k Asignar un valor al índice k Acceder a un atributo Fijando el valor de un atributo

Cuándo se llama? A=NombreClase() del A print A, str(A) A(args) A+B, A+=B A-B, A-=B A*B, A*=B A\B, A\=B A**B, pow(A,B) A==B A

A partir Python 3.0 todas las clases automáticamente son clases de nuevo estilo, independientemente que se haya expecificado explícitamente que la deriven o no de la clase object y todas los objetos son instancias de la clase object.

Clases de Nuevo Estilo. Property

I

Una property es un tipo de objeto que se le asigna a la clase como un atributo de la misma, al igual que un método.

I

En general, una property se asigna en el nivel superior de la instrucción class, empleando la función property.

Clases de Nuevo estilo 1 2 3 4

class Figura ( object ) : def __init__ ( s e l f , c , b ) : s e l f . __color = c s e l f . __border = b

5 6 7 8 9 10 11 12

def get_color ( s e l f ) : p r i n t ’ mtdo . g e t _ c o l o r return s e l f . __color def s e t _ c o l o r ( s e l f , val p r i n t ’ mtdo . s e t _ c o l o r s e l f . __color = val color = property ( fget =

’ ): ’ get_color , fset = set_color )

13 14 15 16 17

def get_border ( s e l f ) : p r i n t ’ mtdo . g e t _ b o r d e r ’ r e t u r n s e l f . __border border = property ( fget = get_border )

18 19 20 21 22 23 24 25

i f __name__== ’ __main__ ’ : f i g = F i g u r a ( ’ a z u l ’ , True ) print fig . color p r i n t fig . border fig . color = ’ amarillo ’ print fig . color fig . border = False # error

Introducción a P YTHON Programación en P YTHON Programación orientada a objetos SQLAlchemy SQLAlchemy ORM Interfaces gráficas de usuario (GUI’s)

SQLAlchemy I

SQLAlchemy es un toolkit de SQL y un Mapeador Objeto Relacional (Object Relational Mapper –ORM)para Python. I

Al ser un ORM permite el mapeo de tablas a objetos. I

I

I

Un ORM es una técnica de programación para convertir datos entre el sistema de tipos utilizado en un lenguaje de POO y el utilizado en una base de datos relacional.

También se puede manejar como un toolkit de SQL sin tener que crear las relaciones ORM.

Bases de datos soportadas por SQLAlchemy: Postgresql, MySQL, Oracle, Microsoft SQL Server, SQLite, Access, Firebird y otros. http://docs.sqlalchemy.org/en/latest/core/engines.html#supported-databases

Algunos tutoriales: I

http://docs.sqlalchemy.org/en/latest/core/tutorial.html

I

http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html

I

http://docs.sqlalchemy.org/en/latest/core/tutorial.html

I

http://docs.sqlalchemy.org/en/latest/orm/tutorial.html

SQLAlchemy. Conexión 1

from s q l a l c h e m y i m p o r t *

2 3 4 5 6 7 8 9 10

user= ’ usuario ’ pwd= ’ m i p a s s w o r d ’ host= ’ localhost ’ database= ’ base_de_datos ’ c a d = ’ mysql : / / ’ + u s e r + ’ : ’ +pwd+ ’@’ + h o s t + ’ / ’ + d a t a b a s e en gi ne = c r e a t e _ e n g i n e ( cad ) engine . connect ( ) e n g i n e . e c h o = T r u e # T r u e : M u e s t r a l a s s e n t e n c i a s SQL que g e n e r a

I

I

db=create_engine(cad): establecemos la conexión con la base de datos. Se crea un objeto db, que “sabe como hablar” con un tipo de base de datos (SQLite, PostgreSQL, Firebird, MySQL, Oracle...). engine.connect(): obtiene una conexión. En caso de que no se produzca la conexión lanza una excepción (OperationalError) Las excepciones de SqlAlchemy pueden consultarse en http://docs.sqlalchemy.org/en/latest/core/exceptions.html

SQLAlchemy. Crear Tabla 1 2 3 4

5 6 7 8 9

m e t a d a t a = MetaData ( e n g i n e ) u s e r s = Table ( ’ c l i e n t e s ’ , metadata , Column ( ’ I d ’ , I n t e g e r , p r i m a r y _ k e y = True , a u t o i n c r e m e n t = T r u e ) , Column ( ’ Nombre ’ , S t r i n g ( 4 0 ) ) , Column ( ’ A p e l l i d o s ’ , S t r i n g (100) ) , Column ( ’ Edad ’ , I n t e g e r ) , Column ( ’ E m a i l ’ , S t r i n g ( 8 0 ) ) , Column ( ’ P a s s w o r d ’ , S t r i n g ( 2 0 ) ) , ) i f not users . e x i s t s ( ) : users . create ()

I metadata = MetaData(db): objeto que permite maneja las tablas de la base de datos

asociada al objeto db. I user=Table(’clientes’, metadata, ...): definimos la estructura de la tabla

’clientes’. Si sabemos a priori que la tabla de datos ya está creada, SqlAlchemy descubre de forma automática la estructura de la tabla de la base de datos, mediante la sentencia: users = Table(’clientes’, metadata, autoload=True) I users.exists(): devuelve True si la tabla existe. I users.create(): crea la tabla, ’clientes’, asociada al objeto users .

SQLAlchemy. Insertar filas (INSERT) 1 2 3

4 5 6 7 8 9 10

i = users . insert () # i n s e r t a una f i l a i . e x e c u t e ( Nombre= ’ M a r i a ’ , A p e l l i d o s = ’ Fdez Fdez ’ , Edad =30 , E m a i l = ’ m a r i a @ h o t m a i l . com ’ , P a s s w o r d = ’ s e c r e t ’ ) # i n s e r t a dos f i l a s i . execute ( { ’ Nombre ’ : ’ J u a n ’ , ’ A p e l l i d o s ’ : ’ D i a z Fdez ’ , ’ Edad ’ : 1 2 , ’ E m a i l ’ : ’ juan@gmail . com ’ , ’ P a s s w o r d ’ : ’ h o l a 0 8 ’ } , { ’ Nombre ’ : ’ T e r e s a ’ , ’ A p e l l i d o s ’ : ’ D i a z ’ , ’ Edad ’ : 4 2 , ’ E m a i l ’ : ’ maria@gmail . com ’ , ’ P a s s w o r d ’ : ’ h o l a 0 9 ’ } )

I

No es necesario escribir la consulta SQL.

I

Se crea un “objeto de tipo SQL” indicando el tipo de consulta que se quiere realizar, que se ejecuta mediante el método execute().

I

Para Insertar filas en la columna se usa i = users.insert().

I

i.execute(): se genera la sentencia “INSERT INTO users VALUES (...)” con los valores de los argumentos que se pasan en el método execute().

SQLAlchemy. Recuperar datos (SELECT * FROM tabla) 1 2

s = users . select () rs = s . execute ()

3 4 5 6 7 8 9 10 11 12 13 14 15

row = r s . f e t c h o n e ( ) p r i n t ’ ID : ’ , row [ 0 ] p r i n t ’ Nombre : ’ , row [ ’ Nombre ’ ] p r i n t ’ Edad : ’ , row . Edad p r i n t ’ P a s s w o r d : ’ , row [ u s e r s . c . P a s s w o r d ] # # p r i n t ’−−−−−−−−−−’ # # rows = r s . f e t c h a l l ( ) # # p r i n t rows p r i n t ’−−−−−−−−−−’ # r s e s un o b j e t o i t e r a b l e f o r row i n r s : p r i n t ’ Nombre= ’ , row . Nombre , ’ Edad ’ , row . Edad I La sentencia SELECT * from (tabla) se realiza creando el objeto s =

users.select() y llamando posteriormente al método rs = s.execute() I El objeto rs tiene los métodos fetchone() (devuelve una única fila) y fetchall()

(devuelve todas las filas – no recomendable). I El objeto rs es un objeto iterable. I A cada una de las columnas de la fila accedemos mediante row.NombreCol,

row[’NombreCol’] , row[id] o row[user.c.NombreCol]

SQLAlchemy. Recuperar datos (SELECT * FROM tabla WHERE..) 1 2 3 4

s = u s e r s . s e l e c t ( u s e r s . c . Edad > 2 0 ) rs = s . execute () f o r row i n r s : p r i n t ’−−−−’ , row . Nombre , row . A p e l l i d o s , ’ e−m a i l = ’ , row [ u s e r s . c . Email ]

Otras consultas: 1 2 3 4 5

def run ( stmt ) : print ’ **** rs = stmt . execute ( ) f o r row i n r s : p r i n t row

***** ’

6 7 8

s = u s e r s . s e l e c t ( ( u s e r s . c . Edad > 2 0 ) & ( u s e r s . c . Nombre ! = ’ T e r e s a ’ ) ) run ( s )

9 10 11

s = u s e r s . s e l e c t ( ( u s e r s . c . Edad < 2 0 ) | ( u s e r s . c . Nombre ! = ’ T e r e s a ’ ) ) run ( s )

12 13 14

s = u s e r s . s e l e c t ( ~ ( u s e r s . c . Nombre== ’ J u a n ’ ) ) run ( s )

SQLAlchemy. Otro ejemplo 1 2

# −*− c o d i n g : u t f −8 −*− import sqlalchemy as s q l a l

3 4 5 6 7 8 9 10 11 12

13

14 15 16

user= ’ usuario ’ pwd= ’ p w d _ u s u a r i o ’ host= ’ localhost ’ database = ’ negocio ’ c a d = ’ mysql : / / ’ + u s e r + ’ : ’ +pwd+ ’@’ + h o s t + ’ / ’ + d a t a b a s e p r i n t ’ cad= ’ , cad try : e n g i n e = s q l a l . c r e a t e _ e n g i n e ( cad , e c h o = F a l s e ) c on ne ct io n = engine . connect ( ) # hace f a l t a para ver s i se e s t a b l e c e la conexion # s i no s e hace , s i l o s d a t o s no s o n c o r r e c t o s da e x c e p c i o n l a p r i m e r a v e z que s e a c c e d e a l a b a s e de d a t o s # e n g i n e . e c h o = T r u e # M u e s t r a l a s e n t e n c i a s s q l que g e n e r a e x c e p t s q l a l . e x c e p t i o n s . DBAPIError , e : p r i n t "ERROR a l c o n e c t a r con l a b a s e de d a t o s " , e . a r g s [ 0 ]

17 18

# db = s q l a l c h e m y . c r e a t e _ e n g i n e ( ’ mysql : / / a n a f e f e : anafefe@localhost / negocio ’)

19 20

m e t a d a t a = s q l a l . MetaData ( e n g i n e )

SQLAlchemy. Otro ejemplo (cont.) 1

T c l i e n t e s = s q l a l . Table ( ’ c l i e n t e s ’ , metadata , a u t o l o a d =True ) # p a r a a c c e d e r a una t a b l a c r e a d a

2 3 4 5 6

NIF= ’ 00778200T ’ Nombre= ’ P e d r o ’ Apellido1= ’ Fernandez ’ Apellido2= ’ Fernandez ’

7 8 9 10

11 12

i = T c l i e n t e s . i n s e r t ( ) # i n s e r t a r en l a b a s e de d a t o s try : i . e x e c u t e ( NIF=NIF , Nombre=Nombre , A p e l l i d o 1 = A p e l l i d o 1 , Apellido2=Apellido2 ) except s q l a l . exceptions . IntegrityError , e : p r i n t " E r r o r −−> " , e

13 14 15

s = T c l i e n t e s . s e l e c t ( ) # h a c e r un S e l e c t rs = s . execute ()

16 17 18 19 20

f o r row i n print print print

rs : ’ Todo= ’ , row ’ N i f = ’ , row . NIF , ’ Nombre= ’ , row . Nombre ’ ============================== ’

SQLAlchemy. Consultas combinadas (JOIN) I

Combinada Interna: permite mostrar los datos de dos o más tablas. Las combinaciones internas solo devuelven filas cuando hay una fila de ambas tablas, como mínimo, que coincide con la condición de la combinación. Las combinaciones internas eliminan las filas que no coinciden con alguna fila de la otra tabla. I I

I

SELECT ... SELECT ...

FROM tabla1, tabla2 WHERE ... FROM tabla1 INNER JOIN tabla2 ON condicion

Combinación Externa: análoga a la combinación interna, pero no es excluyente. Las combinaciones externas devuelven todas las filas de una de las tablas o vistas mencionadas en la clausula FROM, como mínimo, siempre que tales filas cumplan con alguna de las condiciones de búsqueda de WHERE o HAVING La combinación externa puede ser diestra o siniestra, LEFT OUTER JOIN o RIGHT OUTER JOIN I

SELECT ... condicion

FROM tabla1 RIGHT OUTER JOIN tabla2 ON

SQLAlchemy. Consultas combinadas (JOIN) 1 2

from s q l a l c h e m y i m p o r t * ...

3 4 5 6 7 8 9 10

u s e r s = Table ( ’ u s e r s ’ , metadata , Column ( ’ u s e r _ i d ’ , I n t e g e r , p r i m a r y _ k e y = T r u e ) , Column ( ’ name ’ , S t r i n g ( 4 0 ) ) , Column ( ’ a g e ’ , I n t e g e r ) , ) i f not users . e x i s t s ( ) : users . create ()

11 12 13 14 15 16 17 18

emails = Table ( ’ emails ’ , metadata , Column ( ’ e m a i l _ i d ’ , I n t e g e r , p r i m a r y _ k e y = T r u e ) , Column ( ’ a d d r e s s ’ , S t r i n g ( 1 0 0 ) ) , Column ( ’ u s e r _ i d ’ , I n t e g e r , F o r e i g n K e y ( ’ u s e r s . u s e r _ i d ’ ) ) , ) i f not emails . e x i s t s ( ) : emails . create ()

SQLAlchemy. Consultas combinadas (JOIN) (cont.) 1 2 3 4 5 6 7 8 9 10 11 12 13

i = users . insert () i . execute ( { ’ name ’ : ’ Mary ’ , ’ a g e ’ : 3 0 } , { ’ name ’ : ’ J o h n ’ , ’ a g e ’ : 4 2 } , { ’ name ’ : ’ S u s a n ’ , ’ a g e ’ : 5 7 } , { ’ name ’ : ’ C a r l ’ , ’ a g e ’ : 33} ) i = emails . i n s e r t () i . execute ( { ’ a d d r e s s ’ : ’ mary@example . com ’ , ’ u s e r _ i d ’ : 1 } , { ’ a d d r e s s ’ : ’ john@nowhere . n e t ’ , ’ u s e r _ i d ’ : 2 } , { ’ a d d r e s s ’ : ’ john@example . o r g ’ , ’ u s e r _ i d ’ : 2 } , { ’ a d d r e s s ’ : ’ carl@nospam . n e t ’ , ’ u s e r _ i d ’ : 4 } , ) def run ( stmt ) : rs = stmt . execute ( ) f o r row i n r s : p r i n t row

14 15 16

s = s e l e c t ( [ u s e r s , e m a i l s ] , e m a i l s . c . u s e r _ i d == u s e r s . c . u s e r _ i d ) run ( s )

17 18 19 20

s = s e l e c t ( [ u s e r s . c . name , e m a i l s . c . a d d r e s s ] , e m a i l s . c . u s e r _ i d == u s e r s . c . u s e r _ i d ) run ( s )

21 22

s = j o i n ( users , emails ) . s e l e c t ( ) ; run ( s )

23 24 25

s = o u t e r j o i n ( users , emails ) . s e l e c t ( ) ; run ( s ) s = o u t e r j o i n ( emails , u s e r s ) . s e l e c t ( ) ; run ( s )

SQLAlchemy ORM

I

En los ejemplos previos empleamos SQLAlchemy como una capa abstracción para la construcción y manipulación de expresiones SQL.

I

Con SQLAlchemy podemos trabajar como un ORM puramente

I

Podemos mapear las estructuras y propiedades de una base de datos a objetos de Python y viceversa.

SQLAlchemy ORM. Mapper

1 2 3

I

Mapper asocia una tabla con una clase (la clase tiene que ser de nuevo estilo).

I

Define relaciones entre los objetos

u s e r s = Table ( ’ u s e r s ’ , metadata , Column ( ’ u s e r _ i d ’ , I n t e g e r , p r i m a r y _ k e y = T r u e ) , Column ( ’ name ’ , S t r i n g ( 4 0 ) ) , Column ( ’ a g e ’ , I n t e g e r ) , )

4 5 6

i f not users . e x i s t s ( ) : users . create ()

7 8 9 10 11 12

c l a s s User ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , u s e r _ i d =None , name=None , a g e =None ) : self . user_id=user_id s e l f . name = name s e l f . age = age

13 14

u s e r m a p p e r = mapper ( User , u s e r s _ t a b l e )

SQLAlchemy ORM. Session I I I

1

Session: representa una “unidad de trabajo”, que es una colección de objetos para ser almacendados Los objetos se “guardan” en la session, mediante session.add(obj) Se “vuelcan” los datos de los objetos a la base de datos, mediante session.flush().

s e s s i o n = c r e a t e _ s e s s i o n ( ) # c r e a m o s una s e s s i o n

2 3 4 5 6

# c r e a m o s un o b j e t o de l a c l a s e U s e r u s e r =User ( ) u s e r . name= ’ Ana ’ u s e r . a g e =15

7 8 9 10

# i n c l u i m o s e l o b j e t o en l a s e s s i o n y l o d e s c a r g a m o s / v o l c a m o s # en l a t a b l a a s o c i a d a a l a c l a s e U s e r s e s s i o n . add ( u s e r )

11 12 13 14

u s e r =User ( ) u s e r . name= ’ C a r l ’ u s e r . a g e =30

15 16

session . flush () I

De este modo, hemos insertado en la tabla de datos users una nueva fila

SQLAlchemy ORM. Query I I I 1 2

Un objeto Query se usa para hacer consultas empleando los objetos mapeados Se crea a partir de una session Construye sentencias select

# C r e a un o b j e t o q u e r y a s o c i a d o a l a c l a s e U s e r query = s e s s i o n . query ( User )

3 4 5 6

# O b t i e n e t o d o s l o s o b j e t o s U s e r de l a b a s e de d a t o s f o r user in query . a l l ( ) : p r i n t u s e r . name , u s e r . a g e

7 8 9 10

# D e v u e l v e un o b j e t o U s e r : e l p r i m e r u s u a r i o con nombre " mary " mary = s e s s i o n . q u e r y ( U s e r ) . f i l t e r _ b y ( name= ’ mary ’ ) . f i r s t ( ) p r i n t mary . u s e r _ i d , mary . name , mary . a g e

11 12

13

14

# D e v u e l v e t o d o s l o s u s u a r i o s cuyo nombre c o i n c i d e con " Mary " o " Carl " u s e r s = s e s s i o n . q u e r y ( U s e r ) . f i l t e r ( U s e r . name . i n _ ( [ ’ Ana ’ , ’ C a r l ’ ] ) ) . all () for u in users : p r i n t u . u s e r _ i d , u . name , u . a g e

15 16 17 18

# D e v u e l v e t o d o s l o s e l e m e n t o s de l a t a b l a , o r d e n a d o s p o r e d a d f o r i n s t a n c e i n s e s s i o n . query ( User ) . ord er_b y ( User . age ) : p r i n t i n s t a n c e . name , i n s t a n c e . a g e

SQLAlchemy ORM. Trabajando con dos tablas I Autores de obras de arte

Método de conectar: 1 2 3

from s q l a l c h e m y i m p o r t * from s q l a l c h e m y . orm i m p o r t mapper , r e l a t i o n s h i p , c r e a t e _ s e s s i o n import sys

4 5

6 7 8 9

10 11

12

d e f c o n e c t a r ( u s e r = ’ u s u a r i o ’ , pwd= ’ m i p a s s w o r d ’ , h o s t = ’ l o c a l h o s t ’ , database= ’ afi ’ ) : c a d = ’ mysql : / / ’ + u s e r + ’ : ’ +pwd+ ’@’ + h o s t + ’ / ’ + d a t a b a s e try : en gi ne = c r e a t e _ e n g i n e ( cad ) # # e n g i n e = c r e a t e _ e n g i n e ( ’ mysql : / / a n a : a n a 2 0 1 2 @ l o c a l h o s t / a f i ’) e n g i n e . c o n n e c t ( ) # e s t a b l e c e una c o n e x i o n e n g i n e . e c h o = F a l s e # T r u e : M u e s t r a l a s s e n t e n c i a s SQL que genera r e t u r n engine

13 14 15 16

e x c e p t exc . O p e r a t i o n a l E r r o r , e : p r i n t "ERROR : " , e . a r g s [ 0 ] r e t u r n None

SQLAlchemy ORM. Trabajando con dos tablas (cont.) Crear Tablas: 1 2 3 4 5

6 7 8

def c r e a r _ t a b l a s ( metadata ) : a u t o r = Table ( ’ Autor ’ , metadata , Column ( ’ i d _ a u t o r ’ , I n t e g e r , p r i m a r y _ k e y = T r u e ) , Column ( ’ nombre ’ , S t r i n g ( 5 0 ) , ) , Column ( ’ e m a i l ’ , S t r i n g ( 1 0 0 ) , u n i q u e = T r u e ) , # s i q u i s i e r a m o s que f u e s e u n i c a : u n i q u e = T r u e ) i f not autor . e x i s t s ( ) : autor . create ()

9 10 11 12 13 14 15

o b r a = T a b l e ( ’ Obra ’ , m e t a d a t a , Column ( ’ i d _ o b r a ’ , I n t e g e r , p r i m a r y _ k e y = T r u e ) , Column ( ’ t i t u l o ’ , S t r i n g ( 5 0 ) ) , Column ( ’ p r e c i o ’ , F l o a t ) , Column ( ’ i d _ a u t o r ’ , I n t e g e r , F o r e i g n K e y ( a u t o r . c . i d _ a u t o r ) ) , )

16 17 18 19

i f not obra . e x i s t s ( ) : obra . c r e a t e ( ) r e t u r n [ autor , obra ]

SQLAlchemy ORM. Trabajando con dos tablas (cont.) Clases que se van a mapear con las tablas: 1

2

# e l nombre de l o s a t r i b u t o s de l a c l a s e t i e n e n que c o i n c i d e r con l a s columnas # de l a t a b l a

3 4 5 6 7

c l a s s Autor ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , nombre=None , e m a i l =None ) : s e l f . nombre=nombre s e l f . email=email

8 9 10 11 12 13

c l a s s Obra ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , t i t u l o = ’ b l a b l a ’ , p r e c i o =0 , a u t o r =None ) : self . titulo=titulo self . precio=precio self . autor=autor

SQLAlchemy ORM. Trabajando con dos tablas (cont.) Mappers y Creación de instancias: 1 2 3 4 5 6 7

i f __name__== ’ __main__ ’ : engine= conectar ( ) i f e n g i n e ==None : p r i n t ’ Problemas a l c o n e c t a r ’ sys . e x i t ( ) m e t a d a t a = MetaData ( e n g i n e ) autor_tabla , obra_tabla = c r e a r _ t a b l a s ( metadata )

8 9 10

11

# mapea A u t o r con a u t o r _ t a b l a , y Obra con o b r a _ t a b l a mapper ( Autor , a u t o r _ t a b l a , p r o p e r t i e s ={ ’ o b r a s ’ : r e l a t i o n s h i p ( Obra ) } ) mapper ( Obra , o b r a _ t a b l a , p r o p e r t i e s ={ ’ a u t o r ’ : r e l a t i o n s h i p ( A u t o r ) })

12 13 14 15

# c r e a m o s d o s i n s t a n c i a s de A u t o r j u a n = A u t o r ( nombre= ’ J u a n ’ , e m a i l = ’ j u a n @ h o t m a i l . com ’ ) e v a = A u t o r ( nombre= ’ Eva ’ , e m a i l = ’ eva@gmail . com ’ )

16 17 18 19 20

# c r e a m o s t r e s i n s t a n c i a s de Obra o b r a 1 =Obra ( t i t u l o = " Hola " , p r e c i o = 5 0 . 5 , a u t o r = j u a n ) o b r a 2 =Obra ( t i t u l o = " E s c u l t u r a 1 " , p r e c i o =200 , a u t o r = e v a ) o b r a 3 =Obra ( t i t u l o = " P i n t u r a 2 " , p r e c i o =100 , a u t o r = j u a n )

SQLAlchemy ORM. Trabajando con dos tablas (cont.) Funcionamiento: 1 2 3 4 5 6 7 8

# c r e a m o s una s e s i o n session = create_session () # a n h a d i m o s l a s i n s t a n c i a s de t i p o Obra a l a s e s i o n . De # e s t e modo t a m b i e n s e a n h a d e n l a s i n s t a n c i a s de t i p o A u t o r s e s s i o n . add ( o b r a 1 ) s e s s i o n . add ( o b r a 2 ) s e s s i o n . add ( o b r a 3 ) session . flush ()

9 10 11 12 13 14

# c r e a m o s o t r a s e s s i o n y l a usamos p a r a h a c e r c o n s u l t a s # e m p l e a n d o l a s o b j e t o s mapeados session = create_session () query = s e s s i o n . query ( Autor ) J u a n = q u e r y . f i l t e r _ b y ( nombre= " j u a n " ) . f i r s t ( )

15 16

17 18 19

# a c c e d e m o s a l o s a t r i b u t o s d e l o b j e t o Autor , i n c l u i d o s l o s objetos relacionados p r i n t ’ Nombre= ’ , J u a n . nombre p r i n t ’ T i t u l o de l a P r i m e r a o b r a = ’ , J u a n . o b r a s [ 0 ] . t i t u l o p r i n t ’ Nombre= ’ , J u a n . o b r a s [ 0 ] . a u t o r . nombre

Introducción a P YTHON Programación en P YTHON Programación orientada a objetos SQLAlchemy Interfaces gráficas de usuario (GUI’s)

Desarrollo de GUI’s.WxPython

I

Hay varios toolkits de ventanas, multiplataforma, que se pueden usar en Python: I I I I

Tkinter (envoltura de Tcl/Tk) WxPython (envoltura de wxWidgests) PyQt (envoltura de Qt) PyGTK (envoltura de GTK)

Desarrollo de GUI’s.WxPython

WxPython I

Herramienta de desarrollo de Interfaces gráficas para Python.

I

Envoltura (wrapper) para Python de la wxWidgets, implementada en C++.

I

Permite crear programas con una interfaz de usuario robusta y de gran funcionalidad, de forma simple y sencilla.

I

Al igual que Python es OpenSource.

I

Multiplataforma (Linux, Windows y Mac).

I

Muy documentado y con numerosos ejemplos.

Desarrollo de GUI’s. WxPython Herramientas de desarrollo de Interfaces gráficas de WxPython I

WxGlade: genera código en Python, C++, Perl, Lisp y XRC. Multiplataforma. http://wxglade.sourceforge.net/

I

WxFormBuilder: permite generar código C++, XRC y Python (para el framework wxPython). Disponible para Linux y Mac. http://wxformbuilder.org/

I

WxDesigner: IDE de desarrollo de GUIs en wxWidgest. Genera código para C++, Python, Perl, Ruby, Lua. Sin actividad desde el 2007. a C++, Python, Perl y XML. Multiplataforma.

I

VisualWx: diseñador de WxWidgets. Permite exportar a http://visualwx.altervista.org/indexen.php

I

Boa constructor: Entorno de desarrollo de interfaces (al estilo Visual Studio). Sin actividad desde el 2007. http://boa-constructor.sourceforge.net/

I

DialogBlock: herramienta multiplataforma (de pago), de desarrollo de interfaces de usuario en WxWidgets. http://www.dialogblocks.com/

Desarrollo de GUI’s. WxPython

I

Usaremos WxGlade

I

WxGlade es un diseñador y constructor de interfaces gráficas que utiliza wxPython como framework gráfico para Python.

I

En WxGlade diseñamos la interfaz gráfica

I

Con un editor de Python editamos el código generado por WxGlade.

Desarrollo de GUI’s. WxPython

Funcionamiento de una aplicación de WxPython I

Mediante WxPython se crean interfaces gráficas de usuario orientadas a evetos.

I

A cada evento se le puede asociar una método, mediante un proceso denominado binding.

I

El manejador de eventos es el método que se ejecuta a consecuencia de la generación del evento.

I

Una aplicación de WxPython está a la espera de que se generen eventos, asociando los mismos a una función.

Desarrollo de GUI’s. WxPython

Estructura de una aplicación de wxPython I

Importar el módulo wx, donde están definidas todas las clases de wxPython.

I

Creación de la aplicación wxPython. Creación del contenedor:

I

I I I

Componentes. Binding. Manejador de eventos.

Desarrollo de GUI’s. Primer ejemplo. Lo mejor es un ejemplo: guiwx_basic.py. Construimos una ventana vacía. import wx

# Importamos wxPython

class App(wx.App): # Clase hija de wx.App # Método de inicialización de la aplicación def OnInit(self): # wx.Frame: crea la ventana frame=wx.Frame(None,-1,title=’Mi GUI’,size=(200,200)) frame.Show() # Mostramos la ventana return True # Este método siempre devuelve True app=App() # Instanciamos la clase App app.MainLoop() # La ventana permanece abierta esperando eventos

Desarrollo de GUI’s. Primer ejemplo.

I

La clase App hereda de la clase wx.App.

I

Al invocar el método MainLoop() hace que la GUI permanezca a la escucha de eventos de ratøsn y teclado.

I

En el método OnInit creamos los elementos gráficos de la aplicación.

I

En nuestra aplicación creamos el widget frame=wx.Frame(), que por defecto no se muestra.

I

frame.Show() muestra en la GUI el frame creado.

Desarrollo de GUI’s. Eventos

I

Todo control (derivado de wx.Window) define una serie de eventos que se lanzan cuando el usuario interactúa sobre ellos.

I

wxPython define por cada control una tabla de eventos que asocia un tipo de evento con un gestor del mismo.

Desarrollo de GUI’s. Eventos

import wx class App(wx.App): def OnInit(self): self.frame=wx.Frame(None,-1,title=’Mi primera ventana’, \ size=(300,400)) self.cajatexto=wx.TextCtrl(self.frame, -1, size=(220, -1), \ pos=(40,10)) self.Bind(wx.EVT_KEY_UP, self.OnKeyUP,self.cajatexto) butclose=wx.Button(self.frame, -1, ’Close’,pos=(40,50)) self.Bind(wx.EVT_BUTTON, self.OnClose, butclose) self.frame.Show() # self.frame.Fit() return True

Desarrollo de GUI’s. Eventos

def OnClose(self,event): self.frame.Destroy() def OnKeyUP(self, event): keycode = event.GetKeyCode() if keycode==13: # Codigo para el Intro print ’ Valor de la caja de texto= ’, self.cajatexto.GetValue() self.cajatexto.SetValue("") app=App(0) app.MainLoop()

Desarrollo de GUI’s. Ejercicios

Construye la siguiente ventana en WX P YTHON: I I I

Dos cajas de texto: ctrlTexto1 y ctrlTexto2. Tres botones: butCopiar, butBorrar y butClose. Eventos: I

I I

Al pulsar el botón butCopiar se copia el contenido de la caja de texto ctrlTexto1 en la caja de texto ctrlTexto2. Al pulsar el botón butBorrar se borre el texto de ambas cajas de texto. Al pulsar el botón butClose imprima el contenido de la caja ctrlTexto1 y seguidamente se cierre la aplicación.

Desarrollo de GUI’s. Sizer

I

Los widgets pueden disponerse con wx.Point y wx.Size, y mediante coordenadas.

I

wx.Sizer: mecanismo que permite definir la posición de wigtes en diálogos, independientes de la plataforma, teniendo en consideración las diferencias en tamaño y estilo de los controles individuales. I I I

I

Maneja el tamaño y posición de sus widgets. Se asigna a un contendor (wx.Panel o wx.Frame). Los subwidgets que se crean dentro del contenedor hay que incluirlos por separado al sizer. Un sizer puede estar incluido dentro de otro sizer.

Desarrollo de GUI’s. Sizer

I

Tipos: I

I

I I I

wx.GridSizer: dispone los controles en una matriz cuyas celdas son del mismo tamaño. wx.BoxSizer: permite organizar los widgets en horizontal o vertical ((wx.VERTICAL/wx.HORIZONTAL))

wx.FlexGridSizer wx.StaticBoxSizer wx.NotebookSizer

View more...

Comments

Copyright © 2017 DATENPDF Inc.