Sei sulla pagina 1di 63

INSTITUTO TECNOLÓGICO DE TAPACHULA

MATERIA

PROGRAMACIÓN LÓGICA Y FUNCIONAL

CARRERA

INGENIERÍA EN SISTEMAS COMPUTACIONALES

8° SEMESTRE GRUPO ÚNICO

ACTIVIDAD 2.1
RESUMEN –
Modelo de Programación Funcional

18 de SEPTIEMBRE de 2019

EQUIPO

CASA BETA
Contenido
2.1 INTRODUCCIÓN AL MODELO DE PROGRAMACIÓN FUNCIONAL. ................. 6

2.1.1 ¿Qué es la programación funcional? .............................................................. 6

2.1.2 «Variables» inmutables................................................................................... 6

2.1.3 Pattern matching ............................................................................................. 7

2.1.4 Recursividad ................................................................................................... 7

2.1.5 Concurrencia .................................................................................................. 7

2.2 EL TIPO DE DATO ................................................................................................ 8

2.2.1 Números enteros ............................................................................................ 9

2.2.2 Números de punto flotante .............................................................................. 9

2.2.3 Números complejos ........................................................................................ 9

2.3.4 Strings........................................................................................................... 10

2.3.5 Tuplas ........................................................................................................... 11

2.3.6 Listas ............................................................................................................ 12

2.3.6 Diccionarios .................................................................................................. 14

2.3 FUNCIONES ....................................................................................................... 17

2.3.1 Sentencia def ............................................................................................... 17

2.3.2 Argumentos y parámetros............................................................................. 20

2.3.2.1. Por posición .......................................................................................... 20

2.3.2.2. Por nombre ........................................................................................... 20

2.3.2.3. Llamada sin argumentos ....................................................................... 20

2.3.2.4. Parámetros por defecto ......................................................................... 21

2.3.3. Argumentos indeterminados ........................................................................ 21

2.3.3.1. Por posición .......................................................................................... 21

1
2.3.3.2. Por nombre ........................................................................................... 22

2.3.3.3. Por posición y nombre ........................................................................... 22

2.3.4. Sentencia pass ............................................................................................ 23

2.3.5. Sentencia return .......................................................................................... 23

2.3.5.1. Retorno múltiple .................................................................................... 24

2.3.6. Ejemplos de funciones ................................................................................. 25

2.3.6.1 Definición de funciones .......................................................................... 25

2.3.6.2 Invocar funciones ................................................................................... 25

2.3.6.3 Funciones con argumentos múltiple ....................................................... 25

2.4 INTERVALOS...................................................................................................... 26

 Diferencia entre declaración y modificación de variables ......................... 26

2.4.1 El tipo range .................................................................................................. 27

2.4.2 Concatenar range() ....................................................................................... 29

2.4.3 La función len() ............................................................................................. 30

2.5 OPERADORES ................................................................................................... 31

2.5.1 Operadores aritméticos................................................................................. 31

2.5.1.1 Operador Suma ...................................................................................... 31

2.5.1.2 Operador Resta ...................................................................................... 31

2.5.1.3 Operador Negación ................................................................................ 32

2.5.1.4 Operador Multiplicación .......................................................................... 32

2.5.1.5 Operador Exponente .............................................................................. 32

2.5.1.6 Operador división ................................................................................... 32

2.5.1.7 Operador división entera ........................................................................ 32

2.5.1.8 Operador Módulo ................................................................................... 33

2
2.5.1.9 Orden de precedencia ............................................................................ 33

2.5.1.10 Ejemplos .............................................................................................. 34

2.5.2 Operadores de asignaciones ........................................................................ 35

2.5.2.1 Operador = ............................................................................................. 35

2.5.2.2 Operador += ........................................................................................... 35

2.5.2.3 Operador -= ............................................................................................ 36

2.5.2.4 Operador *=............................................................................................ 36

2.5.2.5 Operador /= ............................................................................................ 36

2.5.2.6 Operador **= .......................................................................................... 37

2.5.2.7 Operador //= ........................................................................................... 37

2.5.2.8 Operador %= .......................................................................................... 38

2.5.2.9 Asignación aumentada ........................................................................... 38

2.5.2.10 Ejemplos .............................................................................................. 38

2.5.3 Operadores relacionales ............................................................................... 40

2.5.3.1 Operador == ........................................................................................... 40

2.5.3.2 Operador != ............................................................................................ 40

2.5.3.3 Operador < ............................................................................................. 41

2.5.3.4 Operador > ............................................................................................. 41

2.5.3.5 Operador <= ........................................................................................... 41

2.5.3.6 Operador >= ........................................................................................... 41

2.5.3.7 Ejemplos ................................................................................................ 41

2.5.3.8 Ejemplo de definir variables numéricas .................................................. 42

2.5.3.9 Ejemplo de operador relacional Igual ..................................................... 42

2.5.3.10 Ejemplo de operador relacional Diferente ............................................ 42

3
2.5.3.11 Ejemplo de operador relacional Menor que .......................................... 42

2.5.3.12 Ejemplo de operador relacional Mayor que .......................................... 43

2.5.3.13 Ejemplo de operador relacional Menor o igual que .............................. 43

2.5.3.14 Ejemplo de operador relacional Mayor o igual que .............................. 43

2.5.4 Operadores lógicos ....................................................................................... 43

2.5.4.1 Operador and ......................................................................................... 43

2.5.4.2 Operador or ............................................................................................ 43

2.5.4.3 Operador not .......................................................................................... 44

2.5.4.4 Ejemplos ................................................................................................ 44

2.5.4.5 Definir variables usadas en los siguientes ejemplos: ............................. 44

2.5.4.6 Ejemplo de operador lógico and: ............................................................ 44

2.5.4.7 Ejemplo de operador lógico or: .............................................................. 44

2.5.4.8 Ejemplo de operador lógico not: ............................................................. 45

2.6 APLICACIONES DE LAS LISTAS ....................................................................... 46

2.6.1 Ejemplos del uso de listas en Python ........................................................... 47

2.6.2 Verificar la existencia de un ítem dentro de una lista .................................... 48

2.7 ÁRBOLES ........................................................................................................... 49

2.7.1 Datos importantes de los Árboles ................................................................. 50

2.7.2 Recorrido sobre Árboles ............................................................................... 51

2.7.2.1 Búsquedas no informadas ...................................................................... 51

2.7.2.2 Búsqueda en profundidad ...................................................................... 52

2.7.2.3 Búsqueda en amplitud. ........................................................................... 55

2.7.3 Arboles en Python ........................................................................................ 56

2.8 EVALÚACIÓN PEREZOSA ................................................................................. 58

4
REFERENCIAS BIBLIOGRÁFICAS .......................................................................... 61

5
2.1 INTRODUCCIÓN AL MODELO DE

PROGRAMACIÓN FUNCIONAL.
2.1.1 ¿Qué es la programación funcional?
Es un paradigma de programación declarativa basado en el uso de funciones
matemáticas. La programación funcional genera un código lindo y declarativo -se lee
y se entiende lo que hace. La diferencia entre una función matemática y «función»
utilizada en programación imperativa es que esta última mencionada puede tener
efectos secundarios (side-effects), como cambiar el valor de variables globales o
pasadas por referencia. Al eliminar dichos efectos secundarios, en la programación
funcional, se puede entender y predecir el funcionamiento de un programa más
fácilmente, porque una función que se invoca con los mismos parámetros siempre va
a retornar el mismo resultado.

Podemos nombrar algunos lenguajes de programación funcionales que ya tienen


buena historia recorrida, como lo son Haskell, Miranda y Erlang. También algunos más
nuevos como lo son Clojure y Elixir.

Vale la pena destacar que algunos lenguajes utilizan lazy evalúation, como Haskell y
Miranda, donde cada expresión y argumento será evalúado a medida que se necesite,
o sea, que algunos argumentos quizás nunca sean evalúados; en cambio otros utilizan
eager evalúation, como Erlang y la mayoría de los lenguajes imperativos, donde las
expresiones y parámetros se evalúan al momento que se asignan.

Describamos algunas de las características más importantes de la programación


funcional:

2.1.2 «Variables» inmutables


«Variables» -entre comillas- porque en realidad en funcional, dichas variables nunca
cambian, una vez asignado un valor para una variable, dicho valor no cambia, decimos,
es inmutable. Esto trae ventajas, como eliminar posibles errores en nuestros

6
programas por modificaciones de variables fuera de nuestro control. Aparte de tener
un test unitario mucho más confiable.

2.1.3 Pattern matching


Es una herramienta muy potente y clave para la programación funcional. Es muy
importante a la hora de definir funciones, favorece el código declarativo y lo que hace
es establecer patrones por donde debe seguir el hilo de ejecución.

Por ejemplo:

Esta función en Erlang comprueba si una lista es vacía mediante pattern matching, si
lo es devuelve true, caso contrario devuelve false.

2.1.4 Recursividad
Se da cuando una función se llama a si misma las veces que sea necesaria para
retornar un resultado, siempre con un criterio de paro.

En los lenguajes imperativos es usada sin problemas, pero en los funcionales es pieza
fundamental, de hecho en vez de usar los famosos loops imperativos, en funcional se
utiliza la recursividad. ¿Por qué? Recordemos que las variables son inmutables, lo que
descalificaría la chance de usar un loop convencional.

2.1.5 Concurrencia
Este concepto es importantísimo en el software, y en la programación funcional es una
clave por sobre la imperativa porque -retomamos- los side-effects son reducidos al
mínimo. Al tener múltiples (decenas, cientos, miles, cientos de miles…)
procesos/threads en ejecución, el hecho de que nuestras variables sean inmutables y
no depender de estados, nos garantiza una concurrencia limpia.

7
2.2 EL TIPO DE DATO
El funcionamiento de los programas Python depende de los datos que maneja. Todos
los valores de datos en Python son objetos, y cada objeto, o valor, tiene "un tipo".

Tener en cuenta que, cada tipo de objeto determina qué operaciones va a soportar el
objeto y, por lo tanto, qué operaciones se van a poder realizar con esos valores de los
datos, qué atributos tiene y si va a poder ser "mutable" o no.

En Python también existe un tipo de dato "objeto" que acepta cualquier objeto como
argumento y devuelve el tipo de objeto al incorporado.

Por último, tener en cuenta que, en Python, también se han incorporado a tipos de
datos: números, cadenas, tuplas, listas y diccionarios. Y, si estos no llegan, también
se pueden crear tipos definidos por el usuario (clases).

En Python los objetos tipo número soporta enteros (normales y largos), números de
punto flotante y números complejos.

Todos los números en Python son "objetos inmutables", esto quiere decir que
siempre que se realice una operación con un número el resultado será otro objeto
número distinto.

• Las operaciones con números son "operaciones aritméticas”.

8
2.2.1 Números enteros
 Un número entero puede ser decimal, octal o hexadecimal.

1, 23, 3493 # Decimales


01, 027, 06645 # Octales
0x1, 0x17, 0xDA5 # Hexadecimales

 En Python no es necesario distinguir entre enteros simples y enteros largos,


pues él ya realiza el cambio cuando es necesario.

Así y todo, sí podemos indicar con la letra L que va a ser un entero largo:

1L, 23L, 3493L # Decimales largos


01L, 027L, 06645L # Octales largos
0x1L, 0x17L, 0xDA5L # Hexadecimales largos

2.2.2 Números de punto flotante


 En Python los decimales se indican con el dígito . (punto), una parte exponencial
(con e o E) o ambos.

0., 0.0, .0
1.0, 1.e0, 1.0e0

2.2.3 Números complejos


Un número complejo está realizado por dos números decimales, uno para la parte real
y otro para la parte imaginaria.

Podremos acceder a cada una de esas partes por separado: z.real y z.imag.
Se especifica la parte imaginaria con la letra j o J.

0j, 0.j, 0.0j, .0j


1j, 1.j, 1.0j, 1e0j, 1.e0j, 1.0e0j

Una secuencia es un contenedor de artículos ordenados e indexados por enteros no


negativos.

En Python tenemos: strings (simple y Unicode), tuplas y listas. Se tiene la posibilidad


de crear nuevos tipos de secuencias.

9
Iterables
 El concepto de Python que generaliza la idea de "secuencia" es el concepto de
"iterable".

Todas las secuencias son iterables, pero existen más iterables, como las "listas", por
ejemplo.

Cuando hablamos de iterables nos referimos a "iterables acotados" (que tienen un


principio y un final).

2.3.4 Strings
 Un objeto string (simple o Unicode) es una secuencia de caracteres utilizado
para guardar y representar textos.

Los strings en Python son inmutables. Los objetos string nos van a proporcionar
muchos métodos.

 Para definir un string utilizaremos comillas simples o dobles:

'Este es un string'
"Este también es un string"
 Se utilizará backslash para escapar una comilla:

'Este es un \'string\''
"Este también es un 'string'"
 Para expandir el string a dos líneas utilizaremos también backslash:

"Este es un texto más largo\


que ocupa dos líneas" # No pondremos el comentario en la
primera línea
• Otro modo de crear un string de múltiples líneas es utilizando "tres comillas"
(simples ó dobles, da igual).
"""Este sí que es
un texto muy
muy largo""" # Los comentarios siempre en la última línea
El único carácter que no puede pertenecer a un string, así definido con tres comillas,
es un backslash no escapado.

• Las secuencias de escape para variables string son las siguientes:

10
Secuencia Significado

\<nueva línea> El final de línea se ignora

\\ Backslash

\' Comilla Simple

\" Comilla Doble

\n Nueva línea

\r Retorno de carro

\t Tabulador

 Una variante del tipo string son las raw string, son utilizadas para que no
realice su función el símbolo backlash. Para definir una raw string hay que
colocar delante de la primera comilla una letra r o R.
 Formatear un string automáticamente con el método.

2.3.5 Tuplas

Una tupla es una secuencia de items ordenada e inmutable. Los items de una tupla
pueden ser objetos de cualquier tipo.

Para especificar una tupla, lo hacemos con los elementos separados por comas dentro
de paréntesis.

 Una tupla con únicamente dos elementos es denominada par.


 Para crear una tupla con un único elemento (singleton), se añade una coma al
final de la expresión.
 Para definir una tupla vacía, se emplean unos paréntesis vacíos.

11
(100, 200, 300) # Tupla con tres elementos
(3.14,) # Tupla con un elemento
() # Tupla vacía (los paréntesis NO son opcionales)

También se puede crear una tupla del siguiente modo: saludo = tuple("hola")

#!/usr/bin/python3
# -*- coding: utf-8 -*-
saludo = tuple("hola")
for letra in saludo:
print ('%s' % letra)
# Vemos que, de este modo se crea una tupla igual a:
# saludo = ('h', 'o', 'l', 'a')

• Con tuple(), sin argumentos, creamos una tupla vacía.

2.3.6 Listas
 Una lista es una secuencia ordenada de elementos mutable.
 Los items de una lista pueden ser objetos de distintos tipos.
 Para especificar una lista se indican los elementos separados por comas en el
interior de corchetes.
 Para denotar una lista vacía se emplean dos corchetes vacíos.

[42, 3.14, 'hola', 'casa'] # Lista con tres elementos


[100] # Lista con un elemento
[] # Lista vacía
 También podemos crear una lista del siguiente modo: list("hola") que sería
como crear una lista así: ['h', 'o', 'l', 'a']
 Podemos crear una lista vacía así: list()
 Podemos acceder a datos del siguiente modo:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Definimos una lista de 5 elementos


lista = [42, 3.14, 'hola', 25, 'fin']

# Ver todos los elementos de la lista


print ("Veamos los elementos de la lista:")
print (lista)

12
# Calculamos la longitud de la lista:
print ("\nLa longitud de la lista es de ", len(lista),
"elementos")
# Las listas comienzan con el elemento "0"
print ("\nEl Primer elemento: %s" % lista[0])
# Con los índices negativos accedemos a los elementos al revés
print ("\nEl Último elemento: %s" % lista[-1])
# Para acceder a porciones de la lista:
# El primer índice de la porción especifica el primer elemento
que se desea obtener,
# y el segundo índice especifica el primer elemento que no se
desea obtener
print ("\nElementos segundo, tercero y cuarto: ", lista[1:4])

# append añade un elemento al final de la lista.


lista.append('nuevoFin')
print ("\nAñadimos un elemento final de la lista:")
print (lista)

# insert inserta un elemento en una lista.


# El argumento numérico es el índice del primer elemento que será
desplazado de su posición.
lista.insert(2,'nuevo2')
print ("\nAñadimos un elemento en la posición 2:")
print (lista)

# extend concatena listas.


lista2 = [23, 45, 'lista2']
lista.extend(lista2)
print ("\nConcatenamos las dos listas: ")
print (lista)

# Borrar un elemento de la lista:


lista.remove(23)
print ("\nEliminamos el elemento 23")
print (lista)

# Eliminar un elemento de la lista por el índice:


del lista[1]
print ("\nEliminamos el elemento 1 de la lista:")
print (lista)

# Para eliminar el último elemento de la lista y verlo:


eliminado = lista.pop()
print ("\nSe eliminó el que estaba de último: ", eliminado)
print ("\nAhora la lista:")
print (lista)

13
2.3.6 Diccionarios

Los diccionarios de Python son una lista de consulta de términos de los cuales se
proporcionan valores asociados.

En Python, un diccionario es una colección no-ordenada de valores que son accedidos


a través de una clave. Es decir, en lugar de acceder a la información mediante el índice
numérico, como es el caso de las listas y tuplas, es posible acceder a los valores a
través de sus claves, que pueden ser de diversos tipos.

Las claves son únicas dentro de un diccionario, es decir que no puede haber un
diccionario que tenga dos veces la misma clave, si se asigna un valor a una clave ya
existente, se reemplaza el valor anterior.

No hay una forma directa de acceder a una clave a través de su valor, y nada impide
que un mismo valor se encuentre asignado a distintas claves

La información almacenada en los diccionarios, no tiene un orden particular. Ni por


clave ni por valor, ni tampoco por el orden en que han sido agregados al diccionario.

Cualquier variable de tipo inmutable, puede ser clave de un diccionario: cadenas,


enteros, tuplas (con valores inmutables en sus miembros), etc. No hay restricciones
para los valores que el diccionario puede contener, cualquier tipo puede ser el valor:
listas, cadenas, tuplas, otros diccionarios, objetos, etc.

 Veamos un ejemplo:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Definir una variable diccionario


futbolistas = dict()
futbolistas = {
1: "Casillas", 3: "Piqué",
5: "Puyol", 6: "Iniesta",
7: "Villa", 8: "Xavi Hernández",
9: "Torres", 11: "Capdevila",
14: "Xavi Alonso", 15: "Ramos",
16: "Busquets"}

14
# Veamos el identificador inicial del diccionario
print ("Identificador del diccionario:
{}\n".format(id(futbolistas)))
# Recorrer el diccionario, imprimiendo clave - valor
print ("Vemos que los elementos no van \"ordenados\":")
for k, v in futbolistas.items():
print ("{} --> {}".format(k,v))
# Nº de elementos que tiene un diccionario
numElemen = len(futbolistas)
print ("\nEl número de futbolistas es de {}".format(numElemen))
# Imprimir las claves que tiene un diccionario
keys = futbolistas.keys();
print ("\nLas claves de nuestro diccionario son :
{}".format(keys))
# Imprimir los valores que tiene un diccionario
values = futbolistas.values();
print ("\nLos valores de nuestro diccionario son :
{}".format(values))
# Obtener el valor de un elemento dada su clave
elem = futbolistas.get(6)
print ("\nEl futbolista con clave 6 es {}".format(elem))

# Insertamos un elemento en el diccionario


## si la clave ya existe, el elemento NO se inserta
elem2 = futbolistas.setdefault(10, 'Cesc')
print ("\nInsertamos el elemento con clave 10 y valor Cesc")
print ("Ahora el identificador del diccionario :
{}".format(id(futbolistas)))
print ("Ahora el diccionario queda : {}".format(futbolistas))
# Añadimos, de otro modo, un elemento al diccionario
## si la clave ya existe, el valor se cambia por este nuevo
futbolistas[22] = 'Navas'
print ("\nAñadimos un nuevo elemento, ahora el diccionario queda:
")
print (futbolistas)
print ("Ahora el identificador del diccionario :
{}".format(id(futbolistas)))
# Eliminamos un elemento del diccionario dada su clave
futbolistas.pop(22)
print ("\nEliminamos el elemento con clave 22")
print ("Ahora el diccionario queda: {}".format(futbolistas))
print ("Ahora el identificador del diccionario :
{}".format(id(futbolistas)))
# Hacemos una copia del diccionario
futbolistas_copia = futbolistas.copy()
print ("\nLa copia del diccionario tiene los valores:")
print (futbolistas_copia)

15
print ("El identificador de la copia del diccionario :
{}".format(id(futbolistas_copia)))
# Borramos los elementos de un diccionario
futbolistas_copia.clear()
print ("\nVaciamos el diccionario nuevo creado, ahora los valores
en el: {}".format(futbolistas_copia))
# Creamos un diccionario a partir de una lista de claves
keys = ['nombre', 'apellidos', 'edad']
datos_usuario = dict.fromkeys(keys, 'null')
print ("\nCreamos un diccionario a partir de la lista de
claves:")
print (keys)
print ("y con valor 'null'")
print ("Así el diccionario queda: {}".format(datos_usuario))
# Comprobamos si existe o no una clave en un diccionario
if 2 in futbolistas:
print ("\nEl futbolista con la clave 2 existe en el
diccionario.")
else:
print ("\nEl futbolista con la clave 2 NO existe en el
diccionario.")
if 8 in futbolistas:
print ("\nEl futbolista con la clave 8 existe en el
diccionario.")
else:
print ("\nEl futbolista con la clave 8 NO existe en el
diccionario.")
# Devolvemos los elementos del diccionario en una tupla
tupla = futbolistas.items()
print ("\nEl diccionario convertido en tupla queda así:")
print (tupla)
# Unimos dos diccionarios existentes
suplentes = {
4:'Marchena', 12:'Valdes', 13:'Mata',
17:'Arbeloa', 19:'Llorente', 20:'Javi Martinez',
21:'Silva', 23:'Reina'}
print ("\nUnimos el diccionario: ")
print (futbolistas)
futbolistas.update(suplentes) # Aquí hacemos la unión de los
diccionarios
print ("con el diccionario:")
print (suplentes)
print ("siendo el resultado:")
print (futbolistas)

16
2.3 FUNCIONES
Una función es un bloque de código con un nombre asociado, que recibe cero o más
argumentos como entrada, sigue una secuencia de sentencias, la cuales ejecuta una
operación deseada y devuelve un valor y/o realiza una tarea, este bloque puede ser
llamados cuando se necesite.

El uso de funciones es un componente muy importante del paradigma de la


programación llamada estructurada, y tiene varias ventajas:

 Modularización: permite segmentar un programa complejo en una serie de


partes o módulos más simples, facilitando así la programación y el depurado.
 Reutilización: permite reutilizar una misma función en distintos programas.

Python dispone de una serie de funciones integradas al lenguaje, y también permite


crear funciones definidas por el usuario para ser usadas en su propios programas.

2.3.1 Sentencia def


La sentencia def es una definición de función usada para crear objetos funciones
definidas por el usuario.

Una definición de función es una sentencia ejecutable. Su ejecución enlaza el nombre


de la función en el namespace local actual a un objecto función (un envoltorio alrededor
del código ejecutable para la función). Este objeto función contiene una referencia al
namespace local global como el namespace global para ser usado cuando la función
es llamada.

La definición de función no ejecuta el cuerpo de la función; esto es ejecutado


solamente cuando la función es llamada.

La sintaxis para una definición de función en Python es:

def NOMBRE(LISTA_DE_PARAMETROS):
"""DOCSTRING_DE_FUNCION"""
SENTENCIAS
RETURN [EXPRESION]

17
A continuación, se detallan el significado de pseudo código fuente anterior:

 NOMBRE, es el nombre de la función.


 LISTA_DE_PARAMETROS, es la lista de parámetros que puede recibir una función.
 DOCSTRING_DE_FUNCION, es la cadena de caracteres usada para documentar la
función.
 SENTENCIAS, es el bloque de sentencias en código fuente Python que realizar
cierta operación dada.
 RETURN, es la sentencia return en código Python.
 EXPRESION, es la expresión o variable que devuelve la sentencia return.

Un ejemplo simple de función esta seguidamente:

>>> def hola(arg):


... """El docstring de la función"""
... print "Hola", arg, "!"
...
>>> hola("Plone")
Hola Plone !

Los bloques de function deben estar identados como otros bloques estructuras de
control.

La palabra reservada def se usa para definir funciones. Debe seguirle el nombre de la
función en el ejemplo anterior hola() y la lista de parámetros formales entre paréntesis.
Las sentencias que forman el cuerpo de la función empiezan en la línea siguiente, y
deben estar identado.

La primer sentencia del cuerpo de la función puede ser opcionalmente una cadenas
de caracteres literal; esta es la cadenas de caracteres de documentación de la función,
o docstrings. (Puedes encontrar más acerca de docstrings en la sección Cadenas
de texto de documentación).

Hay herramientas que usan las docstrings para producir automáticamente


documentación en línea o imprimible, o para permitirle al usuario que navegue el
código en forma interactiva; es una buena práctica incluir docstrings en el código que
uno escribe, por lo que se debe hacer un hábito de esto.

18
La ejecución de la función hola() muestra la impresión de un mensaje Hola Plone !
que se imprime por consola. Devolver el objeto por los valores de retorno opcionales.

La ejecución de una función introduce una nueva tabla de símbolos usada para las
variables locales de la función. Más precisamente, todas las asignaciones de variables
en la función almacenan el valor en la tabla de símbolos local; así mismo la referencia
a variables primero mira la tabla de símbolos local, luego en la tabla de símbolos local
de las funciones externas, luego la tabla de símbolos global, y finalmente la tabla de
nombres predefinidos. Así, no se les puede asignar directamente un valor a las
variables globales dentro de una función (a menos se las nombre en la sentencia
global), aunque si pueden ser referenciadas.

Los parámetros reales (argumentos) de una función se introducen en la tabla de


símbolos local de la función llamada cuando esta es ejecutada; así, los argumentos
son pasados por valor (dónde el valor es siempre una referencia a un objeto, no el
valor del objeto). Cuando una función llama a otra función, una nueva tabla de símbolos
local es creada para esa llamada.

La definición de una función introduce el nombre de la función en la tabla de símbolos


actual. El valor del nombre de la función tiene un tipo que es reconocido por el
intérprete como una función definida por el usuario. Este valor puede ser asignado a
otro nombre que luego puede ser usado como una función. Esto sirve como un
mecanismo general para renombrar.

19
2.3.2 Argumentos y parámetros
Al definir una función los valores los cuales se reciben se denominan parámetros, pero
durante la llamada los valores que se envían se denominan argumentos.

2.3.2.1. Por posición

Cuando envía argumentos a una función, estos se reciben por orden en los parámetros
definidos. Se dice por tanto que son argumentos por posición:

>>> def resta(a, b):


... return a - b
...
>>> resta(30, 10)
20
En el ejemplo anterior el argumento 30 es la posición 0 por consiguiente es el
parámetro de la función a, seguidamente el argumento 10 es la posición 1 por
consiguiente es el parámetro de la función b.

2.3.2.2. Por nombre

Sin embargo es posible evadir el orden de los parámetros si indica durante la llamada
que valor tiene cada parámetro a partir de su nombre:

>>> def resta(a, b):


... return a - b
...
>>> (b=30, a=10)
-20
2.3.2.3. Llamada sin argumentos

Al momento de llamar una función la cual tiene definidos unos parámetros, si no pasa
los argumentos correctamente provocará una excepción TypeError:

>>> resta()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: resta() takes exactly 2 arguments (0 given)

20
2.3.2.4. Parámetros por defecto

Para solucionar la excepción TypeError ejecutada al momento de la llamada a una


función sin argumentos, entonces se puede asignar unos valores por defecto nulos a
los parámetros, de esa forma puede hacer una comprobación antes de ejecutar el
código de la función:

>>> def resta(a=None, b=None):


... if a == None or b == None:
... print "Error, debes enviar dos números a la función"
... return
... return a - b
...
>>> resta(30, 10)
20
>>> resta()
Error, debes enviar dos números a la función

2.3.3. Argumentos indeterminados


En alguna ocasión no se sabe previamente cuantos elementos se necesitan enviar a
una función. En estos casos se puede utilizar los parámetros indeterminados por
posición y por nombre.

2.3.3.1. Por posición

Se debe crear una lista dinámica de argumentos, es decir, un tipo tupla, definiendo el
parámetro con un asterisco, para recibir los parámetros indeterminados por posición:

>>> def indeterminados_posicion(*args):


... for arg in args:
... print arg
...
>>> indeterminados_posicion(5,"Hola Plone",[1,2,3,4,5])
5
Hola Plone
[1, 2, 3, 4, 5]

21
2.3.3.2. Por nombre

Para recibir un número indeterminado de parámetros por nombre (clave-valor o en


inglés keyword args), se debe crear un diccionario dinámico de argumentos definiendo
el parámetro con dos asteriscos:

>>> def indeterminados_nombre(**kwargs):


... print kwargs
...
>>> indeterminados_nombre(n=5, c="Hola Plone", l=[1,2,3,4,5])
{'c': 'Hola Plone', 'l': [1, 2, 3, 4, 5], 'n': 5}

Al recibirse como un diccionario, puede iterarlo y mostrar la clave y valor de cada


argumento:

>>> def indeterminados_nombre(**kwargs):


... for kwarg in kwargs:
... print kwarg, "=>", kwargs[kwarg]
...
>>> indeterminados_nombre(n=5, c="Hola Plone", l=[1,2,3,4,5])
c => Hola Plone
l => [1, 2, 3, 4, 5]
n => 5

2.3.3.3. Por posición y nombre

Si requiere aceptar ambos tipos de parámetros simultáneamente en una función,


entonces se debe crear ambas colecciones dinámicas. Primero los argumentos
indeterminados por valor y luego los cuales son por clave y valor:

>>> def super_funcion(*args,**kwargs):


... total = 0
... for arg in args:
... total += arg
... print "sumatorio => ", total
... for kwarg in kwargs:
... print kwarg, "=>", kwargs[kwarg]
...
>>> super_funcion(50, -1, 1.56, 10, 20, 300, cms="Plone", edad=38)
sumatorio => 380.56
edad => 38
cms => Plone

Los nombres args y kwargs no son obligatorios, pero se suelen utilizar por convención.
Muchos frameworks y librerías los utilizan por lo que es una buena practica llamarlos
así.

22
2.3.4. Sentencia pass
Es una operación nula — cuando es ejecutada, nada sucede. Eso es útil como un
contenedor cuando una sentencia es requerida sintácticamente, pero no necesita
código que ser ejecutado, por ejemplo:

>>> # una función que no hace nada (aun)


... def consultar_nombre_genero(letra_genero): pass
...
>>> type(consultar_nombre_genero)
<type 'function'>
>>> consultar_nombre_genero("M")
>>>
>>> # una clase sin ningún método (aun)
... class Persona: pass
...
>>> macagua = Persona
>>> type(macagua)
<type 'classobj'>

2.3.5. Sentencia return


Las funciones pueden comunicarse con el exterior de las mismas, al proceso principal
del programa usando la sentencia return. El proceso de comunicación con el exterior
se hace devolviendo valores. A continuación, un ejemplo de función usando return:

def suma(numero1,numero2):
'''función la cual suma dos números'''
print numero1 + numero2
print "\n"

Esta función se llama de la siguiente forma:

>>> suma(23,74)
97

Nota: Por defecto, las funciones retorna el valor None.

23
2.3.5.1. Retorno múltiple

Una característica interesante, es la posibilidad de devolver valores múltiples


separados por comas:

>>> def prueba():


... return "Plone CMS", 20, [1,2,3]
...
>>> prueba()
('Plone CMS', 20, [1, 2, 3])
En el código anterior los valores múltiples se tratan en conjunto como una tupla
inmutable y se pueden reasignar a distintas variables:

>>> def prueba():


... return "Plone CMS", 20, [1,2,3]
...
>>> prueba()
('Plone CMS', 20, [1, 2, 3])
>>> cadena, numero, lista = prueba()
>>> print cadena, type(cadena)
Plone CMS <type 'str'>
>>> print numero, type(numero)
20 <type 'int'>
>>> print lista, type(lista)
[1, 2, 3] <type 'list'>

En el código anterior puede observa como se asignar a distintas variables en base a


los valores de la tupla inmutable.

24
2.3.6. Ejemplos de funciones
A continuación, se presentan algunos ejemplos de su uso:

2.3.6.1 Definición de funciones

A continuación, se presenta un ejemplo del uso de definir funciones:

def iva():
'''función básica para el calculo del IVA'''
iva = 12
costo = input('¿Cual es el monto a calcular?: ')
calculo = costo * iva / 100
print "El calculo de IVA es: " + str(calculo) + "\n"

2.3.6.2 Invocar funciones

A continuación, se presenta un ejemplo del uso de llamar funciones:

>>> iva()
¿Cual es el monto a calcular?: 300
36

2.3.6.3 Funciones con argumentos múltiple

A continuación, se presenta un ejemplo del uso de funciones con argumentos múltiple:

def suma(numero1,numero2):
'''función la cual suma dos números'''
print numero1 + numero2
print "\n"

Y se llama de la siguiente forma:

>>> suma(23,74)
97

25
2.4 INTERVALOS
El intervalo de una variable está definido como la diferencia entre el valor más alto y el
valor más bajo que esa variable puede guardar.

En el caso de una variable entera, el intervalo cubrirá todos los números dentro de su
intervalo (incluyendo el máximo y el mínimo). En el caso de una variable entera, la
definición está restringida a números enteros, y el intervalo cubrirá todos los números
dentro de su intervalo (incluyendo el máximo y el mínimo).

El intervalo de un array es los límites superior e inferior del mismo.

 Diferencia entre declaración y modificación de variables

o En programación funcional pura una vez declarada una variable no se


puede modificar su valor.
o En algunos lenguajes de programación (como scala) este concepto se
refuerza definiendo la variable como inmutable (con la directiva val).
o En programación imperativa es habitual modificar el valor de una variable
en distintos pasos de ejecución.

26
2.4.1 El tipo range
El tipo range es una lista inmutable de números enteros en sucesión aritmética.

 Inmutable significa que, a diferencia de las listas, los range no se pueden


modificar.
 Una sucesión aritmética es una sucesión en la que la diferencia entre dos
términos consecutivos es siempre la misma.

Un range se crea llamando al tipo de datos con uno, dos o tres argumentos numéricos,
como si fuera una función.

Nota: En Python 2, range() se consideraba una función, pero en Python 3 no se


considera una función, sino un tipo de datos , aunque se utiliza como si fuera una
función.

El tipo range() con un único argumento se escribe range(n) y crea una lista inmutable
de n números enteros consecutivos que empieza en 0 y acaba en n - 1.

Para ver los valores del range(), es necesario convertirlo a lista mediante la función
list().

>>> x = range(10)
>>> x
range(0, 10)
>>> list(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(7)
range(0, 7)
>>> list(range(7))
[0, 1, 2, 3, 4, 5, 6]
Si n no es positivo, se crea un range vacío.

>>> list(range(-2))
[]
>>> list(range(0))
[]

El tipo range con dos argumentos se escribe range(m, n) y crea una lista inmutable de
enteros consecutivos que empieza en m y acaba en n - 1.

>>> list(range(5, 10))


[5, 6, 7, 8, 9]
>>> list(range(-5, 1))
[-5, -4, -3, -2, -1, 0]

27
Si n es menor o igual que m, se crea un range vacío.

>>> list(range(5, 1))


[]
>>> list(range(3, 3))
[]

El tipo range con tres argumentos se escribe range(m, n, p) y crea una lista inmutable
de enteros que empieza en m y acaba justo antes de superar o igualar a n, aumentando
los valores de p en p. Si p es negativo, los valores van disminuyendo de p en p.

>>> list(range(5, 21, 3))


[5, 8, 11, 14, 17, 20]
>>> list(range(10, 0, -2))
[10, 8, 6, 4, 2]
El valor de p no puede ser cero:

>>> range(4,18,0)
Traceback (most recent call last):/span>
File "<pyshell#0>", line 1, in <module>
range(4,18,0)
ValueError: range() arg 3 must not be zero
Si p es positivo y n menor o igual que m, o si p es negativo y n mayor o igual que m,
se crea un range vacío.

>>> list(range(25, 20, 2))


[]
>>> list(range(20, 25, -2))
[]

En los range( m, n, p), se pueden escribir p range distintos que generan el mismo
resultado. Por ejemplo:

>>> list(range(10, 20, 3))


[10, 13, 16, 19]
>>> list(range(10, 21, 3))
[10, 13, 16, 19]
>>> list(range(10, 22, 3))
[10, 13, 16, 19]

En resumen, los tres argumentos del tipo range(m, n, p) son:

 m: el valor inicial
 n: el valor final (que no se alcanza nunca)
 p: el paso (la cantidad que se avanza cada vez).

28
Si se escriben sólo dos argumentos, Python le asigna a p el valor 1. Es decir range(m,
n) es lo mismo que range(m, n, 1)

Si se escribe sólo un argumento, Python, le asigna a m el valor 0 y a p el valor 1. Es


decir range(n) es lo mismo que range(0, n, 1)

El tipo range() sólo admite argumentos enteros. Si se utilizan argumentos decimales,


se produce un error:

>>> range(3.5, 10, 2)


Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
range(3.5, 10, 2)
TypeError: range() integer start argument expected, got float.

Nota: En versiones muy antiguas de Python se podían utilizar argumentos decimales,


que Python truncaba a enteros.

2.4.2 Concatenar range()


No se pueden concatenar tipos range(), ya que el resultado de la concatenación puede
no ser un tipo range()).

>>> range(3) + range(5)


Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
range(3) + range(5)
TypeError: unsupported operand type(s) for +: 'range' and 'range'

Pero sí se pueden concatenar tipos range() previamente convertidos en listas. El


resultado es lógicamente una lista, que no se puede convertir a tipo range().

>>> list(range(3)) + list(range(5))


[0, 1, 2, 0, 1, 2, 3, 4]

No se pueden concatenar tipos range(), ni aunque el resultado sea una lista de


números enteros en sucesión aritmética.

>>> range(1, 3) + range(3, 5)


Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
range(3) + range(5)
TypeError: unsupported operand type(s) for +: 'range' and 'range'
>>> list(range(1, 3)) + list(range(3, 5))
[1, 2, 3, 4]

29
2.4.3 La función len()
La función len() devuelve la longitud de una cadena de caracteres o el número de
elementos de una lista. El argumento de la función len() es la lista o cadena que
queremos "medir".

>>> len("mensaje secreto")


15
>>> len(["a","b","c"])
3
>>> len(range(1, 100, 7))
15

El valor devuelto por la función len() se puede usar como parámetro de range().

>>> list(range(len("mensaje secreto")))


[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> list(range(len(["a","b","c"])))
[0, 1, 2]
>>> list(range(len(range(1, 100, 7))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

30
2.5 OPERADORES
Los operadores son símbolos matemáticos que llevan a cabo una operación específica
entre los operandos y tienen una función en específico. Los operadores reciben
pueden recibir operandos variables. Los operandos serian aquellos argumentos que
reciben los operadores para realizar su función..

Podríamos entenderlo más fácilmente con un ejemplo:

En el caso de una SUMA el operador utilizado es el símbolo «más» (+) y podemos


sumar tanto números, como letras o variables como hemos visto anteriormente. Estos
números o variables serían los Operandos y cuando decimos que pueden ser
dinámicos nos referimos a variables, que pueden cambiar su valor, pero el operando
realizará la misma operación!

Tipos de operadores en python:

Hay diferentes operadores y mas te vale conocerlos a todos!! Porque son de gran
utilidad en el uso de condiciones y funciones entre otras cosas como dije son un
elemento crucial en la programación! Veamos los tipos y cuales son:

2.5.1 Operadores aritméticos

Los valores numéricos son además el resultado de una serie de


operadores aritméticos y matemáticos:

2.5.1.1 Operador Suma

El operador + suma los valores de tipo de datos numéricos.

>>> 3 + 2

2.5.1.2 Operador Resta

El operador - resta los valores de tipo de datos numéricos.

31
>>> 4 - 7

-3

2.5.1.3 Operador Negación

El operador - asigna un valor negativo a un tipo de datos numéricos.

>>> -7

-7

2.5.1.4 Operador Multiplicación

El operador * multiplica los valores de tipo de datos numéricos.

>>> 2 * 6

12

2.5.1.5 Operador Exponente

El operador ** calcula el exponente entre valores de tipo de datos numéricos.

>>> 2 ** 6

64

2.5.1.6 Operador división

El operador división el resultado que se devuelve es un número real.

>>> 3.5 / 2

1.75

2.5.1.7 Operador división entera

El operador división entera el resultado que se devuelve es solo la parte entera.

>>> 3.5 // 22

1.0

32
No obstante hay que tener en cuenta que si utilizamos dos operandos enteros, Python
determinará que quiere que la variable resultado también sea un entero, por lo que el
resultado de, por ejemplo, 3 / 2 y 3 // 2 sería el mismo: 1. Si quisiéramos obtener los
decimales necesitaríamos que al menos uno de los operandos fuera un número real,
bien indicando los decimales:

r = 3.0 / 2

O bien utilizando la función float() para convertir a entero coma flotante o real:

r = float(3) / 2

Esto es así porque cuando se mezclan tipos de números, Python convierte todos los
operandos al tipo más complejo de entre los tipos de los operandos.

2.5.1.8 Operador Módulo

El operador módulo no hace otra cosa que devolver el resto de la división entre los dos
operandos. En el ejemplo, 7 / 2 sería 3, con 1 de resto, luego el módulo es 1.

>>> 7 % 2

2.5.1.9 Orden de precedencia

El orden de precedencia de ejecución de los operadores aritméticos es:

1. Exponente: **
2. Negación: -
3. Multiplicación, División, División entera, Módulo: *, /, //, %
4. Suma, Resta: +, -

Eso quiere decir que se debe usar así:

>>> 2**1/12

0.16666666666666666

>>>

33
Más igualmente se puede omitir este orden de precedencia de ejecución de los
operadores aritméticos usando paréntesis () anidados entre cada nivel calculo, por
ejemplo:

>>> 2**(1/12)

1.0594630943592953

>>>

2.5.1.10 Ejemplos

A continuación, se presentan algunos ejemplos de su uso:

Ejemplo de definir variables numéricas

a, b, c, d = 26, 11.3, 5, 3.5

Ejemplo de operador aritmético Suma, Añade valores a cada lado del


operador.

print a + b

Ejemplo de operador aritmético Resta, Resta el operando de la derecha


del operador del lado izquierdo.

print c - a

Ejemplo de operador aritmético Multiplicación, Multiplica los valores de


ambos lados del operador.

print d * c

Ejemplo de operador aritmético Exponente, Realiza el cálculo


exponencial (potencia) de los operadores.

print c ** 2

Ejemplo de operador aritmético División.

print float(c) / a

34
Ejemplo de operador aritmético División entera.

print 7 / 3

Ejemplo de operador aritmético Cociente de una división, la división de


operandos que el resultado es el cociente en el cual se eliminan los dígitos
después del punto decimal.

print a // c

Ejemplo de operador aritmético Módulo, el cual divide el operando de la


izquierda por el operador del lado derecho y devuelve el resto.

print 7 % 3

2.5.2 Operadores de asignaciones

Los operadores de asignación se utilizan para

Existe en Python todo un grupo de operadores los cuales le permiten


básicamente asignar un valor a una variable, usando el operador “=”. Con
estos operadores pueden aplicar la técnica denominada asignación
aumentada.

2.5.2.1 Operador =

El operador igual a, (=), es el más simple de todos y asigna a la variable


del lado izquierdo cualquier variable o resultado del lado derecho.

2.5.2.2 Operador +=

El operador += suma a la variable del lado izquierdo el valor del lado


derecho.

>>> r = 5; r += 10; r

15

En el ejemplo anterior si la variable “r” es igual a 5 y r += 10, entonces la


variable “r” sera igual a 15. Su equivalente seria el siguiente:
35
>>> r = 5; r = r + 10; r

15

2.5.2.3 Operador -=

El operador -= resta a la variable del lado izquierdo el valor del lado


derecho.

>>> r = 5; r -= 10; r

-5

En el ejemplo anterior si la variable “r” es igual a 5 y r -= 10, entonces la


variable “r” sera igual a -5. Su equivalente seria el siguiente:

>>> r = 5; r = r - 10; r

-5

2.5.2.4 Operador *=

El operador *= multiplica a la variable del lado izquierdo el valor del lado


derecho.

>>> r = 5; r *= 10; r

50

En el ejemplo anterior si la variable “r” es igual a 5 y r *= 10, entonces la


variable “r” sera igual a 50. Su equivalente seria el siguiente:

>>> r = 5; r = r * 10; r

50

2.5.2.5 Operador /=

El operador /= divide a la variable del lado izquierdo el valor del lado


derecho.

>>> r = 5; r /= 10; r

36
0

En el ejemplo anterior si la variable “r” es igual a 5 y r /= 10, entonces la


variable “r” sera igual a 0. Su equivalente seria el siguiente:

>>> r = 5; r = r / 10; r

2.5.2.6 Operador **=

El operador **= calcula el exponente a la variable del lado izquierdo el valor


del lado derecho.

>>> r = 5; r **= 10; r

9765625

En el ejemplo anterior si la variable “r” es igual a 5 y r **= 10, entonces la


variable “r” será igual a 9765625. Su equivalente seria el siguiente:

>>> r = 5; r = r ** 10; r

9765625

2.5.2.7 Operador //=

El operador //= calcula la división entera a la variable del lado izquierdo el


valor del lado derecho.

>>> r = 5; r //= 10; r

En el ejemplo anterior si la variable “r” es igual a 5 y r //= 10, entonces la


variable “r” será igual a 0. Su equivalente seria el siguiente:

>>> r = 5; r = r // 10; r

37
2.5.2.8 Operador %=

El operador %= devuelve el resto de la división a la variable del lado


izquierdo el valor del lado derecho.

>>> r = 5; r %= 10; r

En el ejemplo anterior si la variable “r” es igual a 5 y r %= 10, entonces la


variable “r” será igual a 5. Su equivalente seria el siguiente:

>>> r = 5; r = r % 10; r

2.5.2.9 Asignación aumentada

Es frecuente que una variable tenga que ser definida de nuevo en función
de sí misma. Normalmente se escribir la siguiente sintaxis:

>>> contador = contador + 1

El código anterior, se puede abreviar a su equivalente, usando la


asignación aumentada, de la siguiente manera:

>>> contador += 1

El código anterior, no sólo es más corto de escribir, sino también más


eficiente en tiempo de ejecución.

2.5.2.10 Ejemplos

A continuación, se presentan algunos ejemplos de su uso:

a, b, c = 21, 10, 0

print "Valor de variable 'a':", a

38
print "Valor de variable 'b':", b

c=a+b

print "Operador = | El valor de variable 'c' es ", c

c += a

print "Operador += | El valor de variable 'c' es ", c

c *= a

print "Operador *= | El valor de variable 'c' es ", c

c /= a

print "Operador /= | El valor de variable 'c' es ", c

c=2

c %= a

print "Operador %= | El valor de variable 'c' es ", c

c **= a

print "Operador **= | El valor de variable 'c' es ", c

c //= a

print "Operador //= | El valor de variable 'c' es ", c

39
2.5.3 Operadores relacionales
Los valores booleanos son además el resultado de expresiones que utilizan
operadores relacionales (comparaciones entre valores):

2.5.3.1 Operador ==

El operador == evalúa que los valores sean iguales para varios tipos de datos.

>>> 5 == 3

False

>>> 5 == 5

True

>>> "Plone" == 5

False

>>> "Plone" == "Plone"

True

>>> type("Plone") == str

True

2.5.3.2 Operador !=

El operador != evalúa si los valores son distintos.

>>> 5 != 3

True

>>> "Plone" != 5

True

>>> "Plone" != False

True

40
2.5.3.3 Operador <

El operador < evalúa si el valor del lado izquierdo es menor que el valor del lado
derecho.

>>> 5 < 3

False

2.5.3.4 Operador >

El operador > evalúa si el valor del lado izquierdo es mayor que el valor del lado
derecho.

>>> 5 > 3

True

2.5.3.5 Operador <=

El operador <= evalúa si el valor del lado izquierdo es menor o igual que el
valor del lado derecho.

>>> 5 <= 3

False

2.5.3.6 Operador >=

El operador >= evalúa si el valor del lado izquierdo es mayor o igual que el
valor del lado derecho.

>>> 5 >= 3

True

2.5.3.7 Ejemplos

A continuación, se presentan algunos ejemplos de su uso:

41
2.5.3.8 Ejemplo de definir variables numéricas

a, b, a1, b1, c1 = 5, 5, 7, 3, 3

cadena1, cadena2 = 'Hola', 'Adiós'

lista1, lista2 = [1, 'Lista Python', 23], [11, 'Lista Python', 23]

2.5.3.9 Ejemplo de operador relacional Igual

c = a == b

print c

cadenas = cadena1 == cadena2

print cadenas

listas = lista1 == lista2

print listas

2.5.3.10 Ejemplo de operador relacional Diferente

d = a1 != b

print d

cadena0 = cadena1 != cadena2

print cadena0

2.5.3.11 Ejemplo de operador relacional Menor que

f = b1 < a1

print f

42
2.5.3.12 Ejemplo de operador relacional Mayor que

e = a1 > b1

print e

2.5.3.13 Ejemplo de operador relacional Menor o igual que

h = b1 <= c1

print h

2.5.3.14 Ejemplo de operador relacional Mayor o igual que

g = b1 >= c1 print g

2.5.4 Operadores lógicos

Estos son los distintos tipos de operadores con los que puede trabajar con
valores booleanos, los llamados operadores lógicos o condicionales:

2.5.4.1 Operador and

El operador and evalúa si el valor del lado izquierdo y el lado derecho se


cumple.

>>> True and False

False

2.5.4.2 Operador or

El operador or evalúa si el valor del lado izquierdo o el lado derecho se


cumple.

>>> True or False

True

43
2.5.4.3 Operador not

El operador not devuelve el valor opuesto la valor booleano.

>>> not True

False

Si la expresión es True el valor devuelto es False, de lo contrario si la


expresión es False el valor devuelto es True.

>>> not False

True

2.5.4.4 Ejemplos

A continuación, se presentan algunos ejemplos de su uso:

2.5.4.5 Definir variables usadas en los siguientes ejemplos:

a, b = 10, 20

2.5.4.6 Ejemplo de operador lógico and:

if (a and b):

print "Las variables 'a' y 'b' son VERDADERO."

else:

print "O bien la variable 'a' no es VERDADERO " + \

"o la variable 'b' no es VERDADERO."

2.5.4.7 Ejemplo de operador lógico or:

if (a or b):

print "O bien la variable 'a' es VERDADERA " + \

"o la variable 'b' es VERDADERA " + \

44
"o ambas variables son VERDADERAS."

else:

print "Ni la variable 'a' es VERDADERA ni " + \

"la variable 'b' es VERDADERA."

2.5.4.8 Ejemplo de operador lógico not:

if not(a and b):

print "Ni la variable 'a' NO es VERDADERA " + \

"o la variable 'b' NO es VERDADERA."

else:

print "Las variables 'a' y 'b' son VERDADERAS."

45
2.6 APLICACIONES DE LAS LISTAS
Las listas en Python tienen muchos métodos que podemos utilizar, entre todos ellos
vamos a nombrar los más importantes. Para esto utilizaremos esta lista de ejemplo.

my_list = [2, 5, 'DevCode', 1.2, 5]

Sobre esta vamos a realizar diferentes métodos que son propios de las listas.

Append()
Este método nos permite agregar nuevos elementos a una lista.
my_list.append(10) # [2, 5, 'DevCode', 1.2, 5, 10]
my_list.append([2,5]) # [2, 5, 'DevCode', 1.2, 5, [2, 5]]

Podemos agregar cualquier tipo de elemento a una lista, pero tengan en cuenta lo que
pasa cuando agregamos una lista dentro de otra, esta lista se agrega como uno y solo
un elemento.

Extend()
Extend también nos permite agregar elementos dentro de una lista, pero a diferencia
de append al momento de agregar una lista, cada elemento de esta lista se agrega
como un elemento más dentro de la otra lista.
my_list.extend([2,5]) # [2, 5, 'DevCode', 1.2, 5, 2, 5]

Remove()
El método remove va a remover un elemento que se le pase como parámentro de la
lista a donde se le esté aplicando.
my_list.remove(2) # [5, 'DevCode', 1.2, 5]
En este ejemplo estamos removiendo el elemento 2, de la lista que tiene por nombre
"my_list".

Index()
Index devuelve el número de indice del elemento que le pasemos por parámetro.
my_list.index('DevCode') # 2
Aquí estamos preguntando por el indice de la cadena 'DevCode' dentro de la lista
"my_list", esto devuelve 2.

Count()
Para saber cuántas veces un elemento de una lista se repite podemos utilizar el
metodo count().
my_list.count(5) # 2

46
Contamos cuantas veces se repite el número 5 dentro de la lista, y esto devuelve 2.

Reverse()
También podemos invertir los elementos de una lista.
my_list.reverse() # [5, 1.2, 'DevCode', 5, 2]
Estas son algunos de los métodos más útiles y más utilizados en las listas.Python es
un gran lenguaje de programación que hace las cosas de una manera realmente
sencilla

2.6.1 Ejemplos del uso de listas en Python

Para empezar, agreguemos un elemento al final. Para ellos, utilizaremos el método


append() del objeto lista:
jugadores.append(‘Mayada')

1jugadores.append('Mayada')

Si deseamos agregar en cambio un elemento en una posición determinada,


emplearemos el método insert():

jugadores.insert(2, 'Casco')
1jugadores.insert(2, 'Casco')

Para eliminar un ítem ubicado en una posición determinada, utilizaremos el método


pop().

Si incluimos un índice dentro de los paréntesis, se eliminará el elemento


correspondiente al mismo. Si lo omitimos, por defecto se asumirá que deseamos
remover el último de la lista.

47
1 jugadores.pop(5)
2 jugadores.pop()

2.6.2 Verificar la existencia de un ítem dentro de una lista

Cuando una lista contiene muchos elementos puede resultar difícil precisar a simple
vista si un valor específico está incluido en la misma. Lo mismo sucede si tenemos que
procesar la lista utilizando un script o un programa. Para verificar la existencia de un
ítem dentro de una lista utilizaremos la palabra clave in (o not in) de la siguiente
manera. El resultado será un valor booleano que indicará la respuesta:

48
2.7 ÁRBOLES
Los Árboles son las estructuras de datos más utilizadas, pero también una de las más
complejas, Los Árboles se caracterizan por almacenar sus nodos en forma jerárquica
y no en forma lineal como las Listas Ligadas, Colas, Pilas, etc., de las cuales ya hemos
hablado en días pasados.

49
2.7.1 Datos importantes de los Árboles
Para comprender mejor que es un árbol comenzaremos explicando cómo está
estructurado.

 Nodos: Se le llama Nodo a cada elemento que contiene un Árbol.


 Nodo Raíz: Se refiere al primer nodo de un Árbol, Solo un nodo del Árbol puede
ser la Raíz.
 Nodo Padre: Se utiliza este término para llamar a todos aquellos nodos que
tiene al menos un hijo.
 Nodo Hijo: Los hijos son todos aquellos nodos que tiene un padre.
 Nodo Hermano: Los nodos hermanos son aquellos nodos que comparte a un
mismo padre en común dentro de la estructura.
 Nodo Hoja: Son todos aquellos nodos que no tienen hijos, los cuales siempre
se encuentran en los extremos de la estructura.
 Nodo Rama: Estos son todos aquellos nodos que no son la raíz y que ademas
tiene al menos un hijo.

50
2.7.2 Recorrido sobre Árboles
Los recorridos son algoritmos que nos permiten recorrer un árbol en un orden
específico, los recorridos nos pueden ayudar encontrar un nodo en el árbol, o buscar
una posición determinada para insertar o eliminar un nodo.

Básicamente podemos catalogar la búsqueda en dos tipos, la búsqueda en


profundidad y las búsquedas en amplitud.

2.7.2.1 Búsquedas no informadas

Las búsquedas no informadas son aquellas en que se realiza el viaje por todo el árbol
sin tener una pista de donde pueda estar el dato deseado. Este tipo de búsquedas
también se conocen como búsquedas a ciegas.

Para comprender mejor que es una búsqueda no informada expondremos el siguiente


ejemplo:

Imagine que vamos por la carretera y de repente encontramos dos caminos, el


problema a qui es que uno después de 50 kilómetros está en construcción y el otro
nos lleva a nuestro destino, sin embargo, ninguno de los caminos tiene señalamiento.
Lo que tendríamos que hacer es recorrer el primero camino y después de 50 kilómetros
encontrarnos con que el camino está en construcción, entonces tendríamos que
regresar para irnos por el segundo camino, el cual nos lleva a nuestro destino (Para
esto ya recorrimos los 50 kilómetros de ida y los 50 kilómetros de regreso lo que nos
da 100 kilómetros más a nuestra ruta).

A este tipo de escenarios en los cuales las búsquedas de hacen a ciegas los
conocemos como búsquedas no informadas.

Los siguientes métodos de búsqueda que veremos a continuación (Búsqueda en


profundad y Búsqueda en amplitud) pertenecen a las búsquedas no informadas.

51
2.7.2.2 Búsqueda en profundidad

Recorrido Pre-orden: El recorrido inicia en la Raíz y luego se recorre en pre-orden


cada uno de los sub-árboles de izquierda a derecha.

Esta definición puede ser un poco compleja de entender por lo que mejor les dejo la
siguiente imagen.

Recorrido Pos-orden: Se recorre el pos-orden cada uno de los sub-árboles y al final


se recorre la raíz.

52
Para comprender mejor esta definición observemos la siguiente imagen:

En la imagen podemos observar cómo se realiza el recorrido en Post-Orden, Sin embargo, es importante
notar que el primer nodo que se imprime no es la Raíz pues en este recorrido la Raíz de cada Sub-Árbol es
procesado al final, ya que toda su descendencia ha sido procesada.

Recorrido in-orden: Se recorre en in-orden el primer sub-árbol, luego se recorre la


raíz y al final se recorre en in-orden el demás sub-árbol

53
En la imagen se muestra como es el recorrido In-Orden, Podemos apreciar que la Raíz no
es el primero elemento en ser impreso pues este recorrido recorre su rama izquierda, luego
la raíz del sub-árbol y luego la rama derecha.

54
2.7.2.3 Búsqueda en amplitud.

Se recorre primero la raíz, luego se recorren los demas nodos ordenados por el nivel
al que pertenecen en orden de Izquierda a derecha.

Este tipo de búsqueda se caracteriza por que la búsqueda se hace nivel por nivel y de
izquierda a derecha.

En la imagen se observa cómo es que un nodo es buscado mediante la búsqueda en


profundidad.

55
Si observamos el código de forma minuciosa podemos observar dos puntos muy
interesantes, el primero es que esta función no es recursiva, y la segunda es que se
utiliza una Cola para controlar el flujo del recorrido.

Los pasos para hacer el recorrido es el siguiente:

1. Se agrega la Raíz a la cola de nodos por visitar


2. Mientras que la cola no este vacía se saca el primer elemento de la cola y
continuamos con el paso 3, Pero; si la cola esta vacía entonces nos vamos al
paso 5.
3. Se valida si el elemento sacado de la pila es el que estamos buscando, Si lo es,
entonces hemos terminado, Si no lo es se agregan todos los hijos del nodo a la
pila de nodos pendientes por procesar.
4. Regresamos al paso 2.
5. Terminamos sin un resultado.

2.7.3 Arboles en Python


En Ciencias de la computación, un árbol es una estructura de datos que imita la
estructura de un árbol al revés: La raíz está en la parte superior y sub-árboles con
nodos superiores. Los nodos descendientes o inferiores son llamados nodos hoja. Un
árbol es un tipo de Grafo que no tiene ciclos.

Python no tiene soporte para árboles incorporado.

Un árbol binario es un árbol que tiene máximo dos nodos descendientes (izquierdo y
derecho). Se define una clase llamada ‘Arbol’

class Arbol(object):
def __init__(self):
self.der = None # Rama derecha del árbol
self.izq = None # Rama izquierda del árbol
self.dato = None # Dato del nodo del árbol
raiz = Arbol()
raiz.dato = 'Raiz'
raiz.izq = Arbol()
raiz.izq.dato = 'Izquierda'
raiz.der = Arbol()
raiz.der.dato = 'Derecha'
print(raiz.izq.dato)

56
De esta misma forma se puede ir aumentando el tamaño del árbol y agregándole mas
información:

class Arbol(object):
def __init__(self):
self.der = None
self.izq = None
self.dato = None
raiz = Arbol()
raiz.dato = 'Raiz'
raiz.izq = Arbol()
raiz.izq.dato = 'Izquierda'
raiz.der = Arbol()
raiz.der.dato = 'Derecha'
raiz.izq.izq = Arbol()
raiz.izq.izq.dato = 'Izquierda 2'
raiz.izq.der = Arbol()
raiz.izq.der.dato = 'Izquierda - Derecha'
Lógicamente, si se quiere definir un árbol que no sea binario, entonces se aumentan
las posibles ramas en ‘__init__’:

class Arbol(object):
def __init__(self):
self.der = None
self.der2 = None
self.cent = None
self.izq = None
self.izq2 = None
self.dato = None

Y así de forma sucesiva.

57
2.8 EVALÚACIÓN PEREZOSA
En programación la evaluación perezosa, o llamada por necesidad, o por su nombre
en inglés: lazy evaluation. Es una técnica de evaluación, que consiste en retrasar el
cálculo (o ejecución) de una instrucción hasta que en realidad es necesaria.

Por ejemplo, para calcular el segundo primo entre 10000 y 100000 podemos hacer:

ls = srange(10000,100000)
primos = [t for t in ls if is_prime(t) ]
print primos[1]

pero esto nos obliga a guardar en memoria todos los números naturales entre 10000
y 100000, y después a calcular si cada uno es primo, sólo para quedarnos con el
segundo.

sage: %time
sage: ls = srange(10000,100000)
sage: primos = [t for t in ls if is_prime(t) ]
sage: print primos[2]
10037
CPU time: 0.39 s, Wall time: 0.39 s

Sin embargo, es posible mantener esta sintaxis sin hacer cálculos innecesarios. Para
ello, se usan generadores , objetos que generan los elementos de la lista uno por uno,
según se vayan solicitando desde otras partes del programa. A esta técnica se le
denomina evaluación perezosa, porque no se hacen cálculos hasta que no son
necesarios.

Por ejemplo, la función xsrange es la versión perezosa de srange (con la misma


sintaxis). Mientras que srange(100) inmediatamente calcula los enteros menores que
100 y los guarda en una lista, xsrange(100) devuelve un generador, que no calcula los
números en ese momento:

sage: srange(100)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99]
sage: xsrange(100)
<generator object generic_xsrange at 0x5dacf50>

58
Una vez creado el generador, podemos pedir los números uno por uno, usando el
método next() , o recorrerlos todos, usando un bucle for igual que si fuera una lista:

sage: xlista = xsrange(100)


sage: print xlista.next()
sage: print xlista.next()
0
1
sage: acumulador = 0
sage: for j in xsrange(101):
... acumulador += j
sage: print acumulador
5050

Se pueden escribir generadores propios usando una notación similar a la de


transformaciones de listas, sólo que poniendo paréntesis alrededor de la expresión en
vez de corchetes:

generador = (expresion for x in secuencia if condicion)


sage: genera_cuadrados = (x^2 for x in xsrange(10))
sage: for c in genera_cuadrados:
... print c
0
1
4
9
16
25
36
49
64
81

Ahora podemos modificar el programa original para calcular el segundo primo entre 10000 y
100000, usando una cantidad de memoria y cpu equivalente a un programa tradicional:

sage: %time
sage: ls = xrange(10000,100000)
sage: primos = (t for t in ls if is_prime(t) )
sage: primos.next()
sage: print primos.next()
10009
CPU time: 0.01 s, Wall time: 0.01 s
sage: %time
sage: contador = 2
sage: for j in xsrange(10000,100000):
... if is_prime(j):
... contador -= 1
... if contador == 0:
... break
sage: print j
10009
CPU time: 0.00 s, Wall time: 0.00 s

59
Siguiendo la ejecución del programa paso a paso:

ls = xrange(10000,100000)
primos = (t for t in ls if is_prime(t) )

con estas dos líneas, se definen dos generadores, pero no se realiza ningún cálculo.

primos.next()

al llamar al método next , ponemos a trabajar al generador primos , que debe rodar
hasta devolver un número primo. Para ello, prueba los números de la lista ls uno por
uno. Cuando encuentra uno que pasa el filtro is_prime(t) , lo devuelve. En la primera
llamada a next , primos devuelve el número 10007, el primer primo mayor que 10000.

print primos.next()

pedimos otro número más a primos , que pide a su vez números al generador ls
continuando donde lo dejó. Recorre primero el número 10008 e inmediatamente
después encuentra 10009, que es primo. El programa concluye.

60
REFERENCIAS BIBLIOGRÁFICAS

FUENTE SUBTEMA

Angulo, P. (25 de Noviembre de 2011). Un poco de programación Lógica.


Recuperado el 14 de Septiembre de 2019, de Sage Laboratorio de Matemáticas: 2.8
http://verso.mat.uam.es/~pablo.angulo/doc/laboratorio/b1s3.html

Blancarte, O. (22 de Agosto de 2014). Estructura de Datos - Árboles. Recuperado


el 14 de Septiembre de 2019, de Oscar Blancarte Software Architect:
2.7
https://www.oscarblancarteblog.com/2014/08/22/estructura-de-datos-
arboles/

Brudnick, P. (22 de Marzo de 2017). Introducción a la Programación Funcional.


Recuperado el 16 de Septiembre de 2019, de Fiqus:
2.1
https://fiqus.com/2017/03/22/introduccion-a-la-programacion-funcional/

COVANTEC. (16 de Julio de 2015). Operadores Aritméticos. Recuperado el 14 de


Septiembre de 2019, de COVANTEC: https://entrenamiento-python-
2.5.1
basico.readthedocs.io/es/latest/leccion3/operadores_aritmeticos.html

COVANTEC. (16 de Julio de 2015). Operadores De Asignación. Recuperado el 14


de Septiembre de 2019, de COVANTEC: https://entrenamiento-python-
2.5.2
basico.readthedocs.io/es/latest/leccion3/operadores_asignaciones.html

COVANTEC. (16 de Julio de 2015). Operadores Lógicos. Recuperado el 14 de


Septiembre de 2019, de COVANTEC: https://entrenamiento-python- 2.5.4
basico.readthedocs.io/es/latest/leccion4/operadores_logicos.html

61
COVANTEC. (16 de Julio de 2015). Operadores Relacionales. Recuperado el 14
de Septiembre de 2019, de COVANTEC: https://entrenamiento-python-
2.5.3
basico.readthedocs.io/es/latest/leccion3/operadores_relacionales.html

COVANTEC. (17 de Julio de 2015). Funciones. Recuperado el 15 de Septiembre


de 2019, de COVANTEC: https://entrenamiento-python- 2.3
basico.readthedocs.io/es/latest/leccion5/funciones.html

Manuais IES San Clemente. (1 de Enero de 2018). Python - Tipos de datos.


Recuperado el 16 de Septiembre de 2019, de Manuais Ies San Clemente.net:
2.2
https://manuais.iessanclemente.net/index.php/Python_-_Tipos_de_datos

Marco, B. S. (20 de Febrero de 2017). Introducción a la programación con Python.


Recuperado el 15 de Septiembre de 2019, de MCLibre:
2.4
http://www.mclibre.org/consultar/python/lecciones/python-range.html

Urquiaga, J. C. (19 de Agosto de 2018). Listas en Python. Recuperado el 16 de


Septiembre de 2019, de DevCode: https://devcode.la/tutoriales/listas-python/
2.6

62

Potrebbero piacerti anche