how to think like a computer scientist

127
LOGO Juan G. Vélez Rodríguez Joane M. De Jesús Dátiz 23 de junio de 2010 How to Think Like a Computer Scientist

Upload: joanem28

Post on 08-Dec-2014

546 views

Category:

Education


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: How to Think Like a Computer Scientist

LOGO

Juan G. Vélez RodríguezJoane M. De Jesús Dátiz

23 de junio de 2010

How to Think Like a Computer Scientist

Page 2: How to Think Like a Computer Scientist

Capítulo 6: “Interation”

Page 3: How to Think Like a Computer Scientist

Multiple Assignment

Podemos asignar distintos valores a una misma variable.

Es legal asignarle el mismo nombre a diferentes variables ya que al hacerlo, la variable deja de hacer referencia al valor anterior (valor original) y comienza a referirse a un nuevo valor.

Page 4: How to Think Like a Computer Scientist

Ejemplo

bruce = 5print bruce, bruce = 7print bruce

La coma se interpone y toma prioridad ante el “new line” para que los resultados queden uno al lado del otro y no en distintas líneas.

Resultado en la Pantalla:5 7

Page 5: How to Think Like a Computer Scientist

Diagrama de Estado

bruce 5

7

Deja de ser un 5 para ser un 7.

Page 6: How to Think Like a Computer Scientist

Es importante recalcar que las igualdades en Matemáticas son conmutativas pero la asignación de variables en Python no lo son.

Por ejemplo, en Matemáticas si a = 7 entonces 7 = a.

En Phyton es legal decir que a = 7 pero decir que 7 = a no lo es.

Page 7: How to Think Like a Computer Scientist

The While Statement (Mientras)

Las computadoras realizan tareas repetitivas.

Repetir tareas idénticas es una tarea que las computadoras realizan bastante bien, algo que los seres humanos no realizarían muy bien.

Estas repeticiones se conocen como “Iteration”.

Page 8: How to Think Like a Computer Scientist

Ejemplo de un While

def countdown (n):while n> 0:

print nn = n-1

print “Blastoff!”

Esta función continuará mostrando el valor de n y lo va a reducir de uno en uno hasta llegar a 0 que es cuando el programa termina y muestra la palabra Blastoff!.

Page 9: How to Think Like a Computer Scientist

Lo que ocurre en el While es lo siguiente:

1. Se evalúa la condición, 0 ó 12. Si la condición es falsa (0), se sale del

While y continúa con el próximo estado.

3. Si la condición es cierta (1), se ejecutan cada uno de los estados en el “body” y se regresa al paso 1.

El “body” o cuerpo consiste de todos los estados bajo el encabezamiento que contienen la misma alineación, “tabs”, dentro del loop.

Page 10: How to Think Like a Computer Scientist

Loop (Lazo)

Este tipo de estado se conoce también como un “loop” debido a que luego del tercer paso, regresa nuevamente al comienzo de la función.

Notemos que si la condición es falsa desde el comienzo, los estados dentro del lazo no serán ejecutados pues no será necesario.

El cuerpo del lazo debe cambiar el valor de una o más variables para que eventualmente la condición sea falsa y el lazo termine.

Page 11: How to Think Like a Computer Scientist

Lazo Infinito (Infinite Loop)

Se puede dar el caso en el que un lazo no tenga final y siga repitiéndose para siempre.

Los Científicos de Computadoras comparan esto con las direcciones al usar un “Shampoo”.

Ejemplo: Lavado, enjuague, repetir.

Page 12: How to Think Like a Computer Scientist

Lazo Infinito (Infinite Loop)

En el caso de la función “countdown”, podemos comprobar que el lazo termina ya que el valor de n es finito, podemos ver que n va decreciendo cada vez que el lazo se ejecuta y eventualemente obtenemos el valor de 0.

Page 13: How to Think Like a Computer Scientist

Otros casos…

Hay veces que no es tan fácil de mostrar:

def sequence (n):while n != 1:

print n, if n%2 ==0: # n es un número par

n = n/2else: # n es un número

imparn = n*3+1

Page 14: How to Think Like a Computer Scientist

Cada vez que el programa ejecuta, comprueba si el número es par o impar. Si es par lo divide entre 2. Si es impar, reemplaza el valor por n*3+1.

Debido a que n algunas veces aumenta o disminuye, no hay prueba obvia para decir que n alcanzará el 1 o que el programa termine.

Una de las ventajas que tienen los lazos es que son buenos para generar tablas.

Page 15: How to Think Like a Computer Scientist

TablasAntes de que existieran las computadoras, las personas tenían que calcular logaritmos, senos, cosenos y otras funciones matemáticas a mano.

Para facilitarse la vida, en los libros de matemáticas se incluían grandes tablas que incluían estos valores.

Crear las tablas era lento y aburrido y podían contener errores.

Page 16: How to Think Like a Computer Scientist

Ejemplo de Tablas

El siguiente programa muestra una secuencia de valores en la columna de la izquierda y sus logartimos en la columna de la derecha.

x= 1.0while x <10.0:

print x, ‘\t’ , math.log(x)x = x +1.0

Page 17: How to Think Like a Computer Scientist

Tabla

Si esos valores de la tabla anterior los queremos con un logaritmo de base 2 entonces debemos usar la siguiente fórmula :

Page 18: How to Think Like a Computer Scientist

Continuación

Si realizamos el siguiente cambio en el código:

print x, ‘/t’, math.log(x)/math.log(2.0)

Obtenemos:

Page 19: How to Think Like a Computer Scientist

Vimos que los números 1, 2, 4 y 8 son potencias del 2 ya que sus logaritmos de base 2 son números enteros.

Si queremos encontrar otros logaritmos de potencia 2 podemos modificar el programa de ésta manera:

x = 1.0while x < 100.0

print x, ‘/t’, math.log(x)/math.log(2.0)x = x * 2.0

Page 20: How to Think Like a Computer Scientist

Resultado

Page 21: How to Think Like a Computer Scientist

Tabla de dos dimensiones

Tabla en la cual se leen los valores en la intersección entre una fila y una columna.

Ejemplo: tabla de multiplicar.

Crearemos una tabla de multiplicar del 1 al 6 utilizando un lazo que imprima los múltiplos de dos en una línea.

i = 1 #counterwhile i <= 6: print 2*1, ‘ ’, i = i + 1print #Resultados: 2, 4, 6, 8, 10, 12

Page 22: How to Think Like a Computer Scientist

Encapsulación y Generalización

Encapsulación es el proceso de empacar una pieza del código en una función.

Generalización significa tomar algo en específico, como imprimir los múltiplos de 2 y hacerlo más generalizado, como imprimir los múltiplos de cualquier número entero.

Page 23: How to Think Like a Computer Scientist

Ejemplo

La siguiente función encapsula el lazo anterior y lo generaliza para que imprima los múltiplos de n:

def printMultiples(n):i = 1while I <= 6: print n*i, ‘\t’, i = i + 1

print

Para encapsular, lo que debemos hacer es añadir la primera línea que es la que declara el nombre de la función y la lista de parámetros. Para generalizar, solo reemplazamos el 2 por el parámetro n.

Page 24: How to Think Like a Computer Scientist

Continuación Encapsulación y Generalización

Si invocamos ésta función con el argumento 2, obtenemos los mismos valores en pantalla. Con el argumento 3 obtenemos:

3, 6, 9, 12, 15, 18 Con el argumento 4 obtenemos:

4, 8, 12, 16, 20, 24

Si invocamos printMultiples en repetidas ocasiones con diferentes argumentos obtenemos una tabla de multiplicar.

Page 25: How to Think Like a Computer Scientist

Continuación Encapsulación y GeneralizaciónEn ese caso podemos utilizar otro lazo

(Loop):i = 1while i <= 6:

printMultiples(i)i = i + 1

Obtenemos:

Page 26: How to Think Like a Computer Scientist

Variables Locales

Las variables que han sido definidas dentro de una función no pueden ser accesadas desde afuera de esa función.

Se puede tener múltiples variables con el mismo nombre siempre y cuando no estén dentro de la misma función.

Page 27: How to Think Like a Computer Scientist

Stack Diagram

Dos variables distintas llamadas i que cambian de valor sin afectarse una con la otra.

Page 28: How to Think Like a Computer Scientist

Ejemplo de Generalización

Para crear una tabla de multiplicación de cualquier tamaño, sólo hay que añadir un parámetro a printMultTable:

def printMultTable(high):i = 1while i <= high:

printMultiples(i)i = i + 1

Page 29: How to Think Like a Computer Scientist

Reemplazamos el valor 6 por el de “high”.

Si llamamos “printMultTable ” con el argumento 7 nos muestra:

Page 30: How to Think Like a Computer Scientist

Funciones

Darle un nombre a una secuencia de estados (statements) hace su programa fácil de leer y de ejecutar.

Dividir un programa en varias funciones nos permite separar el programa en partes, ejecutar ellas por separado y luego adjuntarlas en un solo componente.

Page 31: How to Think Like a Computer Scientist

Facilitan la recursión y la iteración. (Loops)

Funciones bien diseñadas son útiles para varios programas. Una vez se escribe y se ejecuta alguna, se pueden reusar.

Page 32: How to Think Like a Computer Scientist

Capítulo 7: “Strings”

Page 33: How to Think Like a Computer Scientist

Datos

Hasta este punto, hemos visto distintos tipos de datos, por ejemplo, “int”, “float”, “string”.

Los “strings” son cualitativamente distintos de los otros dos tipos de datos ya que estan compuestos de pequeñas piezas– caracteres.

Tipos de datos que contienen piezas pequeñas son conocidos como “compound data types.”

Page 34: How to Think Like a Computer Scientist

Los corchetes seleccionan un solo caracter del string:>>> fruit = “banana”>>> letter = fruit[1]>>> print letter

La expresión fruit [1] selecciona el caracter en la posición 1 de la palabra fruit.

Cuando “letter” aparece en la pantalla, nos muestra la letra a.

La primera letra de la palabra banana es b, pero esta letra esta en la posición 0 y es por eso que aparece la letra a, que es la que está en la posición 1.

Page 35: How to Think Like a Computer Scientist

Índice

La expresión que está en corchetes se conoce como índice (index).

Un índice especifica un miembro de un conjunto ordenado, en este caso, el conjunto de caracteres en el string.

El índice indica que caracter es el que queremos, en vez de su nombre. Puede ser un entero.

Page 36: How to Think Like a Computer Scientist

Length (Longitud)

La función “len” nos devuelve el número de caracteres en un “string”.

>>> fruit = “banana”>>> len(fruit)6

Page 37: How to Think Like a Computer Scientist

LengthPara obtener el último caracter de un

“string”, debemos restar 1 del “length”

length = len(fruit)last = fruit[length-1]

Si utilizamos índices negativos, contaremos desde el último hasta el primer caracter. Ejemplo: fruit [-1] último caracter, fruit[-2] penúltimo caracter, etc.

Page 38: How to Think Like a Computer Scientist

Traversal & for Loops

“Traversal” son los recorridos que se hacen a los caracteres de un “string” desde el primero hasta el último, realizando los cambios necesarios a cada uno de los caracteres en ese proceso.

Este proceso es tan común en Python, que existe una alternativa predefinida llamada “for loop”.

Page 39: How to Think Like a Computer Scientist

Ejemplo de un “for”:for char in fruit:print char

Cada vez que se ejecuta el lazo (loop), el próximo caracter disponible en el “string” es asignado a la variable “char”. El “loop” continúa hasta que no haya mas ningún caracter en el “string”.

Page 40: How to Think Like a Computer Scientist

String Slices

Un segmento de un “string ” se conoce como un “slice”. Seleccionar un “slice” es similar a seleccionar un caracter.

El operador [n:m] nos devuelve la parte del “string” desde la posición n hasta la posición m.

Page 41: How to Think Like a Computer Scientist

String SlicesEjemplo:

Si se omite el primer índice, (anterior a la comilla), el “slice” comenzaría al principio del “string”.

>>> fruit = “banana”>>> fruit [:3]‘ban’>>> fruit [3:]‘ana’

Page 42: How to Think Like a Computer Scientist

Comparación de Strings

Se pueden comparar “strings”. Para hacerlo, veamos el siguiente ejemplo:

if word == “banana”print “Yes, we have bananas!”

Se pueden hacer comparaciones para poner palabras en orden alfabético, pero debemos tener mucho cuidado ya que Python no ve la diferencia entre letras mayúsculas y letras minúsculas. Las letras mayúsculas toman prioridad ante las letras minúsculas.

Page 43: How to Think Like a Computer Scientist

Immutable Strings

Los “strings” no se pueden modificar luego de ser creados.

Si necesita hacer cambios, lo mejor es crear un nuevo “string” con las variaciones del original.

Page 44: How to Think Like a Computer Scientist

Función “find”

Es lo contrario del operador [].

En vez de tomar un índice (index) y extraer su correspondiente caracter, lo que hace es tomar el caracter y encuentra el índice donde aparece ese caracter. Si el caracter no aparece, la función nos devuelve un -1.

Page 45: How to Think Like a Computer Scientist

Conteos (Counter)

Al declararse una variable llamada “count”, ésta se inicializa a 0 y se va incrementando cada vez que se encuentra un ‘a’.

El siguiente programa realiza un conteo dentro de un lazo (loop):

Page 46: How to Think Like a Computer Scientist

Módulo “String”

Módulo que contiene varias funciones útiles para manipular “strings”.

>>> import string

Incluye una función llamada “find” que hace lo mismo que vimos anteriormente.

Page 47: How to Think Like a Computer Scientist

Clasificación de Caracteres

Es muy útil examinar un caracter y comprobar si es de letra mayúscula o minúscula, o si es un caracter o un dígito.

El “string” ‘string.lowercase’ contiene todas las letras que el sistema podría considerar letras minúsculas.

El “string” ‘string.uppercase’ contiene todas las letras que el sistema podría considerar letras mayúsculas.

Page 48: How to Think Like a Computer Scientist

Clasificación de Caracteres

El “string” ‘string.whitespace’ contiene todos los espacios en blanco, incluyendo ‘space’, ‘tab’ (\t) y ‘newline’ (\n).

Page 49: How to Think Like a Computer Scientist

Capítulo 8: Listas

Page 50: How to Think Like a Computer Scientist

Listas

Una lista es un conjunto de valores, donde cada valor es identificado por un índice.

Los valores que componen una lista son llamados elementos.

Las listas son similares a los “strings”, que son una cadena de caracteres, a excepción de que los elementos de una lista pueden ser de cualquier tipo.

Las listas y las cadenas de caracteres son llamados secuencias.

Page 51: How to Think Like a Computer Scientist

8.1 Listas de valores

Hay varias maneras de formar una nueva lista; la forma más simple es encasillar los elementos en unos corchetes ([y]).

Ejemplos: Lista de cuatro enteros [10, 20, 30, 40] Listas de “strings” [“un”, “dos”, ”tres”] Lista dentro de otra lista [“hola”, 2.0, 5, [10,20] ]

Si una lista esta dentro de otra entonces se dice que la lista esta anidada.

Page 52: How to Think Like a Computer Scientist

Las listas que contienen enteros consecutivos son comunes, por lo que Phyton provee una forma simple para crearlas:

>>> range (1,5)

[1, 2, 3, 4]

La función rango toma dos argumentos y devuelve una lista que contiene todos los enteros desde el primero hasta el segundo, sin incluir el segundo.

Page 53: How to Think Like a Computer Scientist

Hay dos formas del alcance. Argumento simple: se crea una lista que comienza

en 0.

>>> range(10)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Si existe un tercer argumento, este específica el

espacio entre los valores sucesivos, lo que es llamado “step size”.

Ejemplo: Cuenta desde 1 al 10 de 2 en 2.>>>range(1, 10, 2)[1, 3, 5, 7, 9]

Page 54: How to Think Like a Computer Scientist

Una lista vacía es una lista especial que no contienen elementos.

Este tipo de lista se denota por corchetes [].

Podemos usar todas las formas anteriores de listas para asignar valores a variables.

Page 55: How to Think Like a Computer Scientist

8.2 Acceso de elementos

La sintaxis para accesar elementos de una lista es igual a la sintaxis utilizada para accesar caracteres de un “string”.

Para esto utilizamos los corchetes [], donde la expresión dentro de los mismos especifica el índice.

Recordemos que los índices comienzan en 0. print numbers[0]

numbers[1] = 5

Page 56: How to Think Like a Computer Scientist

Los corchetes pueden apareces en cualquier lugar de una expresión.

Cuando estos aparecen en el lado izquierdo de lo asignado, cambia uno de los elementos de la lista, por lo que el enésimo elemento de la lista ”numbers”, que era 123, es ahora 5.

Cualquier expresión con un número entero puede se utilizada como índice. >>> numbers[3-2]

5 >>>numbers[1.0]

TypeError: sequence index must be integer

Page 57: How to Think Like a Computer Scientist

Sin embargo, si intentamos leer o escribir un elemento que no existe, entonces obtenemos un error al correr el programa. >>> numbers[2] = 5

IndexError: list assignment index out of range

Si un índice tiene un valor negativo, este cuenta desde el final de la lista >>> numbers[-1]

5 >>> numbers[-3]

IndexError: list index out of range

Page 58: How to Think Like a Computer Scientist

En el ejemplo anterior: numbers[-1] es el último elemento de la lista numbers[-2] es el penúltimo elemento de la lista numbers[-3] no existe en la lista

Es muy común usar un “loop” como el índice de una lista.

Ejemplo:

horsemen = ["war", "famine", "pestilence", "death"]

i = 0while i < 4:print horsemen[i]i = i + 1

Page 59: How to Think Like a Computer Scientist

Este “while loop” cuenta desde 0 a 4.

Cuando el “loop” de la variable i es 4, la condición falla y el “loop” termina.

Por lo tanto, el cuerpo del “loop” se ejecuta cuando i es 0, 1, 2 y 3.

Cada vez que pasamos por el “loop”, la variable i es utilizada como un índice en la lista, y se imprime el elemento i de la lista en ese momento. (lista de recorrido)

Page 60: How to Think Like a Computer Scientist

8.3 Largo de la lista

La función “len” devuelve el largo de la lista.

Es buena idea utilizar este valor como el límite superior de un “loop” en lugar de una constante.

En ese caso, si el tamaño de la lista cambia, no tenemos que ir a través del programa cambiando todos los “loops”, pues estos trabajarán correctamente con una lista de cualquier tamaño.

Page 61: How to Think Like a Computer Scientist

Ejemplo:horsemen = ["war", "famine",

"pestilence", "death"]

i = 0while i < len(horsemen):print horsemen[i]i = i + 1

La última vez que el “loop” fue ejecutado, i es len(horsemen)-1, que es el índice del último elemento.

Page 62: How to Think Like a Computer Scientist

Cuando i es igual a len(horsemen), la condición falla y el cuerpo del programa no es ejecutado, lo cual es bueno, porque este valor no es un índice legal.

A pesar de que una lista puede contener otra, la lista anidada cuenta solo como un elemento.[’spam!’, 1, [’Brie’, ’Roquefort’, ’Pol le Veq’], [1,

2, 3]]

En este ejemplo el largo de la lista es 4.

Page 63: How to Think Like a Computer Scientist

8.4 Membrecía de una lista

“in” es un operador “booleano” que prueba la membrecía en una lista.

Además de ser utilizado con “strings”, también se usan con listas y otras secuencias.

Podemos usar “not” en combinación con “in” para probar si un elemento no es miembro de la lista.

El “for loop” también puede ser utilizado con listas.

Page 64: How to Think Like a Computer Scientist

8.5 Listas y “for loops”La sintaxis general de un “for loop”

es:for VARIABLE in LIST:BODY

Este enunciado es equivalente a :i = 0while i < len(LIST):VARIABLE = LIST[i]BODYi = i + 1

El “for loop” es más conciso porque podemos eliminar el “loop” de la variable i.

Page 65: How to Think Like a Computer Scientist

8.6 Operaciones con listas

Operador +>>> a = [1, 2, 3]>>> b = [4, 5, 6]>>> c = a + b>>> print c[1, 2, 3, 4, 5, 6]

Operador * Repite una lista el número dado de veces

>>> [1, 2, 3] * 3[1, 2, 3, 1, 2, 3, 1, 2, 3]

Page 66: How to Think Like a Computer Scientist

8.7 Partes de una lista

Las operaciones de particiones también trabajan con listas.

>>> list = [’a’, ’b’, ’c’, ’d’, ’e’, ’f’]>>> list[1:3][’b’, ’c’]>>> list[:4][’a’, ’b’, ’c’, ’d’]>>> list[3:][’d’, ’e’, ’f’]

Page 67: How to Think Like a Computer Scientist

Si omitimos el primer índice, la partición comienza desde el principio.

Si omitimos el segundo, la partición va al final.

Si omitimos ambas, la partición es realmente una copia de la lista completa.>>> list[:][’a’, ’b’, ’c’, ’d’, ’e’, ’f’]

Page 68: How to Think Like a Computer Scientist

8.8 Las listas son mutables

A diferencia de los “strings”, las listas son mutables, lo que quiere decir que podemos cambiar sus elementos.

Usando corchetes al lado izquierdo de la asignación, podemos actualizar uno de los elementos.

Page 69: How to Think Like a Computer Scientist

Con el operador de partición podemos actualizar varios elementos a la vez.>>> list = [’a’, ’b’, ’c’, ’d’, ’e’, ’f’]>>> list[1:3] = [’x’, ’y’]>>> print list[’a’, ’x’, ’y’, ’d’, ’e’, ’f’]

También podemos remover elementos de una lista asignándoles una lista vacía.>>> list = [’a’, ’b’, ’c’, ’d’, ’e’, ’f’]>>> list[1:3] = []>>> print list[’a’, ’d’, ’e’, ’f’]

Page 70: How to Think Like a Computer Scientist

Podemos añadir elementos a una lista moviéndolos a una partición vacía.>>> list = [’a’, ’d’, ’f’]>>> list[1:1] = [’b’, ’c’]>>> print list[’a’, ’b’, ’c’, ’d’, ’f’]>>> list[4:4] = [’e’]>>> print list[’a’, ’b’, ’c’, ’d’, ’e’, ’f’]

Page 71: How to Think Like a Computer Scientist

Eliminación de una lista

Usando particiones para eliminar elementos de una lista puede ser difícil, por lo que entonces estamos propensos a errores.

“del” remueve un elemento de una lista.

Ejemplo:>>> a = [’one’, ’two’, ’three’]>>> del a[1]>>> a[’one’, ’three’]

Page 72: How to Think Like a Computer Scientist

Como esperamos “del” maneja índices negativos y causa un error en la corrida si el índice esta fuera del alcance.

Podemos usar una partición como un índice para “del”.>>> list = [’a’, ’b’, ’c’, ’d’, ’e’, ’f’]>>> del list[1:5]>>> print list[’a’, ’f’]

Page 73: How to Think Like a Computer Scientist

8.10 Valores y objetos

Si ejecutamos las siguientes asignaciones:a = "banana"b = "banana“sabemos que a y b se refieren a un “string” con letras “banana”.

Sin embargo, no podemos decir que ambos apuntan al mismo “string”.

Page 74: How to Think Like a Computer Scientist

Hay dos estados posibles:

En el primer caso, a y b se refieren a dos cosas diferentes que tienen el mismo valor.

En el segundo caso, ambos se refieren a la misma cosa.

Page 75: How to Think Like a Computer Scientist

Estas “cosas” tienen nombre y se conocen como objetos.

Un objeto es algo a lo que una variable se puede referir.

Cada objeto tiene un identificador único, el que puede ser obtenido con la función “id”.

Page 76: How to Think Like a Computer Scientist

Imprimiendo el identificador de a y b, podemos decir que ambos se refieren al mismo objeto.>>> id(a)135044008>>> id(b)135044008

De hecho, obtenemos el mismo identificador doble, lo que significa que Phyton solo ha creado un “string”, y a y b se refieren a el.

Page 77: How to Think Like a Computer Scientist

Las listas se comportan diferente.

Cuando creamos dos listas, tenemos dos objetos:>>> a = [1, 2, 3]>>> b = [1, 2, 3]>>> id(a)135045528>>> id(b)135041704

Entonces el diagrama de estado es el siguiente:

donde a y b tienen el mismo valor pero no se refieren al mismo objeto.

Page 78: How to Think Like a Computer Scientist

8.11 Alias

Dado que las variables se refieren a objetos, si asignamos una variable a otra, ambas variables se refieren al mismo objeto.>>> a = [1, 2, 3]>>> b = a

En este caso, el diagrama de estado es:

Como la misma lista tiene dos nombres diferentes, a y b, decimos que esta es un alias.

Page 79: How to Think Like a Computer Scientist

Cambios hechos a un alias afectan al otro.

A pesar de que este comportamiento puede ser beneficioso, en algunos casos puede ser inesperado o indeseable.

En general, es más seguro evitar los alias cuando estamos trabajando con objetos mutables.

Claro que para elementos inmutables, no hay problema porque Phyton es libre de “strings” alias, cuando se presenta la oportunidad de economizar.

Page 80: How to Think Like a Computer Scientist

8.12 Clonando listas

Si deseamos modificar una lista y a la vez guardar una copia de la lista original, necesitamos ser capaces de crear una copia de la lista misma, no solo una referencia.

A veces este proceso se conoce como clonación, para evitar la ambigüedad del término copia.

La manera más fácil de clonar una lista es usar el operador de partición.>>> a = [1, 2, 3]>>> b = a[:]>>> print b[1, 2, 3]

Page 81: How to Think Like a Computer Scientist

Tomando cualquier partición de a se crea una nueva lista, que en este caso consiste de la lista completa.

Ahora podemos realizar cualquier cambio a b sin la preocupación de modificar a.>>> b[0] = 5>>> print a[1, 2, 3]

Page 82: How to Think Like a Computer Scientist

8.13 Parámetros de listas

Pasar una lista como un argumento pasa una referencia a la lista, no una copia de la lista.

Por ejemplo, la función “head” toma una lista como un argumento y devuelve el primer elemento.def head(list):return list[0]

Se utiliza la siguiente forma:>>> numbers = [1, 2, 3]>>> head(numbers)1

Page 83: How to Think Like a Computer Scientist

El parámetro “list” y la variable “numbers” son alias para el mismo objeto.

El diagrama de estado es:

Como el objeto de la lista es compartido por dos marcos, entonces lo dibujamos entre ambos.

Si una función modifica el parámetro de una lista, entonces se elimina el cambio.

Page 84: How to Think Like a Computer Scientist

Por ejemplo, “deleteHead” remueve el primer elemento de una lista.def deleteHead(list):del list[0]

Entonces mostramos como se utiliza el comando “deleteHead”.>>> numbers = [1, 2, 3]>>> deleteHead(numbers)>>> print numbers[2, 3]

Page 85: How to Think Like a Computer Scientist

Si una función devuelve una lista, esta devuelve una referencia a la lista.

Por ejemplo, “tail” devuelve una lista que contiene todo menos el primer elemento de la lista.def tail(list):return list[1:]

Page 86: How to Think Like a Computer Scientist

“tail” funciona de la siguiente forma:>>> numbers = [1, 2, 3]>>> rest = tail(numbers)>>> print rest[2, 3]

Como el valor devuelto fue creado por el operador de particiones, es una lista nueva. Por lo que haber creado “rest” no tiene ningún efecto en “numbers”.

Page 87: How to Think Like a Computer Scientist

8.14 Listas anidadas

Una lista anidada es una lista que aparece como un elemento de otra lista.

En esta lista, el tercer elemento es una lista anidada:>>> list = ["hello", 2.0, 5, [10, 20]]

Si imprimimos “list[3]”, obtenemos “[10, 20]”.

Page 88: How to Think Like a Computer Scientist

8.15 Matrices

Las listas anidadas también son utilizadas para representar matrices.

Por ejemplo, la matriz puede ser representada como:>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

“matrix” es una lista con tres elementos, donde cada elemento es una fila de la matriz.

Page 89: How to Think Like a Computer Scientist

Podemos seleccionar una fila entera de una matriz de la siguiente forma:>>> matrix[1][4, 5, 6]

Podemos extraer un solo elemento de la matriz usando un doble índice:>>> matrix[1][1]5

El primer índice selecciona una fila, el segundo índice selecciona una columna.

Page 90: How to Think Like a Computer Scientist

8.16 Listas y “strings”

Dos de las funciones más utilizadas en el módulo “string” envuelve listas de “strings”.

La función “split” rompe un “string” como una lista de palabras. Cada espacio en blanco entre los caracteres es

considerado el límite de una palabra.

>>> import string

>>> song = "The rain in Spain...">>> string.split(song)[’The’, ’rain’, ’in’, ’Spain...’]

Page 91: How to Think Like a Computer Scientist

Existe un argumento opcional llamado delimitador, el cual puede ser usado para especificar cuales caracteres son utilizados como límites de las palabras.

El siguiente ejemplo usa el “string” ai como el delimitador>>> string.split(song, ’ai’)[’The r’, ’n in Sp’, ’n...’]

Notemos que el delimitador no aparece en la lista.

Page 92: How to Think Like a Computer Scientist

Esta toma una lista de “strings” y une los elementos con un espacio entre cada par.>>> list = [’The’, ’rain’, ’in’, ’Spain...’]>>> string.join(list)’The rain in Spain...’

Como “split”, “join” toma un delimitador opcional que es insertado entre los elementos.>>> string.join(list, ’_’)’The_rain_in_Spain...’

Page 93: How to Think Like a Computer Scientist

Capítulo 9: Tuplas

Page 94: How to Think Like a Computer Scientist

9.1 Mutabilidad y tuplas

Un “string” está compuesto de caracteres; mientras una lista está compuesta de elementos de cualquier tipo.

Una de las diferencias más notables es que los elementos de una lista pueden ser modificados, pero los caracteres de un “string” no.

En otras palabras, los “strings” son inmutables y las listas mutables.

Page 95: How to Think Like a Computer Scientist

En Phyton también existen las tuplas, la cual es similar a una lista con la excepción de que es inmutable.

Sintácticamente, una tupla es una lista de valores separados por comas.

Ejemplo:>>> tuple = ’a’, ’b’, ’c’, ’d’, ’e’

Page 96: How to Think Like a Computer Scientist

Aunque no es necesario, convencionalmente las tuplas se escriben entre paréntesis.>>> tuple = (’a’, ’b’, ’c’, ’d’, ’e’)

Para crear un tupla con un solo elemento, tenemos que incluir una coma al final.>>> t1 = (’a’,)>>> type(t1)<type ’tuple’>

Page 97: How to Think Like a Computer Scientist

Sin la coma, Phyton trata (‘a’) como un “string” entre paréntesis.>>> t2 = (’a’)>>> type(t2)<type ’str’>

Si dejamos la sintaxis a un lado, las operaciones en las tuplas son igual a las operaciones en las listas.

Page 98: How to Think Like a Computer Scientist

El operador índice selecciona un elemento de una tupla.>>> tuple = (’a’, ’b’, ’c’, ’d’, ’e’)>>> tuple[0]’a’

El operador partición selecciona el alcance de los elementos.>>> tuple[1:3](’b’, ’c’)

Page 99: How to Think Like a Computer Scientist

Si intentamos modificar uno de los elementos de la tupla obtenemos un error.>>> tuple[0] = ’A’TypeError: object doesn’t support item assignment

Como no podemos modificar los elementos de una tupla, podemos reemplazarlo con una diferente.>>> tuple = (’A’,) + tuple[1:]>>> tuple(’A’, ’b’, ’c’, ’d’, ’e’)

Page 100: How to Think Like a Computer Scientist

9.2 Asignando tuplas

A veces es bueno cambiar los valores de dos variables.

Con la forma convencional de asignación, teníamos que utilizar una variable temporera.

Ejemplo para cambiar a y b:>>> temp = a>>> a = b>>> b = temp

Page 101: How to Think Like a Computer Scientist

Si tenemos que hacer esto a menudo, este proceso sería engorroso.

Phyton provee una forma de asignación de tuplas que resuelve este problema:>>> a, b = b, a

El lado izquierdo es la tupla de las variables y el lado derecho es el de los valores.

Cada valor es asignado a su variable correspondiente.

Page 102: How to Think Like a Computer Scientist

Todas las expresiones en el lado derecho son evaluadas antes de cualquier asignación.

Esto hace que la asignación de tuplas sea versátil.

El número de variables en el lado izquierdo y el número de variables en el derecho tienen que ser iguales.

Ejemplo:

>>> a, b, c, d = 1, 2, 3ValueError: unpack tuple of wrong size

Page 103: How to Think Like a Computer Scientist

9.3 Tuplas como valores devueltos

Las funciones pueden devolver tuplas como respuestas.

Por ejemplo, podemos escribir una función que cambia dos parámetros:def swap(x, y):return y, x

Después podemos asignar el valor devuelto a una tupla con dos variables:a, b = swap(a, b)

Page 104: How to Think Like a Computer Scientist

En este caso, no es ventajoso realizar una función “swap”.

De hecho, existe un peligro en intentar encapsular “swap”, el cual es el siguiente error:def swap(x, y): # incorrect versionx, y = y, x

Si llamamos la función de la siguiente manera:swap(a, b)

entonces a y x son alias para el mismo valor.

Page 105: How to Think Like a Computer Scientist

Cambiando x dentro de “swap” hace que x se refiera a un valor diferente, pero no tiene efecto en “in_main_”.

Similarmente, cambiar y no tiene ningún efecto en b.

Esta función corre sin producir un mensaje de error, pero no realiza lo que se pretende.

Este es un buen ejemplo para un error de semántica.

Page 106: How to Think Like a Computer Scientist

9.4 Números aleatorios

Muchos programas de computadoras hacen lo mismo cada vez que son ejecutados, por lo que podemos llamarlos determinísticos.

El determinismo es usualmente bueno, porque esperamos que el mismo cálculo arroje el mismo resultado.

Para algunas aplicaciones, queremos que la computadora sea impredecible. Ejemplo: Juegos

Page 107: How to Think Like a Computer Scientist

Hacer un programa no determinístico no es sencillo, pero existen formas para que lo sea lo menos posible.

Una de las formas es generando números aleatorios y utilizarlos para determinas la salida del programa.

Phyton provee una función pre-construida que genera números seudo-aleatorios, los cuales no son completamente aleatorios en sentido matemático, pero para nuestros propósitos si lo son.

Page 108: How to Think Like a Computer Scientist

El módulo “random” contiene una función llamada “random” que devuelve un número decimal entre 0.0 y 1.0.

Cada vez que realizamos la operación, obtenemos el siguiente número en una serie larga.

Ejemplo:import randomfor i in range(10):x = random.random()print x

Page 109: How to Think Like a Computer Scientist

9.2 Lista de números aleatoriosEl primer paso es generar una lista de

valores aleatorios.

“randomList” toma un argumento entero y devuelve una lista de números aleatorios con el largo dado.

Se comienza con una lista de n ceros.

Cada vez que pasamos a través del “loop”, este reemplaza uno de los elementos con un número aleatorio.

Page 110: How to Think Like a Computer Scientist

El valor devuelto es una referencia a la lista completa.def randomList(n):s = [0] * nfor i in range(n):s[i] = random.random()return s

Los números generados por “random” son distribuidos uniformemente, lo que significa que cada valor es igualmente probable.

Page 111: How to Think Like a Computer Scientist

Si dividimos el alcance de los valores posibles en “buckets” del mismo tamaño, y contamos el número de veces que el valor aleatorio cae en cada “bucket”, tendremos seguramente el mismo número en cada uno.

Podemos probar esta teoría escribiendo un programa que divida el alcance en “buckets” y cuente el número de valores en cada uno.

Page 112: How to Think Like a Computer Scientist

9.6 Contando

Una buena propuesta para problemas como este es dividir el problema en partes y buscar soluciones computacionales a estos problemas.

En este caso, deseamos recorrer una lista de números y contar el número de veces que un valor cae en el rango dado.

Podemos proceder copiando el programa y adaptándolo para el problema actual.

Page 113: How to Think Like a Computer Scientist

El programa original es:count = 0for char in fruit:if char == ’a’:count = count + 1print count

Este primer paso es para reemplazar “fruit” with “t” y “char” con “num”.

Esto no cambia el programa, solo lo hace más fácil para leer.

Page 114: How to Think Like a Computer Scientist

El segundo paso es cambiar la prueba.

No tenemos la intención de encontrar valores, deseamos saber si “num” esta entre los valores “low” y “high”.

Ejemplo:count = 0for char in fruit:if char == ’a’:count = count + 1print count

Page 115: How to Think Like a Computer Scientist

El último paso es encapsular este código en la función “inBucket”.

Los parámetros son la lista y los valores “low” y “high”.def inBucket(t, low, high):count = 0for num in t:if low < num < high:count = count + 1return count

Page 116: How to Think Like a Computer Scientist

Copiando y modificando un programa existente, somos capaces de escribir esta función rápidamente y economizar tiempo.

Este plan de desarrollo se conoce como pareo de patrones.

Si trabajamos en un problema que hemos resuelto anteriormente, reusamos la solución.

Page 117: How to Think Like a Computer Scientist

9.7 Muchos “buckets”Si el número de “buckets” aumenta,

la función “inBucket” se vuelve un poco difícil.

Con dos “buckets”:low = inBucket(a, 0.0, 0.5)high = inBucket(a, 0.5, 1)

Con cuatro “buckets” se vuelve engorroso:bucket1 = inBucket(a, 0.0, 0.25)bucket2 = inBucket(a, 0.25, 0.5)bucket3 = inBucket(a, 0.5, 0.75)bucket4 = inBucket(a, 0.75, 1.0)

Page 118: How to Think Like a Computer Scientist

Existen dos problemas. Tenemos que declarar un nombre nuevo para cada

resultado de la variable. Tenemos que calcular el rango para cada “bucket”.

Podemos resolver el segundo problema primero. Si el número de “buckets” es “numBuckets”,

entonces el ancho de cada “bucket” es “1.0/numBuckets”.

Usamos un “loop” para calcular el rango de cada “bucket”.

Page 119: How to Think Like a Computer Scientist

La variable “loop”, i, cuenta desde 0 a “numBuckets-1”bucketWidth = 1.0 / numBucketsfor i in range(numBuckets):low = i * bucketWidthhigh = low + bucketWidthprint low, "to", high

Para calcular el limite inferior para cada “bucket”, multiplicamos la variable “loop” por el ancho del “bucket”.

Page 120: How to Think Like a Computer Scientist

El limite superior es la suma del inferior y el “bucketWidth”.

Ejemplo:Con “numBuckets=8”, el “output” es:

0.0 to 0.1250.125 to 0.250.25 to 0.3750.375 to 0.50.5 to 0.6250.625 to 0.750.75 to 0.8750.875 to 1.0

Page 121: How to Think Like a Computer Scientist

Podemos confirmar que cada “bucket” tiene el mismo ancho, que no se solapan, y que cubren completamente el alcance desde 0.0 a 1.0.

Para el primer problema, necesitamos una forma para guardar ocho enteros, usando la variable “loop” para indicar uno a la vez.

Tenemos que crear una lista “bucket” fuera del “loop”, porque solo queremos recorrerla una vez

Page 122: How to Think Like a Computer Scientist

Dentro del “loop”, llamaremos el “inBucket” repetidamente y actualizaremos el enésimo elemento i de la lista.

Ejemplo:numBuckets = 8buckets = [0] * numBucketsbucketWidth = 1.0 / numBucketsfor i in range(numBuckets):low = i * bucketWidthhigh = low + bucketWidthbuckets[i] = inBucket(t, low, high)print buckets

Page 123: How to Think Like a Computer Scientist

Con una lista de 1000 valores, el código produce la siguiente lista “bucket”:[138, 124, 128, 118, 130, 117, 114, 131]

Estos números están bien cerca de 125, que es lo que esperamos.

Al estar tan cerca podemos creer que el generador de números aleatorios está funcionando.

Page 124: How to Think Like a Computer Scientist

9.8 Solución por una pruebaA pesar de que el programa funciona,

no es tan eficiente como podría ser.

Cada vez que se llama el “inBucket”, se recorre la lista completa.

Si el numero de “buckets” aumenta, también el número de recorridas.

Sería mejor si pasamos una sola vez por la lista y computamos el índice del “bucket” en el cual falla para cada valor.

Page 125: How to Think Like a Computer Scientist

Luego podemos aumentar el contador apropiado.

Deseamos tomar un valor en el rango de 0.0 a 1.0 para calcular el índice del “bucket” en el cual se falla.

Dado que el problema es el inverso del problema anterior, podemos pensar que debemos dividir por el “bucketWidth” en vez de multiplicar, como en el ejemplo anterior.

Dado que “bucketWidth”=“1.0/numBuckets”, dividiendo por “bucketWidth” es lo mismo que multiplicar por “numBuckets”.

Page 126: How to Think Like a Computer Scientist

Si multiplicamos un número en el rango 0.0 a 1.0 por “numBuckets”, obtenemos un número en el rango desde 0.0 hasta “numBuckets”.

Si redondeamos ese número al entero menor, obtenemos exactamente lo que estamos buscando, un índice del “bucket”.numBuckets = 8buckets = [0] * numBucketsfor i in t:index = int(i * numBuckets)buckets[index] = buckets[index] + 1

Page 127: How to Think Like a Computer Scientist

Usamos le función “int” para convertir un número decimal en un entero.

Una lista que cuenta el número de valores en cada rango se conoce como un histograma, el cual se realiza con la función “histogram”.