Contenido Tematico #011 - 012
Contenido Tematico #011 - 012
Contenido Tematico #011 - 012
Actividad De Aprendizaje N° 11 – 12
Estructura de un programa
Dado que ya hemos construido un conjunto de módulos y hemos definido las variables necesarias para su
funcionamiento, podemos agruparlos en un programa.
Un programa no es ni más ni menos que el conjunto de órdenes o instrucciones que resuelven un problema
dado.
Definición Llamada
def funcion1(): funcion1()
def funcion2(nombre): funcion2(20)
def funcion3(nombre=100): funcion3(nombre=10) o funcion3(23) o funcion3()
def funcion4(arg1, arg2): funcion4(22,11) o funcion4(arg2=12, arg1=22)
Recordamos que un módulo es un archivo de texto con instrucciones en Python cuya extensión es “.py”. Más
adelante veremos algunas formas más complejas de trabajar con módulos pero, en principio, vamos a retomar
con la definición de funciones.
· Reuso de código: Al definir una función, como mencionamos anteriormente, evitamos repetir
sentencias o bloques de código para su uso en diferente puntos de nuestro programa. Si pensamos en
funciones parametrizadas esta característica se potencia aún mucho más.
· Abstracción de código: Con las funciones podemos dividir nuestro programa en partes más pequeñas,
cada una llevando a cabo una acción específica. De esta manera, invocamos a una función para
realizar un conjunto de instrucciones, y, desde nuestro programa sólo nos importa qué es lo que hace
la función y no cómo lo hace. Cada porción de código encerrado en una función resuelve una tarea
específica y no interfiere con el funcionamiento de las otras funciones o el resto del programa.
ý Googleame: Abstraer
¿Pueden pensar en un ejemplo donde se ponga en práctica este concepto?
Como pueden ver, en la Tabla 7.1 si una función posee parámetros, los mismos pueden o no tener valores por
defecto. La función3 posee un único argumento y, por defecto tiene el valor 100. Esto significa que podemos
invocar a esta función sin ningún argumento y, en este caso tomará el valor por defecto (100) o, enviando un
valor cualquiera.
En el caso que la función posea más de un parámetro, al invocarla, los mismos se asocian en el mismo orden
en que fueron definidos. Esto es, en el caso de la funcion4, cuando invocamos con los valores 22 y 11. se asume
que 22 será el valor asociado al parámetro arg1 y 24 será el valor de arg2.
Si conocemos el nombre de los parámetros, entonces podemos invocar a la función enviando los valores
independientemente del orden en que la función los espera asociando los valores a los correspondientes
nombres de argumentos, como se muestra en la última invocación a la funcion4. Si bien esto último no es lo
más adecuado, muchas veces es útil cuando queremos que la función utilice alguno de los valores por defecto
de sus parámetros, y sólo enviarle los que necesitemos1
. Los parámetros que poseen valores por defecto deben ir al final de la lista de parámetros.
Veamos un ejemplo donde invocamos a una misma función de distintas formas. Presten especial atención a
las tres últimas, ya que son incorrectas. ¿Pueden explicar la causa del error?
MÓDULO PROFESIONAL N° 01
PROGRAMA DE ESTUDIOS: ELECTRÓNICA INDUSTRIAL
“Educación Para El
UNIDAD DIDACTICA: INSTALACIONES ELECTRICAS Mejoramiento Tecnológico”
Veamos otro ejemplo donde definimos una función con varios argumentos:
def imprimir_datos_vehiculo(patente, marca, color, tipo_motor, ruedas):
print("Patente: " + patente) print("Marca: " + marca)
print("Color: " + color) print("Tipo de motor: " + tipo_motor)
print("Cantidad de ruedas: " + str(ruedas)) print("-" * 80) #
Separador
Podemos invocar a esta función enviando los parámetros por posición, es decir, el primer parámetro se
corresponde con patente, el segundo parámetro se corresponde con marca, etc...
imprimir_datos_vehiculo("xcz 001", "Chevrord", "rojo", "naftero", 4) imprimir_datos_vehiculo("bsc 120",
"Fioen", "blanco", "naftero", 4) imprimir_datos_vehiculo("xzc 100", "Forvrolet", "azul", "gasolero", 4)
imprimir_datos_vehiculo("czx 010", "ScanBenz", "blanco", "gasolero", 6) imprimir_datos_vehiculo("aaa 023",
"Mercenia", "negro", "gasolero", 10)
En este caso, hay que recordar el orden de los 5 argumentos al invocar a la función. De no hacerlo, se
asociarán en forma incorrecta. Si conocemos el nombre de los parámetros, entonces podría utilizar sus
nombres y esto me permitiría ponerlos en cualquier orden:
imprimir_datos_vehiculo("xcz 001", tipo_motor = "naftero", marca = "Chevrord", ruedas = 4, color =
"rojo")
. Como se mencionó anteriormente cuando mezclamos parámetros con nombre y sin nombre en la
invocación de una función, los que no tienen nombre tienen que estar en orden y deben situarse al principio
de la lista de argumentos
Retornando valores
En muchos casos, definimos funciones que nos deben retornar valores. En este caso, utilizaremos la
sentencia return, que nos permite especificar qué valor retornará la ejecución de la función. Si bien no es
obligatorio usar return (sino, piensen en todos los ejemplos que les presentamos hasta el momento), es muy
útil en muchos casos.
Veamos el siguiente ejemplo:
La función que definimos, además de permitirle al usuario que elija la dirección en la que queremos mover al
robot, nos retorna qué movimiento fue el que más elegimos. ¿Cómo deberíamos invocar y usar este valor
retornado?
La sentencia return corta la ejecución de la función que la contiene. Esto significa que si detrás de esta
sentencia escribimos otras, las mismas no se ejecutarán. En el siguiente ejemplo lo único que hace
funcion_poco_util() es retornar el valor True, nunca realiza ninguna cuenta ni imprime nada en pantalla:
MÓDULO PROFESIONAL N° 01
PROGRAMA DE ESTUDIOS: ELECTRÓNICA INDUSTRIAL
“Educación Para El
UNIDAD DIDACTICA: INSTALACIONES ELECTRICAS Mejoramiento Tecnológico”
Si bien con ambas sentencias logramos incorporar las funcionalidades necesarias para manejar el robot en
nuestros programas, las diferencias están en cómo voy a utilizar esas funciones.
Antes de seguir, veamos un concepto importante que debemos tener claro: los espacios de nombres.
Un espacio de nombres es una tabla que indica a qué objetos hace referencia cada nombre.
En el caso de la función del ejemplo último, funcion_poco_util(), el espacio de nombres asociado a la función
tendrá una entrada para cada variable y parámetro que define, indicando que el nombre a, representa a tal
o cual elemento (según sea el parámetro con el que invoque a la función).
Supongamos que definimos el siguiente módulo:
#Archivo: bailes.py
def baile_lento():
# Implementación de la función...
.....
def baile_rock():
# Implementación de la función...
..... def
baile_samba():
# Implementación de la función...
.....
Si desde mi programa quiero utilizar estas funciones, puedo importar todas o sólo la que quiero utilizar. Si
quiero importar todas, puedo hacerlo de dos formas:
import bailes
O bien:
La diferencia entre ambas tiene que ver en cómo se altera el espacio de nombres de mi programa, es decir,
qué nombres se agregan y a qué harán referencia. En el primer caso, si bien se agregan todas las funciones
que representan a los distintos bailes, sólo se incorpora a mi espacio de nombres el nombre del módulo (bailes)
por lo cual para utilizar alguna de las funciones debo antes anteponer el nombre del módulo.
import bailes ....
bailes.baile_rock()
En cambio, si las importamos de la segunda manera los nombres de las funciones son las que se incorporan a
nuestro espacio de nombres directamente.
.. baile_rock()
¿Cuál es la mejor forma? En realidad utilizar la segunda opción puede ser un riesgo ya que si en mi programa
ya tengo una función o una variable que se llama baile_rock() la misma será reemplazada en nuestro espacio
de nombres por la referencia a la función del módulo bailes.
También podemos importar sólo algunas funciones o variables de un módulo. Esto lo podemos hacer de la
siguiente forma:
from bailes import baile_rock, baile_lento
.. baile_rock()
De esta manera, sólo agrego al espacio de nombres de mi programa los nombres de las funciones importadas
y puedo invocarlas sin anteponer el nombre del módulo.