Clase 4: Modularizando código



Documentos relacionados
Nano Taller de Python

Programación I: Funciones y módulos

Tutorial: Primeros Pasos con Subversion

Creación de Funciones de Conducción

Centro de Capacitación en Informática

Curso de Python Inicial

La plantilla propone aprovechar esta estructura en común y sólo modificar el contenido del área del documento que sea diferente.

Tutorial: Python + Soap Web Service. Daniel Montenegro Cordero

Manual de NetBeans y XAMPP

Utilización del sistema operativo GNU/ Linux en las netbooks

Capítulo 1 Documentos HTML5

PARTE 3 ECUACIONES DE EQUIVALENCIA FINANCIERA T E M A S

Adaptación al NPGC. Introducción. NPGC.doc. Qué cambios hay en el NPGC? Telf.: Fax.:

BREVE MANUAL DE SOLVER

GENERACIÓN DE CÓDIGO

Manual para la utilización de PrestaShop

ÍTEMS DEL MENÚ CREACIÓN Y GESTIÓN (Última revisión: lunes, 9 de marzo de 2009)

Curso de PHP con MySQL Gratis

Fórmulas. Objetivos y Definición. Definir fórmulas nos brinda una forma clave de compartir conocimiento y obtener código generado optimizado

Sesión 8 Sensor de Ultrasonido

Clase 3: Archivos (texto, csv, dbf, Excel)

Internet Information Server

CRECE EN INTERNET. Llegar a buen puerto: buscando información

Ejemplos de conversión de reales a enteros

Programando con Enchanting

Programa diseñado y creado por Art-Tronic Promotora Audiovisual, S.L.

D.T.Informática S.L. [Sistema hada] hilo Administrador Desarrollo Activo

COMO CONFIGURAR UNA MAQUINA VIRTUAL EN VIRTUALBOX PARA ELASTIX

Introducción a PHP. * No es necesario declarar previamente las variables.

HERRAMIENTAS DE ACCESS ACCESS Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

Estructuras de Datos y Algoritmos Tecnólogo en Informática

Modulo 1 El lenguaje Java

Capítulo 9. Archivos de sintaxis

VMWare Workstation

CREACIÓN Y CONFIGURACIÓN DE WIKIS

Plantillas Office. Manual de usuario Versión 1.1

Informe de Segunda Presentación

Este taller estará orientado a aquellas personas que no han visto jamás Python y también a aquellos que quieran pasar de Python 2 al 3

TUTORIAL DE PHP. M. en C. Erika Vilches. Parte 2.

Introducción a la Programación en MATLAB

MANUAL DE LA CONFIGURACIÓN Y USO DEL MÓDULO DE ASM PARA PRESTASHOP

PROGRAMACIÓN EN PYTHON 2. Clara Higuera Laboratorio Integrado de Biofísica y Bioinformática Nov-2015

TUTORIAL DE INSTALACIÓN PARA VIRTUALBOX

GENERAR DOCUMENTOS HTML USANDO LENGUAJE PHP. EJERCICIO RESUELTO EJEMPLO SENCILLO. (CU00733B)

Pruebas de unidad con JUnit

Servicio de Informática Vicerrectorado de Tecnologías de la Información y la Comunicación

Servicio de Informática Vicerrectorado de Tecnologías de la Información y la Comunicación

Programando con Pl/Python

Como montar un servidor web + Anonimización con Tor

Facturación Automática de Ventas WhitePaper Noviembre de 2006

Vamos a ver las dos formas básicas de arrancar PowerPoint.

Generador de Proxy remoto JavaScript.

Programación estructurada

SIIGO Pyme. Templates. Cartilla I

Indicaciones específicas para los análisis estadísticos.

Un kilobyte (KB) son 1024 bytes, un Megabyte (MB) son 1024 KB, un Gigabyte son 1024 Mb

Capítulo 12: Indexación y asociación

H E R R A M I E N T A S D E A N Á L I S I S D E D A T O S HERRAMIENTAS DE ANÁLISIS DE DATOS

CONSULTAS DE RESUMEN SQL SERVER Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

INGENIERÍA DE SOFTWARE:

Algoritmos y Programación I Con lenguaje Python

LABORATORIO Nº 2 GUÍA PARA REALIZAR FORMULAS EN EXCEL

Manual de operación Tausend Monitor

Introducción a PYTHON. Cesar Husillos & Víctor Terrón. Abril de 2014

MANUAL DE USUARIO PLAN GENÉRICO DE AUTOCONTROL EN HOSTELERÍA ASOCIACIÓN DE EMPRESARIOS DE HOSTELERÍA DE GIPUZKOA 1

FEDERACIÓN ARGENTINA DE EMPLEADOS DE COMERCIO Y SERVICIOS. Página 1 de 22 MESA DE AYUDA: ayuda@faecys.org.ar

Preliminares. Tipos de variables y Expresiones

MANUAL DE LA CONFIGURACIÓN Y USO DEL MÓDULO DE ASM PARA PRESTASHOP

Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro

En cualquier caso, tampoco es demasiado importante el significado de la "B", si es que lo tiene, lo interesante realmente es el algoritmo.

Clase 4: Un poco más de Python

8. Sentencia return y métodos

Partes de un programa en Java. A. Ejemplo de un Programa en Java /* Programa Ejemplo de Java: Muestra una Ventana Archivo: Ejemplo1.

CVS Concurrent Versions System Manual de Usuario

select nombre from profesores where categoria='aso6';

Charla N 6: Utilidades de Consulta de datos.

INSTALACIÓN DE GITLAB

Descarga, instalación y uso de herramientas:

Manual de rol gestor de GAV para moodle 2.5

Fundamentos de la Programación

Formularios. Formularios Diapositiva 1

Instituto Tecnológico Las Américas (ITLA) Sistemas Operativos 3 (SO3) Daniel Alejandro Moreno Martínez. Matrícula:

ReStructuredText, Sphinx, Sagepedia Cómo escribir documentación para python y Sage

Objetivos de la práctica: - Practicar uso de ficheros: abrir, cerrar y tratamiento de información contenida en el fichero.

INSTRUCTIVO DEL COMANDO MAKE

El proceso de edición digital en Artelope y CTCE

**NOTA** las partes tachadas todavía no están escritas, se ira actualizando poco a poco el documento

Prof. Dr. Paul Bustamante

Configurar un Servidor FTP. Serv-U

Roberto Quejido Cañamero

LABORATORIO Nº 3 PRÁCTICA DE FUNCIONES EN MICROSOFT EXCEL

Curso PHP Módulo 1 R-Luis

Tutorial Servicios Web

Práctica 5. Curso

AGREGAR UN EQUIPO A UNA RED Y COMPARTIR ARCHIVOS CON WINDOWS 7

MANUAL DE USUARIO APLICACIÓN SYSACTIVOS

MANUAL DE AYUDA TAREA PROGRAMADA COPIAS DE SEGURIDAD

Instalación de FileZilla FTP Server

MANUAL COPIAS DE SEGURIDAD

Transcripción:

Clase 4: Modularizando código Ejercicio preparatorio: Determinar si un número es primo o no El siguiente código verifica si un número es primo. Hay muchas maneras de hacer esto y esta está lejos de ser la mejor, solo se muestra a modo de ejemplo. n = int(raw_input('verificar si este nro. es primo: ')) primo = for i in xrange(2,n): if n%i == 0: print '%s no es primo' %n primo = False break if primo: print '%s es primo' %n El uso de la variable primo sirve para "marcar" que el flujo del programa pasó por un lugar determinado. A eso se lo denomina "flag". Ejemplo de uso de este código: >>> Verificar si este nro. es primo: 25 No es primo >>> Verificar si este nro. es primo: 61 61 es primo Usando else en el for. El bloque bajo el else se ejecuta en el caso que todos los elementos del ciclo se hayan recorrido (o sea, que no haya salido por break). Esto evita usar el flag del ejemplo anterior. n = int(raw_input('verificar si este nro. es primo: ')) for i in range(2,n): if n%i == 0: print '%s no es primo' %n break else: print '%s es primo' %n Ejemplo de uso: >>> Verificar si este nro. es primo: 25 No es primo >>> Verificar si este nro. es primo: 61 61 es primo Funciones Ya hemos usado funciones si consideramos a las funciones incoorporadas en Python (built-in). Ejemplos:

>>> len([2,3,4,5]) 4 >>> max([1,6,98,2,32,21,8]) 98 >>> range(5) [0, 1, 2, 3, 4] >>> dir(str) [' add ', ' class ', ' contains ', ' delattr ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getitem ', ' getnewargs ', ' getslice ', ' gt ', ' hash ', ' init ', ' le ', ' len ', ' lt ', ' mod ', ' mul ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' rmod ', ' rmul ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] Las funciones len() (de lenght, longitud), max(), y min() tienen nombres bastante autoexplicativos. La función dir() lista los métodos (funciones) asociadas a un objeto, en este caso vemos los métodos asociado a las cadenas. Las funciones usan parámetros o argumentos (buscarlos en los ejemplos de arriba). Se pueden usar funciones sin parametros: >>> dir() [' builtins ', ' doc ', ' file ', ' name ', ' package ', 'esprimo', 'i', 'main', 'n', 'primo'] En el caso de dir() sin parámetros, se muestran los nombres de las variables que están en memoria en el momento de ser llamada. Otras funciones requieren parámetros de manera obligatoria: >>> range() Traceback (most recent call last): File "<pyshell#11>", line 1, in <module> range() TypeError: range expected at least 1 arguments, got 0 El concepto es el mismo: Un nombre que invoca un conjunto de instrucciones para ser ejecutado. Es una manera de modularizar nuestro código. Creando funciones Forma genérica def Nombre(param1, param2,.): ''' DOCSTRING ''' <CODIGO> return DATA

Por ejemplo la siguiente función convierte el valor ingresado de pulgadas a centimetros: def p_cm(p): ''' Ingresa pulgadas, devuelve centimetros ''' cm = p * 2.54 return cm Ahora estamos en condiciones de "funcionalizar" el código anterior que determinaba si un número es o no es primo: def esprimo(n): for i in range(2,n): if n%i == 0: return False return Usando funciones El modo general es: >>> Nombre(parametro) Ejemplos: Usando la función p_cm (función que convierte de pulgadas a centimetros): >>> print p_cm(5) 12.7 Usando la funcón esprimo (devuelve si n es primo y False en caso contrario): >>> print esprimo(2) >>> print esprimo(5) >>> print esprimo(10) False Todas las funciones devuelven algo. Las que aparentemente no devuelven nada, están devolviendo None: def guarda_lista(lista, nombre): Una lista (lista) se guarda en un archivo (nombre) fh = open(nombre,'w') for x in lista: fh.write('%s\n'%x) fh.close() return None Uso de la función: >>> guarda_lista([1,2,3],'algo.txt') >>>

Notar que retorna la función anterior. Los valores deberían retornarse solo via return, para cumplir con la llamada "integridad referencial" (esto es, que una función no modifique el resto del programa). Python no obliga al programador a cumplir con dicha propiedad ya que es posible alterar un dato mutable dentro de una función y esta modificación puede ser vista desde fuera de la misma. Ámbito de una función Los valores declarados en una función son reconocidos solamente dentro de la función. Cuando un valor no es encontrado en el ámbito donde se la invoca, se busca en el ámbito inmediatamente anterior. Se puede usar global para declarar variables globales dentro de funciones, aunque su uso no es recomendable. Estas variables globales nos permiten cambiar el contenido de las variables del módulo que contiene a la función. Ver: def test(): z = 10 print ('Valor de z: %s'%z) return None def test2(): global z z=10 print ('Valor de: %s'%z) return None Probando el ámbito de las variables: >>> z=50 >>> test() Valor de z: 10 >>> z 50 >>> test2() Valor de z: 10 >>> z 10 Parámetros Los parámetros se declaran en la primera linea de la función. Parametros con valores pre-establecidos (por defecto) Se indican los valores por defecto de la forma clave=valor: def fn(par=valor1, par2=valor2,...) Podemos reescribir la función guarda_lista teniendo un archivo de salida pre-establecido: def guarda_lista(lista, nombre='salida.txt'): Una lista (lista) se guarda en un archivo (nombre) fh = open(nombre,'w')

for x in lista: fh.write('%s\n'%x) fh.close() return None Ahora se lo puede usar: guarda_lista([1,2,3]) Cantidad indeterminada de parametros El último parametro es precedido por un * : def promedio(*numeros): total = sum(numeros) return float(total)/len(numeros) Número indeterminado de parametros en clave (keyword) En este caso se usa ** y se interpreta como un diccionario: def cli(nombre, **parametros): linea = '' for pname,pval in parametros.iteritems(): linea += ' -%s %s' %(pname,pval) return nombre+linea Funciones para procesar secuencias Las funciones map(), filter() y reduce() son muy útiles a la hora de trabajar con secuencias (listas, tuplas, strings). map() map(función, secuencia) llama a cada ítem de función y devuelve una lista de los valores que devuelve función. Por ejemplo, para obtener el logaritmo en base 10 de los números del 1 al 5: import math print map(math.log10,range(1,6)) Lo que dá como resultado: [0.0, 0.3010299956639812, 0.47712125471966244, 0.6020599913279624, 0.69897000433601886] filter() filter(función, secuencia) devuelve una secuencia que consiste en los ítems de secuencia para los cuales función(item) es verdadero. De esta manera podemos por ejemplo usar la función que determina si un número es primo o no para filtrar los números del 1 al 10 y devolver solo los primos: print filter(esprimo,range(1,11)) Lo que devuelve:

[1, 2, 3, 5, 7] Hay que notar que filter(p,s) es el equivalente a [x for x in S if P(x)], aunque se prefiere la forma con filter() por claridad. reduce() reduce(función, secuencia) aplica función (de 2 argumentos) de manera acumulativa sobre los items de la secuencia hasta llegar a obtener un valor único. Ejemplo: >>> def multiple(a,b):... return a*b... >>> print reduce(multiple,range(1,5)) 24 Lambda: Funciones "en línea" sin nombre Son funciones anónimas (no relacionadas con un nombre) y se las suele usar con funciones como las vistas anteriormente (filter(), map() y reduce()). Por ejemplo la función par() me devuelve si un número es par o no: def par(n): if n % 2 == 0: return return False Para ver los números pares de una lista, usando par() y filter(): filter(par,lista) Con lambda se puede hacer lo mismo aunque sin definir previamente la función par(): >>> filter(lambda x: if x%2==0 else False,range(10)) [0, 2, 4, 6, 8] Docstrings El str con triple comillas que está como primera linea en la definición de una función es la documentación del módulo. Es optativa pero recomendable. Los interpretes interactivos la usan para proporcionar la ayuda en línea y hay programas que arman la documentación en base a dichos strings. Por esta razón, existe un lenguaje que permite ser escrito dentro de un Docstring que no dificulta la lectura del código fuente y a su vez permite generar documentación formateada para la web (html) como para imprimir (pdf). Este lenguaje se llama ReStructuredText (se abrevia rst o ReST). También se lo puede usar para hacer tests, para mas información sobre como usar Docstrings para hacer test, ver mas adelante la sección "Testeo de módulos". Este libro está hecho integramente en rst y pasado a HTML y a PDF utilizando rst2web y rst2pdf respectivamente. Para mas info ver:

PEP-257: http://www.python.org/dev/peps/pep-0257 rest: http://docutils.sourceforge.net/rst.html Generadores En lineas generales un generador es una función que guarda su estado interno al salir. Usa yield en lugar de return y se la usa para devolver valores de manera gradual (elemento por elemento) en lugar de devolver un contenedor con varios elementos. Función que devuelve todos los números primos hasta un valor dado: def esprimo(n): for i in range(2,n-1): if n%i == 0: return False return def putn(n): p = [] for i in xrange(1,n): if isprime(i): p.append(i) return p El problema con la función putn() es que devuelve todos los valores juntos, cuando se podrian devolver de manera progresiva usando un generador: def gputn(n): for i in xrange(1,n): if esprime(i): yield i En este código no existe la lista p ya que cada valor es devuelto de manera individual. Módulos Usando módulos Python trae varios modulos, lo que en su conjunto se lo conoce como la biblioteca estándar (standard library) >>> import os >>> os.getcwd() '/home/sbassi' >>> os.sep '/' >>> getcwd() Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> getcwd() NameError: name 'getcwd' is not defined >>> from os import getcwd >>> getcwd() '/home/sbassi'

Tambien puede importarse todo el contenido de un módulo con from os import *, pero no es recomendable. Cambiar el nombre de un objeto al importarlo Para abreviar un nombre es posible usar un alias: >>> import xml.etree.elementtree as e >>> e <module 'xml.etree.elementtree' from '/usr/lib/python2.6/xml/etree/elementtree.pyc'> Instalando módulos Una manera de instalar un módulo es copiando el módulo al llamado PYTHONPATH. Esta denominación engloba varios directorios como el mismo donde está el programa, el directorio donde está el ejecutable de Python y un directorio especial para módulos. En el caso particular de mi instalación de Python, el PYTHONPATH comprende los siguiente directorios: >>> import sys >>> sys.path ['/home/sbassi', '/usr/bin', '/usr/local/lib/python2.6/dist-packages/xlrd-0.7.1-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/biopython-1.52-py2.6-linux-i686.egg', '/usr/local/lib/python2.6/dist-packages/cheetah-2.4.1-py2.6-linux-i686.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages/pil', '/usr/lib/python2.6/dist-packages/numeric', '/usr/local/lib/python2.6/dist-packages'] También se puede usar el gestor de paquetes de nuestro sistema operativo (apt-get install módulo en el caso de Ubuntu). Si bien esta es la manera mas fácil de instalar módulos, hay que tener en cuenta que a veces los paquetes disponibles por este sistema pueden no ser los mas recientes. Esto se debe a que suele haber un retraso entre la aparición de un paquete y su incorporación a repositorio de paquetes del sistema operativo. Instalación fácil con easy_install Desde la línea de comando: # apt-get install python-setuptools # easy_install nombre_del_modulo Para instalar módulos con Easy install sin ser administrador podemos usar virtualenv. Este programa nos que permite instalar módulos de manera independiente de la instalación principal de Python. virtualenv se puede instalar como administrador: # easy_install virtualenv o se puede bajar e instalar a un directorio de usuario (sin instalación general): $ wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.3.2.tar.gz $ tar xfz virtualenv-1.3.2.tar.gz $ cd virtualenv-1.3.2 Luego, para usar el interprete de Python con el módulo instalado, se ejecuta de esta manera:

$ mkdir M_DIR $ virtualenv --no-site-packages M_DIR New python executable in M_DIR/bin/python Also creating executable in M_DIR/bin/python Installing setuptools...done. Luego hay que ir a ese directorio y activar el entorno virtual: $ cd M_DIR $. bin/activate (M_DIR)$ Esto es válido para *nix, para Windows hay que usar: > \path\to\env\bin\activate.bat (M_DIR)> IMPORTANTE: Tener en cuenta el prompt que indica con el nombre del directorio entre paréntesis que estamos en el entorno virtual. Ejemplo de uso: (M_DIR)$ easy_install Numpy Searching for Numpy Reading http://pypi.python.org/simple/numpy/ (...cut...) Finished processing dependencies for Numpy (M_DIR)$ easy_install biopython (...cut...) Finished processing dependencies for biopython De esta manera instalamos Numpy y Biopython sin afectar la instalación original. Instalación estándar La siguiente es la manera mas frecuente de instalar módulos (si el módulo lo permite): python setup.py install El archivo setup.py debe ser provisto por el módulo. Creación de módulos Los módulos son archivos.py con código Python: # utils.py file def savelist(lt,fn="temp.txt"): """ Una lista (lt) es guardada

en un archivo (fn) """ fh = open(fn,"w") for x in lt: fh.write("%s\n"%x) fh.close() return None Asi puede usarse la función creada en nuestro nuevo módulo (suponiendo que lo hayamos instalado correctamente): >>> import utils >>> utils.savelist([1,2,3]) Testeo de módulos Python cuenta con una herramienta que permite probar que los componentes de un módulo tiene el comportamiento esperado. Para eso se ejecuta el módulo como un programa individual (en lugar de ser llamado dentro de otro programa). Como primera medida hay que poder diferenciar cuando un módulo corre de manera stand-alone o dentro de un programa (como módulo). Para eso se verifica la variable especial name if name == " main ": # Hacer algo Para testear, usar el módulo doctest: def esprimo(n): """ Ver si n es un nro. primo. Ejemplo de uso: >>> esprimo(0) False >>> esprimo(1) >>> esprimo(2) >>> esprimo(3) >>> esprimo(4) False >>> esprimo(5) """ if n<=0: # Solo para >0. return False for x in range(2,n): if n%x==0: return False else: pass return

def _test(): import doctest doctest.testmod() if name == " main ": _test() Si esta función (esprimo()) es llamada desde nuestro programa, se ejecuta normalmente. En cambio, si ejecutamos esto directamente (no desde otro programa), se ejecuta el test. Estos tests son utiles para saber si hay algún problema luego de modificar la función testeada. Por ejemplo podemos querer optimizar la velocidad, hacer algunas modificaciones y luego gracias al test descubrimos que no solo modificamos la velocidad, sino también los resultados. Agradecimientos Claudio Canepa Alejandro Santos