Programación básica con Python

Esta sesión pretende ser una introducción a algunos aspectos básicos de la programación como el uso de variables, listas, ficheros, etc. Utilizaremos Python como lenguaje de programación.

Python es un lenguaje de programación poderoso y fácil de aprender. Cuenta con estructuras de datos eficientes y de alto nivel y un enfoque simple pero efectivo a la programación orientada a objetos. Su sintaxis simple, clara y sencilla (que se asemeja al pseudocódigo); el tipado dinámico, el gestor de memoria, la gran cantidad de librerías disponibles y la potencia del lenguaje, entre otros, hacen que desarrollar una aplicación en Python sea sencillo y muy rápido.

Para la sesión necesitaremos un editor de textos. En Mac podeis usar TextEdit y en Linux gedit. En Windows os recomiendo instalar Notepad++. Para un editor más avanzado, os recomiendo probar SublimeText.

Python es un lenguaje interpretado, lo cual puede ahorrarte mucho tiempo durante el desarrollo ya que no es necesario compilar ni enlazar. El intérprete puede usarse interactivamente, lo que facilita experimentar con características del lenguaje, escribir programas descartables, o probar funciones cuando se hace desarrollo de programas de abajo hacia arriba.

El intérprete de Python estándar incluye un modo interactivo en el cual se escriben las instrucciones en una especie de intérprete de comandos: las expresiones pueden ser introducidas una a una, pudiendo verse el resultado de su evaluación inmediatamente, lo que da la posibilidad de probar porciones de código en el modo interactivo antes de integrarlo como parte de un programa. Esto resulta útil tanto para las personas que se están familiarizando con el lenguaje como para los programadores más avanzados.

Por lo general, el intérprete de Python se instala en /usr/local/bin/python y es posible iniciarlo ingresando la orden:

python

…en la terminal. En máquinas con Windows, la instalación de Python por lo general se encuentra en C:\Python27, aunque se puede cambiar durante la instalación.

En este modo espera el siguiente comando con el prompt primario, usualmente tres signos mayor-que (>>>); para las líneas de continuación espera con el prompt secundario, por defecto tres puntos (…). Antes de mostrar el prompt primario, el intérprete muestra un mensaje de bienvenida reportando su número de versión y una nota de copyright:

alabarga@TRAVELLER:~$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

Datos numéricos

El intérprete actúa como una simple calculadora; podés ingresar una expresión y este escribirá los valores. La sintaxis es sencilla: los operadores +, -, * y / funcionan como en la mayoría de los lenguajes (por ejemplo, Pascal o C); los paréntesis pueden ser usados para agrupar. Por ejemplo:

>>> 4
>>> 2+2

Entre los operadores aritméticos que Python utiliza, podemos encontrar los siguientes:

Variables

Una variable es un espacio para almacenar datos modificables, en la memoria de un ordenador. En Python, una variable se define con la sintaxis:

nombre_de_la_variable = valor_de_la_variable

Cada variable, tiene un nombre y un valor, el cual define a la vez, el tipo de datos de la variable. Se suelen utilizar nombres descriptivos y en minúsculas. Para nombres compuestos, se separan las palabras por guiones bajos.
Existe un tipo de “variable”, denominada constante, la cual se utiliza para definir valores fijos, que no requieran ser modificados.Se suelen utilizar nombres en mayúsculas

Para imprimir un valor en pantalla, en Python, se utiliza la palabra clave print:

>>> ancho = 20
>>> largo = 5*9
>>> area = ancho * largo
>>> print area

Selection_107

Funciones

Una función, es la forma de agrupar expresiones y sentencias (algoritmos) que realicen
determinadas acciones, pero que éstas, solo se ejecuten cuando son llamadas. Es decir,
que al colocar un algoritmo dentro de una función, al correr el archivo, el algoritmo no será
ejecutado si no se ha hecho una referencia a la función que lo contiene.

En Python, la definición de funciones se realiza mediante la instrucción def más un
nombre de función descriptivo -para el cuál, aplican las mismas reglas que para el nombre
de las variables- seguido de paréntesis de apertura y cierre. Como toda estructura de
control en Python, la definición de la función finaliza con dos puntos (:) y el algoritmo que
la compone, irá identado con 4 espacios:

def mi_funcion():
    # aquí el algoritmo

Una función, no es ejecutada hasta tanto no sea invocada. Para invocar una función, simplemente se la llama por su nombre:

def saludar():
    print "Hola Mundo"
saludar()

Una función también puede devolver datos, y éstos, pueden ser asignados a una variable:

def saludo():
    return "Hola Mundo"
frase = saludo()
print frase

Un parámetro es un valor que la función espera recibir cuando sea llamada (invocada), a
fin de ejecutar acciones en base al mismo. Una función puede esperar uno o más
parámetros (que irán separados por una coma) o ninguno.

def mi_funcion(param1, param2):
    # algoritmo
>>> def suma(a,b):
...     return a + b
... 
>>> suma(1,2)
3

Tipos de datos

Una variable (o constante) puede contener valores de diversos tipos. Entre ellos:

Cadena de texto (string):

mi_cadena = "Hola Mundo!"
mi_cadena_multilinea = """
Esta es una cadena
de varias lineas
"""

Número entero:

edad = 35

Número real:

precio = 7435.28

Booleano (verdadero / Falso):

verdadero = True

Las cadenas de texto pueden ser concatenadas (pegadas juntas) con el operador + y repetidas con *:

>>> palabra = 'Ayuda' + 'A'
>>> palabra
'AyudaA'
>>> '<' + palabra*5 + '>'
''

Desde la versión 2.0 de Python, se encuentra disponible un nuevo tipo de datos para que los
programadores almacenen texto: el objeto Unicode. Puede ser usado para almacenar y manipular datos Unicode y se integran bien con los objetos existentes para cadenas de texto, mediante auto-conversión cuando es necesario.

Unicode tiene la ventaja de tener un número ordinal para cada carácter usado tanto en textos modernos como antiguos. Previamente, había sólo 256 ordinales posibles para los caracteres en scripts. Los textos eran típicamente asociados a un código que relaciona los ordinales a caracteres en scripts. Esto lleva a mucha confusión, especialmente al internacionalizar software. Unicode resuelve estos problemas definiendo una sola codificación para todos los scripts.

Crear cadenas Unicode en Python es tan simple como crear cadenas de texto normales:

>>> u'Hola Mundo!'
u'Hola Mundo!'

La función incorporada len() devuelve la longitud de una cadena de texto:

>>> s = 'supercalifrastilisticoespialidoso'
>>> len(s)
33

Listas

Python tiene varios tipos de datos compuestos, usados para agrupar otros valores. El más versátil es la lista, la cual puede ser escrita como una lista de valores separados por coma (ítems) entre corchetes. No es necesario que los ítems de una lista tengan todos el mismo tipo.

>>> a = [1, 2, 3, 4]
>>> a
[1, 2, 3, 4]

b = range(1,5)

Tuplas

Una tupla es una variable que permite almacenar varios datos inmutables (no pueden
ser modificados una vez creados) de tipos diferentes

>>> a = (1, 2, 3, 4)
>>> a
(1, 2, 3, 4)

Diccionarios

Mientras que a las listas y tuplas se accede solo y únicamente por un número de índice, los diccionarios permiten utilizar una clave para declarar y acceder a un valor:

mi_diccionario = {'clave_1': valor_1, 'clave_2': valor_2,'clave_3': valor_3}
print mi_diccionario['clave_2']
ciudades = {'Madrid':3207247,'Barcelona':1611822,'Valencia':792303,'Sevilla':700169,'Zaragoza':682004,'Malaga':568479}

Datos originales

Estructuras de Control de Flujo

Una estructura de control, es un bloque de código que permite agrupar instrucciones de
manera controlada. En este capítulo, hablaremos sobre dos estructuras de control:

• Estructuras de control condicionales
• Estructuras de control iterativas

Identación
Para hablar de estructuras de control de flujo en Python, es imprescindible primero, hablar
de identación. En un lenguaje informático, la identación es lo que la sangría al
lenguaje humano escrito (a nivel formal). Así como para el lenguaje formal, cuando uno
redacta una carta, debe respetar ciertas sangrías, los lenguajes informáticos, requieren
una identación.

No todos los lenguajes de programación, necesitan de una identación, aunque sí, se
estila implementarla, a fin de otorgar mayor legibilidad al código fuente. La mayoría utilizan otros caracteres de control como paréntesis, llaves o puntos y coma. Pero en el caso
de Python, la identación es obligatoria, ya que de ella, dependerá su estructura.

Así, una identación de 4 (cuatro) espacios en blanco, indicará que las instrucciones identadas, forman parte de una misma estructura de control.

Una estructura de control, entonces, se define de la siguiente forma:

inicio de la estructura de control:
    expresiones

Las estructuras de control condicionales, son aquellas que nos permiten evaluar si una o
más condiciones se cumplen, para decir qué acción vamos a ejecutar. La evaluación de condiciones, solo puede arrojar 1 de 2 resultados: verdadero o falso (True o False).

Para describir la evaluación a realizar sobre una condición, se utilizan operadores
relacionales (o de comparación):

Y para evaluar más de una condición simultáneamente, se utilizan operadores lógicos:

Las estructuras de control de flujo condicionales, se definen mediante el uso de tres
palabras claves reservadas, del lenguaje: if (si), elif (sino, si) y else (sino).

Veamos algunos ejemplos:

Si semáforo esta en verde, cruzar la calle. Sino, esperar.

if semaforo == verde:
    print "Cruzar la calle"
else:
    print "Esperar"

Si gasto hasta $100, pago con dinero en efectivo. Sino, si gasto más de $100 pero menos de $300, pago con tarjeta de débito. Sino, pago con tarjeta de crédito.

compra = 120 # cambialo por el valor que quieras
if compra <= 100:
    print "Pago en efectivo"
elif compra > 100 and compra < 300:
    print "Pago con tarjeta de débito"
else:
    print "Pago con tarjeta de crédito"

Selection_108

Selection_109

Estructuras de control iterativas

A diferencia de las estructuras de control condicionales, las iterativas (también llamadas
cíclicas o bucles), nos permiten ejecutar un mismo código, de manera repetida, mientras
se cumpla una condición.

En Python se dispone de dos estructuras cíclicas:
• El bucle for
• El bucle while

Las veremos en detalle a continuación.

Bucle for
El bucle for, en Python, es aquel que nos permitirá iterar sobre una variable compleja, del
tipo lista o tupla:

Por cada nombre en mi_lista, imprimir nombre

mi_lista = ['Juan', 'Antonio', 'Pedro', 'Herminio']
for nombre in mi_lista:
    print nombre
for anio in range(2001, 2013):
    print "Informe anual", str(anio)

Bucle while
Este bucle, se encarga de ejecutar una misma acción “mientras que” una determinada
condición se cumpla:

i = 0
while (i<10):
    print i
    i = i + 1
num = 8
guess = 0
while guess != num :  
    guess = raw_input("Introduzca un número del 1 al 9:")
    guess = int(guess)
print "Acertaste!"

Módulos

Si salís del intérprete de Python y entrás de nuevo, las definiciones que hiciste (funciones y variables) se pierden. Por lo tanto, si querés escribir un programa más o menos largo, es mejor que uses un editor de texto para preparar la entrada para el interprete y ejecutarlo con ese archivo como entrada. Esto es conocido como crear un guión, o script. Si tu programa se vuelve más largo, quizás quieras separarlo en distintos archivos para un mantenimiento más fácil. Quizás también quieras usar una función útil que escribiste desde distintos programas sin copiar su definición a cada programa.

Para soportar esto, Python tiene una manera de poner definiciones en un archivo y usarlos en un script o en una instancia interactiva del intérprete. Tal archivo es llamado módulo; las definiciones de un módulo pueden ser importadas a otros módulos o al módulo principal (la colección de variables a las que tenés acceso en un script ejecutado en el nivel superior y en el modo calculadora).

Un módulo es una archivo conteniendo definiciones y declaraciones de Python. El nombre del archivo es el nombre del módulo con el sufijo .py agregado. Dentro de un módulo, el nombre del mismo (como una cadena) está disponible en el valor de la variable global __name__.

El encoding (o codificación) es otro de los elementos del lenguaje que no puede omitirse
a la hora de hablar de estructuras de control.

El encoding no es más que una directiva que se coloca al inicio de un archivo Python, a fin de indicar al sistema, la codificación de caracteres utilizada en el archivo.

# -*- coding: utf-8 -*-

def suma(a,b):
     return a + b

if __name__ == 'main':
   print "Uso: c = suma(a,b)" 

La función dir()
La función integrada dir() se usa para encontrar qué nombres define un módulo. Devuelve una lista ordenada de cadenas:

>>> import operaciones
>>> dir(operaciones)

Estos módulos, a la vez, pueden formar parte de paquetes. Un paquete, es una carpeta que contiene archivos .py. Pero, para que una carpeta pueda ser considerada un paquete, debe
contener un archivo de inicio llamado __init__.py. Este archivo, no necesita contener
ninguna instrucción. De hecho, puede estar completamente vacío.

Selection_110

El zen de Python

>>> import this

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

>>> import math
>>> print 'El valor de PI es aproximadamente %5.3f.' % math.pi
>>> print 'El valor de PI es aproximadamente {0:5.6f}'.format(math.pi)
El valor de PI es aproximadamente 3.141593

Programación orientada a objetos

En Python todo es un “objeto” y debe ser manipulado -y entendido- como tal. Pero ¿Qué
es un objeto? Básicamente, es una entidad que tiene propiedades y métodos.

Las clases son los modelos sobre los cuáles se construirán nuestros objetos. En Python, una clase se define con la instrucción class seguida de un nombre genérico para el objeto.

class Objeto:
    pass

Las propiedades, como hemos visto antes, son las características intrínsecas del objeto.
Éstas, se representan a modo de variables. Los métodos son funciones, solo que técnicamente se denominan métodos.

class Pincel(object):
    color = "rojo"
    def pintar(self):
        print "Lo pinto todo de color %s" % self.color

Las clases por sí mismas, no son más que modelos que nos servirán para crear objetos
en concreto. Podemos decir que una clase, es el razonamiento abstracto de un objeto,
mientras que el objeto, es su materialización. A la acción de crear objetos, se la denomina
“instanciar una clase” y dicha instancia, consiste en asignar la clase, como valor a una
variable.

>>> p = Pincel()
>>> p
<__main__.Pincel object at 0x7f68afff4e10>
>>> dir(p)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'color', 'pintar']
>>> p.color
'rojo'
>>> p.pintar()
Lo pinto todo de color rojo

Explorando los tipos de datos básicos

>>> cadena = "esta es una cadena" 
>>> dir(cadena)
['__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']
>>> cadena.upper()
'ESTA ES UNA CADENA'
>>> cadena.split(' ')
['esta', 'es', 'una', 'cadena']
>>> cadena = "esta es una cadena" 
>>> dir(cadena)
['__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']
>>> cadena.upper()
'ESTA ES UNA CADENA'
>>> cadena.split(' ')
['esta', 'es', 'una', 'cadena']
>>> lista = [4,1,3,5,7,9] 
>>> dir(lista)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> lista
[4, 1, 3, 5, 7, 9]
>>> lista.append(8)
>>> lista
[4, 1, 3, 5, 7, 9, 8]
>>> lista.reverse()
>>> lista
[8, 9, 7, 5, 3, 1, 4]
>>> lista.sort()
>>> lista
[1, 3, 4, 5, 7, 8, 9]
from datetime import datetime
today = datetime.now() # fecha actual
today.strftime("%d/%m/%Y")
today.strftime("%H:%M")

Formatos de fecha

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]   

Leyendo y escribiendo archivos

La función open() devuelve un objeto archivo, y es normalmente usado con dos argumentos:
open(nombre_de_archivo, modo).

Selection_117

>>> f = open('lorem_ipsum.txt', 'r')
f.read()

for linea in f:
    print linea,

Descargar archivo

>>> f = open('nuevo.txt', 'w')
f.write('Esto es una prueba\n')
f.close()
import csv

ifile  = open('ciudades.txt', "w")
reader = csv.reader(ifile)  # csv.reader(csvfile, delimiter=' ', quotechar='|')
headerline = datareader.next()

rownum = 0
for row in reader:
    print row

Descargar archivo

Acceso a Internet

Hay varios módulos para acceder a internet y procesar sus protocolos. Los más utilizados son urllib y urllib2.

urllib2 acepta objectos de tipo Request, lo que permite modificar las cabeceras de la petición, mientras que urllib accepta sólo URLs. Por otro lado, urllib proporciona el método urlencode que se usa para generar URLs con parámetros. Por eso, a veces se utilizan ambos.

import urllib2
response = urllib2.urlopen('http://pythonforbeginners.com/')
print response.info()
html = response.read()
# do something
response.close()  # best practice to close the file
import urllib
urllib.urlretrieve ("http://periodismodatos.okfn.es/wp-content/uploads/2014/02/logo_transparente-720.png", "logo.png")
import urllib2
mp3file = urllib2.urlopen("http://periodismodatos.okfn.es/wp-content/uploads/2014/02/logo_transparente-720.png")
output = open('logo.png','wb')
output.write(mp3file.read())
output.close()

# You can also use the with statement:
with open(file, 'w') as f: f.write(response.read())

# Prepare the data
query_args = { 'q':'query string', 'foo':'bar' }

# This urlencodes your data (that's why we need to import urllib at the top)
data = urllib.urlencode(query_args)

# Send HTTP POST request
request = urllib2.Request(url, data)

response = urllib2.urlopen(request)
 
html = response.read()

# Print the result
print html
import requests
url = "http://periodismodatos.okfn.es/"
html = requests.get(url).content
print html

Más información

Referencias

Python for beginners http://www.pythonforbeginners.com/
Introducción a Python para ingenieros http://picachu.dmt.upm.es/python/index.html
El tutorial de Python http://docs.python.org.ar/tutorial/pdfs/TutorialPython2.pdf
Python para Principiantes http://www.cursosdeprogramacionadistancia.com/static/pdf/material-sin-personalizar-python.pdf

Un comentario en “Programación básica con Python