Salta al contenido principal

Funciones en Python (2024)

Sitio: Facultad de Ingeniería U.Na.M.
Curso: Informática ET241/EM241/IC241/IN241/IM204
Libro: Funciones en Python (2024)
Imprimido por: Invitado
Día: miércoles, 18 de diciembre de 2024, 05:16

1. Introducción

¿Qué es una función?

Una función en Python (y en cualquier otro lenguaje de programación) es un bloque de líneas de código o un conjunto de instrucciones cuya finalidad es realizar una tarea específica. Puede reutilizarse a voluntad para repetir dicha tarea.

Las funciones nos ayudan a que el código sea más fácil de leer y entender, porque evitan tener que repetir códigos dentro de un programa.

Anteriormente, usamos algunas funciones como, por ejemplo, max() para obtener el valor máximo de una lista. Si quisiéramos, en lugar de utilizar esta función, escribir todo el código para hallar el valor máximo, tendríamos que escribir todo lo siguiente: 


En lugar de tener que escribir todas estas líneas, simplemente llamamos a la función max() cada vez que sea necesario. Es por eso que una de las grandes ventajas de usar funciones es que reduce el número total de líneas de código.

Una función tiene tres componentes importantes:

  1.     los parámetros o argumentos que recibe , que son los valores que recibe la función como entrada y los utiliza.
  2.     el código de la función, que son las operaciones o procesos que hace la función.
  3.     el resultado (o valor de retorno), que es el valor final o salida  que entrega o regresa la función.


Recordemos el modelo computacional visto al inicio:



Observación: Hay un Estándar que establece las notaciones de las funciones:

https://docs.python.org/3/glossary.html#term-annotation

Vamos a resumirlas:

1) Una función puede recibir cero o mas argumentos

2) Una función puede no retornar nada o retornar varios argumentos

3) Los nombres de las funciones se escriben en minúsculas y no llevan espacios.

4) Los Argumentos pasados (al llamar)  son reemplazado respectivamente por los parámetros (lo que reciben) de la función ( el mismo orden).

Aquí se pueden ver mas dealltes sobres las funciones : https://entrenamiento-python-basico.readthedocs.io/es/latest/leccion5/funciones.html


2. Funciones Predefinidas

Hay varias funciones que ya venimos utilizando desde el comienzo de la asignatura, como por ejemplo print()input(), int(), float()max(), min(), len(), etc. Todas estas son funciones que ya están incluidas en Python. Se suelen denominar Built-in Functions. (Ver documentación ACÁ)

No es necesario escribir el código, sino que solamente hay que llamarlas para poder utilizarlas.

Acá hay una lista en orden alfabético de estas funciones.

Built-in Functions


Ahora, vamos a ver cómo podemos crear nuestras propias funciones.

3. Creación de funciones

Antes de crear una función tenemos que hacernos las siguientes preguntas:

1) ¿Es necesario crear una función?
Crear una función es la mejor solución si:
  • Tenemos un fragmento de código que se usa en muchos sitios. En este caso, utilizar una función nos evitaría tener código repetido, y haría que modificarlo fuera más fácil, ya que bastaría con cambiar la función una vez.
  • Tenemos que escribir un código muy largo. Es mejor crear funciones que agrupen ciertos fragmentos de código en funcionalidades específicas, haciendo que el código resultante sea más fácil de leer.
  • No existe una función built-in que realice lo que necesitamos.
2) ¿Qué queremos que haga la función? ¿Cuál es el proceso?
Tenemos que definir claramente qué parte del problema o consigna tiene que ser resuelto por una función. 

3) ¿Qué valores (entradas) debe recibir la función para que realice lo que queremos?

4) ¿Qué tipo de resultados (salidas) ofrece la función? 
Tenemos que definir si la función solamente debe hacer alguna operación y mostrar el resultado, o si debe retornar algún valor para que sea utilizado en el resto del código.

¿Cómo crear una función en Python?

Cualquier función debe tener:

  • Un nombre que represente qué hace esa función.
  • Los argumentos de entrada: Los valores que la función debe recibir para poder operar correctamente.
  • El código a ejecutar (Proceso): Las operaciones o instrucciones que debe hacer.
  • Los parámetros de salida o valor de retorno: los resultados que la función debe mostrar o regresar.

Sintaxis

  • Para definir una función nueva en Python se utiliza la palabra reservada def seguida de un nombre y los argumentos de entrada entre paréntesis, y luego los dos puntos (:)
  • En la siguientes líneas (con la identación correspondiente), se escribe el conjunto de sentencias que debe realizar la función.
  • Finalmente, se utiliza la palabra clave return para devolver un valor si es necesario.


NOTA: LAS DECLARACIONES DE LAS FUNCIONES DEBEN ESTAR ANTES DEL CÓDIGO PRINCIPAL O MAIN SCRIPT!!!


4. Argumentos de entrada

Hay diferentes formas de pasarle argumentos a una función:

  • Teniendo funciones sin argumentos de entrada.
  • Pasando los argumentos por posición.
  • Pasando los argumentos por nombre.
  • Teniendo argumentos por defecto.




4.1. Sin argumentos

Funciones sin argumentos de entrada

Empecemos con un ejemplo de la función más sencilla de todas. Una función sin parámetros de entrada ni parámetros de salida.

Primeramente, declaramos o definimos la función:


Después tenemos que llamar a la función por su nombre.


Si ejecutamos, en el terminal se debería ver: Hola!



4.2. Un solo argumento

Funciones con un solo argumento de entrada

Vamos a complicar un poco las cosas pasando un argumento de entrada

En la declaración de la función, tenemos que indicar entre paréntesis que espera recibir un argumento. El nombre que pongamos entre los paréntesis será el nombre de la variable que le damos al argumento y con el que operaremos dentro de la función.

Por ejemplo, definimos la misma función anterior pero con un argumento de entrada.


Ahora cuando llamemos a la función, sí o sí debemos pasarle un argumento. Por ejemplo:


Entonces, al ejecutar, veremos en el terminal: Hola Anastasia

Python permite pasar argumentos también de otras formas. A continuación las explicamos.


4.3. Por posición

Argumentos por posición

Los argumentos por posición o posicionales son la forma más básica e intuitiva de pasar parámetros. Si tenemos una función suma() que acepta dos parámetros, se puede llamar como se muestra a continuación:


Al tratarse de parámetros posicionales, se interpreta que el primer número es y el segundo b

El número de parámetros es fijo, por lo que si intentamos llamar a la función con solo uno, dará error. Por ejemplo:


Tampoco es posible usar más argumentos de los tiene la función definidos, ya que no sabría que hacer con ellos. 


4.4. Por nombre

Argumentos por nombre

Otra forma de llamar a una función, es usando el nombre del argumento con = y su valor. El siguiente código hace lo mismo que el código anterior, con la diferencia de que los argumentos no son posicionales.


Al indicar en la llamada a la función el nombre de la variable y el valor, el orden ya no importa.

Como es de esperar, si indicamos un argumento que no ha sido definido como parámetro de entrada, tendremos un error.


4.5. Por defecto

Argumentos por defecto

Tal vez queramos tener una función con algún parámetro opcional, que pueda ser usado o no dependiendo de diferentes circunstancias. Para ello, lo que podemos hacer es asignar un valor por defecto a la función. En el siguiente caso c valdría cero salvo que se indique lo contrario.


Dado que el parámetro c tiene un valor por defecto, la función puede ser llamada sin ese valor.

5. Variables Globales y Locales

Variables Globales en Python

En Python las variables declaradas fuera de una función se conocen como variables globales. Se puede acceder a estas variables tanto dentro como fuera de una función, ya que tienen un alcance global.

Por ejemplo:


La variable a en el código se declara fuera de la función. Sin embargo al llamar a la función mostrar(), se pudo acceder a a porque se declaró con un alcance global.

Otro ejemplo:



Variables Locales en Python

Veamos qué pasa si hacemos lo contrario, si declaramos una variable dentro de una función y queremos acceder a ella fuera de la función.


En este caso, tenemos un NameError porque la variable a no está definida globalmente.

Las variables definidas dentro de las funciones se llaman variables locales. Su valor sólo se puede utilizar dentro de la función en la que se declaran.



 Tener en cuenta que no es buena idea llamar con el mismo nombre a variables locales y globales ya que se presta a confusión.

6. Pasaje por Valor

Pasaje de variables a funciones por valor

Veamos el siguiente ejemplo:


Al "pasarle la variable x" como argumento, en realidad le estoy pasando una copia del valor que contiene esta variable. Por lo tanto, dentro de la función se comporta como una variable local y cualquier modificación que se le haga no tiene efecto sobre la variable x.

7. Pasaje por Referencia

Pasaje de Variables a funciones por Referencia

Veamos el siguiente ejemplo:


En el caso de las listas y diccionarios, al pasarlos como argumentos a las funciones, no se crea una copia de los mismos sino que se trabajan como variables globales y cualquier modificación que se les haga dentro de la función, afecta al contenido de la variable. 

Es decir que no se le está pasando los valores a la función, sino una referencia de su dirección en memoria, es por ello que se denomina pasaje por referencia.

Ejemplo con diccionario:



7.1. Más información

Repasemos unos conceptos.

En Python todo es un objeto.


Cada Objeto se almacena en una Dirección que es única para ese objeto ( cada objeto tiene su "casa")

Para facilitar y no tener que recordar una dirección se usa un nombre ( ej: "La_Facultad" ) que para nosotros sería el nombre de la variable, pero en realidad es una referencia a un objeto ( 'Juan Manuel de Rosas 325")

Una declaración típica:

< identifier > = < expression>

Ver que hay un igual este igual NO es simplemente una asignación, implica la creación referencia a un Objeto.

x = 1 # declaro el objeto 1, y la referencia x, señala a objeto 1.

# una o varias sentencias.

x = x + 2 # no es un suma algebraica solamente aunque parece, es una sentencia de asignación => crea una referencia a un nuevo objeto

Esta asignación se lee de derecha a izquiera de la siguiente manera:

La referencia a x nueva, se actualiza para apuntar a una nuevo valor que resulta del valor apuntado anteriormente mas dos.
La dirección nueva de x y la anterior NO son la misma.

El espacio de la x anterior es reclamado por un "Recolector de Basura" que recupera las direcciones sin uso para usar mas tarde.

Veamos como sería de manera Gráfica:

 Figura 1

Es importante entender  que el igual, no es una simple asignación, si no la creación de un Nuevo objeto. 

Si hay un igual => es un nuevo objeto!!

Veamos otro ejemplo:

 Figura 2

La salida de esto sería:

  Figura 3

Con esto en mente es mas fácil entender los que sigue.

Pasaje por valor

Si usamos un parámetro pasado por valor, se creará una copia local de la variable, lo que implica que cualquier modificación sobre la misma no tendrá efecto sobre la original.
Veamos este caso:

Aquí se prestaría a confusión, ya que la x definida en la función deja de existir en la línea 2, por que hay un igual.
Es decir se crea un objeto NUEVO, solo que se toma el valor de x y se crea un objeto nuevo con un valor duplicado.
ese valor duplicado se muestra en main en línea 6 que es lo que retorna la función duplicar.
En la línea 7 se muestra el valor ingresado.. se puede ver que no cambió.


Se podría dar otro nombre a la variable x dentro de la función y NO CAMBIARÍA NADA.
Esto se conoce como pasaje por valor.
Se deja al alumno en análisis del siguiente código:

¿Que saldría tendría y por que?

Pasaje por referencia

En Python al pasar una variable como argumento de una función estas se pasan por referencia o por valor.

Con una variable pasada como referencia, se actuará directamente sobre la variable pasada, por lo que las modificaciones afectarán a la variable original.

Vimos en la sección anterior el pasaje por Valor.

  Figura 4

En este scritp el valor de z no se duplica, por mas que se lo duplica en la función, esto no se refleja entre las líneas 11 a 13.

Por otro lado se aconseja NO  declarar las Variables como Globales, recordemos que así si se podían cambiar los valores.

Pero va a ser necesario que la función pueda realizar cambios.

 Así que ¿cual es la solución para que una función pueda alterar un valor y que el mismo sea permanente sin que la variable sea Global?

Respuesta : Pasaje por Referencia!!

En el paso por valor, que vimos en la sección anterior , lo que se pasa como argumento es el valor que contenía la variable, una copia no el valor original (parámetro), por eso las modificaciones hechas en las NO se reflejan fuera de la función, por que es una COPIA.

Si se relaciona con el concepto de Objetos vemos que al poner el = dentro de la función creo OTRO OBJETO. En la figura 4, dentro de la función en la línea 9 hay un igual..

esto hace que se cree un NUEVO OBJETO, pero se referencia a el valor z por 2.. y esta z dentro de la función no es lo mismo que la z fuera de la función, son objetos distintos que tienen igual nombre.. podríamos pensar que son dos alumnos que se llaman Juan y está en distintas aulas .. pero no son la misma persona.

En el paso por  referencia lo que se pasa como argumento es la referencia al objeto o nombre del objeto PERO NO SE PUEDE USAR EL = , POR QUE SE CREA OTRO OBJETO. 

Por eso debo pasar datos que pueda modificar sin usar el =.

Veamos con un ejemplo:

 Figura 5

  • Vemos que el valor de x0 NO se altera, dentro de la función vale 4 y fuera de la función SIEMPRE vale 1. Dentro de la función línea 23 hay un igual => Creo un nuevo objeto!
  • Vemos que el valor de y0, que se llama dentro de la función y1, SI CAMBIA, de hecho se agrega un valor 23 y se mantiene al finalizar la función. Dentro de la función línea 24 NO hay un igual => NO creo otro objeto, es el MISMO.
  • y0 es una LISTA,  x0 es un entero
  • x0 no se puede cambiar, para cambiar uso el = y esto crea otro objeto
  • y0 SI se puede cambiar, no uso el = , si uso un método append.

¿Por que uno  si y0  y otro no?

La respuesta es que las variables de tipo números enteros ( nombre de referencia de los objetos) son inmutables, no ha manera de hacer nada con ellos sin usar el =.

Es decir, una vez creados, su valor no puede ser modificado y si quiero modificar tengo que usar el =

¿Pero cuando hago a = 1 y luego a = 2, si se puede cambiar?

Respuesta:  Claro, pero desde la perspectiva del lenguaje, no estás cambiando el valor de a de 1 a 2 sino quitando la referencia a 1 y poniéndosela a 2. El igual hace eso.

En términos más simples, no «cambias» el valor de un objeto sino que le asignas una nueva referencia.

Objetos Python según su mutabilidad:

MutablesInmutables
dict
list
 bool
 bytes
 complex
 decimal
 int
 float
 str/unicode
 tuple
 range

Podemos ver aquí como Listas y Diccionarios se vuelven mas importantes.

Tradicionalmente:

    Los tipos simples se pasan por valor: Enteros, flotantes, cadenas, lógicos, etc.
    Los tipos compuestos se pasan por referencia: Listas, diccionarios.

En este punto parecería que solo pasando Objetos Mutables ( ej. Lista como y0 )  podemos cambiar un valor.

Bueno no es necesariamente hay una alternativa, se puede devolverlos modificados y reasignarlos, veamos las dos alternativas de modificar valores.

1) Pasando un objeto alterable ( Lista, Diccionario)

2) Pasando un objeto in-alterable pero usando en return para regresar una copia del nuevo objeto

3) Usando una variable Global ( NO USAR ESTE!!)

 Figura 2.

Pasar los argumentos por referencia es pasar tipos de dato mutables y cambiarlos sin usar el igual., y los inmutables por valor.

Vemos un caso en el que uso una lista, pero dentro de la función uso un =, por lo tanto se crea Otro objeto veamos un ejemplo:

 Figura 3

Cuando se pasan por Referencia SI se pueden cambiar si no uso el  , cuando se pasan por valor NO se pueden cambiar!


8. Valores de Retorno

Sentencia return

El uso de la sentencia return permite realizar dos cosas:

  • Salir de la función y transferir la ejecución de vuelta a donde se realizó la llamada.
  • Devolver uno o varios parámetros, resultado de la ejecución de la función.

Siempre se debe colocar al final de la declaración de la función.

Ejemplos:





8.1. Muestra del valor de retorno

Muestra del valor de retorno

Por lo general, siempre que se utiliza la sentencia return es porque queremos utilizar de alguna forma el valor de retorno. Una de las formas de utilizarlo es mostrarlo mediante print().

Veamos el siguiente ejemplo:


En este caso, en la línea 7, primeramente se llama a la función suma() pasándole los valores de x e y como argumentos. La función hace sus operaciones y retorna un valor. El valor que la función retorna se muestra con print.

En el siguiente enlace se puede ver cómo se comportan las variables locales y globales, y el valor de retorno en cada línea de ejecución: ENLACE A PYTHON TUTOR


8.2. Asignación del valor de retorno

Asignación del valor de retorno a una variable

También podemos asignar ese valor de retorno a una variable:


En este caso, en la línea 7 primeramente se llama a la función suma() pasándole los valores de x e y como argumentos. La función ejecuta sus operaciones y retorna un valor. El valor que se retorna se asigna a la variable resultado. Luego en la línea 8 lo mostramos con un print.

En el siguiente enlace se puede ver cómo se comportan las variables locales y globales, y el valor de retorno en cada línea de ejecución: ENLACE A PYTHON TUTOR


8.3. Utilizar el valor de retorno

Utilizar el valor de retorno 

También se puede utilizar el valor de retorno dentro de condiciones de estructuras if o while

Por ejemplo:


Solamente se debe tener en cuenta que cada vez que analice la condición se llamará a la función nuevamente.

Como ejemplo de esto, prueben el siguiente código:


8.4. Múltiples Valores de Retorno


Una función puede retornar más de un valor. Una de las formas es hacerlo mediante una lista, como se muestra en el siguiente ejemplo:



En este caso en la línea 11, asignamos el valor de retorno a la variable valores
En la línea 12, mostramos el tipo de dato que se asignó a la variable y vemos que es de tipo "list".

Otra forma de retornar múltiples valores es con la sentencia return y los valores separados por coma pero encerrados entre [] (corchetes) , tal como se muestra a continuación:



En este caso, vemos que el tipo de dato que retornó la función es una lista.


El siguiente ejemplo es a modo INFORMATIVO, ya que el tipo de datos retornado NO SE VE en esta materia.

Si solo utilizamos la sentencia return y los valores separados por coma, tal como se muestra a continuación: 



En este caso, vemos que el tipo de dato que retornó la función es "tuple". 

Las tuplas son una estructura de datos muy similares a las listas, con la diferencia que son inmutables. Es decir, sus valores no pueden ser modificados.




9. Funciones que llaman a funciones

Una función puede llamar a otras funciones. Por ejemplo:

En este caso, la función promedio() llama a la función suma() para poder realizar el cálculo del promedio.

En el siguiente enlace puede ver la ejecución línea a línea del código y también visualizar qué valores van tomando las variables: ENLACE A PYTHON TUTOR




10. Funciones que se llaman a sí mismas

De la misma forma que una función puede llamar a otra, una función también se puede llamar a sí misma. Esto se conoce como recursividad.

Por ejemplo:



En el siguiente enlace se puede ver cómo se ejecuta el código línea por línea y los valores que van tomando las variables: ENLACE A PYTHON TUTOR


11. Preguntas

Tenemos el siguiente código:

def suma3y3(): 
     print(f'el resultado es {3+3}') 


¿Qué obtenemos en pantalla cuando lo ejecutamos?

  1. Obtenemos 6 en la pantalla.
  2. No aparece nada en la pantalla.
  3. Aparece "el resultado es 6" en la pantalla.
  4. Obtenemos un error.

_____________________________________________________________________________________________________

¿Qué son las variables locales?

  1. Aquellas que están dentro del contexto de la función y podemos acceder a ellas desde cualquier bloque.
  2. Aquellas que están definidas fuera del contexto de las funciones y podemos acceder a ellas desde cualquier bloque.
  3. Aquellas que están dentro del contexto de la función y solo podemos acceder a ellas desde dentro de la función.
  4. Aquellas que están definidas fuera del contexto de las funciones y no podemos acceder a ellas desde cualquier bloque.

_______________________________________________________________________________________________________

¿Cuántos errores hay en el siguiente código?

variable1=10
def mifuncion(parametro) 
    variable2=20 
    print(f"La variable1 tiene valor {variable1}') 
     print(f'La variable2 tiene valor {variable2}') 
    print(f'El parámetro tiene valor {parametro}') 

mifuncion("entrada")
  1. uno
  2. dos
  3. tres
  4. 4 o mas
_________________________________________________________________________________________________________

En la definición de una función, los parámetros a pasarle se separan con:
  1. .
  2. ,
  3. ;
  4. -





12. Ejercicios Resueltos

En muchos de los ejercicios resueltos, se muestra el código sin Funciones, la idea es que el alumno interprete y luego pueda plantear una solución CON funciones.

13. Ejercicio tipo final



13.1. Ordenar una lista. Método Burbuja

Cargar por teclado una lista de números reales, luego ordenar  de menor a a mayor comparando UNO contra TODOS utilizando una función (esto se conoce como método de la burbuja).

Googlear en internet buscar información sobre el método.

Una propuesta de solución sería.



13.2. Ordenar Listas. Varios Métodos

Este método ordena la lista en su lugar, utilizando solo "comparando entre elementos".

No se suprimen las excepciones: si falla alguna operación de comparación, fallará toda la operación de clasificación (y la lista probablemente quedará en un estado parcialmente modificado).

sort () acepta dos argumentos: key y reverse.

El valor posible para reverse es True.

Para key hay varias alternativas, veremos algunas mas adelante.

Veremos como usar métodos para ordenar listas. El método sort está documentado en:

https://docs.python.org/3.7/library/stdtypes.html?highlight=sort#list.sort

En la documentación sobre el uso para ordenar está en : https://docs.python.org/3/howto/sorting.html , podemos ver que existen dos métodos que permiten ordenar listas. Ellos son.

  1. sort ( cambia el orden de la lista  original)
  2. sorted (regresa otra lista, sin modificar la original)

Consigna:

Cargar por teclado una lista de números reales, luego ordenar  de  mayor a menor utilizando el método sort.

Una propuesta de solución sería.



13.3. Carga de Matrices

Cargar una una matriz con números reales definiendo las dimensiones.

Luego de cargada la matriz, mostrar los valores de la misma de manera estética ( una fila por línea).

Este ejercicio demuestra que la forma de visualizar una matriz no es lo mismo que una lista, es por eso que requiere de crear una lista para cada fila.

Recordemos que el método append, inserta un elemento al final de una lista. Una propuesta de solución sería.

13.4. Diccionario de Pacientes

"""
ESCRIBIR UN CODIGO QUE PERMITA:

MOSTRAR UN MENU CON LAS SIGUIENTES OPCIONES:
    1-CARGA DE DATOS DE PACIENTES
    2-MOSTRAR DATOS DE PACIENTE
    F-FINALIZAR EL PROGRAMA
    
PARA MOSTRAR EL MENU SE UTILIZARA UNA FUNCION LLAMADA mostrar_menu.

SI SE INGRESA 1 SE DEBERA LLAMAR A LA FUNCION carga, QUE CARGARA
UN DICCIONARIO QUE TENGA COMO CLAVES NUMEROS DE DNI, Y COMO VALORES
LISTAS QUE A SU VEZ CONTENGAN LA EDAD DEL PACIENTE Y SU ALTURA.

SI SE INGRESA 2 SE DEBERA INGRESAR POR TECLADO EL DNI DE UN
PACIENTE Y PASARSELO COMO ARGUMENTO A LA FUNCION
mostrar_paciente, BUSCARA EL DNI DENTRO DEL DICCIONARIO Y SI
HAY COINCIDENCIA RETORNARA LOS DATOS DEL PACIENTE PARA QUE
SEAN MOSTRADOS POR PANTALLA. SI NO HAY COINCIDENCIA SE DEBERA
MOSTRAR EL MENSAJE "PACIENTE INEXISTENTE".

SI SE INGRESA F O f SE DEBERA FINALIZAR EL PROGRAMA.

Una propuesta de solución sería.


13.5. Lista de Pares e Impares

CONSIGNA

Realizar un programa que permita:

a) Llamar a una función que muestre un menú como el siguiente y retorne solo opciones 1, 2, 3 o F

1.- Cargar listas

2.- Buscar valor en la lista

F.- Finalizar

c) Si elige 1.  debe llamar a una función que debe ir ingresando valores hasta que ingrese el cero. Por cada valor que ingresa lo debe cargar a la lista pares o impares según corresponda.  Al final mostrar ambas listas.

d) Si elige 2. llamar a una función que pida que ingrese un número y la función lo busque en la lista que corresponda.  Si es par debe buscarlo en la lista pares o si es impar buscarlo en la lista impares.  Mostrar si se encuentra o no y si estuviera, en qué posición de la lista.

f) El programa solo termina con F para finalizar.

Una propuesta de solución sería.


13.6. Manejo de Matrices

A continuación se presenta la consigna y la solución desarrollada por los alumnos en clase. Para cada función se presentaron códigos de lo más variado. No existió un criterio para definir el código de quién se subía al aula. En parte, sirve para ver la variedad de formas de pensar que existen.

"""
CONSIGNA:
Dada una matriz cuadrada, se requieren determinadas funciones para conformar un
programa más complejo.
Las funciones requeridas son las siguientes:
    
    media: Recibe como argumento la matriz bajo análisis. Devuelve el promedio
    de todos los valores de la matriz.
    
    buscaPositivo: Recibe como argumento la matriz bajo análisis. Si existe un
    número positivo devuelve True, caso contrario, False. Además, admite el 
    parámetro reverse=True, con el cual, realiza lo propio pero con valores
    negativos.
    
    buscaMayor: Recibe como argumento la matriz bajo análisis. Devuelve el
    mayor número de la matriz. Además, admite el parámetro reverse=True,
    con el cual, realiza lo propio pero con el menor valor.
    
    mayoresQue: Recibe como argumento la matriz bajo análisis y un valor.  
    Devuelve la cantidad de elementos que son mayores que el valor recibido
    como parámetro. Además, admite el parámetro reverse=True, con el cual, 
    realiza lo propio pero con los elementos menores al valor recibido.
    
    --DESAFIO--
    moda: Recibe como argumento la matriz bajo análisis. Retorna el valor que
    más se repite. Si hay más de un valor con la misma cantidad de
    repeticiones, se retorna cualquiera de ellos.
    
El programa presentará un informe, a raíz de analizar una matriz dada, con cada 
una de las opciones ofrecidas por las funciones. Ej:
    - La media de los valores de la Matriz es: ...
    - Existen ... valores Mayores que la media
    - Existen ... valores Menores que la media
    - La Matriz tiene valores Positivos
    - La Matriz No tiene valores Negativos
    - El Mayor valor encontrado es: ...
    - El Menor valor encontrado es: ...

Una propuesta de solución sería.

13.7. Diccionarios de Facturas

Crear un diccionario que permita almacenar N facturas. La es clave el numero de factura y el valor el importe de la misma.

El número de factura debe estar entre 1 y 100000 y no se puede repetir.  La carga finaliza cuando el usuario contesta que no desea cargar mas datos.

Luego, realizar las funciones necesarias para:

1) Mostrar todo el diccionario

2) Imprimir solo los facturas con importe superior a 1000

3) consultar la factura ingresando el nro de factura

Una solución propuesta sería:


13.8. Valor dentro de un intervalo

Se desea saber si un número se encuentra dentro de un segmento, fuera del segmento por encima o debajo.

Crear una función que regresa True o False. Recibe como argumento 3 números Reales: min,max,x.

y verifica si min<=x<=max, en ese caso regresa True. Caso contrario False.

Observación: Ver que sucede si no se puede garantizar que min<=max?  . Plantee el mismo ejercicio pero asumiendo que se pueden ingresar máximo y mínimo en distinto orden. El Programa deberá detectar el mayor y menor de manera de lograr el intervalo (mínino, máximo)

Una propuesta de solución sería:



13.9. Diccionario Banderas de Países

Banderas de países

Realizar un programa con menú para cargar banderas de países con bandas tricolores.

El país sería la clave y los colores van en una lista. Cada opción llama a una función:
    Menú:
    A- cargar una bandera de país
    B- buscar por país
    C- buscar por color
    S- salir

* Cuando el usuario ingresa una opción del menú incorrecta, mostrar un mensaje
 * El programa finaliza cuando presiona la "S", considerar también las minúsculas

* A la carga, se le pasa como parámetro el nombre del pais y retorna True cuando finaliza la carga.

* Considerar antes de cargar un pais si éste ya no fue cargado, en ese caso emitir un mensaje
y permitir el reingreso de otro nombre de pais.
* Permitir la carga de más de un pais, preguntando luego de la carga del primero si quiere ingresar otro, si presiona el usuario "S" permitirá ingresar un segundo, en caso que presione cualquier otra tecla, volverá al menú principal.

 * Permitir al usuario ingresar el color que busca, si está que muestre el país, pero si no está retorne False y emita un mensaje en el programa principal.

Si el usuario elige la opcion A debe llamar a la funcion carga con argumento el nombre del pais, retorna un booleano.

Si el usuario elige la opción B debe llamar a la función buscapais que recibe como argumento el país a buscar y en la función muestra si encontró el nombre del país y los colores. Retorna un booleano que se evalúa en el programa principal por el False indicando que no se encontró el país.

Si el usuario elige la opción C debe llamar a la función buscacolor recibe como argumento el color a buscar. En la función, si encuentra, indica qué país tiene ese color caso contrario, emite un mensaje de "no encontrado". No retorna nada. 

Controlar que para realizar la opcion B o C antes debe haber cargado por lo menos un país.

Una propuesta de solución sería.

# DEFINICIÓN DE LAS FUNCIONES       
def carga(clave):
    lista=[]
    for i in range(3): #bucle para cargar los tres colores
        color=input("ingrese color: ")
        lista.append(color)        
        bande[clave]=lista
    print (bande)
    return True
def buscapais(p): # el parámetro es el nombre del pais   
    if p in bande:
        print("Está el pais", p, "sus colores son :", bande[p])
        return True        
    else:
        return False
        
def buscacolor(c):
    encuentra=False  # variable para saber si encuentra el color
    for k in bande:
        for l in range(len(bande)):
            if bande[k][l]==c:
                print("tiene el color ", c, " la bandera de ", k)
                encuentra= True   # cambia de valor cuando encuentra el color         
       
    if not(encuentra): # si terminaron los bucles y no cambió el valor 
        print("ninguna bandera cargada tiene el color ", c)  
        
# PROGRAMA PRINCIPAL    
bande={}  # defino un diccionario vacío en el programa principal
cargado=False #variable para saber si se cargó un país, se ocupará en B y C
opc="X"
while opc != "S" and opc != "s":
    print ("Menú")
    print ("A- cargar una bandera ")    # carga(p) retorna True
    print ("B- buscar por país ")       # buscapais(p) retorna True o False si encuentra el pais
    print ("C- buscar por color ")      # buscacolor(c) retorna True o False si encuentra el color
    print ("S- salir ")
    opc=input("elija una opción del menú:")
    if opc =="S" or opc=="s":
        print("Salió del programa")
        break
    elif opc =="A" or opc=="a":
        repe="S"
        while repe =="S":
            pais=input("ingrese el pais: ")
            cargado=carga(pais)
            repe=input("Presione S si desea cargar otro país o N si no:")
    elif opc =="B" or opc=="b":
        if cargado ==False: 
            print ("No puede buscar un pais porque no se cargó ninguno, elija la opción A")
        else:
            pais=input("ingrese el pais a buscar: ")
            if not(buscapais(pais)):
                print("no se encuentra el pais ", pais)
    elif opc =="C" or opc=="c":
        if cargado==False:
            print ("No puede buscar un color porque no se cargó banderas, elija la opción A")
        else:
            color=input("ingrese el color a buscar: ")
            buscacolor(color)
    else:
        print("Opción incorrecta, por favor reintente")


13.10. Ejercicio Funciones Diccionarios con Listas

Consigna 16) de Ejercicios propuestos

Se tiene que almacenar el Stock de repuestos de una empresa, los valores a almacenar serán: nombre del repuesto y valores máximo, mínimo y actual del Stock.

El valor máximo y mínimo son parámetros que permiten determinar cuándo debo comprar ese repuesto (si llegué o estoy por debajo del mínimo) y el máximo para saber que tengo stock suficiente.

Definir un diccionario con 3 nombres de claves, para todas las claves (repuestos) con los valores de cada ítem en cero (máx., min, stock)

Luego llamar a una función que permita realizar una carga inicial.

A continuación se presenta un menú permite:

1) Seleccionar y modificar el stock actual (no puede ser negativo)

2) Dar de baja un ítem

3) Dar de alta un ítem (no puede ser negativos los valores de stock)

4) Mostrar quien tiene stock crítico (por debajo del mínimo)

5) Listar los ítems

S o s) Salir.

Para cada ítem del menú llamar a una función que realice lo solicitado.


RESOLUCION


def cargaini():
    print("\n Cargando el diccionario...\n")
    for i in st:
        l=[]
        
        max1=int(input("Ingrese stock maximo"))
        while max1<0:
            max1=int(input("Error. ReIngrese stock maximo"))
        min1=int(input("ingrese stock minimo"))
        while min1<0:
            min1=int(input("Error. ReIngrese stock minimo"))
        act=int(input("ingrese stock actual"))
        while act<0:
            act=int(input("Error. ReIngrese stock actual"))
        l.append(max1)
        l.append(min1)
        l.append(act)
        st[i]=l

def modificar(clave):
    act=int(input("Ingrese nuevo stock actual"))
    while act<0:
            act=int(input("Error. ReIngrese stock actual"))
    st[clave][2]=act

def baja():
    cl=input("ingrese el item a da de baja :")
    if cl in st:
        st.pop(cl)
        return True
    else:
        return False
    
def alta(clave):
    l=[]
    max1=int(input("Ingrese stock maximo"))
    while max1<0:
            max1=int(input("Error. ReIngrese stock maximo"))
    min1=int(input("ingrese stock minimo"))
    while min1<0:
            min1=int(input("Error. ReIngrese stock minimo"))
    act=int(input("ingrese stock actual"))
    while act<0:
            act=int(input("Error. ReIngrese stock actual"))
    l.append(max1)
    l.append(min1)
    l.append(act)
    st[clave]=l

def control():
    band=False
    for i in st:
        if st[i][2]<st[i][1]:
            print("item con stock insuficiente: ",i)
            band=True
    if not band:
        print("no hubo items a mostrar")

def menu():
   print("\n1. Modificar st actual \n2. Baja \n3. Alta \n4. Control stock actual \n5. Mostrar dicc \ns. Salir \n")
   op=input("ingrese opcion: ")
   while op!='s' and op!='S':
    if op=='1':
        cl=input("ingrese el item a modificar :")
        if cl in st:
            modificar(cl)
        else:
            print("no existe ese item")
    elif op=='2':
            if baja():
                print("elemento borrado con exito")
            else:
                print("No se pudo borrar el item")
    elif op=='3':
        cl=input("ingrese el item a da de alta :")
        if cl in st:
            print("YA existe ese item")
        else:
            alta(cl)
    elif op=='4':
        control()
    elif op=='5':
        print("\nDiccionario cargado: ")
        for i in st:
            print(i, ": ", st[i])
    elif op=='S' or op=='s':
        print("chau")
    else:
        print("error opcion incorrecta!")
    
    print("\n1. Modificar st actual \n2. Baja \n3. Alta \n4. Control stock actual \n5. Mostrar dicc \ns. Salir \n")
    op=input("Ingrese opcion: ")
    
st={'rep1':[0,0,0],'rep2':[0,0,0],'rep3':[0,0,0]}

cargaini()

menu()




13.11. Ejercicio Contraseñas

Consigna

Escribir una función que permita validar/catalogar una frase ingresada como posible contraseña. De acuerdo al análisis, se devolverá el nivel de seguridad correspondiente.
La función recibe como argumento la contraseña y retorna el nivel de seguridad.

Se considerarán las siguientes pautas:

* Longitud menor a 6: No válido como clave. Seguridad 0
* Al menos un carácter en minúscula. Seguridad +1
* Al menos un carácter en mayúscula. Seguridad +1
* Al menos un carácter numérico. Seguridad +1
* Al menos un carácter símbolo. Seguridad +1
* Longitud mayor a 10. Seguridad +1

Mostrar al finalizar, la clave ingresada seguida del nivel de seguridad (Seguridad 5 es el máximo, se cumplen todos los requisitos).

Resolución Propuesta