Cartilla Lenguaje de Programación Python
Cartilla Lenguaje de Programación Python
LENGUAJE DE PROGRAMACIÓN
CARTILLA DE APRENDIZAJE
LENGUAJE DE PROGRAMACIÓN PYTHON
1. INTRODUCCIÓN ........................................................................................................ 5
1.1. ¿Qué es un programa? ........................................................................................ 5
1.2. Diagrama de flujo................................................................................................. 6
2. INSTALACIÓN DEL LENGUAJE Y PASOS PARA CREAR NUESTRO PRIMER
PROGRAMA ...................................................................................................................... 9
3. CODIFICACIÓN DEL DIAGRAMA DE FLUJO EN PYTHON..................................... 14
4. ERORES SINTÁCTICOS Y LÓGICOS ..................................................................... 17
5. ESTRUCTURA DE PROGRAMACIÓN SECUENCIAL.............................................. 19
6. ESTRUCTURAS CONDICIONALES SIMPLES Y COMPUESTAS ............................ 22
6.1. Estructura condicional simple ............................................................................ 22
6.2. Estructura condicional compuesta ..................................................................... 25
Operadores .............................................................................................................. 27
7. ESTRUCTURAS CONDICIONALES ANIDADAS ...................................................... 29
8. CONDICIONES COMPUESTAS CON OPERADORES LÓGICOS ........................... 32
8.1. Operador AND ................................................................................................... 32
8.2. Operador OR ..................................................................................................... 34
9. ESTRUCTURA REPETITIVA WHILE........................................................................ 37
10. ESTRUCTURA REPETITIVA FOR........................................................................ 49
11. DEFINICIÓN DE COMENTARIOS EN EL CÓDIGO FUENTE ............................... 56
12. VARIABLES ENTERAS, FLOTANTES Y CADENAS DE CARACTERES .............. 58
13. PROCESAR CADENAS DE CARACTERES ......................................................... 62
14. ESTRUCTURA DE DATOS TIPO LISTA............................................................... 69
15. LISTAS: CARGA POR TECLADO DE SUS ELEMENTOS .................................... 73
16. LISTAS: MAYOR Y MENOR ELEMENTO ............................................................. 77
17. LISTAS PARALELAS ............................................................................................ 81
18. LISTAS: ORDENAMIENTO DE SUS ELEMENTOS .............................................. 84
19. LISTAS: COMPONENTES DE TIPO LISTA .......................................................... 91
20. LISTAS: COMPONENTES DE TIPO LISTA .......................................................... 94
21. LISTAS: CARGA POR TECLADO DE COMPONENTES DE TIPO LISTA ........... 101
22. LISTAS: ELIMINACIÓN DE ELEMENTOS .......................................................... 113
23. CONCEPTO DE FUNCIONES - PROGRAMACIÓN ESTRUCTURADA .............. 118
24. FUNCIONES: PARÁMETROS ............................................................................ 123
25. FUNCIONES: RETORNO DE DATOS ................................................................ 128
26. FUNCIONES: PARÁMETROS DE TIPO LISTA................................................... 133
27. FUNCIONES: RETORNO DE UNA LISTA .......................................................... 139
28. FUNCIONES: CON PARÁMETROS CON VALOR POR DEFECTO.................... 149
29. FUNCIONES: LLAMADA A LA FUNCIÓN CON ARGUMENTOS NOMBRADOS 152
30. FUNCIONES: CON CANTIDAD VARIABLE DE PARÁMETROS......................... 156
31. ESTRUCTURA DE DATOS TIPO TUPLA ........................................................... 158
32. LISTAS Y TUPLAS ANIDADAS........................................................................... 165
1. INTRODUCCIÓN
Este curso está pensado para ser cursado por una persona que no conoce nada de
programación y se emplea el lenguaje Python como primer lenguaje para acercarse
a la programación de computadoras.
El objetivo fundamental de este tutorial es permitir que el estudiante pueda resolver
problemas de distinta índole (matemáticos, administrativos, juegos, contables etc.)
empleando como herramienta la computadora.
Hay que tener en cuenta que para llegar a ser un programador se debe recorrer un
largo camino donde cada tema es fundamental para conceptos futuros. Es
importante no dejar temas sin entender y relacionar.
La programación a diferencia de otras materias que ha estudiado como podría ser
la historia requiere un estudio metódico y ordenado (en historia se puede estudiar
la edad media sin tener grandes conocimientos de la edad antigua, esto no pasa
con el aprendizaje de la programación)
La programación es una actividad nueva para el estudiante, no hay en los estudios
primarios y secundarios una materia parecida.
Es bueno tenerse paciencia cuando los problemas no se resuelven por completo,
pero es de fundamental importancia dedicar tiempo al análisis individual de los
problemas.
Podemos identificar:
Datos conocidos:
Horas trabajadas en el mes.
Pago por hora.
Proceso:
Cálculo del sueldo multiplicando la cantidad de horas por el pago por hora.
Información resultante:
Sueldo mensual.
Tipos de variable.
Una variable puede almacenar:
Para la descarga del lenguaje Python lo hacemos del sitio: python.org (descargar la
versión más actual 3.8)
Acotaciones
Si el editor que viene por defecto con Python no le convence por ser muy limitado
y aplicado fundamentalmente en el aprendizaje de programación, puede
consultar otros editores disponibles para Python.
Problema
Diagrama de flujo:
lado=int(lado)
Ahora se vuelve a guardar en la variable lado el valor que ingresó el operador pero
en formato entero que posibilita hacer operaciones matemáticas con el mismo.
Un formato simplificado para ingresar un valor entero por teclado y evitarnos escribir
las dos líneas anteriores es:
superficie=lado*lado
Para mostrar un mensaje por pantalla tenemos la función print que le pasamos como
parámetro una cadena de caracteres a mostrar que debe estar entre simple o doble
comillas:
print("La superficie del cuadrado es")
print(superficie)
Algunas consideraciones
Hay más restricciones que iremos aprendiendo a medida que avance el curso.
Existe otro tipo de errores llamados ERRORES LOGICOS. Este tipo de errores en
programas grandes (miles de líneas) son más difíciles de localizar. Por ejemplo un
programa que permite hacer la facturación pero la salida de datos por impresora es
incorrecta.
4.1. Problema
superficie=lado*lado*lado
5.2. Problema:
Realizar la carga del precio de un producto y la cantidad a llevar. Mostrar cuanto se
debe pagar (se ingresa un valor entero en el precio del producto)
Diagrama de flujo:
Tenemos dos entradas: precio y cantidad, una operación para calcular el importe y
una salida.
Programa: ejercicio4.py
1.4. Problema:
Ingresar el sueldo de una persona, si supera los 3000 dolares mostrar un mensaje
en pantalla indicando que debe abonar impuestos.
Diagrama de flujo:
"Esta persona debe abonar impuestos", en caso que la persona cobre 3000 o menos
no aparece nada por pantalla.
Programa: ejercicio9.py
La palabra clave "if" indica que estamos en presencia de una estructura condicional;
seguidamente disponemos la condición y finalizamos la línea con el caracter dos
puntos.
En una estructura condicional compuesta tenemos actividades tanto por la rama del
verdadero como por la rama del falso.
1.6. Problema:
Realizar un programa que solicite ingresar dos números distintos y muestre por
pantalla el mayor de ellos.
Diagrama de flujo:
Se hace la entrada de num1 y num2 por teclado. Para saber cuál variable tiene un
valor mayor preguntamos si el contenido de num1 es mayor (>) que el contenido de
num2, si la respuesta es verdadera vamos por la rama de la derecha e imprimimos
num1, en caso que la condición sea falsa vamos por la rama de la izquierda (Falsa)
e imprimimos num2.
Operadores
• Operadores Relacionales:
• Operadores Matemáticos
Hay que tener en cuenta que al disponer una condición debemos seleccionar que
operador relacional se adapta a la pregunta.
Ejemplos:
Los problemas que se pueden presentar son infinitos y la correcta elección del
operador solo se alcanza con la práctica intensiva en la resolución de problemas.
6.5.3 Se ingresa por teclado un número positivo de uno o dos dígitos (1..99)
mostrar un mensaje indicando si el número tiene uno o dos dígitos.
(Tener en cuenta que condición debe cumplirse para tener dos dígitos
un número entero)
7.1. Problema:
Confeccionar un programa que pida por teclado tres notas de un alumno, calcule el
promedio e imprima alguno de estos mensajes:
• Diagrama de flujo:
En caso que la condición nos dé falso, por la rama del falso aparece otra estructura
condicional, porque todavía debemos averiguar si el promedio del alumno es
superior o igual a cuatro o inferior a cuatro.
• Programa: ejercicio14.py
7.2.2 Se ingresa por teclado un valor entero, mostrar una leyenda que indique
si el número es positivo, negativo o nulo (es decir cero)
Cuando vinculamos dos condiciones con el operador “and”, las dos condiciones
deben ser verdaderas para que el resultado de la condición compuesta de
Verdadero y continúe por la rama del verdadero de la estructura condicional.
8.2. Problema:
Confeccionar un programa que lea por teclado tres números enteros distintos y nos
muestre el mayor.
• Diagrama de flujo:
Este ejercicio se puede resolver sin operadores lógicos pero el utilizarlos nos
permite que sea más simple la solución.
Es decir que se mostrará el contenido de num1 si y sólo si num1 > num2 y num1 >
num3.
• Programa: ejercicio19.py
8.3. Operador OR
8.4. Problema:
Se carga una fecha (día, mes y año) por teclado. Mostrar un mensaje si corresponde
al primer trimestre del año (enero, febrero o marzo) Cargar por teclado el valor
numérico del día, mes y año.
Ejemplo: día: 10 mes: 2 año: 2018
• Diagrama de flujo:
La carga de una fecha se hace por partes, ingresamos las variables dia, mes y año.
Mostramos el mensaje "Corresponde al primer trimestre" en caso que el mes
ingresado por teclado sea igual a 1, 2 ó 3.
8.5.1 Realizar un programa que pida cargar una fecha cualquiera, luego
verificar si dicha fecha corresponde a Navidad.
8.5.2 Se ingresan por teclado tres números, si todos los valores ingresados
son menores a 10, imprimir en pantalla la leyenda "Todos los números
son menores a diez".
8.5.3 Se ingresan por teclado tres números, si al menos uno de los valores
ingresados es menor a 10, imprimir en pantalla la leyenda "Alguno de
los números es menor a diez".
8.5.4 Se ingresan tres valores por teclado, si todos son iguales se imprime
la suma del primero con el segundo y a este resultado se lo multiplica
por el tercero.
- El test o prueba de condición antes de cada repetición, que motivará que se repitan
o no las instrucciones.
En caso que la condición sea Falsa continúa por la rama del Falso y sale de la
estructura repetitiva para continuar con la ejecución del algoritmo.
El bloque se repite MIENTRAS la condición sea Verdadera.
9.1. Problema 1:
• Diagrama de flujo:
No existe una RECETA para definir una condición de una estructura repetitiva, sino
que se logra con una práctica continua solucionando problemas.
Una vez planteado el diagrama debemos verificar si el mismo es una solución válida
al problema (en este caso se debe imprimir los números del 1 al 100 en pantalla),
para ello podemos hacer un seguimiento del flujo del diagrama y los valores que
toman las variables a lo largo de la ejecución:
Programa: ejercicio28.py
Respuestas:
9.2. Problema 2:
Codificar un programa que solicite la carga de un valor positivo y nos muestre desde
1 hasta el valor ingresado de uno en uno.
Ejemplo: Si ingresamos 30 se debe mostrar en pantalla los números del 1 al 30.
Es de FUNDAMENTAL importancia analizar los diagramas de flujo y la posterior
codificación en Python de los siguientes problemas, en varios problemas se
presentan otras situaciones no vistas en el ejercicio anterior.
• Diagrama de flujo:
A la prueba del diagrama la podemos realizar dándole valores a las variables; por
ejemplo, si ingresamos 5 el seguimiento es el siguiente:
Programa: ejercicio29.py
Los nombres de las variables n y x pueden ser palabras o letras (como en este caso)
La variable x recibe el nombre de CONTADOR. Un contador es un tipo especial de
variable que se incrementa o disminuye con valores constantes durante la ejecución
del programa.
9.3. Problema 3:
• Diagrama de flujo:
Hemos dado el nombre de suma a nuestro acumulador. Cada ciclo que se repita la
estructura repetitiva, la variable suma se incrementa con el contenido ingresado en
la variable valor.
Este es un seguimiento del diagrama planteado. Los números que toma la variable
valor dependerá de qué cifras cargue el operador durante la ejecución del programa.
El promedio se calcula al salir de la estructura repetitiva (es decir primero sumamos
los 10 valores ingresados y luego los dividimos por 10)
Hay que tener en cuenta que cuando en la variable valor se carga el primer valor
(en este ejemplo 5) al cargarse el segundo valor (16) el valor anterior 5 se pierde,
por ello la necesidad de ir almacenando en la variable suma los valores ingresados.
• Programa: ejercicio30.py
El resultado del promedio es un valor real es decir con coma. Si queremos que el
resultado de la división solo retorne la parte entera del promedio debemos utilizar el
operador //:
9.4. Problema 4:
• Diagrama de flujo:
Podemos observar que dentro de una estructura repetitiva puede haber estructuras
condicionales (inclusive puede haber otras estructuras repetitivas que veremos más
adelante)
Cada vez que ingresamos un largo de pieza (largo) verificamos si es una medida
correcta (debe estar entre 1.20 y 1.30 el largo para que sea correcta), en caso de
ser correcta la CONTAMOS (incrementamos la variable cantidad en 1).
• Programa: ejercicio31.py
Cuando queremos cargar por teclado un valor con decimales debemos utilizar la
función float en lugar de int:
9.5.1 Escribir un programa que solicite ingresar 10 notas de alumnos y nos informe
cuántos tienen notas mayores o iguales a 7 y cuántos menores.
9.5.3 En una empresa trabajan n empleados cuyos sueldos oscilan entre $100 y
$500, realizar un programa que lea los sueldos que cobra cada empleado e
informe cuántos empleados cobran entre $100 y $300 y cuántos cobran más
de $300. Además el programa deberá informar el importe que gasta la
empresa en sueldos al personal.
9.5.5 Mostrar los múltiplos de 8 hasta el valor 500. Debe aparecer en pantalla 8 -
16 - 24, etc.
9.5.6 Realizar un programa que permita cargar dos listas de 15 valores cada una.
Informar con un mensaje cual de las dos listas tiene un valor acumulado
mayor (mensajes "Lista 1 mayor", "Lista 2 mayor", "Listas iguales")
Tener en cuenta que puede haber dos o más estructuras repetitivas en un
algoritmo.
9.5.7 Desarrollar un programa que permita cargar n números enteros y luego nos
informe cuántos valores fueron pares y cuántos impares.
Emplear el operador “%” en la condición de la estructura condicional (este
operador retorna el resto de la división de dos valores, por ejemplo 11%2
retorna un 1):
if valor%2==0:
10.1. Problema 1:
Realizar un programa que imprima en pantalla los números del 0 al 100. Este
problema lo podemos resolver perfectamente con el ciclo while pero en esta
situación lo resolveremos empleando el for.
Programa: ejercicio39.py
• Programa: ejercicio40.py
10.2. Problema 2:
Programa: ejercicio41.py
La función range puede tener dos parámetros, el primero indica el valor inicial que
tomará la variable x, cada vuelta del for la variable x toma el valor siguiente hasta
llegar al valor indicado por el segundo parámetro de la función range menos uno.
10.3. Problema 3:
• Programa: ejercicio42.py
La función range puede tener también tres parámetros, el primero indica el valor
inicial que tomará la variable x, el segundo parámetro el valor final (que no se
incluye) y el tercer parámetro indica cuanto se incrementa cada vuelta x.
En nuestro ejemplo la primer vuelta del for x recibe el valor 1, la segunda vuelta
toma el valor 3 y así sucesivamente hasta el valor 99.
10.4. Problema 4:
• Programa: ejercicio43.py
Como vemos la variable f del for solo sirve para iterar(repetir) las diez veces el
bloque contenido en el for.
El resultado hubiese sido el mismo si llamamos a la funcion range con los valores:
range(1,11)
10.5. Problema 5:
Escribir un programa que solicite por teclado 10 notas de alumnos y nos informe
cuántos tienen notas mayores o iguales a 7 y cuántos menores.
• Programa: ejercicio44.py
Nuevamente utilizamos el for ya que sabemos que el ciclo repetitivo debe repetirse
10 veces. Recordemos que si utilizamos el while debemos llevar un contador y
recordar de incrementarlo en cada vuelta.
10.6. Problema 6:
Escribir un programa que lea 10 números enteros y luego muestre cuántos valores
ingresados fueron múltiplos de 3 y cuántos de 5. Debemos tener en cuenta que hay
números que son múltiplos de 3 y de 5 a la
vez.
• Programa: ejercicio45.py
10.7. Problema 7:
Programa: ejercicio46.py
10.8.1 Confeccionar un programa que lea n pares de datos, cada par de datos
corresponde a la medida de la base y la altura de un triángulo. El programa
deberá informar:
10.8.3 Desarrollar un programa que muestre la tabla de multiplicar del 5 (del 5 al 50)
10.8.6 Escribir un programa que pida ingresar coordenadas (x,y) que representan
puntos en el plano.
Un programa en Python puede definir además del algoritmo propiamente dicho una
serie de comentarios en el código fuente que sirvan para aclarar los objetivos de
ciertas partes del programa.
Tengamos en cuenta que un programa puede requerir mantenimiento del mismo en
el futuro. Cuando hay que implementar cambios es bueno encontrar en el programa
comentarios sobre el objetivo de las distintas partes del algoritmo, sobretodo si es
complejo.
Existen dos formas de definir comentarios en Python:
• Comentarios de una sola línea, se emplea el caracter #:
Se deben utilizar tres comillas simples o dobles seguidas al principio y al final del
comentario.
11.1. Problema 1:
Mostrar la tabla de multiplicar del 5 empleando primero el while y seguidamente de
nuevo empleando el for.
• Programa: ejercicio55.py
11.2.1 Realizar un programa que solicite la carga de valores enteros por teclado y
los sume. Finalizar la carga al ingresar el valor -1. Dejar como comentario
dentro del código fuente el enunciado del problema.
Hasta este momento hemos visto cómo definir variables enteras y flotantes. Realizar
su carga por asignación y por teclado.
Como vemos el intérprete de Python diferencia una variable flotante de una variable
entera por la presencia del carácter punto.
Para realizar la carga por teclado utilizando la función input debemos llamar a la
función int o float para convertir el dato devuelto por input:
A estos dos tipos de datos fundamentales (int y float) se suma un tipo de dato muy
utilizado que son las cadenas de caracteres.
Una cadena de caracteres está compuesta por uno o más caracteres. También
podemos iniciar una cadena de caracteres por asignación o ingresarla por teclado.
Inicialización de una cadena por asignación:
Para la carga por teclado de una cadena de caracteres utilizamos la función input
que retorna una cadena de caracteres:
12.1. Problema 1:
Realizar la carga por teclado del nombre, edad y altura de dos personas. Mostrar
por pantalla el nombre de la persona con mayor altura.
Programa: ejercicio58.py
Es importante notar que cuando cargamos un entero el dato devuelto por la función
input se lo pasamos a la función int que tiene por objetivo convertirlo a entero:
Cuando cargamos un valor con decimal el dato devuelto por la función input se lo
pasamos a la función float que tiene por objetivo convertirlo a float:
12.2. Problema 2:
Realizar la carga de dos nombres por teclado. Mostrar cual de los dos es mayor
alfabéticamente o si son iguales.
• Programa: ejercicio59.py
Por ejemplo 'luis' es mayor a 'carlos' porque la 'l' se encuentra más adelante en el
abecedario que la 'c'.
12.3. Problema 3:
Realizar la carga de enteros por teclado. Preguntar después que ingresa el valor si
desea cargar otro valor debiendo el operador ingresar la cadena 'si' o 'no' por
teclado.
• Programa: ejercicio60.py
Para resolver este problema hemos inicializado una variable de tipo cadena de
caracteres (también se las llama variables de tipo string) con el valor "si", esto hace
que la condición del while se verifique verdadera la primera vez. Dentro del while
luego de cargar el valor entero se pide la carga por teclado que confirme si desea
cargar otro valor, en caso que cargue el string "si" el ciclo repetitivo while se vuelve
a repetir.
Es importante notar que el string "si" es distinto al string "Si", es decir las mayúsculas
no tienen el mismo valor alfabético que las minúsculas (después veremos que
podemos convertir mayúsculas a minúsculas y viceversa)
12.4.1 Realizar la carga de dos nombres de personas distintos. Mostrar por pantalla
luego ordenados en forma alfabética.
Ya hemos visto que podemos cargar una cadena de caracteres por asignación:
Podemos utilizar los operadores relacionales para identificar si dos cadenas son
iguales, distintas o cual es la mayor alfabética:
13.1. Problema 1:
Realizar la carga del nombre de una persona y luego mostrar el primer caracter del
nombre y la cantidad de letras que lo componen.
• Programa: ejercicio62.py
13.2. Problema 2:
• Programa: ejercicio63.py
Con que una de las condiciones del if sea verdadera luego se ejecuta el bloque del
verdadero.
13.3. Problema 3:
Ingresar un mail por teclado. Verificar si el string ingresado contiene solo un caracter
"@".
• Programa: ejercicio64.py
Para analizar cada caracter del string ingresado disponemos una estructura while
utilizando un contador llamado x que comienza con el valor cero y se repetirá
tantas veces como caracteres tenga la cadena (mediante la función len obtenemos
la cantidad de caracteres):
while x<len(mail):
if mail[x]=="@":
cantidad=cantidad+1
if cantidad==1:
print("Contiene solo un caracter @ el mail ingresado")
else:
print("Incorrecto")
Los string en Python son inmutables, esto quiere decir que una vez que los
inicializamos no podemos modificar su contenido:
nombre="juan"
nombre[0]="m" #esto no se puede
No hay que confundir cambiar parte del string con realizar la asignación de otro
string a la misma variable, luego si es correcto asignar otro valor a un string:
nombre="juan"
print(nombre)
nombre="ana"
print(nombre)
Los string tienen una serie de métodos (funciones aplicables solo a los string) que
nos facilitan la creación de nuestros programas.
Los primeros tres métodos que veremos se llaman: lower, upper y capitalize.
13.4. Problema 4:
Inicializar un string con la cadena "mAriA" luego llamar a sus métodos upper(),
lower() y capitalize(), guardar los datos retornados en otros string y mostrarlos por
pantalla.
• Programa: ejercicio65.py
Para llamar a un método del string debemos disponer entre el nombre del string y
el método el carácter punto:
nombre2=nombre1.upper()
13.5.1 Cargar una oración por teclado. Mostrar luego cuantos espacios en blanco
se ingresaron. Tener en cuenta que un espacio en blanco es igual a
" ", en cambio una cadena vacía es ""
13.5.2 Ingresar una oración que pueden tener letras tanto en mayúsculas como
minúsculas. Contar la cantidad de vocales. Crear un segundo string con toda
la oración en minúsculas para que sea más fácil disponer la condición que
verifica que es una vocal.
13.5.3 Solicitar el ingreso de una clave por teclado y almacenarla en una cadena de
caracteres. Controlar que el string ingresado tenga entre 10 y 20 caracteres
para que sea válido, en caso contrario mostrar un mensaje de error.
Hasta ahora hemos trabajado con variables que permiten almacenar un único valor:
edad=12
altura=1.79
nombre="juan"
En Python existe un tipo de variable que permite almacenar una colección de datos
y luego acceder por medio de un subíndice (similar a los string)
Para crear una lista por asignación debemos indicar sus elementos encerrados
entre corchetes y separados por coma.
14.1. Problema 1:
Definir una lista que almacene 5 enteros. Sumar todos sus elementos y mostrar
dicha suma.
• Programa: ejercicio69.py
lista=[10,7,3,7,2]
suma=0
x=0
suma=suma+lista[x]
x=x+1
Cuando llamamos a la función print pasando como dato una lista luego se muestra
en pantalla todos los elementos de la lista entre corchetes y separados por coma tal
cual como la definimos:
14.2. Problema 2:
Definir una lista por asignación que almacene los nombres de los primeros cuatro
meses de año. Mostrar el primer y último elemento de la lista solamente.
• Programa: ejercicio70.py
Como queremos imprimir solo el primer y último elemento de la lista indicamos entre
corchetes la posición de la lista del cual queremos rescatar el valor.
Si llamamos a print y pasamos solo el nombre de la lista luego se nos muestra todos
los elementos:
14.3. Problema 3:
Definir una lista por asignación que almacene en la primer componente el nombre
de un alumno y en las dos siguientes sus notas. Imprimir luego el nombre y el
promedio de las dos notas.
• Programa: ejercicio71.py
Como vemos en este problema los elementos de una lista pueden ser de distinto
tipo, aquí tenemos el primer elemento de tipo string y los dos siguientes de tipo int.
Recordemos que el operador // se utiliza para dividir dos valores y retornar solo la
parte entera.
14.4.1 Definir por asignación una lista con 8 elementos enteros. Contar cuantos de
dichos valores almacenan un valor superior a 100.
14.4.2 Definir una lista por asignación con 5 enteros. Mostrar por pantalla solo los
elementos con valor iguales o superiores a 7.
14.4.3 Definir una lista que almacene por asignación los nombres de 5 personas.
Contar cuántos de esos nombres tienen 5 o más caracteres.
Una lista en Python es una estructura mutable (es decir puede ir cambiando durante
la ejecución del programa)
Hemos visto que podemos definir una lista por asignación indicando entre corchetes
los valores a almacenar:
lista.append(100)
print(len(lista)) # imprime un 4
print(lista[0]) # imprime un 10
print(lista[3]) # imprime un 100
15.1 Problema 1:
Definir una lista vacía y luego solicitar la carga de 5 enteros por teclado y añadirlos
a la lista. Imprimir la lista generada.
• Programa: ejercicio75.py
El algoritmo propuesto crea primero una lista vacía (debemos asignar los corchetes
de apertura y cerrado sin contenido):
lista= [ ]
for x in range(5):
valor=int(input("Ingrese un valor entero:"))
lista.append(valor)
print(lista)
15.2. Problema 2:
Realizar la carga de valores enteros por teclado, almacenarlos en una lista. Finalizar
la carga de enteros al ingresar el cero. Mostrar finalmente el tamaño de la lista.
• Programa: ejercicio76.py
En este problema la lista crecerá hasta que el operador ingrese el valor cero. La
carga del primer valor se efectúa antes del ciclo while ya que la condición depende
del valor ingresado:
Luego dentro del ciclo while procedemos a agregar al final de la lista el valor
ingresado y solicitar la carga del siguiente valor:
while valor!=0:
lista.append(valor)
valor=int(input("Ingresar valor (0 para finalizar):"))
print(len(lista))
15.3.1 Almacenar en una lista los sueldos (valores float) de 5 operarios. Imprimir la
lista y el promedio de sueldos.
15.3.2 Cargar por teclado y almacenar en una lista las alturas de 5 personas (valores
float)
Obtener el promedio de las mismas. Contar cuántas personas son más altas
que el promedio y cuántas más bajas.
15.3.3 Una empresa tiene dos turnos (mañana y tarde) en los que trabajan 8
empleados (4 por la mañana y 4 por la tarde) Confeccionar un programa que
permita almacenar los sueldos de los empleados agrupados en dos listas.
Imprimir las dos listas de sueldos.
Es una actividad muy común la búsqueda del mayor y menor elemento de una lista.
Es necesario que la lista tenga valores del mismo tipo por ejemplo enteros. Pueden
ser de tipo cadenas de caracteres y se busque cual es mayor o menor
alfabéticamente, pero no podemos buscar el mayor o menor si la lista tiene enteros
y cadenas de caracteres al mismo tiempo.
16.1. Problema 1:
Crear y cargar una lista con 5 enteros. Implementar un algoritmo que identifique el
mayor valor de la lista.
• Programa: ejercicio80.py
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
Para identificar el mayor de una lista primero tomamos como referencia el primer
elemento, considerando a este en principio como el mayor de la lista:
mayor=lista[0]
if lista[x]>mayor:
mayor=lista[x]
print("Mayor de la lista")
print(mayor)
16.2. Problema 2:
Crear y cargar una lista con 5 enteros por teclado. Implementar un algoritmo que
identifique el menor valor de la lista y la posición donde se encuentra.
• Programa: ejercicio81.py
lista=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
menor=lista[0]
Por otro lado la segunda variable almacena un cero que es la posición donde se
encuentra el menor hasta este momento:
posicion=0
for x in range(1,5):
if lista[x]<menor:
En caso que sea menor a la que hemos considerado "menor" hasta este momento
procedemos a actualizar la variable "menor" con el nuevo valor y también
actualizamos la variable "posicion" con el valor del contador del for que nos indica
que posición de la lista estamos analizando:
menor=lista[x]
posicion=x
Cuando salimos del for mostramos la lista completa, el menor de la lista y la posición
que tiene en la lista dicho menor:
print("Lista completa")
print(lista)
print("Menor de la lista")
print(menor)
print("Posicion del menor en la lista")
print(posicion)
16.3.1 Ingresar por teclado los nombres de 5 personas y almacenarlos en una lista.
Mostrar el nombre de persona menor en orden alfabético.
16.3.2 Cargar una lista con 5 elementos enteros. Imprimir el mayor y un mensaje si
se repite dentro de la lista (es decir si dicho valor se encuentra en 2 o más
posiciones en la lista)
Podemos decir que dos listas son paralelas cuando hay una relación entre las
componentes de igual subíndice (misma posición) de una lista y otra.
Si tenemos dos listas que ya hemos inicializado con 5 elementos cada una. En una
se almacenan los nombres de personas en la otra las edades de dichas personas.
Decimos que la lista nombres es paralela a la lista edades si en la componente 0 de
cada lista se almacena información relacionada a una persona (Juan - 12 años)
Es decir hay una relación entre cada componente de las dos listas.
17.1. Problema 1:
• Programa: ejercicio84.py
Definimos dos listas para almacenar los nombres y las edades de las personas
respectivamente:
nombres=[]
edades=[]
for x in range(5):
nom=input("Ingrese el nombre de la persona:")
nombres.append(nom)
ed=int(input("Ingrese la edad de dicha persona:"))
edades.append(ed)
for x in range(5):
if edades[x]>=18:
print(nombres[x])
17.2.1 Crear y cargar dos listas con los nombres de 5 productos en una y sus
respectivos precios en otra. Definir dos listas paralelas. Mostrar cuantos
productos tienen un precio mayor al primer producto ingresado.
a) Ingresar nombre y nota de cada alumno (almacenar los datos en dos listas
paralelas)
17.2.3 Realizar un programa que pida la carga de dos listas numéricas enteras de
4 elementos cada una. Generar una tercer lista que surja de la suma de los
elementos de la misma posición de cada lista. Mostrar esta tercer lista.
Se puede ordenar tanto listas con componentes de tipo int, float como cadena de
caracteres. En este último caso el ordenamiento es alfabético.
18.1. Problema 1:
Se debe crear y cargar una lista donde almacenar 5 sueldos. Desplazar el valor
mayor de la lista a la última posición.
En este ejemplo: ¿es 1200 mayor a 750? La respuesta es verdadera, por lo tanto
intercambiamos el contenido de la componente 0 con el de la componente 1.
Si hay 5 componentes hay que hacer 4 comparaciones, por eso el for se repite 4
veces.
Pero con un único for no se ordena una lista. Solamente está ordenado el último
elemento de la lista.
18.2. Problema 2:
Se debe crear y cargar una lista donde almacenar 5 sueldos. Ordenar de menor a
mayor la lista.
Ahora bien como vimos en el problema anterior con los 4 elementos que nos quedan
podemos hacer el mismo proceso visto anteriormente, con lo cual quedará ordenado
otro elemento de la lista. Este proceso lo repetiremos hasta que quede ordenado
por completo la lista.
Como debemos repetir el mismo algoritmo podemos englobar todo el bloque en otra
estructura repetitiva.
• Programa: ejercicio89.py
Como sabemos cada vez que se repite en forma completa el for interno queda
ordenada una componente de la lista. A primera vista diríamos que deberíamos
repetir el for externo la cantidad de componentes de la lista, en este ejemplo la lista
sueldos tiene 5 componentes.
Si observamos, cuando quedan dos elementos por ordenar, al ordenar uno de ellos
queda el otro automáticamente ordenado (podemos imaginar que si tenemos una
lista con 2 elementos no se requiere el for externo, porque este debería repetirse
una única vez)
Ejemplo: En la primera ejecución del for interno el valor 1200 queda ubicado en la
posición 4 de la lista. En la segunda ejecución comparamos si el 820 es mayor a
1200, lo cual seguramente será falso.
Podemos concluir que la primera vez debemos hacer para este ejemplo 4
comparaciones, en la segunda ejecución del for interno debemos hacer 3
comparaciones y en general debemos ir reduciendo en uno la cantidad de
comparaciones.
Si bien el algoritmo planteado funciona, un algoritmo más eficiente, que se deriva
del anterior es el plantear un for interno con la siguiente estructura:
for k in range(4):
for x in range(4-k):
if sueldos[x]>sueldos[x+1]:
aux=sueldos[x]
sueldos[x]=sueldos[x+1]
sueldos[x+1]=aux
18.3.2 Solicitar por teclado la cantidad de empleados que tiene la empresa. Crear y
cargar una lista con todos los sueldos de dichos empleados. Imprimir la lista
de sueldos ordenamos de menor a mayor.
18.3.3 Cargar una lista con 5 elementos enteros. Ordenarla de menor a mayor y
mostrarla por pantalla, luego ordenar de mayor a menor e imprimir
nuevamente.
Cuando se tienen listas paralelas y se ordenan los elementos de una de ellas hay
que tener la precaución de intercambiar los elementos de las listas paralelas.
19.1. Problema 1:
• Programa: ejercicio93.py
alumnos=[]
notas=[]
for x in range(5):
nom=input("Ingrese el nombre del alumno:")
alumnos.append(nom)
no=int(input("Ingrese la nota de dicho alumno:"))
notas.append(no)
for k in range(4):
for x in range(4-k):
if notas[x]<notas[x+1]:
aux1=notas[x]
notas[x]=notas[x+1]
notas[x+1]=aux1
aux2=alumnos[x]
alumnos[x]=alumnos[x+1]
alumnos[x+1]=aux2
for x in range(5):
print(alumnos[x],notas[x])
Algo que no habíamos utilizado en Python hasta ahora es imprimir varios datos en
la misma línea, esto se logra pasando más de un parámetro a la función print
separándolos por una coma:
print(alumnos[x],notas[x])
19.2.1 Crear y cargar en un lista los nombres de 5 países y en otra lista paralela la
cantidad de habitantes del mismo. Ordenar alfabéticamente e imprimir los
resultados. Por último ordenar con respecto a la cantidad de habitantes (de
mayor a menor) e imprimir nuevamente.
Hasta ahora hemos trabajado con listas cuyos componentes son de tipo:
enteros
flotantes
cadenas de caracteres
Ejemplo
notas=[8, 6, 8]
alturas=[1.73, 1.55, 1.92]
dias=["lunes", "martes", "miércoles"]
Pero lo que la hace tan flexible a esta estructura de datos es que podemos
almacenar componentes de tipo LISTA.
En la línea anterior hemos definido una lista de tres elementos de tipo lista, el
primer elemento de la lista es otra lista de dos elementos de tipo entero. De forma
similar los otros dos elementos de la lista notas son listas de dos elementos de
tipo entero.
20.1 Problema 1:
Crear una lista por asignación. La lista tiene que tener cuatro elementos. Cada
elemento debe ser una lista de 3 enteros.
• Programa: ejercicio95.py
Al principio puede complicarse trabajar con listas de listas pero a medida que
practiquemos esta estructura de datos veremos que podemos desarrollar algoritmos
más complejos.
[1,2,3]
[4,5,6]
print(lista)
Aparece:
print(lista[0])
[1, 2, 3]
print(lista[0][0])
Nos muestra:
Para acceder mediante un for a todos los elementos de la lista contenida en la primer
componente de la lista principal debemos codificar:
for x in range(len(lista[0])):
print(lista[0][x])
Recordemos que la función len retorna la cantidad de elementos que contiene una
lista.
En este caso le pasamos como parámetro lista[0] que hace referencia a la primer
componente de la lista principal.
Cada ciclo del for accedemos a: lista[0][0] cuando x vale 0, lista[0][1] cuando x vale
1 y lista[0][2] cuando x vale 2.
Por último con el ciclo anidado k podemos acceder a cada elemento de la lista
principal y mediante el for interno acceder a cada elemento entero de las listas
contenidas en la lista principal:
for k in range(len(lista)):
for x in range(len(lista[k])):
print(lista[k][x])
20.2. Problema 2:
Crear una lista por asignación. La lista tiene que tener 2 elementos. Cada elemento
debe ser una lista de 5 enteros.
Calcular y mostrar la suma de cada lista contenida en la lista principal.
• Programa: ejercicio96.py
suma1=lista[0][0]+lista[0][1]+lista[0][2]+lista[0][3]+lista[0][4]
print(suma1)
suma2=lista[1][0]+lista[1][1]+lista[1][2]+lista[1][3]+lista[1][4]
print(suma2)
La segunda forma es utilizar una estructura repetitiva para sumar todos los
elementos de una lista (el primer subíndice siempre es 0 y el segundo varía con la
variable x):
suma1=0
for x in range(len(lista[0])):
suma1=suma1+lista[0][x]
suma2=0
for x in range(len(lista[1])):
suma2=suma2+lista[1][x]
print(suma1)
print(suma2)
La última forma planteada es utilizar una estructura repetitiva anidada que suma
cada fila, el for externo (k) se repite 2 veces que es el tamaño de la variable "lista":
for k in range(len(lista)):
suma=0
for x in range(len(lista[k])):
suma=suma+lista[k][x]
print(suma)
20.3. Problema 3:
Crear una lista por asignación. La lista tiene que tener 5 elementos. Cada elemento
debe ser una lista, la primera lista tiene que tener un elemento, la segunda dos
elementos, la tercera tres elementos y así sucesivamente.
Sumar todos los valores de las listas.
• Programa: ejercicio97.py
Lo primero que es importante notar que las listas contenidas en las lista principal
no tienen porque ser del mismo tamaño.
La forma más sencilla es utilizar dos ciclos repetitivos. El primero se repite tantas
veces como elementos tenga la lista principal:
for k in range(len(lista)):
El segundo ciclo nos sirve para recorrer y acceder a cada elemento entero de
cada lista:
for x in range(len(lista[k])):
suma=suma+lista[k][x]
Imprimir la lista. Luego fijar con el valor cero todos los elementos mayores a 50 del
primer elemento de "lista".
Volver a imprimir la lista.
Imprimir la lista. Luego fijar con el valor cero todos los elementos mayores a 10
contenidos en todos los elementos de la variable "lista".
Volver a imprimir la lista.
20.4.3 Crear una lista por asignación con la cantidad de elementos de tipo lista
que usted desee. Luego imprimir el último elemento de la lista principal.
En el concepto anterior vimos que fácilmente podemos definir por asignación una
lista cuyas componentes sean también listas:
En muchas situaciones debemos crear una nueva lista ingresando los datos por
teclado o por operaciones del mismo programa.
21.1. Problema 1:
Crear y cargar una lista con los nombres de tres alumnos. Cada alumno tiene dos
notas, almacenar las notas en una lista paralela. Cada componente de la lista
paralela debe ser también una lista con las dos notas. Imprimir luego cada nombre
y sus dos notas.
Nuestro objetivo como lo pide el problema es cargar los datos por teclado.
• Programa: ejercicio101.py
nombres=[]
notas=[]
for x in range(3):
nom=input("Ingrese el nombre del alumno:")
nombres.append(nom)
for x in range(3):
print(nombres[x],notas[x][0],notas[x][1])
21.2. Problema 2:
· Nombres de 3 empleados
a) Realizar la carga de los nombres de empleados y los tres sueldos por cada
empleado.
Una lista para almacenar los nombres de los empleados, por ejemplo si lo cargamos
por asignación:
Una lista paralela a la anterior para almacenar los sueldos en los últimos tres meses
por cada empleado:
Otra lista paralela donde almacenamos el total de sueldos cobrados por cada
empleado que resulta de sumar los tres sueldos de cada empleado contenidos en
la lista sueldos:
Es importante notar que estos datos no los cargaremos por asignación sino los
cargaremos por teclado a las dos primeras listas y la tercera la generaremos
extrayendo los datos de la lista sueldos.
• Programa: ejercicio102.py
Definimos 3 listas:
nombres=[]
sueldos=[]
totalsueldos=[]
En el primer for realizamos la carga de cada nombre de empleado y sus tres últimos
sueldos, en la lista nombres añadimos strings y en la lista sueldos añadimos otra
lista con tres enteros que representan los sueldos:
for x in range(3):
nom=input("Ingrese el nombre del empleado:")
nombres.append(nom)
su1=int(input("Ingrese el primer sueldo:"))
su2=int(input("Ingrese el segundo sueldo:"))
su3=int(input("Ingrese el tercer sueldo:"))
sueldos.append([su1, su2, su3])
for x in range(3):
total=sueldos[x][0]+sueldos[x][1]+sueldos[x][2]
totalsueldos.append(total)
Imprimimos ahora el nombre del empleado seguido por el ingreso total en sueldos
de los últimos tres meses:
for x in range(3):
print(nombres[x], totalsueldos[x])
Finalmente el problema requiere mostrar el nombre del empleado que recaudó más
en sueldos en los últimos tres meses.
posmayor=0
mayor=totalsueldos[0]
for x in range(1,3):
if totalsueldos[x]>mayor:
mayor=totalsueldos[x]
posmayor=x
Finalmente cuando salimos del ciclo procedemos a mostrar el nombre del empleado
que recaudó más en los últimos tres meses:
21.3. Problema 3:
Solicitar por teclado dos enteros. El primer valor indica la cantidad de elementos
que crearemos en la lista. El segundo valor indica la cantidad de elementos que
tendrá cada una de las listas internas a la lista principal.
Mostrar la lista y la suma de todos sus elementos.
Por ejemplo si el operador carga un 2 y un 4 significa que debemos crear una lista
similar a:
lista=[[1,1,1,1], [1,1,1,1]]
• Programa: ejercicio103.py
Lo primero que hacemos en este problema además de definir la lista es cargar dos
enteros por teclado:
lista=[]
elementos=int(input("Cuantos elementos tendra la lista:"))
sub=int(input("Cuantos elementos tendran las listas internas:"))
El primer for se repetirá tantas veces como indica el primer valor ingresado por
teclado almacenado en la variable "elementos", cada vuelta de este for se crea un
elemento en la "lista" y se carga una lista vacía []:
for k in range(elementos):
lista.append([])
for x in range(sub):
valor=int(input("Ingrese valor:"))
lista[k].append(valor)
suma=0
for k in range(len(lista)):
for x in range(len(lista[k])):
suma=suma+lista[k][x]
El for de las "k" se repite tantas veces como elementos tenga "lista" y el for de las
x se repite tantas veces como elementos tenga la lista en la posición k.
21.4. Problema 4:
La primer lista cada elemento es una sublista con el nombre del padre y la madre
de una familia.
La segunda lista está constituida por listas con los nombres de los hijos de cada
familia. Puede haber familias sin hijos.
También imprimir solo el nombre del padre y la cantidad de hijos que tiene dicho
padre.
Como son listas paralelas podemos decir que la familia cuyos padres son "juan" y
"ana" tiene tres hijos llamados "marcos", "alberto", "silvia". La segunda familia no
tiene hijos y la tercera tiene solo uno.
• Programa: ejercicio104.py
padres=[]
hijos=[]
El primer for es para cargar y crear cada elemento de la lista "padres", crear una
elemento de la lista hijos con una lista vacía y solicitar que se cargue cuantos hijos
tiene la familia:
for k in range(3):
pa=input("Ingrese el nombre del padre:")
ma=input("Ingrese el nombre de la madre:")
padres.append([pa, ma])
cant=int(input("Cuantos hijos tienen esta familia:"))
hijos.append([])
El for interno se ingresan los nombres de los hijos y se agregan a la lista hijos en la
posición respectiva. El for interno puede llegar a no ejecutarse si se ingresa un 0 en
cantidad de hijos:
for x in range(cant):
nom=input("Ingrese el nombre del hijo:")
hijos[k].append(nom)
Para imprimir los nombres de ambos padres y sus hijos también implementamos un
for anidado:
21.5.1 Se desea saber la temperatura media trimestral de cuatro paises. Para ello
se tiene como dato las temperaturas medias mensuales de dichos paises.
21.5.2 Se debe ingresar el nombre del país y seguidamente las tres temperaturas
medias mensuales.
21.5.3 Seleccionar las estructuras de datos adecuadas para el almacenamiento de
los datos en memoria.
a - Cargar por teclado los nombres de los paises y las temperaturas medias
mensuales.
Hemos visto que una lista la podemos iniciar por asignación indicando sus
elementos.
lista.append(120)
lista.pop(0)
Otra cosa que hay que hacer notar que cuando un elemento de la lista se elimina
no queda una posición vacía, sino se desplazan todos los elementos de la derecha
una posición.
22.1. Problema 1:
Crear una lista por asignación con 5 enteros. Eliminar el primero, el tercero y el
último de la lista.
• Programa: ejercicio108.py
Parecería que con esas tres llamadas al método pop se eliminan los tres primeros
elementos pero no es así, si imprimimos cada vez que borramos uno veremos que
estamos borrando el primero, tercero y quinto.
22.2. Problema 2:
Crear una lista y almacenar 10 enteros pedidos por teclado. Eliminar todos los
elementos que sean iguales al número entero 5.
• Programa: ejercicio109.py
Llevamos un contador llamado "posicion" que nos indica que elemento de la lista
estamos verificando en el if, en el caso que se debe borrar llamamos al método pop
pasando el contador y no incrementamos en uno el contador "posicion" ya que los
elementos de la derecha se desplazan una posición a izquierda.
En el caso que no se debe borrar se incrementa en uno el contador "posicion" para
analizar el siguiente elemento de la lista en la próxima vuelta del ciclo:
posicion=0
while posicion<len(lista):
if lista[posicion]==5:
lista.pop(posicion)
else:
posicion=posicion+1
22.3.1 Crear dos listas paralelas. En la primera ingresar los nombres de empleados
y en la segunda los sueldos de cada empleado.
Ingresar por teclado cuando inicia el programa la cantidad de empleados de
la empresa.
Borrar luego todos los empleados que tienen un sueldo mayor a 10000 (tanto
el sueldo como su nombre)
22.3.2 Crear una lista de 5 enteros y cargarlos por teclado. Borrar los elementos
mayores o iguales a 10 y generar una nueva lista con dichos valores.
Hasta ahora hemos trabajado con una metodología de programación lineal. Todas
las instrucciones de nuestro archivo *.py se ejecutan en forma secuencial de
principio a fin.
Esta forma de organizar un programa solo puede ser llevado a cabo si el mismo es
muy pequeño (decenas de líneas)
Los primeros problemas que presentaremos nos puede parecer que sea más
conveniente utilizar programación lineal en vez de programación estructurada por
funciones.
A medida que avancemos veremos que si un programa empieza a ser más complejo
(cientos de líneas, miles de líneas o más) la división en pequeñas funciones nos
permitirá tener un programa más ordenado y fácil de entender y por lo tanto en
mantener.
23.1. Problema 1:
• Programa: ejercicio112.py
# programa principal
presentacion()
carga_suma()
finalizacion()
La sintaxis para declarar una función es mediante la palabra clave def seguida por
el nombre de la función (el nombre de la función no puede tener espacios en blanco,
comenzar con un número y el único caracter especial permitido es el _ )
Luego del nombre de la función deben ir entre paréntesis los datos que llegan, si no
llegan datos como es el caso de nuestras tres funciones solo se disponen paréntesis
abierto y cerrado. Al final disponemos los :
Luego de definir las funciones tenemos al final de nuestro archivo *.py las llamadas
de las funciones:
Si no hacemos las llamadas a las funciones los algoritmos que implementan las
funciones nunca se ejecutarán.
Cuando en el bloque del programa principal se llama una función hasta que no
finalice no continua con la llamada a la siguiente función:
Hemos declarado dos funciones, una que permite cargar dos enteros sumarlos y
mostrar el resultado:
def carga_suma():
valor1=int(input("Ingrese el primer valor:"))
valor2=int(input("Ingrese el segundo valor:"))
suma=valor1+valor2
print("La suma de los dos valores es:",suma)
Y otra función que tiene por objetivo mostrar una línea separadora con asteriscos:
def separacion():
print("*******************************")
Ahora nuestro bloque principal del programa, recordemos que estas líneas son las
primeras que se ejecutarán cuando iniciemos el programa:
# programa principal
for x in range(5):
carga_suma()
separacion()
Lo nuevo que debe quedar claro es que la llamada a las funciones desde el bloque
principal de nuestro programa puede hacerse múltiples veces (esto es lógico,
recordemos que print es una función ya creada en Python y la llamamos múltiples
veces dentro de nuestro algoritmo)
Vimos en el concepto anterior que una función resuelve una parte de nuestro
algoritmo.
Tenemos por un lado la declaración de la función por medio de un nombre y el
algoritmo de la función seguidamente. Luego para que se ejecute la función la
llamamos desde el bloque principal de nuestro programa.
Ahora veremos que una función puede tener parámetros para recibir datos. Los
parámetros nos permiten comunicarle algo a la función y la hace más flexible.
24.1. Problema 1:
Confeccionar una aplicación que muestre una presentación en pantalla del
programa. Solicite la carga de dos valores y nos muestre la suma. Mostrar
finalmente un mensaje de despedida del programa.
• Programa: ejercicio116.py
Ahora para resolver este pequeño problema hemos planteado una función llamada
mostrar_mensaje que recibe como parámetro un string (cadena de caracteres) y lo
muestra en pantalla.
Los parámetros van seguidos del nombre de la función encerrados entre paréntesis
(y en el caso de tener más de un parámetro los mismos deben ir separados por
coma):
def mostrar_mensaje(mensaje):
print("*************************************************")
print(mensaje)
print("*************************************************")
Un parámetro podemos imaginarlo como una variable que solo se puede utilizar
dentro de la función.
El string que le pasamos: "El programa calcula la suma de dos valores ingresados
por teclado." lo recibe el parámetro de la función.
Una función con parámetros nos hace más flexible la misma para utilizarla en
distintas circunstancias. En nuestro problema la función mostrar_mensaje la
utilizamos tanto para la presentación inicial de nuestro programa como para mostrar
24.2. Problema 2:
Confeccionar una función que reciba tres enteros y nos muestre el mayor de ellos.
La carga de los valores hacerlo por teclado.
• Programa: ejercicio117.py
La función cargar solicita el ingreso de tres enteros por teclado y llama a la función
mostrar_mayor y le pasa a sus parámetros las tres variable enteras valor1, valor2 y
valor3.
Los parámetros son la forma que nos permite comunicar la función cargar con la
función mostrar_mayor.
24.3. Problema 3:
• Programa: ejercicio118.py
def mostrar_perimetro(lado):
per=lado*4
print("El perimetro es",per)
def mostrar_superficie(lado):
sup=lado*lado
print("La superficie es",sup)
def cargar_dato():
la=int(input("Ingrese el valor del lado de un cuadrado:"))
respuesta=input("Quiere calcular el perimetro o la superficie[ingresar texto:
perimetro/superficie]?")
if respuesta=="perimetro":
mostrar_perimetro(la)
if respuesta=="superficie":
mostrar_superficie(la)
# programa principal
cargar_dato()
Definimos dos funciones que calculan y muestran el perimetro por un lado y por otro
la superficie:
def mostrar_perimetro(lado):
per=lado*4
print("El perimetro es",per)
def mostrar_superficie(lado):
sup=lado*lado
print("La superficie es",sup)
La tercer función permite cargar el lado del cuadrado e ingresar un string que indica
que cálculo deseamos realizar si obtener el perímetro o la superficie. Una vez que
se ingreso la variable respuesta procedemos a llamar a la función que efectúa el
calculo respectivo pasando como dato la variable local "la" que almacena el valor
del lado del cuadrado.
Los parámetros son la herramienta fundamental para pasar datos cuando hacemos
la llamada a una función.
24.4.1 Desarrollar una función que reciba un string como parámetro y nos muestre
la cantidad de vocales. Llamarla desde el bloque principal del programa 3
veces con string distintos.
24.4.2 Confeccionar una función que reciba tres enteros y los muestre ordenados
de menor a mayor. En otra función solicitar la carga de 3 enteros por teclado
y proceder a llamar a la primer función definida.
Vimos que una función la definimos mediante un nombre y que puede recibir datos
por medio de sus parámetros.
Los parámetros son la forma para que una función reciba datos para ser
procesados. Ahora veremos otra característica de las funciones que es la de
devolver un dato a quien invocó la función (recordemos que una función la podemos
llamar desde el bloque principal de nuestro programa o desde otra función que
desarrollemos)
25.1 Problema 1:
Confeccionar una función que le enviemos como parámetro el valor del lado de un
cuadrado y nos retorne su superficie.
• Programa: ejercicio120.py
Aparece una nueva palabra clave en Python para indicar el valor devuelto por la
función: return
La variable local sup es la que retorna la función mediante la palabra clave return:
def retornar_superficie(lado):
sup=lado*lado
return sup
Hay que tener en cuenta que las variables locales (en este caso sup) solo se pueden
consultar y modificar dentro de la función donde se las define, no se tienen acceso
a las mismas en el bloque principal del programa o dentro de otra función.
superficie=retornar_superficie(va)
retornar_superficie(va)
25.2 Problema 2:
Confeccionar una función que le enviemos como parámetros dos enteros y nos
retorne el mayor.
• Programa: ejercicio121.py
Nuevamente tenemos una función que recibe dos parámetros y retorna el mayor
de ellos:
def retornar_mayor(v1,v2):
if v1>v2:
mayor=v1
else:
mayor=v2
return mayor
Si queremos podemos hacerla más sintética a esta función sin tener que guardar
en una variable local el valor a retornar:
def retornar_mayor(v1,v2):
if v1>v2:
return v1
else:
return v2
25.3. Problema 3:
Confeccionar una función que le enviemos como parámetro un string y nos retorne
la cantidad de caracteres que tiene. En el bloque principal solicitar la carga de dos
nombres por teclado y llamar a la función dos veces. Imprimir en el bloque
principal cual de las dos palabras tiene más caracteres.
• Programa: ejercicio122.py
Hemos definido una función llamada largo que recibe un parámetro llamado
cadena y retorna la cantidad de caracteres que tiene dicha cadena (utilizamos la
función len para obtener la cantidad de caracteres)
la1=largo(nombre1)
la2=largo(nombre2)
Solo nos queda analizar cual de las dos variables tiene un valor mayor para indicar
cual tiene más caracteres:
if la1==la2:
print("Los nombres:",nombre1,nombre2,"tienen la misma cantidad de
caracteres")
else:
if la1>la2:
print(nombre1,"es mas largo")
else:
print(nombre2,"es mas largo")
25.4.1 Elaborar una función que reciba tres enteros y nos retorne el valor promedio
de los mismos.
25.4.2 Elaborar una función que nos retorne el perímetro de un cuadrado pasando
como parámetros el valor de un lado.
def retornar_superficie(lado1,lado2):
25.4.4 En el bloque principal del programa cargar los lados de dos rectángulos y
luego mostrar cual de los dos tiene una superficie mayor.
Hasta ahora hemos resuelto problemas enviando datos simples como enteros, float
y cadenas de caracteres. En este concepto veremos que una función puede recibir
tanto datos simples como estructuras de datos.
La estructura de datos vista hasta este momento y que podemos enviarle a una
función es la lista.
26.1. Problema 1:
Definir por asignación una lista de enteros en el bloque principal del programa.
Elaborar tres funciones, la primera recibe la lista y retorna la suma de todos sus
elementos, la segunda recibe la lista y retorna el mayor valor y la última recibe la
lista y retorna el menor.
• Programa: ejercicio127.py
def sumarizar(lista):
suma=0
for x in range(len(lista)):
suma=suma+lista[x]
return suma
De forma similar definimos las otras dos funciones que también reciben la lista y
luego implementan los algoritmos para identificar el mayor y el menor de la lista:
def mayor(lista):
may=lista[0]
for x in range(1,len(lista)):
if lista[x]>may:
may=lista[x]
return may
def menor(lista):
men=lista[0]
for x in range(1,len(lista)):
if lista[x]<men:
men=lista[x]
return men
Las llamadas a estas dos funciones desde el bloque principal es similar a cuando
llamamos a sumarizar (como cada una retorna un entero procedemos a llamarlas
dentro de la función print):
No hay ningún problema de definir dicha variable con el mismo nombre que el
parámetro de la función, es decir sería correcto nuestro programa si definíamos en
el bloque principal el siguiente código:
def sumarizar(lista):
suma=0
for x in range(len(lista)):
suma=suma+lista[x]
return suma
def mayor(lista):
may=lista[0]
for x in range(1,len(lista)):
if lista[x]>may:
may=lista[x]
return may
def menor(lista):
men=lista[0]
for x in range(1,len(lista)):
if lista[x]<men:
men=lista[x]
return men
Debe quedar claro que la variable global definida en el bloque principal se llama
"lista" y los parámetros de las tres funciones también se llaman "lista".
26.2. Problema 2:
Crear y cargar por teclado en el bloque principal del programa una lista de 5 enteros.
Implementar una función que imprima el mayor y el menor valor de la lista.
• Programa: ejercicio128.py
Es importante notar que la función mayormenor no retorna nada sino ella es la que
tiene el objetivo de mostrar el mayor y menor valor de la lista.
26.3.1 Crear una lista de enteros por asignación. Definir una función que reciba una
lista de enteros y un segundo parámetro de tipo entero. Dentro de la función
mostrar cada elemento de la lista multiplicado por el valor entero enviado.
lista=[3, 7, 8, 10, 2]
multiplicar(lista,3)
26.3.2 Desarrollar una función que reciba una lista de string y nos retorne el que
tiene más caracteres. Si hay más de uno con dicha cantidad de caracteres
debe retornar el que tiene un valor de componente más baja.
En el bloque principal iniciamos por asignación la lista de string:
26.3.3 Definir una lista de enteros por asignación en el bloque principal. Llamar a
una función que reciba la lista y nos retorne el producto de todos sus
elementos. Mostrar dicho producto en el bloque principal de nuestro
programa.
Hemos avanzado y visto que una función puede recibir como parámetros tipos de
datos simples como enteros, flotantes etc. y estructuras de datos tipo lista.
También hemos visto que la función mediante la palabra clave return puede retornar
un tipo de dato simple desde donde se la invocó.
Lo nuevo en este concepto es que una función también puede retornar una
estructura de datos tipo lista. Con esto estamos logrando que una función retorne
varios datos ya que una lista es una colección de datos.
27.1. Problema 1:
Confeccionar una función que cargue por teclado una lista de 5 enteros y la retorne.
Una segunda función debe recibir una lista y mostrar todos los valores mayores a
10. Desde el bloque principal del programa llamar a ambas funciones.
• Programa: ejercicio132.py
lista=carga_lista()
def carga_lista():
Dentro de la función definimos una variable local de tipo lista llamada li (el nombre
de la variable local puede ser cualquiera, inclusive se podría llamar lista ya que no
hay conflictos en definir variables con el mismo nombre en una función y en el
bloque principal):
li=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
li.append(valor)
return li
Esto quiere decir que en el bloque principal del programa lista recibe la referencia
de "li":
lista=carga_lista()
imprimir_mayor10(lista)
def imprimir_mayor10(li):
print("Elementos de la lista mayores a 10")
for x in range(len(li)):
if li[x]>10:
print(li[x])
27.2. Problema 2:
Confeccionar una función que cargue por teclado una lista de 5 enteros y la retorne.
Una segunda función debe recibir una lista y retornar el mayor y el menor valor de
la lista. Desde el bloque principal del programa llamar a ambas funciones e imprimir
el mayor y el menor de la lista.
• Programa: ejercicio133.py
Lo interesante que tenemos que sacar de este ejemplo es que cuando tenemos que
retornar varios valores podemos utilizar una lista.
def retornar_mayormenor(li):
ma=li[0]
me=li[0]
for x in range(1,len(li)):
if li[x]>ma:
ma=li[x]
else:
if li[x]<me:
me=li[x]
La sintaxis para devolver ambos datos es crear una lista e indicando en cada
elementos la variable respectiva:
return [ma,me]
Ahora cuando llamo a esta función desde el bloque principal del programa sabemos
que nos retorna una lista y que el primer elemento representa el mayor de la lista y
el segundo elemento representa el menor de la lista:
rango=retornar_mayormenor(lista)
print("Mayor elemento de la lista:",rango[0])
print("Menor elemento de la lista:",rango[1])
• Importante
Hemos visto que podemos retornar en una función una lista. Python también nos
permite descomponer los valores devueltos por la función en varias variables que
reciban cada elemento de esa lista:
lista=carga_lista()
mayor, menor=retornar_mayormenor(lista)
print("Mayor elemento de la lista:",mayor)
print("Menor elemento de la lista:",menor)
Como vemos definimos las variables mayor y menor y le asignamos el valor que
retorna la función mayormenor. Cada elemento de la lista se guarda en el mismo
orden, es decir la componente 0 de la lista se guarda en la variable mayor y la
componente 1 de la lista se guarda en la variable menor. Esto se hace para que el
27.3. Problema 3:
• Programa: ejercicio134.py
Para resolver este problema debemos crear y cargar dos listas paralelas. En una
guardamos los nombres de las personas y en la otra almacenamos las edades.
Definimos una función cargar_datos que crea y carga las dos listas paralelos. Las
variables locales que almacenan dichas listas son nom y ed:
def cargar_datos():
nom=[]
ed=[]
for x in range(5):
v1=input("Ingrese el nombre de la persona:")
nom.append(v1)
v2=int(input("Ingrese la edad:"))
ed.append(v2)
return [nom,ed]
Esta función retorna una lista cuyos elementos son listas (es decir estamos en
presencia de listas con elementos tipo lista):
return [nom,ed]
nombres,edades=cargar_datos()
Ahora en las variables globales nombres y edades tenemos almacenados los dos
listas que cargamos en la función cargar_datos.
Como la función cargar_datos() retorna una lista de listas luego las dos variables
receptoras son listas.
En el bloque principal luego de llamar a cargar_datos que nos retorna las dos listas
procedemos a llamar a las otras funciones mayores_edad y promedio_edades
(nombres y edades son dos variables globales que normalmente se inicializan con
datos que devuelve una función y luego se las enviamos a otras funciones para que
las procesen):
# bloque principal
nombres,edades=cargar_datos()
mayores_edad(nombres,edades)
promedio_edades(edades)
El algoritmo de la función que imprime los nombres de las personas mayores
de edad es (recibe las dos listas):
def mayores_edad(nom,ed):
print("Nombres de personas mayores de edad")
for x in range(len(nom)):
if ed[x]>=18:
print(nom[x])
def promedio_edades(ed):
suma=0
for x in range(len(ed)):
suma=suma+ed[x]
promedio=suma//5
print("Edad promedio de las personas:",promedio)
27.4.2 Desarrollar una aplicación que permita ingresar por teclado los nombres de
5 artículos y sus precios.
Los parámetros por defecto nos permiten crear funciones más flexibles y que se
pueden emplear en distintas circunstancias.
28.1. Problema 1:
Confeccionar una función que reciba un string como parámetro y en forma opcional
un segundo string con un caracter. La función debe mostrar el string subrayado con
el caracter que indica el segundo parámetro
• Programa: ejercicio138.py
titulo_subrayado("Sistema de Administracion")
titulo_subrayado("Ventas","-")
def titulo_subrayado(titulo,caracter="*"):
print(titulo)
print(caracter*len(titulo))
Como vemos el parámetro caracter tiene una asignación de un valor por defecto
para los casos que llamamos a la función con un solo parámetro.
print(titulo)
print(caracter*len(titulo))
• Importante
Los parámetros por defecto deben ser los últimos que se declaren en la función. Se
genera un error sintáctico si tratamos de definir una función indicando primero el o
los parámetros con valores por defecto:
29.1. Problema 1:
Confeccionar una función que reciba el nombre de un operario, el pago por hora y
la cantidad de horas trabajadas. Debe mostrar su sueldo y el nombre. Hacer la
llamada de la función mediante argumentos nombrados.
• Programa: ejercicio140.py
def calcular_sueldo(nombre,costohora,cantidadhoras):
sueldo=costohora*cantidadhoras
print(nombre,"trabajo",cantidadhoras,"y cobra un sueldo de",sueldo)
calcular_sueldo("juan",10,120)
Pero también podemos indicar los datos en cualquier orden pero con la obligación
de anteceder el nombre del parámetro:
calcular_sueldo(costohora=12,cantidadhoras=40,nombre="ana")
calcular_sueldo(cantidadhoras=90,nombre="luis",costohora=7)
• Importante
Ahora vamos a profundizar la función print que hemos utilizado desde los primeros
conceptos.
Como hemos trabajado hasta ahora cada vez que se llama a la función print se
muestran todos los datos que le enviamos separados por coma y provoca un salto
de línea al final.
print("uno")
print("dos")
En pantalla aparece:
uno
dos
La función print tiene un parámetro llamado end, también hay que tener en cuenta
que este parámetro por defecto tiene asignado "\n" que es el salto de línea y es por
eso que cada vez que se ejecuta un print se produce un salto de línea.
Podemos indicar al parámetro end otro valor, por ejemplo un guión:
print("uno",end="-")
print("dos")
uno-dos
Ahora vemos que al llamar a print pidiendo que imprima "uno" e indicando que en
lugar de producir un salto de línea muestre un guión:
print("uno",end="-")
29.2. Problema 2:
Cargar una lista de 10 enteros, luego mostrarlos por pantalla a cada elemento
separados por una coma.
• Programa: ejercicio141.py
def imprimir(lista):
for x in range(len(lista)):
print(lista[x], end=",")
print("uno","dos","tres")
print("uno","dos","tres",sep=",")
uno,dos,tres
29.3.1 Elaborar una función que muestre la tabla de multiplicar del valor que le
enviemos como parámetro. Definir un segundo parámetro llamado termino
que por defecto almacene el valor 10. Se deben mostrar tantos términos de
la tabla de multiplicar como lo indica el segundo parámetro.
Llamar a la función desde el bloque principal de nuestro programa con
argumentos nombrados.
30.1. Problema 1:
Confeccionar una función que reciba entre 2 y n (siendo n = 2,3,4,5,6 etc.) valores
enteros, retornar la suma de dichos parámetros.
• Programa: ejercicio143.py
def sumar(v1,v2,*lista):
suma=v1+v2
for x in range(len(lista)):
suma=suma+lista[x]
return suma
Sumamos los dos primeros valores y luego recorremos la lista y también sumamos
sus elementos.
print(sumar(1,2))
Podemos llamar la función enviando 4 parámetros, en este caso la lista tiene dos
elementos:
print(sumar(1,2,3,4))
Puede ser que tengamos una función que recibe una cantidad fija de parámetros y
necesitemos llamarla enviando valores que se encuentran en una lista o tupla. La
forma más sencilla es anteceder el caracter * al nombre de la variable:
su=sumar(*li)
30.2.1 Confeccionar una función que reciba una serie de edades y me retorne la
cantidad que son mayores o iguales a 18 (como mínimo se envía un entero
a la función)
Una tupla permite almacenar una colección de datos no necesariamente del mismo
tipo. Los datos de la tupla son inmutables a diferencia de las listas que son mutables.
Una vez inicializada la tupla no podemos agregar, borrar o modificar sus elementos.
La sintaxis para definir una tupla es indicar entre paréntesis sus valores:
31.1. Problema 1:
Como vemos el lenguaje Python diferencia una tupla de una lista en el momento
que la definimos:
tupla=(1, 2, 3)
fecha=(25, "Diciembre", 2016)
punto=(10, 2)
persona=("Rodriguez", "Pablo", 43)
punto[0]=70
Utilizamos una tupla para agrupar datos que por su naturaleza están relacionados
y que no serán modificados durante la ejecución del programa.
31.2. Problema 2:
Desarrollar una función que solicite la carga del dia, mes y año y almacene dichos
datos en una tupla que luego debe retornar. La segunda función a implementar debe
recibir una tupla con la fecha y mostrarla por pantalla.
• Programa: ejercicio147.py
def cargar_fecha():
dd=int(input("Ingrese numero de dia:"))
mm=int(input("Ingrese numero de mes:"))
aa=int(input("Ingrese numero de año:"))
return (dd,mm,aa)
fecha=cargar_fecha()
def imprimir_fecha(fecha):
print(fecha[0],fecha[1],fecha[2],sep="/")
31.3. Problema 3:
Definir una tupla con tres valores enteros. Convertir el contenido de la tupla a tipo
lista. Modificar la lista y luego convertir la lista en tupla.
• Programa: ejercicio148.py
x=10
y=30
punto=x,y
print(punto)
tenemos dos variables enteras x e y. Luego se genera una tupla llamada punto
con dos elementos.
dd,mm,aa=fecha
# bloque principal
empleado1=cargar_empleado()
empleado2=cargar_empleado()
mayor_sueldo(empleado1,empleado2)
Hemos visto dos estructuras de datos fundamentales en Python que son las listas y
las tuplas.
La lista es una estructura mutable (es decir podemos modificar sus elementos,
agregar y borrar) en cambio una tupla es una secuencia de datos inmutable, es decir
una vez definida no puede cambiar.
En Python vimos que podemos definir elementos de una lista que sean de tipo lista,
en ese caso decimos que tenemos una lista anidada.
En general podemos crear y combinar tuplas con elementos de tipo lista y viceversa,
es decir listas con componente tipo tupla.
• Programa: ejercicio151.py
Por ejemplo definimos la lista llamada empleado con tres elementos: en el primero
almacenamos su nombre, en el segundo su edad y en el tercero la fecha de ingreso
a trabajar en la empresa (esta se trata de una tupla) Podemos más adelante durante
la ejecución del programa agregar otro elemento a la lista con por ejemplo la fecha
que se fue de la empresa:
alumno=("pedro",[7, 9])
print(alumno)
Podemos durante la ejecución del programa agregar una nueva nota a dicho
alumno:
alumno[1].append(10)
print(alumno)
32.1. Problema 1:
En la primer función definimos una lista llamada paises y dentro de una estructura
repetitiva cargamos un string con el nombre del pais y una variable entera con la
cantidad de habitantes, luego agregamos un elemento a la lista de tipo tupla:
def cargar_paisespoblacion():
paises=[]
for x in range(5):
nom=input("Ingresar el nombre del pais:")
cant=int(input("Ingrese la cantidad de habitantes:"))
paises.append((nom,cant))
return países
def imprimir(paises):
print("Paises y su poblacion")
for x in range(len(paises)):
print(paises[x][0],paises[x][1])
Para identificar el nombre del pais con mayor población iniciamos una variable pos
con el valor 0 indicando que en dicha posición de la lista se encuentra el pais con
mayor poblacion, luego dentro del for controlamos las demás tuplas almacenadas
en la lista si hay un pais con mayor población:
def pais_maspoblacion(paises):
pos=0
for x in range(1,len(paises)):
if paises[x][1]>paises[pos][1]:
pos=x
print("Pais con mayor cantidad de habitantes:",paises[pos][0])
32.2.1 Almacenar en una lista 5 empleados, cada elemento de la lista es una sub
lista con el nombre del empleado junto a sus últimos tres sueldos (estos tres
valores en una tupla)
32.2.2 Se tiene que cargar los votos obtenidos por tres candidatos a una elección.
En una lista cargar en la primer componente el nombre del candidato y en la
segunda componente cargar una lista con componentes de tipo tupla con el
nombre de la provincia y la cantidad de votos obtenidos en dicha provincia.
Se deben cargar los datos por teclado, pero si se cargaran por asignación tendría
una estructura similar a esta:
1) Función para cargar todos los candidatos, sus nombres y las provincias con
los votos obtenidos.
2) Imprimir el nombre del candidato y la cantidad total de votos obtenidos en
todas las provincias.
Hasta ahora siempre que recorremos una lista o una tupla utilizando un for
procedemos de la siguiente manera:
lista=[2, 3, 50, 7, 9]
for x in range(len(lista)):
print(lista[x])
lista=[2, 3, 50, 7, 9]
for x in range(len(lista)):
if lista[x]<10:
lista[x]=0
Ahora veremos una segunda forma de acceder a los elementos de una lista con la
estructura repetitiva for sin indicar subíndices.
lista=[2, 3, 50, 7, 9]
Como podemos ver la instrucción for requiere una variable (en este ejemplo llamada
elemento), luego la palabra clave in y por último el nombre de la lista. El bloque del
for se ejecuta tantas veces como elementos tenga la lista, y en cada vuelta del for
la variable elemento almacena un valor de la lista.
33.1. Problema 1:
• Programa: ejercicio155.py
def cargar():
lista=[]
for x in range(5):
num=int(input("Ingrese un valor:"))
lista.append(num)
return lista
def imprimir(lista):
print("Lista completa")
for elemento in lista:
print(elemento)
def mayor(lista):
may=lista[0]
for elemento in lista:
if elemento>may:
may=elemento
print("El elemento mayor de la lista es",may)
def sumar_elementos(lista):
suma=0
for elemento in lista:
suma=suma+elemento
print("La suma de todos sus elementos es",suma)
33.2. Problema 2:
1) Carga de empleados.
2) Impresión de los empleados y sus sueldos.
3) Nombre del empleado con sueldo mayor.
4) Cantidad de empleados con sueldo menor a 1000.
• Programa: ejercicio156.py
def cargar():
empleados=[]
for x in range(5):
nombre=input("Nombre del empleado:")
sueldo=int(input("Ingrese el sueldo:"))
empleados.append((nombre,sueldo))
return empleados
Algo nuevo podemos ver ahora en el for para recuperar cada tupla almacenada en
la lista. Podemos ver que desempaquetamos la tupla que devuelve el for en cada
vuelta en las variables nombre y sueldo. Esto nos facilita la impresión de los datos
sin tener que indicar subíndices para los elementos de la tupla:
def imprimir(empleados):
print("Listado de los nombres de empleados y sus sueldos")
for nombre,sueldo in empleados:
print(nombre,sueldo)
Para obtener el sueldo mayor y el nombre del empleado definimos una variable local
llamada empleado que almacene el primer elemento de la lista empleados.
En cada vuelta del for en la variable emp se almacena una tupla de la lista
empleados y procedemos a analizar si el sueldo es mayor al que hemos
considerado mayor hasta ese momento, en caso afirmativo actualizamos la variable
empleado:
def mayor_sueldo(empleados):
empleado=empleados[0]
for emp in empleados:
if emp[1]>empleado[1]:
empleado=emp
print("Empleado con mayor sueldo:",empleado[0],"su sueldo
es",empleado[1])
def sueldos_menor1000(empleados):
cant=0
for empleado in empleados:
if empleado[1]<1000:
cant=cant+1
print("Cantidad de empleados con un sueldo menor a 1000 son:",cant)
# bloque principal
empleados=cargar()
imprimir(empleados)
mayor_sueldo(empleados)
sueldos_menor1000(empleados)
33.3.1 Definir una función que cargue una lista con palabras y la retorne.
Luego otra función tiene que mostrar todas las palabras de la lista que tienen
más de 5 caracteres.
33.3.2 Almacenar los nombres de 5 productos y sus precios. Utilizar una lista y cada
elemento una tupla con el nombre y el precio.
La estructura de datos tipo diccionario utiliza una clave para acceder a un valor. El
subíndice puede ser un entero, un float, un string, una tupla etc. (en general
cualquier tipo de dato inmutable)
Recordemos que las listas son mutables y las tuplas inmutables. Un diccionario es
una estructura de datos mutable es decir podemos agregar elementos, modificar y
borrar.
Como vemos debemos encerrar entre llaves los elementos separados por coma. A
cada elementos debemos indicar del lado izquierdo del caracter : la clave y al lado
derecho el valor asignado para dicha clave. Por ejemplo para la clave "peras"
tenemos asociado el valor entero 32.
34.1. Problema 1:
En el bloque principal del programa definir un diccionario que almacene los nombres
de paises como clave y como valor la cantidad de habitantes. Implementar una
función para mostrar cada clave y valor.
• Programa: ejercicio159.py
def imprimir(paises):
for clave in paises:
print(clave, paises[clave])
34.2. Problema 2:
• Programa: ejercicio160.py
if clave in diccionario:
print(diccionario[clave])
Esto muy conveniente hacerlo ya que si no existe la clave produce un error al tratar
de accederlo:
print(diccionario[clave])
34.3. Problema 3:
1) Cargar el diccionario.
2) Listado completo del diccionario.
3) Ingresar por teclado una palabra en ingles y si existe en el diccionario mostrar su
traducción.
• Programa: ejercicio161.py
def cargar():
diccionario={}
continua="s"
while continua=="s":
caste=input("Ingrese palabra en castellano:")
ing=input("Ingrese palabra en ingles:")
diccionario[ing]=caste
continua=input("Quiere cargar otra palabra:[s/n]")
return diccionario
def imprimir(diccionario):
print("Listado completo del diccionario")
for ingles in diccionario:
print(ingles,diccionario[ingles])
def consulta_palabra(diccionario):
pal=input("Ingrese la palabra en ingles a consultar:")
if pal in diccionario:
print("En castellano significa:",diccionario[pal])
Ya vimos en conceptos anteriores que podemos definir elementos de una lista que
sean también de tipo lista o de tipo tupla.
Hemos dicho que un diccionario consta de claves y valores para esas claves.
Desarrollaremos problemas donde los valores para esas claves sean tuplas y o
listas.
35.1. Problema 1:
• Programa: ejercicio163.py
def cargar():
productos={}
continua="s"
while continua=="s":
codigo=int(input("Ingrese el codigo del producto:"))
descripcion=input("Ingrese la descripcion:")
precio=float(input("Ingrese el precio:"))
stock=int(input("Ingrese el stock actual:"))
productos[codigo]=(descripcion,precio,stock)
continua=input("Desea cargar otro producto[s/n]?")
return productos
def imprimir(productos):
print("Listado completo de productos:")
for codigo in productos:
print(codigo,productos[codigo][0],productos[codigo][1],productos[codigo][2])
Para la consulta por el codigo del artículo ingresamos un entero por teclado y luego
verificamos si dicho número está como clave dentro del diccionario productos, en el
caso afirmativo mostramos los valores de la tupla:
def consulta(productos):
codigo=int(input("Ingrese el codigo de articulo a consultar:"))
if codigo in productos:
print(productos[codigo][0],productos[codigo][1],productos[codigo][2])
Finalmente la función para listar todos los artículos con stock en cero procedemos
a analizar el stock de cada producto dentro de un for, en el caso que la tercer
componente de la tupla almacena un cero significa que no hay productos en stock:
def listado_stock_cero(productos):
print("Listado de articulos con stock en cero:")
for codigo in productos:
if productos[codigo][2]==0:
print(codigo,productos[codigo][0],productos[codigo][1],productos[codigo][2])
35.2. Problema 2:
Confeccionar una agenda. Utilizar un diccionario cuya clave sea la fecha. Permitir
almacenar distintas actividades para la misma fecha (se ingresa la hora y la
actividad)
• Programa: ejercicio164.py
def cargar():
agenda={}
El primer ciclo se repite mientras haya más fechas que cargar. Solicitamos que
ingrese una fecha, creamos una lista para guardar todas las horas y actividades que
hay par dicha fecha:
continua1="s"
while continua1=="s":
fecha=input("ingrese la fecha con formato dd/mm/aa:")
continua2="s"
lista=[]
El segundo ciclo se repite mientras haya más actividades para el mismo día:
while continua2=="s":
hora=input("Ingrese la hora de la actividad con formato hh:mm ")
actividad=input("Ingrese la descripcon de la actividad:")
lista.append((hora,actividad))
continua2=input("Ingresa otra actividad para la misma fecha[s/n]:")
Cuando se terminan de cargar todas las actividades para una determinada fecha se
procede a insertar la lista en el diccionario:
agenda[fecha]=lista
continua1=input("Ingresa otra fecha[s/n]:")
return agenda
Para imprimir todas las fechas y actividades por fecha también disponemos dos
ciclos repetitivos anidados, en este caso for in:
def imprimir(agenda):
print("Listado completa de la agenda")
for fecha in agenda:
print("Para la fecha:",fecha)
for hora,actividad in agenda[fecha]:
print(hora,actividad)
De forma similar para consultar las actividades de la agenda una determinada fecha
procedemos a ingresar la fecha y en el caso que haya una clave en el diccionario
con ese dato procedemos a recuperar la lista de actividades para dicha fecha:
def consulta_fecha(agenda):
fecha=input("Ingrese la fecha que desea consultar:")
if fecha in agenda:
for hora,actividad in agenda[fecha]:
print(hora,actividad)
else:
print("No hay actividades agendadas para dicha fecha")
# bloque principal
agenda=cargar()
imprimir(agenda)
consulta_fecha(agenda)
35.3.1 Se desea almacenar los datos de 3 alumnos. Definir un diccionario cuya clave
sea el número de documento del alumno. Como valor almacenar una lista
con componentes de tipo tupla donde almacenamos nombre de materia y su
nota.
1) Carga de los alumnos (de cada alumno solicitar su dni y los nombres de las
materias y sus notas)
2) Listado de todos los alumnos con sus notas
3) Consulta de un alumno por su dni, mostrar las materias que cursa y sus notas.
enteros
float
string
tuplas
Mutables:
listas
diccionarios
Esto tiene mucha importancia cuando enviamos a una función una variable mutable,
veremos con un ejemplo como podemos pasar como parámetro una lista a una
función y posteriormente cambiar su contenido y esto se vea reflejado en la variable
que le enviamos al llamarla.
36.1. Problema 1:
• Programa: ejercicio166.py
La primer función permite la carga de una lista de enteros hasta que el operador no
desee cargar más valores:
def cargar():
lista=[]
continua="s"
while continua=="s":
valor=int(input("Ingrese un valor:"))
lista.append(valor)
continua=input("Agrega otro elemento a la lista[s/n]:")
return lista
Lo nuevo aparece en la función fijar_cero que recibe como parámetro una lista
llamada "li" y dentro de la función modificamos los elementos de la lista, estos
cambios luego se ven reflejados en la variable definida en el bloque principal de
nuestro programa:
def fijar_cero(li):
for x in range(len(li)):
if li[x]<10:
li[x]=0
36.2. Problema 2:
• Programa: ejercicio167.py
En este problema tenemos que intercambiar los elementos de una lista y dejarlos
ordenados. La primer función para crear la lista y cargarla no presenta nada nuevo
a lo visto en problemas anteriores:
def cargar():
nombres=[]
for x in range(5):
nom=input("Ingrese nombre:")
nombres.append(nom)
return nombres
def ordenar(nombres):
for k in range(4):
for x in range(4):
if nombres[x]>nombres[x+1]:
aux=nombres[x]
nombres[x]=nombres[x+1]
nombres[x+1]=aux
# bloque principal
nombres=cargar()
ordenar(nombres)
imprimir(nombres)
36.3. Problema 3:
• Programa: ejercicio168.py
La primer función nos permite cargar los nombres de contactos con sus respectivos
teléfonos en un diccionario llamado "contactos", la función retorna este diccionario
y se almacena posteriormente en una variable global:
def cargar():
contactos={}
continua="s"
while continua=="s":
nombre=input("Ingrese el nombre del contacto:")
telefono=input("Ingrese el numero de telefono:")
contactos[nombre]=telefono
continua=input("Ingresa otro contacto[s/n]?:")
return contactos
# bloque principal
contactos=cargar()
def modificar_telefono(contactos):
nombre=input("Ingrese el nombre de contacto a modificar el telefono:")
if nombre in contactos:
telefono=input("Ingrese el nuevo numero telefonico")
contactos[nombre]=telefono
else:
print("No existe un contacto con el nombre ingresado")
# bloque principal
contactos=cargar()
modificar_telefono(contactos)
def imprimir(contactos):
print("Listado de todos los contactos")
for nombre in contactos:
print(nombre,contactos[nombre])
El lenguaje Python nos facilita una sintaxis muy sencilla par recuperar un trozo de
una lista, tupla o cadena de caracteres.
Veremos con una serie de ejemplos como podemos rescatar uno o varios elementos
de las estructuras de datos mencionadas.
• Programa: ejercicio170.py
Para recuperar una "porción" o trozo de una lista debemos indicar en el subíndice
dos valores separados por el caracter ":".
Del lado izquierdo indicamos a partir de que elementos queremos recuperar y del
lado derecho hasta cual posición sin incluir dicho valor.
lista1=[0,1,2,3,4,5,6]
lista2=lista1[2:5]
print(lista2) # 2,3,4
lista4=lista1[:3]
print(lista4) # 0,1,2
lista5=lista1[2:]
print(lista5) # 2,3,4,5,6
37.1. Problema 1:
• Programa: ejercicio171.py
def meses_faltantes(numeromes):
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembr
e','octubre','noviembre','diciembre')
return meses[numeromes:]
# bloque principal
Utilizamos el concepto de porciones que nos brinda Python para recuperar en forma
muy sencilla un trozo de una tupla. La función meses_faltantes recibe como
parámetro un entero y retorna una tupla:
def meses_faltantes(numeromes):
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembr
e','octubre','noviembre','diciembre')
return meses[numeromes:]
Ing. Álvaro Galeano Martínez 198
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
Como vemos generamos una tupla a partir del valor "numeromes" hasta el final de
la tupla:
return meses[numeromes:]
# bloque principal
Hay que tener en cuenta que el concepto de "porciones" se puede aplicar en forma
indistinta a listas, tuplas y cadenas de caracteres.
37.2. Problema 2:
Confeccionar una función que reciba una cadena de caracteres y nos devuelva los
tres primeros.
En el bloque principal del programa definir una tupla con los nombres de meses.
Mostrar por pantalla los primeros tres caracteres de cada mes.
• Programa: ejercicio172.py
def primeros_tres(cadena):
return cadena[:3];
# bloque principal
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembr
e','octubre','noviembre','diciembre')
for x in meses:
print(primeros_tres(x))
def primeros_tres(cadena):
return cadena[:3];
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembr
e','octubre','noviembre','diciembre')
for x in meses:
print(primeros_tres(x))
• Acotaciones
Hemos visto que para acceder a un elemento de una lista, tupla o cadena de
caracteres debemos indicar mediante un subíndice que comienza a numerarse a
partir de cero.
También hemos visto el concepto anterior que podemos generar otra lista, tupla o
cadena de caracteres indicando una porción con el caracter ":"
Ahora veremos que podemos utilizar un valor negativo para acceder a un elemento
de la estructura de datos.
• Programa: ejercicio175.py
print(lista1[-1]) # 6
print(lista1[-2]) # 5
38.1. Problema 1:
Confeccionar una función que reciba una palabra y verifique si es capicúa (es decir
que se lee igual de izquierda a derecha que de derecha a izquierda)
• Programa: ejercicio176.py
def capicua(cadena):
indice=-1
iguales=0
Un for que se repita tantas veces como caracteres tenga la palabra dividido 2:
for x in range(0,len(cadena)//2):
Dentro del for verificamos si el caracter del principio de lista coincide con el caracter
del fin de la lista, si es así incrementamos el contador de coincidencias:
if cadena[x]==cadena[indice]:
iguales=iguales+1
indice=indice-1
if iguales==(len(cadena)//2):
print("Es capicua")
else:
print("No es capicua")
38.2.1 Cargar una cadena de caracteres por teclado. Mostrar la cadena del final al
principio utilizando subíndices negativos.
Todos los conceptos que hemos visto hasta ahora los hemos resuelto utilizando
solo la sintaxis que nos provee Python y un conjunto de funciones básicas que se
incluyen automáticamente como por ejemplo son print, range, len etc.
En Python se incluye una biblioteca extra de funciones, variables, clases etc. que
nos facilitan la resolución de problemas en una gran diversidad de áreas como
matemáticas, estadísticas, compresión de datos, internet, interfaces visuales etc.
39.1. Problema 1:
Confeccionar un programa que simule tirar dos dados y luego muestre los valores
que salieron. Imprimir un mensaje que ganó si la suma de los mismos es igual a 7.
Para resolver este problema requerimos un algoritmo para que se genere un valor
aleatorio entre 1 y 6. Como la generación de valores aleatorios es un tema muy
frecuente la biblioteca estándar de Python incluye un módulo que nos resuelve la
generación de valores aleatorios.
• Programa: ejercicio179.py
import random
dado1=random.randint(1,6)
39.2. Problema 2:
• Programa: ejercicio180.py
def cargar():
lista=[]
for x in range(10):
lista.append(random.randint(0,1000))
return lista
El módulo random cuenta con otra función llamada shuffle que le pasamos como
parámetro una lista y nos la devuelve con los elementos mezclados (pensemos esto
nos podría servir si estamos desarrollando un juego de naipes y necesitamos
mezclarlos):
def mezclar(lista):
random.shuffle(lista)
# bloque principal
lista=cargar()
print("Lista generada aleatoriamente")
imprimir(lista)
mezclar(lista)
print("La misma lista luego de mezclar")
imprimir(lista)
import random
Con esa sintaxis todas las funcionalidades del módulo "random" pueden ser
accedidas desde nuestro módulo.
Ahora veremos que en Python tenemos otra sintaxis para las situaciones que
queremos acceder a una o pocas funcionalidades de un módulo.
Por ejemplo si queremos acceder solo a la función randint del módulo random en
Python lo podemos expresar con la siguiente sintaxis:
valor=randint(1,10)
print(valor)
40.1. Problema 1:
Para resolver este problema utilizaremos dos funcionalidades que nos provee el
módulo math de la biblioteca estándar de Python. Podemos consultar el módulo
math aquí
• Programa: ejercicio183.py
El módulo math tiene dos funciones llamadas sqrt (para obtener la raíz cuadrada) y
la función pow para elevar un valor a cierta potencia.
Utilizamos la sintaxis para importar solo dichas dos funcionalidades del módulo
math:
Una vez importadas las dos funciones podemos hacer uso de las mismas en nuestro
programa indicando directamente su nombre:
r1=sqrt(valor)
r2=pow(valor,3)
Podemos definir un nombre distinto para una funcionalidad que importamos de otro
módulo. Esto puede tener como objetivo que nuestro programa sea más legible o
evitar que un nombre de función que importamos colisione con un nombre de
función de nuestro propio módulo.
Resolveremos el mismo problema anterior pero definiendo dos alias para las
funciones sqrt y pow del módulo math.
• Programa: ejercicio184.py
Como vemos para definir un alias a una funcionalidad que importamos de un módulo
debemos disponer la palabra clave as seguida del nuevo nombre:
r1=raiz(valor)
r2=elevar(valor,3)
No hay que implementar el algoritmo para calcular el factorial sino hay que
importar dicha funcionalidad del módulo math.
El módulo math tiene una función llamada factorial que recibe como
parámetro un entero del que necesitamos que nos retorne el factorial.
A medida que una aplicación sea más grande vimos que disponer todo el algoritmo
en forma secuencial es difícil de mantener y desarrollar. Para eso vimos que
podemos resolver por partes utilizando funciones.
41.1. Problema 1:
Confeccionar una aplicación que permita cargar por teclado una lista de enteros,
obtener y mostrar el mayor y calcular su suma. Definir un módulo con las funciones
de carga, identificar el mayor y sumar. En el módulo principal del programa importar
el otro módulo y llamar a sus funciones.
Para ser un poco más ordenados crearemos una carpeta llamada proyecto1 y
dentro de la misma crearemos los dos módulos llamados:
operacioneslista.py
principal.py
El módulo operacioneslista.py contiene todas las funciones que nos permiten cargar
una lista, imprimir el mayor de una lista y sumar todos los elementos y mostrar dicho
valor.
• módulo: operacioneslista.py
• módulo: principal.py
Como podemos ver nuestro módulo principal solo tiene cuatro líneas:
import operacioneslista
lista=operacioneslista.cargar()
operacioneslista.imprimir_mayor(lista)
operacioneslista.imprimir_suma(lista)
41.2. Problema 2:
Confeccionar un módulo que implemente dos funciones, una que retorne el mayor
de dos enteros y otra que retorne el menor de dos enteros.
En el módulo principal importar solo la función que retorne el mayor, luego cargar
dos enteros y mostrar el mayor de ellos
Crear una carpeta llamada proyecto2 y dentro de la misma crear dos módulos
llamados:
mayormenor.py
principal.py
Por otro lado el programa principal que importa solo la función mayor es:
• módulo: principal.py
Un objeto es una entidad independiente con sus propios datos y programación. Las
ventanas, menúes, carpetas de archivos pueden ser identificados como objetos; el
motor de un auto también es considerado un objeto, en este caso, sus datos
(atributos) describen sus características físicas y su programación (métodos)
Por ejemplo, un objeto Auto contiene ruedas, motor, velocidad, color, etc, llamados
atributos. Encapsulados con estos datos se encuentran los métodos para arrancar,
detenerse, dobla, frenar etc.
Cuando otra parte del programa (otros objetos) necesitan que el auto realice alguna
de estas tareas (por ejemplo, arrancar) le envía un mensaje. A estos objetos que
envían mensajes no les interesa la manera en que el objeto auto lleva a cabo sus
tareas ni las estructuras de datos que maneja, por ello, están ocultos.
Entonces, un objeto contiene información pública, lo que necesitan los otros objetos
para interactuar con él e información privada, interna, lo que necesita el objeto para
operar y que es irrelevante para los otros objetos de la aplicación.
Una clase es un molde del que luego se pueden crear múltiples objetos, con
similares características.
Un poco más abajo se define una clase Persona y luego se crean dos objetos de
dicha clase.
Una clase es una plantilla (molde), que define atributos (lo que conocemos como
variables) y métodos (lo que conocemos como funciones).
La clase define los atributos y métodos comunes a los objetos de ese tipo, pero
luego, cada objeto tendrá sus propios valores y compartirán las mismas funciones.
Debemos declarar una clase antes de poder crear objetos (instancias) de esa clase.
Al crear un objeto de una clase, se dice que se crea una instancia de la clase o un
objeto propiamente dicho.
43.1. Problema 1:
Implementaremos una clase llamada Persona que tendrá como atributo (variable)
su nombre y dos métodos (funciones), uno de dichos métodos inicializará el atributo
nombre y el siguiente método mostrará en la pantalla el contenido del mismo.
Definir dos objetos de la clase Persona.
• Programa: ejercicio186.py
Los métodos de una clase se definen utilizando la misma sintaxis que para la
definición de funciones.
Como veremos todo método tiene como primer parámetro el identificador self que
tiene la referencia del objeto que llamó al método.
Luego dentro del método diferenciamos los atributos del objeto antecediendo el
identificador self:
self.nombre=nom
Decíamos que una clase es un molde que nos permite definir objetos. Ahora veamos
cual es la sintaxis para la creación de objetos de la clase Persona:
# bloque principal
persona1=Persona()
persona1.inicializar("Pedro")
persona1.imprimir()
persona2=Persona()
persona2.inicializar("Carla")
persona2.imprimir()
Luego para llamar a los métodos debemos disponer luego del nombre del objeto el
operador . y por último el nombre del método (función)
En el caso que tenga parámetros se los enviamos (salvo el primer parámetro (self)
que el mismo Python se encarga de enviar la referencia del objeto que se creó):
persona1.inicializar("Pedro")
También podemos definir tantos objetos de la clase Persona como sean necesarios
para nuestro algoritmo:
persona2=Persona()
persona2.inicializar("Carla")
persona2.imprimir()
43.2. Problema 2:
Implementar una clase llamada Alumno que tenga como atributos su nombre y su
nota. Definir los métodos para inicializar sus atributos, imprimirlos y mostrar un
mensaje si está regular (nota mayor o igual a 4)
Definir dos objetos de la clase Alumno.
• Programa: ejercicio187.py
def inicializar(self,nombre,nota):
self.nombre=nombre
self.nota=nota
No hay problema que los atributos se llamen iguales a los parámetros ya que
siempre hay que anteceder la palabra "self" al nombre del atributo:
self.nombre=nombre
Tener en cuenta que cuando se crean los atributos en el método inicializar luego
podemos acceder a los mismos en los otros métodos de la clase, por ejemplo en el
método mostrar_estado verificamos el valor almacenado en el atributo nota:
def mostrar_estado(self):
if self.nota>=4:
print("Regular")
else:
print("Libre")
Decimos que una clase es un molde que nos permite crear luego objetos de dicha
clase, en este problema el molde Alumno lo utilizamos para crear dos objetos de
dicha clase:
# bloque principal
alumno1=Alumno()
alumno1.inicializar("diego",2)
alumno1.imprimir()
alumno1.mostrar_estado()
alumno2=Alumno()
alumno2.inicializar("ana",10)
alumno2.imprimir()
alumno2.mostrar_estado()
Es fundamental la definición de objetos de una clase para que haya tenido sentido
la declaración de dicha clase.
43.3.1 Confeccionar una clase que permita carga el nombre y la edad de una
persona. Mostrar los datos cargados. Imprimir un mensaje si es mayor de
edad (edad>=18)
Las ventajas de implementar el método init en lugar del método inicializar son:
Debemos definir un método llamado init (es decir utilizamos dos caracteres de
subrayado, la palabra init y seguidamente otros dos caracteres de subrayado).
44.1. Problema 1:
• Programa: ejercicio190.py
Definimos el método init donde cargamos por teclado el nombre del empleado
y su sueldo:
empleado1=Empleado()
Los otros dos métodos tienen por objeto mostrar los datos del empleado y mostrar
una leyenda si paga impuestos o no:
def imprimir(self):
print("Nombre:",self.nombre)
print("Sueldo:",self.sueldo)
def paga_impuestos(self):
if self.sueldo>3000:
print("Debe pagar impuestos")
else:
print("No paga impuestos")
empleado1.imprimir()
empleado1.paga_impuestos()
44.2. Problema 2:
Desarrollar una clase que represente un punto en el plano y tenga los siguientes
métodos: inicializar los valores de x e y que llegan como parámetros, imprimir en
que cuadrante se encuentra dicho punto (concepto matemático, primer cuadrante si
x e y son positivas, si x<0 e y>0 segundo cuadrante, etc.)
• Programa: ejercicio191.py
En este problema el método init aparte del parámetro self que siempre va
tenemos otros dos parámetros:
Desde el bloque principal donde creamos un objeto de la clase Punto pasamos los
datos a los parámetros:
punto1=Punto(10,-2)
44.3.1 Desarrollar una clase que represente un Cuadrado y tenga los siguientes
métodos: inicializar el valor del lado llegando como parámetro al método
init (definir un atributo llamado lado), imprimir su perímetro y su
superficie.
44.3.2 Implementar la clase Operaciones. Se deben cargar dos valores enteros por
teclado en el método init , calcular su suma, resta, multiplicación y
división, cada una en un método, imprimir dichos resultados.
Hasta ahora todos los problemas planteados hemos llamado a los métodos desde
donde definimos un objeto de dicha clase, por ejemplo:
empleado1=Empleado("diego",2000)
empleado1.paga_impuestos()
Utilizamos la sintaxis:
Ahora bien que pasa si queremos llamar dentro de la clase a otro método que
pertenece a la misma clase, la sintaxis es la siguiente:
Es importante tener en cuenta que esto solo se puede hacer cuando estamos dentro
de la misma clase.
45.1. Problema 1:
Plantear una clase Operaciones que solicite en el método init la carga de dos
enteros e inmediatamente muestre su suma, resta, multiplicación y división. Hacer
cada operación en otro método de la clase Operación y llamarlos desde el mismo
método init
• Programa: ejercicio194.py
Nuestro método init además de cargar los dos enteros procede a llamar a los
métodos que calculan la suma, resta, multiplicación y división de los dos valores
ingresados.
El método que calcula la suma de los dos atributos cargados en el método init
define una variable local llamada suma y guarda la suma de los dos atributos.
Posteriormente muestra la suma por pantalla:
def sumar(self):
suma=self.valor1+self.valor2
print("La suma es",suma)
De forma similar los otros métodos calculan la resta, multiplicación y división de los
dos valores ingresados:
def sumar(self):
suma=self.valor1+self.valor2
print("La suma es",suma)
def restar(self):
resta=self.valor1-self.valor2
print("La rersta es",resta)
def multiplicar(self):
multi=self.valor1*self.valor2
print("El producto es",multi)
def dividir(self):
divi=self.valor1/self.valor2
print("La division es",divi)
# bloque principal
operacion1=Operacion()
45.2. Problema 2:
Plantear una clase que administre dos listas de 5 nombres de alumnos y sus notas.
Mostrar un menú de opciones que permita:
1- Cargar alumnos.
2- Listar alumnos.
3- Mostrar alumnos con notas mayores o iguales a 7.
4- Finalizar programa.
• Programa:
ejercicio195.py
El bloque principal del programa es muy sencillo, solo creamos un objeto de la clase
Alumno y llamamos posteriormente al método menu:
# bloque principal
alumnos=Alumnos()
alumnos.menu()
class Alumnos:
El método menu muestra una serie de opciones y solicita al operador que elija una
de ellas, según cual de ellas selecciona procede a llamar al método respectivo:
def menu(self):
opcion=0
while opcion!=4:
print("1- Cargar alumnos")
print("2- Listar alumnos")
print("3- Listado de alumnos con notas mayores o iguales a 7")
print("4- Finalizar programa")
opcion=int(input("Ingrese su opcion:"))
if opcion==1:
self.cargar()
elif opcion==2:
self.listar()
elif opcion==3:
self.notas_altas()
Algo que no utilizamos hasta ahora del lenguaje Python son una forma simplificada
de if anidados con la sentencia elif:
if opcion==1:
self.cargar()
elif opcion==2:
self.listar()
elif opcion==3:
self.notas_altas()
if opcion==1:
self.cargar()
else:
if opcion==2:
self.listar()
else:
if opcion==3:
self.notas_altas()
Pero podemos comprobar que si hay muchos if anidados la nueva sintaxis es más
clara.
def cargar(self):
for x in range(5):
nom=input("Ingrese nombre del alumno:")
self.nombres.append(nom)
no=int(input("Nota del alumno:"))
self.notas.append(no)
El método listar muestra las dos listas paralelas por completo e imprime una línea
separadora para que se vea in forma más clara:
def listar(self):
print("Listado completo de alumnos")
for x in range(5):
print(self.nombres[x],self.notas[x])
print(" ")
Finalmente el método notas_altas muestra solo los elementos de las listas cuyas
notas sean igual o superior a 7:
def notas_altas(self):
print("Alumnos con notas superiores o iguales a 7")
for x in range(5):
if self.notas[x]>=7:
print(self.nombres[x],self.notas[x])
print(" ")
45.3.1 Confeccionar una clase que administre una agenda personal. Se debe
almacenar el nombre de la persona, teléfono y mail
Debe mostrar un menú con las siguientes opciones:
46.1. Problema 1:
• Programa: ejercicio197.py
class Cliente:
self.nombre=nombre
def depositar(self,monto):
self.monto=self.monto+monto
def extraer(self,monto):
self.monto=self.monto-monto
Lo más común para que otro objeto conozca el monto depositado por un cliente es
la implementación de un método que lo retorne:
def retornar_monto(self):
return self.monto
def imprimir(self):
print(self.nombre,"tiene depositado la suma de",self.monto)
La segunda clase de nuestro problema es el Banco. Esta clase define tres atributos
de la clase Cliente (la clase Cliente colabora con la clase Banco):
class Banco:
def operar(self):
self.cliente1.depositar(100)
self.cliente2.depositar(150)
self.cliente3.depositar(200)
self.cliente3.extraer(150)
def depositos_totales(self):
total=self.cliente1.retornar_monto()+self.cliente2.retornar_monto()+self.clien
te3.retornar_monto()
print("El total de dinero del banco es:",total)
self.cliente1.imprimir()
self.cliente2.imprimir()
self.cliente3.imprimir()
# bloque principal
banco1=Banco()
banco1.operar()
banco1.depositos_totales()
46.2. Problema 2:
Plantear un programa que permita jugar a los dados. Las reglas de juego son:
se tiran tres dados si los tres salen con el mismo valor mostrar un mensaje que
"gano", sino "perdió".
• Programa: ejercicio198.py
import random
La clase Dado define un método tirar que almacena en el atributo valor un número
aleatorio comprendido entre 1 y 6:
class Dado:
def tirar(self):
self.valor=random.randint(1,6)
Los otros dos métodos de la clase Dado tienen por objetivo mostrar el valor del dado
y retornar dicho valor a otra clase que lo requiera:
def imprimir(self):
print("Valor del dado:",self.valor)
def retornar_valor(self):
return self.valor
class JuegoDeDados:
juego_dados=JuegoDeDados()
juego_dados.jugar()
Acotación
Para cortar una línea en varias líneas en Python podemos encerrar entre paréntesis
la condición:
if (self.dado1.retornar_valor()==self.dado2.retornar_valor()
and self.dado1.retornar_valor()==self.dado3.retornar_valor()):
if self.dado1.retornar_valor()==self.dado2.retornar_valor() and \
self.dado1.retornar_valor()==self.dado3.retornar_valor():
En el método init de la clase Socio pedir la carga por teclado del nombre
y su antigüedad.
Definir una responsabilidad para imprimir el nombre del socio con mayor
antigüedad en el club.
47. HERENCIA
Vimos en el concepto anterior que dos clases pueden estar relacionadas por la
colaboración. Ahora veremos otro tipo de relaciones entre clases que es la
Herencia.
Clase padre
Clase de la que desciende o deriva una clase. Las clases hijas (descendientes)
heredan (incorporan) automáticamente los atributos y métodos de la clase padre.
Subclase
Siempre hacia abajo en la jerarquía hay una especialización (las subclases añaden
nuevos atributos y métodos.
Cuando la relación entre dos clases es del tipo "...tiene un..." o "...es parte de...",
no debemos implementar herencia. Estamos frente a una relación de colaboración
de clases no de herencia.
Si tenemos una ClaseA y otra ClaseB y notamos que entre ellas existe una
relacion de tipo "... tiene un...", no debe implementarse herencia sino declarar en
la clase ClaseA un atributo de la clase ClaseB.
Por ejemplo: tenemos una clase Auto, una clase Rueda y una clase Volante.
Vemos que la relación entre ellas es: Auto "...tiene 4..." Rueda, Volante "...es parte
de..." Auto; pero la clase Auto no debe derivar de Rueda ni Volante de Auto
porque la relación no es de tipo-subtipo sino de colaboración. Debemos declarar
en la clase Auto 4 atributos de tipo Rueda y 1 de tipo Volante.
Luego si vemos que dos clase responden a la pregunta ClaseA "..es un.." ClaseB
es posible que haya una relación de herencia.
Por ejemplo:
47.1. Problema 1:
Plantear una clase Persona que contenga dos atributos: nombre y edad. Definir
como responsabilidades la carga por teclado y su impresión.
En el bloque principal del programa definir un objeto de la clase persona y llamar a
sus métodos.
Declarar una segunda clase llamada Empleado que herede de la clase Persona y
agregue un atributo sueldo y muestre si debe pagar impuestos (sueldo superior a
3000)
• Programa: ejercicio200.py
La clase Persona no tiene ninguna sintaxis nueva, como vemos definimos sus
métodos init e imprimir, y sus dos atributos nombre y edad:
class Persona:
def imprimir(self):
print("Nombre:",self.nombre)
print("Edad:",self.edad)
# bloque principal
persona1=Persona()
persona1.imprimir()
class Empleado(Persona):
Con esta sintaxis indicamos que la clase Empleado hereda de la clase Persona.
Luego de esto podemos decir que la clase Empleado ya tiene dos atributos
heredados que son el nombre y la edad, también hereda las funcionalidades
init e imprimir.
def imprimir(self):
super().imprimir()
print("Sueldo:",self.sueldo)
La tercer funcionalidad es:
def paga_impuestos(self):
if self.sueldo>3000:
print("El empleado debe pagar impuestos")
else:
print("No paga impuestos")
empleado1=Empleado()
empleado1.imprimir()
empleado1.paga_impuestos()
47.2 Problema 2:
Solamente el método operar es distinto para las clases Suma y Resta (esto hace
que no lo podamos disponer en la clase Operacion en principio), luego los métodos
cargar1, cargar2 y mostrar_resultado son idénticos a las dos clases, esto hace que
podamos disponerlos en la clase Operacion. Lo mismo los atributos valor1, valor2 y
resultado se definirán en la clase padre Operacion.
• Programa: ejercicio201.py
class Operacion:
def cargar1(self):
self.valor1=int(input("Ingrese primer valor:"))
def cargar2(self):
self.valor2=int(input("Ingrese segundo valor:"))
def mostrar_resultado(self):
print(self.resultado)
Como la clase Operación se trata de una clase genérica que busca agrupar
funcionalidades y atributos para otras clases podemos definir un método operar pero
no podemos implementar ninguna funcionalidad:
def operar(self):
pass
En Python para indicar que un método está vacío se utiliza la palabra clave "pass".
En el bloque principal de nuestro programa no creamos objetos de la clase
Operación. La clase Operación tiene sentido que otras clases hereden de esta.
Tanto la clase Suma y Resta heredan de la clase Operación y reescriben el método
operar con la funcionalidad que le corresponde a cada clase:
class Suma(Operacion):
def operar(self):
self.resultado=self.valor1+self.valor2
class Resta(Operacion):
def operar(self):
self.resultado=self.valor1-self.valor2
# bloque princpipal
suma1=Suma()
suma1.cargar1()
suma1.cargar2()
suma1.operar()
print("La suma de los dos valores es")
suma1.mostrar_resultado()
resta1=Resta()
resta1.cargar1()
resta1.cargar2()
resta1.operar()
print("La resta de los valores es:")
resta1.mostrar_resultado()
47.3.1 Declarar una clase Cuenta y dos subclases CajaAhorra y PlazoFijo. Definir
los atributos y métodos comunes entre una caja de ahorro y un plazo fijo y
agruparlos en la clase Cuenta.
Hemos visto como definimos atributos en una clase anteponiendo la palabra clave
self:
Los atributos son independientes por cada objeto o instancia de la clase, es decir si
definimos tres objetos de la clase Persona, todas las personas tienen un atributo
nombre pero cada uno tiene un valor independiente:
Para definir una variable de clase lo hacemos dentro de la clase pero fuera de sus
métodos:
48.1 Problema 1:
• Programa: ejercicio203.py
La clase Cliente define una variable de clase llamada suspendidos que es de tipo
lista y por ser variable de clase es compartida por todos los objetos que definamos
de dicha clase:
class Cliente:
suspendidos=[]
def imprimir(self):
print("Codigo:",self.codigo)
print("Nombre:",self.nombre)
self.esta_suspendido()
def suspender(self):
Cliente.suspendidos.append(self.codigo)
def esta_suspendido(self):
if self.codigo in Cliente.suspendidos:
print("Esta suspendido")
else:
print("No esta suspendido")
print(" ")
Para probar esta clase en el bloque principal creamos cuatro objetos de la clase
Cliente:
# bloque principal
cliente1=Cliente(1,"Juan")
cliente2=Cliente(2,"Ana")
cliente3=Cliente(3,"Diego")
cliente4=Cliente(4,"Pedro")
Suspendemos dos clientes:
cliente3.suspender()
cliente4.suspender()
Y luego imprimimos los datos de cada cliente:
cliente1.imprimir()
cliente2.imprimir()
cliente3.imprimir()
cliente4.imprimir()
print(Cliente.suspendidos)
Es importante remarcar que todos los objetos acceden a una única lista llamada
suspendidos gracias a que se definió como variable de clase.
Podemos hacer que se ejecute un método definido por nosotros cuando pasamos
un objeto a la función print o cuando llamamos a la función str (convertir a string)
Python nos permite redefinir el método que se debe ejecutar. Esto se hace
definiendo en la clase el método especial str
Esta característica definida en Python nos permite crear programas muy legibles y
flexibles.
class Persona:
# bloque principal
persona1=Persona("Jose","Rodriguez")
persona2=Persona("Ana","Martinez")
print(str(persona1)+"-"+str(persona2)) # Jose,Rodriguez-Ana,Martinez
49.1. Problema 1:
• Programa: ejercicio205.py
class Punto:
# bloque principal
punto1=Punto(10,3)
punto2=Punto(3,4)
print(punto1)
print(punto2)
Hay que tener en cuenta que cuando pasamos a la función print el objeto punto1 en
ese momento se llama el método especial str que tiene por objetivo retornar un
string que nos haga más legible lo que representa dicho objeto.
49.2. Problema 2:
Declarar una clase llamada Familia. Definir como atributos el nombre del padre,
madre y una lista con los nombres de los hijos.
Definir el método especial str que retorne un string con el nombre del padre, la
madre y de todos sus hijos.
• Programa: ejercicio206.py
class Familia:
El método especial str genera un string con los nombres del padre, madre y
todos los hijos:
# bloque principal
familia1=Familia("Pablo","Ana",["Pepe","Julio"])
familia2=Familia("Jorge","Carla")
familia3=Familia("Luis","Maria",["marcos"])
print(familia1)
print(familia2)
print(familia3)
Python nos permite redefinir los operadores matemáticos cuando planteamos una
clase.
Para el operador +:
add (self,objeto2)
Para el operador -:
sub (self,objeto2)
Para el operador *:
mul (self,objeto2)
Para el operador /:
truediv (self,objeto2)
50.1. Problema 1:
• Programa:
ejercicio208.py
El objeto que llega corresponde al que se encuentra luego del operador +, es decir
clie2:
print(cli1+cli2)
Debemos redefinir los operadores +,-,*,/ etc. solo para las clases que con solo leer
su nombre el programador intuya que operación implementaría dicho operador.
50.2. Problema 2:
Desarrollar una clase llamada Lista, que permita pasar al método init una lista
de valores enteros.
• Programa: ejercicio209.py
class Lista:
Cuando sumamos a la lista un entero llega como parámetro el entero. Dentro del
método generamos una nueva lista y la retornamos:
51.1. Problema 1:
Crear una clase Persona que tenga como atributo el nombre y la edad.
El operador == retornará verdadero si las dos personas tienen la misma edad, el
operador > retornará True si la edad del objeto de la izquierda tiene una edad mayor
a la edad del objeto de la derecha del operador >, y así sucesivamente
• Programa: ejercicio210.py
def eq (self,objeto2):
if self.edad==objeto2.edad:
return True
else:
return False
El método recibe como referencia (self) que es la dirección del objeto ubicado a la
izquierda del operador relacionar y como parámetro (objeto2) la referencia del objeto
ubicado a la derecha del operador. Solo nos queda analizar el atributo edad de cada
objeto y retornar True si los dos almacenan el mismo valor, en caso contrario
retornamos False.
51.2. Problema 2:
• Programa: ejercicio211.py
def eq (self,objeto2):
if self.retornar_superficie()==objeto2.retornar_superficie():
return True
else:
return False
2. PyDev IDE: Este entorno de desarrollo es una adaptación del editor Eclipse.
Lo podemos descargar del sitio de: pydev
En el último año se esta convirtiendo en el editor de texto más utilizado por los
programadores profesionales de todo el mundo.
Otro dato que nos puede hacer dimensionar el empleo de Visual Studio Code para
programar con Python es la cantidad de descargas de la extensión:
Una vez descargado procedemos a instalarlo siguiendo los pasos del asistente:
El tema o aspecto visual por defecto es el oscuro, pero para que se vea más fácil
en este tutorial lo cambiaremos por un aspecto más claro.
Como vemos en el fondo del editor aparecen los 5 comandos más comunes que
tenemos que hacer normalmente cuando trabajamos con el editor de texto VSCode
como puede ser "Abrir archivo" con el atajo de teclas Ctrl + O.
Cuando seleccionamos una extensión se nos muestra una pestaña con toda la
información de dicha extensión:
Ya tenemos todo listo para probar nuestro primer programa en Python utilizando el
editor VS Code, procedemos a crear un archivo 'ejercicio212.py' y codificar:
• Programa: ejercicio211.py
Acotaciones
Hemos visto en forma resumida los pasos para la instalación del editor VS Code y
de la extensión para trabajar con Python. Le sugiero que luego se tome su tiempo
para conocer en forma más profunda el editor VS Code mediante el tutorial VS Code
Ya
Abriremos algún programa que hemos desarrollado para ver como podemos
depurarlo.
• Programa: ejercicio069.js
Disponiendo la flecha del mouse sobre el nombre de una variable (por ejemplo
'suma') se nos muestra su contenido:
Con esta mecánica podemos identificar errores lógicos que tenga nuestro algoritmo.
Pip es un programa que viene con Python y nos permite instalar paquetes de
terceros con el objetivo de valernos de librerías de código desarrolladas por la
comunidad de Python.
El sitio que podemos visitar para conocer que paquetes están disponibles se
llama pypi.org . En este momento hay más de 191000 paquetes disponibles sobre
temas tan diversos como:
Como podemos ver existen paquetes en Python que nos pueden facilitar el
desarrollo de programas en una diversidad de temas muy amplio.
Para poder descargar un paquete del repositorio pypi.org debemos conocer solo el
nombre del paquete.
Instalación de un paquete
Codificaremos un programa mínimo que muestre una ventana con el mensaje "Hola
Mundo" empleando el paquete wxPython:
• Programa: ejercicio213.py
55.1. Problema:
• Programa: ejercicio214.py
La ejecución de este programa nos muestra una ventana con un botón en su interior:
Conclusión
• Si queremos conocer todos los archivos que tiene un paquete que hayamos
instalado lo hacemos mediante la sintaxis:
Esto nos muestra una lista completa de archivos que contiene el paquete:
Para conocer todos los paquetes instalados en nuestro entorno de Python debemos
utilizar el comando 'list':
pip list
Como podemos ver en el listado de paquetes además del paquete que instalamos
en el concepto anterior hay otros que vienen por defecto cuando instalamos Python.
Los desarrolladores de paquetes para Python están constantemente actualizando
sus funcionalidades y sacan nuevas versiones. Si queremos saber si alguno de
nuestros paquetes está desactualizado podemos ejecutar el comando list pasando
el parámetro --outdated (se nos muestran todos los paquetes desactualizados):
Si por alguna razón queremos instalar una versión más vieja de un paquete
debemos indicar en el comando 'install' la versión del mismo:
Para profundizar y tener todas las actualizaciones del programa 'pip' debemos visitar
la guía de referencia oficial.
La interfaz gráfica de usuario, conocida también como GUI (graphical user interface)
son fundamentales cuando queremos implementar programas para usuarios finales
que faciliten la entrada y salida de datos.
Vimos en el concepto anterior que Python puede hacer uso de la GUI wxPython
mediante la instalación del paquete respectivo. Python por defecto instala el módulo
'tkinter' para la implementación de interfaces visuales. El editor IDLE que viene con
Python está desarrollado utilizando este módulo.
57.1. Problema:
• Programa: ejercicio215.py
import tkinter as tk
ventana1=tk.Tk()
ventana1.title("Hola Mundo")
Para que se muestre la ventana en el monitor debemos llamar por último al método
'mainloop' que pertenece a la clase Tk:
ventana1.mainloop()
Acotaciones
Si utilizamos el editor VSCode en lugar del editor IDLE podemos tener grandes
ventajas cuando codificamos el programa. Por ejemplo luego de escribir el nombre
del objeto podemos ver que gracias a 'IntelliSense' se nos muestran todos sus
métodos y una descripción del mismo:
• Programa: ejercicio215.py
Planteamos una clase llamada 'Aplicacion' y en su método ' init ' creamos el
objeto de la clase 'Tk' para que se muestre la ventana.
Debemos crear luego un objeto de la clase 'Aplicacion':
aplicacion1=Aplicacion()
En las interfaces visuales las ventanas son controles visuales contenedores de otros
controles como los botones y etiquetas de texto.
Veremos los pasos que debemos dar si queremos que se muestren objetos de la
clase Button y Label en nuestras ventanas.
58.1. Problema:
Mostrar una ventana y en su interior dos botones y una label. La label muestra
inicialmente el valor 1. Cada uno de los botones permiten incrementar o
decrementar en uno el contenido de la label
• Programa: ejercicio216.py
self.valor=1
self.ventana1=tk.Tk()
self.ventana1.title("Controles Button y Label")
self.label1=tk.Label(self.ventana1, text=self.valor)
Para ubicar los controles visuales en la ventana veremos más adelante que hay
diferentes Layout, por ahora en forma muy sencilla mediante la llamada al método
grid indicaremos en los parámetros column y row la ubicación del mismo:
self.label1.grid(column=0, row=0)
Para que el texto de la Label se muestre de color rojo llamamos al método configure
y le pasamos en el parámetro foreground el string "red":
self.label1.configure(foreground="red")
self.boton1=tk.Button(self.ventana1, text="Incrementar",
command=self.incrementar)
self.boton1.grid(column=0, row=1)
self.boton2=tk.Button(self.ventana1, text="Decrementar",
command=self.decrementar)
self.boton2.grid(column=0, row=2)
Para que los botones se encuentren abajo de la Label al llamar al método grid
pasamos en el parámetro row los valores 1 y 2. Como todos los controles se
encuentran en la misma columna pasamos en column el valor 0.
No olvidar a llamar al final del método init al método mainloop():
self.ventana1.mainloop()
def incrementar(self):
self.valor=self.valor+1
self.label1.config(text=self.valor)
def decrementar(self):
self.valor=self.valor-1
self.label1.config(text=self.valor)
aplicacion1=Aplicacion()
Acotaciones
self.label1.config(text=self.valor)
O mediante la sintaxis:
self.label1["text"]=self.valor
58.2. Problema:
• Programa: ejercicio217.py
import sys
58.3.1 Disponer dos objetos de la clase Button con las etiquetas: "varón" y "mujer",
al presionarse mostrar en la barra de títulos de la ventana la etiqueta del
botón presionado.
58.3.2 Mostrar los botones del 1 al 5. Cuando se presiona mostrar en una Label
todos los botones presionados hasta ese momento.
Hemos visto hasta ahora los controles Button y Label, ahora veremos otro control
visual indispensable para hacer la entrada de datos por teclado.
En tkinter el control de entrada de datos por teclado se llama Entry. Con este control
aparece el típico recuadro que cuando se le da foco aparece el cursor en forma
intermitente esperando que el operador escriba algo por teclado.
59.1. Problema:
• Programa: ejercicio220.py
self.dato=tk.StringVar()
self.entry1=tk.Entry(self.ventana1, widt=10, textvariable=self.dato)
self.entry1.grid(column=0, row=1)
Cuando trabajamos con la clase Entry debemos también crear un objeto de la clase
StringVar y pasar dicho objeto al parámetro textvariable cuando se crea el objeto de
la clase Entry.
La clase StringVar al igual que la clase Entry están declaradas en el módulo tkinter.
def calcularcuadrado(self):
valor=int(self.dato.get())
cuadrado=valor*valor
self.label2.configure(text=cuadrado)
59.2. Problema:
• Programa: ejercicio221.py
Para que el botón aparezca debajo del control Entry debemos fijar el parámetro
'column' con el valor 1:
self.boton1.grid(column=1, row=1)
Debemos pensar nuestra pantalla como una cuadrícula donde definimos la fila y
columna para cada control:
self.label1.grid(column=0, row=0)
self.entry1.grid(column=1, row=0)
self.boton1.grid(column=1, row=1)
def ingresar(self):
self.ventana1.title(self.dato.get())
60.1. Problema:
Mostrar dos controles de tipo Radiobutton con las etiquetas "Varón" y "Mujer",
cuando se presione un botón actualizar una Label con el Radiobutton seleccionado.
• Programa: ejercicio224.py
self.radio1=tk.Radiobutton(self.ventana1,text="Varon",
variable=self.seleccion, value=1)
self.radio1.grid(column=0, row=0)
self.radio2=tk.Radiobutton(self.ventana1,text="Mujer", variable=self.seleccion,
value=2)
self.radio2.grid(column=0, row=1)
self.seleccion=tk.IntVar()
self.seleccion.set(2)
def mostrarseleccionado(self):
if self.seleccion.get()==1:
self.label1.configure(text="opcion seleccionada=Varon")
if self.seleccion.get()==2:
self.label1.configure(text="opcion seleccionada=Mujer")
60.2. Problema:
Disponer dos controles de tipo Entry para el ingreso de enteros. Mediante dos
controles Radiobutton permitir seleccionar si queremos sumarlos o restarlos. Al
presionar un botón mostrar el resultado de la operación seleccionada.
• Programa: ejercicio225.py
def operar(self):
if self.seleccion.get()==1:
suma=int(self.dato1.get())+int(self.dato2.get())
self.label3.configure(text=suma)
if self.seleccion.get()==2:
resta=int(self.dato1.get())-int(self.dato2.get())
self.label3.configure(text=resta)
60.3.1 Disponer tres controles de tipo Radiobutton con las etiquetas 'Rojo', 'Verde'
y 'Azul'. Cuando se presione un botón cambiar el color de fondo del
formulario.
self.ventana1.configure(bg="red")
61.1. Problema:
• Programa: ejercicio227.py
self.seleccion1=tk.IntVar()
self.check1=tk.Checkbutton(self.ventana1,text="Python",
variable=self.seleccion1)
self.check1.grid(column=0, row=0)
def verificar(self):
cant=0
if self.seleccion1.get()==1:
cant+=1
if self.seleccion2.get()==1:
cant+=1
if self.seleccion3.get()==1:
cant+=1
self.label1.configure(text="cantidad:"+str(cant))
61.2. Problema:
• Programa: ejercicio228.py
def cambiarestado(self):
if self.seleccion.get()==1:
self.boton1.configure(state="normal")
if self.seleccion.get()==0:
self.boton1.configure(state="disabled")
El control visual Listbox se emplea para mostrar una lista de items. El usuario puede
seleccionar uno o más elementos de la lista según como se lo configure al crearlo.
62.1. Problema:
Disponer un Listbox con una serie de nombres de frutas. Permitir la selección solo
de uno de ellos. Cuando se presione un botón recuperar la fruta seleccionada y
mostrarla en una Label.
• Programa: ejercicio230.py
self.listbox1=tk.Listbox(self.ventana1)
self.listbox1.insert(0,"papa")
self.listbox1.insert(1,"manzana")
self.listbox1.insert(2,"pera")
self.listbox1.insert(3,"sandia")
self.listbox1.insert(4,"naranja")
self.listbox1.insert(5,"melon")
def recuperar(self):
if len(self.listbox1.curselection())!=0:
self.label1.configure(text=self.listbox1.get(self.listbox1.curselection()[0]))
El método curselection retorna una tupla con todas las posiciones seleccionadas del
Listbox. Como se trata de un Listbox que permite la selección de un único item luego
por eso accedemos al item de la tupla de la posición 0.
62.2. Problema:
• Programa: ejercicio231.py
self.listbox1=tk.Listbox(self.ventana1, selectmode=tk.MULTIPLE)
Para mostrar todas las frutas seleccionadas ahora debemos disponer un for para
recorrer la tupla que retorna el método curselection y concatenarlas:
def recuperar(self):
if len(self.listbox1.curselection())!=0:
todas=''
for posicion in self.listbox1.curselection():
todas+=self.listbox1.get(posicion)+"\n"
self.label1.configure(text=todas)
Barra de scroll
Por defecto no aparece una barra de scroll si la cantidad de item supera el tamaño
del cuadro del Listbox. Para que se muestre una barra de scroll la debemos crear y
enlazar con el Listbox.
• Programa: ejercicio232.py
self.listbox1=tk.Listbox(self.ventana1, selectmode=tk.MULTIPLE,
yscrollcommand=self.scroll1.set)
self.scroll1.configure(command=self.listbox1.yview)
Tk hemos dicho que es una biblioteca de controles visuales que los podemos
acceder desde Python y desde otros lenguajes de programación.
Para hacer uso de este conjunto de Widget (controles visuales) debemos importar
el paquete ttk.
Todo lo que conocemos hasta ahora de los controles visuales del módulo tkinter
funciona prácticamente sin cambios, lo que deberemos hacer es crear objetos de la
clase Button, Entry etc. recuperándolos ahora del módulo tkinter.ttk
Veamos algunos de los ejemplos ya resueltos pero haciendo uso de los Widget de
este nuevo módulo.
63.1. Problema:
Mostrar una ventana y en su interior dos botones y una label utilizando el módulo
ttk. La label muestra inicialmente el valor 1. Cada uno de los botones permiten
incrementar o decrementar en uno el contenido de la label
• Programa: ejercicio234.py
Como los tres controles (Label y Button) son de este nuevo módulo podemos ver
que su representación visual es distinta:
Si bien los cambios visuales que aparecen en la clase Button no son significativos
el módulo tkinter.ttk trae nuevas funcionalidades, nuevos controles y permite que
Analicemos que cambios debemos disponer a nuestra aplicación para utilizar las
componentes Button y Label del módulo tkinter.ttk.
import tkinter as tk
self.ventana1=tk.Tk()
El segundo y último cambio es que cada vez que debemos crear un control visual
lo referenciamos del nuevo módulo ttk:
self.label1=ttk.Label(self.ventana1, text=self.valor)
...
self.boton1=ttk.Button(self.ventana1, text="Incrementar",
command=self.incrementar)
...
self.boton2=ttk.Button(self.ventana1, text="Decrementar",
command=self.decrementar)
self.label1=tk.Label(self.ventana1, text=self.valor)
63.2. Problema:
• Programa: ejercicio235.py
self.dato1=tk.StringVar()
63.3. Problema:
Mostrar dos controles de tipo Radiobutton con las etiquetas "Varón" y "Mujer",
cuando se presione un botón actualizar una Label con el Radiobutton seleccionado.
• Programa: ejercicio236.py
63.4. Problema:
• Programa: ejercicio237.py
Acotaciones
63.5. Problema:
Disponer un Listbox con una serie de nombres de frutas. Permitir la selección solo
de uno de ellos. Cuando se presione un botón recuperar la fruta seleccionada y
mostrarla en una Label.
• Programa: ejercicio238.py
Notemos que la clase Listbox la recuperamos del módulo tkinter a través de su alias
tk:
self.listbox1=tk.Listbox(self.ventana1)
Si tratamos de recuperarla del otro módulo se nos informará que no existe mediante
un mensaje de error:
Podemos indicar cual elemento muestre por defecto mediante el método 'current'.
Por defecto el operador puede además de seleccionar un elemento cargar por
teclado cualquier cadena.
64.1. Problema:
Mostrar en una ventana un control de tipo Combobox con los días de la semana.
Cuando se presione un botón actualizar una Label con el día seleccionado.
• Programa: ejercicio239.py
self.opcion=tk.StringVar()
diassemana=("lunes","martes","miércoles","jueves","viernes","sábado","domingo")
self.combobox1=ttk.Combobox(self.ventana1,
width=10,
textvariable=self.opcion,
values=diassemana)
self.combobox1.current(0)
self.combobox1.grid(column=0, row=1)
Debemos pasar en el parámetro values una tupla con los elementos que debe
mostrar el control Combobox. Asociamos al parámetro textvariable un objeto de la
clase StringVar para poder posteriormente recuperar el valor seleccionado.
Mediante el método current podemos indicar cual de los elementos debe aparecer
seleccionado.
self.combobox1=ttk.Combobox(self.ventana1,
width=10,
textvariable=self.opcion,
values=diassemana,
state='readonly')
Para implementar los típicos menú de barra horizontales que aparecen en las
aplicaciones cuando utilizamos la librería Tk necesitamos crear objetos de la clase
Menu que se encuentra declarada en el paquete tkinter y no en el paquete tkinter.ttk.
Veremos con un ejemplo implementar un menú con una serie de opciones.
65.1. Problema:
• Programa: ejercicio241.py
import tkinter as tk
self.ventana1=tk.Tk()
menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1)
opciones1.add_command(label="Rojo", command=self.fijarrojo)
opciones1.add_command(label="Verde", command=self.fijarverde)
opciones1.add_command(label="Azul", command=self.fijarazul)
menubar1.add_cascade(label="Colores", menu=opciones1)
opciones2 = tk.Menu(menubar1)
opciones2.add_command(label="640x480", command=self.ventanachica)
opciones2.add_command(label="1024x800", command=self.ventanagrande)
menubar1.add_cascade(label="Tamaños", menu=opciones2)
Variantes en un menú.
Los menú desplegables muestran una línea de puntos antes de la primer opción. Si
el operador hace clic sobre la misma el menú desplegable se muestra en una barra
de herramientas fuera de la ventana principal (puede tener sentido si en un
programa debemos seleccionar opciones en forma muy seguida y no queremos
tener que estar abriendo el menú desplegable):
Podemos disponer dentro de un menú desplegable una opción que despliegue otro
submenú, la interfaz visual debe ser similar a esta:
65.2.1 Mediante dos controles de tipo Entry permitir el ingreso de dos números.
Crear un menú que contenga una opción que cambie el tamaño de la ventana
con los valores ingresados por teclado. Finalmente disponer otra opción que
finalice el programa
La clase Notebook nos permite crear un cuaderno con una serie de pestañas en la
parte superior. En cada pestaña asociamos un objeto de la clase Frame y dentro de
esta podemos disponer distintos controles visuales que hemos visto hasta ahora
como pueden ser Label, Button, Radiobutton, Checkbutton, Entry etc.
66.1. Problema:
Confeccionar una aplicación que muestre un cuaderno con tres pestañas. Los títulos
de cada pestaña deben ser 'Button', 'Label' y 'Entry'. Según la pestaña seleccionada
mostrar un mensaje informando el objetivo de la clase y un ejemplo de la misma.
• Programa: ejercicio243.py
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.pagina1 = ttk.Frame(self.cuaderno1)
Lo mismo sucede con los dos botones que se agregan a 'pagina1', esto hace que
solo sean visibles cuando la primer pestaña esté seleccionada:
67.1. Problema:
• Programa: ejercicio244.py
self.ventana1=tk.Tk()
self.labelframe1=ttk.LabelFrame(self.ventana1, text="Login:")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.login()
El algoritmo del método login tiene por objetivo crear las 2 Label, 2 Entry y Button
y añadirlos dentro del LabelFrame:
def login(self):
self.label1=ttk.Label(self.labelframe1, text="Nombre de usuario:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.entry1=ttk.Entry(self.labelframe1)
self.entry1.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, text="Ingrese clave:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.entry2=ttk.Entry(self.labelframe1, show="*")
self.entry2.grid(column=1, row=1, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe1, text="Ingresar")
self.boton1.grid(column=1, row=2, padx=4, pady=4)
Para que los controles no aparezcan pegados unos con otros utilizamos los
parámetros padx y pady.
self.labelframe2=ttk.LabelFrame(self.ventana1, text="Operaciones")
self.labelframe2.grid(column=0, row=1, padx=5, pady=10)
self.operaciones()
def operaciones(self):
self.boton2=ttk.Button(self.labelframe2, text="Agregar usuario")
self.boton2.grid(column=0, row=0, padx=4, pady=4)
self.boton3=ttk.Button(self.labelframe2, text="Modificar usuario")
self.boton3.grid(column=1, row=0, padx=4, pady=4)
self.boton4=ttk.Button(self.labelframe2, text="Borrar usuario")
self.boton4.grid(column=2, row=0, padx=4, pady=4)
El empleo de los LabelFrame nos permite crear interfaces visuales más claras
para los operadores de nuestro programa.
Esta nueva representación visual se obtiene solo cambiando dos números de fila:
1. Grid
2. Pack
3. Place
68.1. Problema:
• Programa: ejercicio246.py
• tk.TOP
• tk.LEFT
• tk.RIGHT
• tk.BOTTOM
Podemos pasar los parámetros padx y pady para dejar espacio entre los controles
visuales y el borde del contenedor:
Este tipo de Layout define una tabla con columnas y filas, cada vez que agregamos
un Widget indicamos en que columna y fila se debe ubicar:
Un tema que no vimos es que podemos expandir celdas de la tabla para que se
ocupen más de una columna o más de una fila.
68.2. Problema:
• Programa: ejercicio247.py
Los dos primeros botones como ocupan una celda única no varía con lo que hemos
visto hasta ahora:
Este tipo de Layout Manager nos permite disponer un Widget en una posición y con
un tamaño con valor absoluto a nivel de píxeles. Hay que tener cuidado en que
casos utilizar este tipo de administrador de diseños ya que si agrandamos o
reducimos el tamaño de la ventana puede ser que los controles queden fuera de la
ventana y el operador no pueda visualizarlos.
68.3. Problema:
• Programa: ejercicio248.py
self.ventana1.geometry("800x600")
self.ventana1.resizable(0,0)
self.boton1=ttk.Button(self.ventana1, text="Confirmar")
self.boton1.place(x=680, y=550, width=90, height=30)
La ubicación del segundo botón queda con los siguientes valores:
self.boton2=ttk.Button(self.ventana1, text="Cancelar")
self.boton2.place(x=580, y=550, width=90, height=30)
Podemos utilizar el método 'place' para ubicar cualquiera de los controles visuales
que hemos visto hasta ahora: Button, Label, Entry, etc.
Recomendación
Siempre que tenga que implementar una interfaz gráfica es conveniente que en un
papel se haga un croquis y a partir de este agrupar controles relacionados dentro
de Frame o LabelFrame.
Para usar estos diálogos lo primero que debemos hacer es importar el paquete:
Podemos crear un alias para el nombre del paquete para no tener que escribir
messagebox todas las veces.
69.1. Problema:
Confeccionar una aplicación que permita ingresar dos valores enteros y al presionar
un botón nos muestre la suma en el título de la ventana. Si el operador no ingresa
en alguno de los dos controles Entry datos informar mediante un diálogo el error
que se está cometiendo.
• Programa: ejercicio249.py
def agregar_componentes(self):
self.label1=ttk.Label(self.labelframe1, text="Ingrese primer valor:")
self.label1.grid(column=0, row=0, padx=5, pady=5, sticky="e")
self.dato1=tk.StringVar()
self.entry1=ttk.Entry(self.labelframe1, textvariable=self.dato1)
self.entry1.grid(column=1, row=0, padx=5, pady=5)
self.label2=ttk.Label(self.labelframe1, text="Ingrese segundo valor:")
self.label2.grid(column=0, row=1, padx=5, pady=5, sticky="e")
self.dato2=tk.StringVar()
self.entry2=ttk.Entry(self.labelframe1, textvariable=self.dato2)
self.entry2.grid(column=1, row=1, padx=5, pady=5)
self.boton1=ttk.Button(self.labelframe1, text="Sumar", command=self.sumar)
self.boton1.grid(column=1, row=2, padx=5, pady=5, sticky="we")
def agregar_menu(self):
self.menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=self.menubar1)
self.opciones1 = tk.Menu(self.menubar1, tearoff=0)
self.opciones1.add_command(label="Acerca de...", command=self.acerca)
self.menubar1.add_cascade(label="Opciones", menu=self.opciones1)
def sumar(self):
if self.dato1.get()=="" or self.dato2.get()=="":
mb.showerror("Cuidado","No puede dejar los cuadros de entrada de
números vacíos")
else:
suma=int(self.dato1.get())+int(self.dato2.get())
self.ventana1.title("La suma es "+str(suma))
Esta función tiene dos parámetros, el primero es el mensaje del título y el segundo
el cuerpo propiamente del mensaje.
Por otro lado cuando se selecciona la opción del menú "Acerca de..." se ejecuta el
método acerca:
def acerca(self):
mb.showinfo("Información", "Este programa fue desarrollado para el
aprendizaje de Python y tkinter.")
Existe otra función similar en este módulo llamado 'showwarning' (dispone otro
ícono en el diálogo):
El paquete 'messagebox' cuenta con otra función que nos muestra un diálogo con
dos botones con los mensajes "Si" o "No", luego desde nuestro programa podemos
identificar cual de los dos botones se ha presionado.
69.2. Problema:
• Programa: ejercicio250.py
self.opciones1.add_command(label="Salir", command=self.salir)
def salir(self):
respuesta=mb.askyesno("Cuidado", "¿Quiere salir del programa?")
if respuesta==True:
sys.exit()
Vimos en el concepto anterior que tkinter nos provee una serie de diálogos para
mostrar mensajes de información y error. En muchas situaciones podemos necesitar
crear otras ventanas con más funcionalidades que los simples ventanas de
mensajes.
Para crear diálogos en tkinter debemos crear un objeto de la clase TopLevel y pasar
como parámetro la referencia de la ventana principal.
Un diálogo se asemeja mucho a lo que es la ventana principal, podemos disponer
dentro de la misma objetos de la clase Label, Button, Entry etc.
Lo más común es que un diálogo tenga por objetivo la entrada de datos para luego
ser utilizados en la ventana principal.
70.1. Problema:
Confeccionar una aplicación que muestre un diálogo cuando se seleccione una
opción de un menú.
• Programa: ejercicio251.py
Para resolver este problema hemos declarado dos clases, la primer que muestra la
ventana principal:
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.agregar_menu()
self.ventana1.mainloop()
Separamos la creación del menú en otro método:
def agregar_menu(self):
self.menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=self.menubar1)
self.opciones1 = tk.Menu(self.menubar1, tearoff=0)
self.opciones1.add_command(label="Configurar ventana",
command=self.configurar)
self.menubar1.add_cascade(label="Opciones", menu=self.opciones1)
def configurar(self):
dialogo1 = DialogoTamano(self.ventana1)
s=dialogo1.mostrar()
Una vez que el operador cierra el diálogo el método 'mostrar' retorna una tupla con
los dos valores ingresados por teclado, estos los usamos para dimensionar la
ventana principal:
self.ventana1.geometry(s[0]+"x"+s[1])
Ahora analicemos la clase DialogoTamano, en el método init recibimos como
parámetro la referencia de la ventana principal:
class DialogoTamano:
self.dialogo=tk.Toplevel(ventanaprincipal)
self.dialogo.protocol("WM_DELETE_WINDOW", self.confirmar)
Es común no permitir el cambio de tamaño del diálogo con las flechas del mouse:
self.dialogo.resizable(0,0)
self.dialogo.grab_set()
def mostrar(self):
self.dialogo.wait_window()
return (self.dato1.get(), self.dato2.get())
Finalmente el método 'confirmar' cierra el diálogo y permite que finalice el método
'mostrar' retornando los dos enteros:
def confirmar(self):
self.dialogo.destroy()
Este control visual es muy utilizado para seleccionar un valor de una lista. Se
dispone de dos botones para subir o bajar en la lista de valores posibles:
71.1. Problema:
En una aduana hay una máquina que sortea las personas cuyo equipaje serán
revisados.
Luego se presiona el botón sortear y aparece al lado de este botón una Label de
color rojo o verde (En caso de ser rojo se revisa su equipaje, en caso de ser verde,
no se revisa)
• Programa: ejercicio252.py
self.spinbox1.set(0)
def sortear(self):
if int(self.spinbox1.get())==0:
mb.showerror("Cuidado","Debe seleccionar un valor distinto a cero en
bultos")
valor=random.randint(1,3)
if valor==1:
self.label2.configure(text="Se deben revisar")
self.label2.configure(background="red")
else:
self.label2.configure(text="No se revisan")
self.label2.configure(background="green")
Acotaciones
Hemos visto anteriormente el control Entry que nos permite ingresar una cadena de
caracteres por teclado. El Widget ScrolledText es similar al Widget Entry con la
salvedad que nos permite ingresar múltiples líneas.
Cuenta con métodos sofisticados para extraer trozos del texto ingresado en la
componente.
Para poder utilizar esta nueva componente debemos importar el módulo scrolledtext
del paquete tkinter (podemos crear un alias para no tener que escribir scrolledtext):
72.1. Problema:
• Programa: ejercicio253.py
def copiar(self):
iniciofila=self.dato1.get()
iniciocolumna=self.dato2.get()
finfila=self.dato3.get()
fincolumna=self.dato4.get()
datos=self.scrolledtext1.get(iniciofila+"."+iniciocolumna, finfila+"."+fincolumna)
self.scrolledtext2.delete("1.0", tk.END)
self.scrolledtext2.insert("1.0", datos)
En nuestro problema estos cuatro números los estamos cargando por teclado en
los controles Entry.
self.scrolledtext2.delete("1.0", tk.END)
self.scrolledtext2.insert("1.0", datos)
El control Canvas nos permite acceder a una serie de primitivas gráficas: líneas,
rectángulos, óvalos, arcos etc. para graficar dentro de la misma.
Problema:
• Programa: ejercicio254.py
import tkinter as tk
self.canvas1.grid(column=0, row=0)
Para dibujar una línea la clase Canvas cuenta con el método 'create_line', El primer
y segundo parámetro representan la columna y fila donde se inicia la línea (en
nuestro ejemplo 0,0) y los otros dos valores representan la columna y fila donde
finaliza nuestra línea:
Para dibujar un rectángulo debemos indicar dos puntos que se encuentren dentro
del control Canvas, los dos primeros valores indican el vértice superior izquierdo y
los dos siguientes el vértice inferior derecho:
El rectángulo aparece con color relleno en blanco dado que pasamos el parámetro
fill con dicho valor.
Para dibujar un óvalo los parámetros son idénticos al método 'create_rectangle' con
la diferencia que en lugar de dibujar un rectángulo dibuja un óvalo contenido en
dicho rectángulo:
self.canvas1.create_oval(300,10,400,150, fill="red")
73.1. Problema:
Crear una aplicación que solicite el ingreso de tres valores por teclado que
representan las cantidades de votos obtenidas por tres partidos políticos. Luego
mostrar un gráfico de barras horizontales.
La interfaz visual debe ser similar a esta:
• Programa: ejercicio255.py
self.canvas1.delete(tk.ALL)
valor1=int(self.dato1.get())
valor2=int(self.dato2.get())
valor3=int(self.dato3.get())
if valor1>valor2 and valor1>valor3:
mayor=valor1
else:
if valor2>valor3:
mayor=valor2
else:
mayor=valor3
largo=votos del partido/votos del partido con mas votos * 400 píxeles.
Entonces los largos de las tres barras se calculan:
largo1=valor1/mayor*400
largo2=valor2/mayor*400
largo3=valor3/mayor*400
self.canvas1.create_rectangle(10,10,10+largo1,90,fill="red")
self.canvas1.create_rectangle(10,120,10+largo2,200,fill="blue")
self.canvas1.create_rectangle(10,230,10+largo3,310,fill="green")
Imprimimos un texto dentro del control Canvas mediante la primitiva
'create_text':
self.canvas1.create_text(largo1+70, 50, text="partido A", fill="white",
font="Arial")
self.canvas1.create_text(largo2+70, 160, text="partido B", fill="white",
font="Arial")
self.canvas1.create_text(largo3+70, 270, text="partido C", fill="white",
font="Arial")
73.2. Problema:
Crear una aplicación que solicite el ingreso de tres valores por teclado que
representan las cantidades de votos obtenidas por tres partidos políticos. Luego
mostrar un gráfico de tartas:
• Programa: ejercicio256.py
def grafico_tarta(self):
self.canvas1.delete(tk.ALL)
valor1=int(self.dato1.get())
valor2=int(self.dato2.get())
valor3=int(self.dato3.get())
suma=valor1+valor2+valor3
Una actividad muy común es poder detectar cuando hemos presionado el mouse
dentro de un control Canvas (o de cualquier otro Widget que hayamos visto) y a
partir de eso disparar un evento.
Veremos con una serie de ejemplos la posibilidades de tkinter nos provee.
74.1. Problema:
Confeccionar un programa que cree un objeto de la clase Canvas y nos muestre en
el título de la ventana la coordenada actual del mouse dentro del control Canvas y
al presionar el botón izquierdo del mouse se dibuje un círculo en dicha posición.
La interfaz visual debe ser similar a esta:
• Programa: ejercicio258.py
Todos los métodos que capturan eventos reciben un parámetro con información del
evento propiamente dicho. Los atributos x e y almacenan la coordenada actual de
la flecha del mouse.
El método 'presion_mouse' se dispara cuando presionamos el botón izquierdo del
mouse dentro del objeto canvas1. Dibujamos un círculo teniendo en cuenta donde
se encuentra la flecha del mouse en este momento:
self.canvas1.create_oval(evento.x-5,evento.y-5,evento.x+5,evento.y+5,
fill="red")
Acotaciones
La diversidad de eventos que podemos capturar es muy grande, veamos algunos
ejemplos:
• Para capturar el evento clic del botón izquierdo del mouse indicamos en el
método bind <Button-1>, el botón central <Button-2> y el botón derecho del
mouse <Button-3>
• Si necesitamos capturar el evento clic del botón derecho del mouse y a su
vez que se encuentre presionada la tecla Shift tenemos que codificar:
self.canvas1.bind("<Shift Button-1>", self.presion_mouse)
En lugar de Shift podemos verificar si se está presionando la tecla control:
self.canvas1.bind("<Control Button-1>", self.presion_mouse)
Inclusive detectar el evento si se presiona Shift, Control y el botón izquierdo del
mouse:
self.canvas1.bind("<Control Shift Button-1>", self.presion_mouse)
La tecla Alt, Shift, Control y el botón izquierdo del mouse:
self.canvas1.bind("<Control Shift Alt Button-1>", self.presion_mouse)
Si necesitamos hacer algo cuando la flecha del mouse entra al control podemos
plantear la captura del evento:
self.canvas1.bind("<Enter>", self.entrada)
Y si queremos detectar cuando la flecha del mouse sale de la componente:
self.canvas1.bind("<Leave>", self.salida)
Para detectar el doble clic de un botón del mouse:
self.canvas1.bind("<Double-Button-1>", self.presion_mouse)
74.2. Problema:
Programa: ejercicio259.py
Para poder dibujar a mano alzada vamos a identificar los eventos cuando se
presiona el botón izquierdo del mouse:
self.canvas1.bind("<ButtonPress-1>", self.boton_presion)
self.canvas1.bind("<Motion>", self.mover_mouse)
self.canvas1.bind("<ButtonRelease-1>", self.boton_soltar)
Cuando creamos una figura con los métodos que provee la clase Canvas, el mismo
nos retorna un Id (identificador) de dicha figura. Luego podemos hacer referencia a
la misma mediante ese Id.
Podemos asociar además a una o más figuras un Tag (marca) y luego borrar todas
las figuras que tienen dicho Tag.
75.1. Problema:
Mediante cinco botones permitir: borrar la línea, borrar el rectángulo, borrar el óvalo,
borrar todos los cuadrados y borrar todas las figuras contenidas en el objeto Canvas.
La interfaz visual debe ser similar a esta:
• Programa: ejercicio260.py
Los tres cuadrados que creamos definimos el parámetro tag con el string
"cuadrado":
self.canvas1.create_rectangle(100,300,150,350,fill="#aaaaaa",
tag="cuadrado")
self.canvas1.create_rectangle(200,300,250,350,fill="#555555",
tag="cuadrado")
self.canvas1.create_rectangle(300,300,350,350,fill="#cccccc",
tag="cuadrado")
El método 'crear_botones' tiene solo el objetivo de crear los 5 botones que necesita
la aplicación y los agrupa en un LabelFrame.
def borrar_linea(self):
self.canvas1.delete(self.linea)
def borrar_rectangulo(self):
self.canvas1.delete(self.rectangulo)
def borrar_ovalo(self):
self.canvas1.delete(self.ovalo)
Para eliminar todos los cuadrados también llamamos al método delete y le pasamos
el string que almacenamos en su tag:
def borrar_cuadrados(self):
self.canvas1.delete("cuadrado")
Finalmente para borrar todos las figuras que tiene un control Canvas debemos
llamar a delete y pasar la variable ALL que define el módulo tkinter:
def borrar_todos(self):
self.canvas1.delete(tk.ALL)
Acotaciones
Cuando trabajamos con el editor Visual Studio Code podemos navegar la referencia
de variables, métodos, clases etc. presionando la tecla Control y posicionando la
flecha del mouse sobre el identificar:
Si hacemos clic luego que aparece subrayado se abre el archivo que contiene
dicha definición:
Esta posibilidad de navegar el código fuente de los módulos nos puede facilitar
entender su funcionamiento. Según lo visto la variable ALL del módulo tkinter
almacena la cadena 'all', luego podemos escribir la eliminación de todos los gráficos
con la sintaxis:
def borrar_todos(self):
self.canvas1.delete('all')
76.1. Problema:
• Programa: ejercicio261.py
Creamos un objeto de la clase Canvas de 600 píxeles de ancho por 400 de alto:
self.cuadrado=self.canvas1.create_rectangle(150,10,200,60, fill="red")
self.ventana1.bind("<KeyPress>", self.presion_tecla)
76.2.1 Modificar el problema que desplaza un cuadrado con las teclas de flechas de
tal modo que la figura no pueda salir del espacio definido para el Canvas.
Para saber la posición actual de una figura la clase Canvas cuenta con el
método 'coords':
• Programa: ejercicio263.py
Creamos una componente Canvas de 700 píxeles de ancho por 500 píxeles de alto,
sabiendo que los archivos de las cartas tienen un tamaño de 200*300 píxeles:
archi1=tk.PhotoImage(file="carta1.png")
Los valores posibles del parámetro anchor son: "n", "ne", "e", "se", "s", "sw", "w",
"nw" y "center"
Los mismos pasos hacemos para la lectura y muestra de las otras dos imágenes:
archi2=tk.PhotoImage(file="carta2.png")
self.canvas1.create_image(240, 100, image=archi2, anchor="nw")
archi3=tk.PhotoImage(file="carta3.png")
self.canvas1.create_image(450, 100, image=archi3, anchor="nw")
Acotaciones
Los formatos reconocidos de la clase PhotoImage son: GIF, PNG, PGM y PPM.
Si el archivo se encuentra en otra carpeta debemos indicar el path del mismo:
archi1=tk.PhotoImage(file="C:/programaspython/carta1.png")
77.2. Problema propuesto
77.2.1 Disponer un botón y mostrar al azar una de las tres cartas del problema
anterior. Cada vez que se presione el botón generar un valor aleatorio y a
partir de dicho valor mostrar una carta.
Otro algoritmo útil cuando trabajamos con figuras dentro de un control Canvas es la
posibilidad de arrastrar y soltar figuras.
Debemos capturar los eventos cuando se hace clic dentro de una figura y luego
cada vez que se desplaza la flecha del mouse.
78.1. Problema:
Se cuenta con dos archivos de tipo png con las imágenes de distintas cartas.
Mostrarlas a cada una dentro de una componente de tipo Canvas y permitir
moverlas dentro del control mediante el mouse.
Puede descargar estas dos imágenes y copiarlas en la carpeta donde codifica sus
programas en Python:
La interfaz visual debe ser similar a esta luego de mover con el mouse las imágenes:
• Programa: ejercicio265.py
Creamos primero el control de tipo Canvas y las dos imágenes respectivas. A cada
una de las imágenes iniciamos el parámetro 'tags' con un valor:
self.carta_seleccionada = None
Existen muchos modos de almacenar datos como son los archivos de texto,
archivos binarios, bases de datos etc.
Archivo de texto
Como es una actividad tan común en todo programa el lenguaje Python incluye por
defecto todas las funcionalidades para trabajar con archivos de texto.
79.1. Problema:
Crear un archivo de texto llamado 'datos.txt', almacenar tres líneas de texto. Abrir
luego el archivo creado con un editor de texto.
• Programa: ejercicio267.py
Luego de ejecutar este programa (no muestra nada por pantalla) debemos abrir con
un editor de texto el archivo de texto que se acaba de crear llamado 'datos.txt':
Para crear un archivo de texto debemos llamar a la función open y pasar dos
parámetros, el primero indica el nombre del archivo a crear y el segundo un string
con el caracter "w" (la "w" write indica crear el archivo de texto):
archi1=open("datos.txt","w")
archi1 = open("c:/administracion/datos.txt","w")
archi1.write("Primer línea.\n")
archi1.write("Primer línea.")
archi1.write("Segunda línea.")
archi1.write("Tercer línea.")
Luego de trabajar con el archivo de texto debemos liberarlo para que otro programa
pueda acceder a su contenido:
archi1.close()
79.2. Problema:
• Programa: ejercicio268.py
archi1=open("datos.txt","r")
El método 'read' recupera todas las líneas del archivo de texto (recupera el archivo
completo):
contenido=archi1.read()
Luego de trabajar con el archivo de texto debemos liberarlo para que otro programa
pueda acceder a su contenido:
archi1.close()
archi1=open("datos.txt","r")
contenido=archi1.read(6)
print(contenido) # imprime: Primer
archi1.close()
79.3. Problema:
Antes de la estructura repetitiva 'while' leemos la primer lína del archivo de texto:
linea=archi1.readline()
while linea!='':
print(linea, end='')
linea=archi1.readline()
• Programa: ejercicio270.py
Es una forma más compacta de recorrer cada una de las líneas del archivo de texto.
Mediante el método 'readlines' podemos recuperar cada una de las líneas del
archivo de texto y almacenarlas en una lista.
79.4. Problema:
Leer el contenido del archivo de texto 'datos.txt' y almacenar sus líneas en una lista.
Imprimir la cantidad de líneas que tiene el archivo y su contenido.
• Programa: ejercicio271.py
Mediante la llamada al método 'readlines' obtenemos una lista con todas las líneas
del archivo 'datos.txt':
lineas=archi1.readlines()
Una variante del método 'readlines' es pasar como un parámetro entero que
represente que línea queremos recuperar:
linea=archi1.readlines(2)
print(linea, end='') # imprime ['Primer línea.\n']
Hemos visto que cuando llamamos a la función 'open' el segundo parámetro puede
ser "w", "r" y si queremos que se abra para añadir sin borrar las líneas actuales del
archivo debemos hacerlo con el parámetro "a" (append).
79.5. Problema:
Abrir el archivo de texto 'datos.txt' y luego agregar 2 líneas. Imprimir luego el archivo
completo.
• Programa: ejercicio272.py
archi1=open("datos.txt","a")
archi1.close()
archi1=open("datos.txt","r")
contenido=archi1.read()
print(contenido)
archi1.close()
79.6. Problema:
• Programa: ejercicio273.py
79.7. Problema:
Crear un archivo de texto llamado 'datos.txt' con una codificación utf-8, almacenar
tres líneas de texto. Abrir luego el archivo creado con el editor VS Code.
• Programa: ejercicio274.py
Si ahora abrimos el archivo de texto creado con un editor que permite trabajar con
archivos con codificación utf-8 el resultado es:
Confeccionar una interfaz visual que contenga un menú de opciones que permitan
"Guardar archivo", "Recuperar archivo" y "Salir del programa".
• Programa: ejercicio275.py
Y la creación del menú con las tres opciones, este método es llamado desde el
método init :
def agregar_menu(self):
menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1, tearoff=0)
opciones1.add_command(label="Guardar archivo", command=self.guardar)
opciones1.add_command(label="Recuperar archivo",
command=self.recuperar)
opciones1.add_separator()
opciones1.add_command(label="Salir", command=self.salir)
menubar1.add_cascade(label="Archivo", menu=opciones1)
def guardar(self):
nombrearch=fd.asksaveasfilename(initialdir = "/",title = "Guardar
como",filetypes = (("txt files","*.txt"),("todos los archivos","*.*")))
if nombrearch!='':
archi1=open(nombrearch, "w", encoding="utf-8")
archi1.write(self.scrolledtext1.get("1.0", tk.END))
archi1.close()
mb.showinfo("Información", "Los datos fueron guardados en el archivo.")
def recuperar(self):
nombrearch=fd.askopenfilename(initialdir = "/",title = "Seleccione
archivo",filetypes = (("txt files","*.txt"),("todos los archivos","*.*")))
En el caso que se haya seleccionado un archivo del disco duro procedemos a abrirlo
y cargar su contenido en el 'ScrolledText':
if nombrearch!='':
archi1=open(nombrearch, "r", encoding="utf-8")
contenido=archi1.read()
archi1.close()
self.scrolledtext1.delete("1.0", tk.END)
self.scrolledtext1.insert("1.0", contenido)
Con Python podemos comunicarnos con un gestor de bases de datos para enviar y
recuperar datos.
Existen gran cantidad de gestores de bases de datos y el primero que veremos para
ver cual es la mecánica para conectarnos desde Python será el gestor de base de
datos MySQL.
Instalación de MySQL.
• MySQL
• PHPMyAdmin (que nos permitirá administrar las bases de datos existentes
en MySQL)
• PHP (Lenguaje que nos permite ejecutar el PHPMyAdmin)
• Apache (Servidor Web que nos permite ejecutar PHPMyAdmin y PHP en un
servidor)
Aparece la interfaz desde donde debemos iniciar el gestor de base de datos MySQL:
Se nos abre una aplicación web PHPMyAdmin que nos permite administrar nuestras
bases de datos de MySQL:
Crearemos una base de datos seleccionando la opción "Nueva" que aparece del
lado izquierdo de la página.
Una vez que se crea la podemos ver que aparece en la columna izquierda y
podemos pasar a crear tablas en la misma. Crearemos la tabla artículos que tendrá
3 campos:
Los datos a ingresar para cada campo para la creación de la tabla articulos son:
Luego de ejecutar el programa pip podemos ver que nos informa de la instalación
del paquete 'mysql-connector':
• Programa: ejercicio276.py
Lo primero que hacemos es importar el módulo que nos permite conectarnos con
MySQL:
import mysql.connector
conexion1=mysql.connector.connect(host="localhost", user="root",
passwd="")
cursor1=conexion1.cursor()
cursor1.execute("show databases")
Mediante un for podemos ver todas las bases de datos existentes en nuestro
servidor de MySQL:
conexion1.close()
• Programa: ejercicio277.py
conexion1=mysql.connector.connect(host="localhost",
user="root",
passwd="",
database="bd1")
Luego de crear el cursor solicitamos que se ejecute el comando SQL 'show tables'
que nos retorna todas las tablas existentes de la base de datos activa indicada
cuando llamamos a 'connect':
cursor1=conexion1.cursor()
cursor1.execute("show tables")
• Programa: ejercicio278.py
Por el momento si queremos controlar que se han cargado las tres filas en la tabla
'articulos' podemos abrir el 'PHPMyAdmin' y ver el contenido de la tabla:
La variable datos es una tupla que contiene los datos que se utilizarán en la
sustitución %s:
datos=("naranjas", 23.50)
cursor1.execute(sql, datos)
Es fundamental llamar al final al método 'commit' para que queden firmes los
comandos SQL 'insert':
conexion1.commit()
• Programa: ejercicio279.py
Cuando ejecutamos el programa podemos ver que se recuperan todas las filas de
la tabla 'articulos':
cursor1=conexion1.cursor()
cursor1.execute("select codigo, descripcion, precio from articulos")
for fila in cursor1:
print(fila)
Las otras dos actividades fundamentales que podemos hacer con una tabla es
borrar filas y modificar datos.
• Programa: ejercicio280.py
Cuando ejecutamos el programa podemos ver que se eliminó el artículo cuyo código
es 1 y se modificó el precio del artículo con código 3:
Luego de crear el cursor podemos llamar al método 'execute' varias veces y pasar
distintos comando SQL:
cursor1=conexion1.cursor()
cursor1.execute("delete from articulos where codigo=1")
cursor1.execute("update articulos set precio=50 where codigo=3")
Siempre que pasemos un comando SQL: insert, delete o update debemos llamar al
método commit para que quede firme los cambios en la base de datos:
conexion1.commit()
82.1. Problema:
Desarrollar una aplicación visual con la librería tkinter que permita implementar los
algoritmos de carga de artículos, consulta por código y listado completo.
El primer paso será crear una carpeta llamada 'proyecto3' y dentro de esta
crearemos los dos módulos:
• módulo: formularioarticulos.py
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
from tkinter import scrolledtext as st
import artículos
class FormularioArticulos:
def init (self):
self.articulo1=articulos.Articulos()
También en el método init llamamos a una serie de métodos para crear
cada una de las páginas del objeto de la clase 'Notebook':
self.ventana1=tk.Tk()
self.ventana1.title("Mantenimiento de artículos")
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.carga_articulos()
self.consulta_por_codigo()
self.listado_completo()
self.cuaderno1.grid(column=0, row=0, padx=10, pady=10)
self.ventana1.mainloop()
def agregar(self):
datos=(self.descripcioncarga.get(), self.preciocarga.get())
Luego llamamos al método alta del objeto 'articulo1' y le pasamos la tupla con los
datos a añadir:
self.articulo1.alta(datos)
mb.showinfo("Información", "Los datos fueron cargados")
self.descripcion.set("")
self.precio.set("")
En este momento nos conviene analizar el método 'alta' de la clase 'Articulos' que
se encuentra en el otro módulo:
def consultar(self):
datos=(self.codigo.get(), )
respuesta=self.articulo1.consulta(datos)
if len(respuesta)>0:
self.descripcion.set(respuesta[0][0])
self.precio.set(respuesta[0][1])
else:
self.descripcion.set('')
self.precio.set('')
mb.showinfo("Información", "No existe un artículo con dicho código")
Creamos una tubla con un solo dato (es obligatoria la coma para que Python lo
considere una tupla):
datos=(self.codigo.get(), )
Listado completo
Para mostrar todas las filas de la tabla 'articulos' hemos dispuesto un objeto de la
clase 'scrolledtext':
def listar(self):
respuesta=self.articulo1.recuperar_todos()
self.scrolledtext1.delete("1.0", tk.END)
for fila in respuesta:
self.scrolledtext1.insert(tk.END, "código:"+str(fila[0])+
"\ndescripción:"+fila[1]+
"\nprecio:"+str(fila[2])+"\n\n")
def recuperar_todos(self):
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio from articulos"
cursor.execute(sql)
cone.close()
return cursor.fetchall()
Hemos resuelto en los dos conceptos anteriores algoritmos en Python que acceden
a una base de datos de MySQL. Veremos otras funcionalidades que nos provee el
paquete mysql-connector.
Cuando insertamos una fila en una tabla que contiene un campo que se auto
incrementa podemos recuperar dicho valor en el mismo momento que efectuamos
la inserción.
• Programa: ejercicio281.py
La clase cursor a parte del método 'execute' cuenta con otro método llamado
'executemany' que tiene el objetivo de insertar múltiples filas de una tabla.
• Programa: ejercicio282.py
En conceptos anteriores vimos como crear una base de datos de MySQL utilizando
la aplicación PHPMyAdmin, en algunas situaciones podemos necesitar crear una
base de datos desde el mismo programa de Python. La misma metodología será si
queremos crear tablas.
• Programa: ejercicio283.py
conexion1=mysql.connector.connect(host="localhost",
user="root",
passwd="")
cursor1=conexion1.cursor()
sql="create database bd2"
cursor1.execute(sql)
Luego de crear la base de datos si queremos activarla para poder crear tablas,
insertar filas en tablas, consultarlas etc. debemos activarla mediante el comando
SQL 'use' con el nombre de la base de datos:
sql="use bd2"
cursor1.execute(sql)
Ya estando en uso la base de datos 'bd2' podemos efectuar la creación de una tabla:
Recordemos que las triple comillas nos permiten en Python definir un string de
múltiples líneas.
Cuando queremos crear una base de datos que ya existe se genera un error,
podemos primero borrarla y luego ya si crearla sin problemas.
• Programa: ejercicio284.py
Este programa es una variante del anterior donde primero verificamos si existe la
base de datos 'bd2' y en caso afirmativo la eliminamos:
Una vez que borramos la base de datos 'bd2' en el caso que exista procedemos a
crearla:
No se puede crear una tabla con el mismo nombre de una existente, en esos
casos debemos borrar la actual y crear una nueva.
• Programa: ejercicio285.py
84.1. Problema:
Realizar la carga de dos números enteros por teclado e imprimir su suma, luego
preguntar si quiere seguir sumando valores.
• Programa: ejercicio296.py
Disponemos un while infinito que solo terminará cuando el if contenido dentro del
while se verifique verdadero y se ejecute la instrucción break que finaliza
inmediatamente el while.
Pero que pasa si el programa lo utilizará otro usuario que no tenga cuidado en la
entrada de datos, podemos modificar este programa para que no se interrumpa al
ingresar valores no numéricos y le informe con un mensaje que valores están
permitidos ingresar por teclado.
• Programa: ejercicio297.py
Para capturar las excepciones en Python aparecen dos palabras claves nuevas try
y except.
El algoritmo principal se dispone dentro del bloque try:
try:
valor1=int(input("Ingrese primer valor:"))
valor2=int(input("Ingrese segundo valor:"))
suma=valor1+valor2
print("La suma es",suma)
Siempre que el operador ingrese valores numéricos solo se ejecuta el bloque del
try, pero cuando ingresa un dato no numérico por teclado se genera la excepción
'ValueError' que debe ser capturada luego de la palabra clave except y seguida por
el nombre de excepción capturada:
except ValueError:
print("debe ingresar números.")
El algoritmo que dispongamos en éste bloque puede hacer cualquier cosa, en este
caso solo informar al operador que debe ingresar solo números.
Luego de ejecutar el bloque 'except' continúa el programa activo con las
instrucciones siguiente sin su interrupción.
Python provee un conjunto de excepciones por defecto que podemos hace uso en
nuestros programas.
85.1. Problema:
Realizar la carga de dos números por teclado e imprimir la división del primero
respecto al segundo, capturar la excepción ZeroDivisionError.
• Programa: ejercicio298.py
85.2. Problema:
Almacenar en una tupla los nombres de meses del año. Solicitar el ingreso del
número de mes y mostrar seguidamente el nombre de dicho mes. Capturar la
excepción IndexError.
• Programa: ejercicio299.py
meses=("enero","febrero","marzo","abril","mayo","junio",
"julio","agosto","septiembre","octubre","noviembre","diciembre")
try:
nromes=int(input("Ingrese un número de mes [1-12]:"))
if nromes>0:
print(meses[nromes-1])
else:
print("En número de mes debe ir entre 1 y 12")
except IndexError:
print("En número de mes debe ir entre 1 y 12")
85.3. Problema:
Realizar la carga de dos números por teclado e imprimir la división del primero
respecto al segundo, capturar las excepciones ZeroDivisionError y ValueError.
• Programa: ejercicio300.py
Debemos disponer los dos bloques 'except' a la misma altura indicando el nombre
de la excepción a capturar:
except ZeroDivisionError:
print("No se puede dividir por cero.")
except ValueError:
print("Los valores a ingresar deben ser enteros")
85.4. Problema:
Realizar la carga de dos números por teclado e imprimir la división del primero
respecto al segundo. Capturar cualquier tipo de excepción que se dispare.
• Programa: ejercicio301.py
except:
print("Problemas con la entrada u operación")
Nuestro algoritmo que responde a cualquier excepción que se dispara siempre será
muy general ya que no analizamos en particular que excepción se generó.
try:
[algoritmo principal]
except [nombre de la excepción 1]:
[algoritmo alternativo 1]
except [nombre de la excepción 2]:
[algoritmo alternativo 2]
except [nombre de la excepción 3]:
[algoritmo alternativo 3]
try:
[algoritmo principal]
except [nombre de la excepción 1]:
[algoritmo alternativo 1]
except [nombre de la excepción 2]:
[algoritmo alternativo 2]
except [nombre de la excepción 3]:
[algoritmo alternativo 3]
finally:
[algoritmo que siempre se ejecuta]
86.1. Problema:
Almacenar una serie de string en un archivo de texto. Tratar de llamar al método
'write' pasando un entero.
• Programa: ejercicio301.py
Si ejecutamos este programa al llamar al método write con un dato entero se genera
la excepción 'TypeError':
archi1.write(3334)
except TypeError:
print("No se puede grabar un entero con write")
finally:
archi1.close()
print("Se cerró el archivo")
try:
archi1=open("datos.txt","w")
archi1.write("Primer línea.\n")
archi1.write("Segunda línea.\n")
archi1.write("Tercer línea.\n")
archi1.write(3334)
archi1.close()
print("Se cerró el archivo")
except TypeError:
print("No se puede grabar un entero con write")
De esta forma el algoritmo tiene el problema que nunca cerrará el archivo ya que no
se ejecutará el bloque:
archi1.close()
print("Se cerró el archivo")
Es muy común utilizar la cláusula 'finally' para liberar recursos solicitados dentro del
bloque 'try'. Veamos con otro ejemplo ya resuelto anteriormente accediendo a una
base de datos de MySQL.
86.2. Problema:
• Programa: ejercicio302.py
SQLite también es un gestor de bases de datos relacionales pero con objetivos muy
diferentes a MySQL, SQLServer, Oracle etc.
Este gestor de base de datos tiene por objetivo ser parte de la misma aplicación con
la que colabora, es decir no cumple los conceptos de cliente y servidor.
Para entender sus usos podemos dar algunos ejemplos donde se utiliza el gestor
SQLite:
• Firefox usa SQLite para almacenar los favoritos, el historial, las cookies etc.
• También el navegador Opera usa SQLite.
• La aplicación de comunicaciones Skype de Microsoft utiliza SQLite
• Los sistemas operativos Android y iOS adoptan SQLite para permitir el
almacenamiento y recuperación de datos.
SQLite es Open Source y se ha instalado por defecto con Python, es decir forma
parte de la biblioteca estándar, no tenemos que instalar ningún módulo con pip.
En principio no se requiere tener más que Python instalado para poder trabajar con
SQLite. Podemos desde nuestra propia aplicación crear la base de datos y sus
tablas.
• Programa: ejercicio303.py
Para poder trabajar con bases de datos de tipo SQLite debemos primero importar
el módulo 'sqlite3':
import sqlite3
Para crear o abrir una conexión con una base de datos existente debemos llamar a
la función 'connect' del módulo 'sqlite3':
conexion=sqlite3.connect("bd1.db")
La primera vez que ejecutemos este programa como no existe la base de datos
'bd1.db' se crea, consiste en un único archivo que se localiza en la misma carpeta
de nuestra aplicación:
try:
conexion.execute("""create table articulos (
codigo integer primary key autoincrement,
descripcion text,
precio real
)""")
print("se creo la tabla articulos")
except sqlite3.OperationalError:
print("La tabla articulos ya existe")
import sqlite3
conexion=sqlite3.connect("bd1.db")
conexion.execute("""create table if not exists articulos (
codigo integer primary key AUTOINCREMENT,
descripcion text,
precio real
)""")
conexion.close()
• Programa: ejercicio304.py
Luego de efectuar todos los insert debemos llamar a 'commit' para que se actualicen
los datos realmente en la tabla de la base de datos:
conexion.commit()
• Programa: ejercicio305.py
Si ejecutamos este programa luego de haber cargado las tres filas del ejercicio
anterior el resultado será el siguiente:
• Programa: ejercicio306.py
El resultado de este comando SQL select puede ser de una fila si existe el código
de artículo ingresado o cero filas:
El método fechone de la clase Cursor retorna una tupla con la fila de la tabla que
coincide con el código ingresado o retorna 'None':
fila=cursor.fetchone()
if fila!=None:
print(fila)
else:
print("No existe un artículo con dicho código.")
• Programa: ejercicio307.py
En este caso el resultado del comando 'select' pueden ser muchas filas:
cursor=conexion.execute("select descripcion from articulos where precio<?",
(precio, ))
Llamamos al método 'fetchall' de la clase Cursor y nos retorna una lista con todas
las filas de la tabla que cumplen la condición de tener un precio inferior al ingresado:
filas=cursor.fetchall()
if len(filas)>0:
for fila in filas:
print(fila)
else:
print("No existen artículos con un precio menor al ingresado.")
Desarrollar una aplicación visual con la librería tkinter que permita implementar los
algoritmos de carga de artículos, consulta por código y listado completo.
Trabajaremos con la base de datos 'bd1.db' que creamos en el concepto anterior.
Las interfaz visual para la carga debe ser:
El primer paso será crear una carpeta llamada 'proyecto4' y dentro de esta
crearemos los dos módulos:
• módulo: formularioarticulos.py
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
from tkinter import scrolledtext as st
import articulos
class FormularioArticulos:
def init (self):
self.articulo1=articulos.Articulos()
self.ventana1=tk.Tk()
self.ventana1.title("Mantenimiento de artículos")
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.carga_articulos()
self.consulta_por_codigo()
self.listado_completo()
self.cuaderno1.grid(column=0, row=0, padx=10, pady=10)
self.ventana1.mainloop()
def carga_articulos(self):
self.pagina1 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina1, text="Carga de artículos")
self.labelframe1=ttk.LabelFrame(self.pagina1, text="Artículo")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, text="Descripción:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.descripcioncarga=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labelframe1,
textvariable=self.descripcioncarga)
self.entrydescripcion.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, text="Precio:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.preciocarga=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelframe1, textvariable=self.preciocarga)
self.entryprecio.grid(column=1, row=1, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe1, text="Confirmar",
command=self.agregar)
Ing. Álvaro Galeano Martínez 466
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
def agregar(self):
datos=(self.descripcioncarga.get(), self.preciocarga.get())
self.articulo1.alta(datos)
mb.showinfo("Información", "Los datos fueron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
def consulta_por_codigo(self):
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Consulta por código")
self.labelframe2=ttk.LabelFrame(self.pagina2, text="Artículo")
self.labelframe2.grid(column=0, row=0, padx=5, pady=10)
self.label1=ttk.Label(self.labelframe2, text="Código:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.codigo=tk.StringVar()
self.entrycodigo=ttk.Entry(self.labelframe2, textvariable=self.codigo)
self.entrycodigo.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe2, text="Descripción:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.descripcion=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labelframe2, textvariable=self.descripcion,
state="readonly")
self.entrydescripcion.grid(column=1, row=1, padx=4, pady=4)
self.label3=ttk.Label(self.labelframe2, text="Precio:")
self.label3.grid(column=0, row=2, padx=4, pady=4)
self.precio=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelframe2, textvariable=self.precio,
state="readonly")
self.entryprecio.grid(column=1, row=2, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe2, text="Consultar",
command=self.consultar)
self.boton1.grid(column=1, row=3, padx=4, pady=4)
def consultar(self):
datos=(self.codigo.get(), )
respuesta=self.articulo1.consulta(datos)
if len(respuesta)>0:
self.descripcion.set(respuesta[0][0])
self.precio.set(respuesta[0][1])
else:
self.descripcion.set('')
self.precio.set('')
mb.showinfo("Información", "No existe un artículo con dicho código")
def listado_completo(self):
self.pagina3 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina3, text="Listado completo")
self.labelframe3=ttk.LabelFrame(self.pagina3, text="Artículo")
self.labelframe3.grid(column=0, row=0, padx=5, pady=10)
self.boton1=ttk.Button(self.labelframe3, text="Listado completo",
command=self.listar)
self.boton1.grid(column=0, row=0, padx=4, pady=4)
self.scrolledtext1=st.ScrolledText(self.labelframe3, width=30, height=10)
self.scrolledtext1.grid(column=0,row=1, padx=10, pady=10)
def listar(self):
respuesta=self.articulo1.recuperar_todos()
self.scrolledtext1.delete("1.0", tk.END)
for fila in respuesta:
self.scrolledtext1.insert(tk.END,
"código:"+str(fila[0])+"\ndescripción:"+fila[1]+"\nprecio:"+str(fila[2])+"\n\n")
aplicacion1=FormularioArticulos()
• módulo: articulos.py
import sqlite3
class Articulos:
def abrir(self):
conexion=sqlite3.connect("c:/programaspython/bd1.db")
return conexion
cursor=cone.cursor()
sql="insert into articulos(descripcion, precio) values (?,?)"
cursor.execute(sql, datos)
cone.commit()
cone.close()
def recuperar_todos(self):
try:
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio from articulos"
cursor.execute(sql)
return cursor.fetchall()
finally:
cone.close()
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
from tkinter import scrolledtext as st
import artículos
class FormularioArticulos:
def init (self):
self.articulo1=articulos.Articulos()
También en el método init llamamos a una serie de métodos para crear cada
una de las páginas del objeto de la clase 'Notebook':
self.ventana1=tk.Tk()
self.ventana1.title("Mantenimiento de artículos")
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.carga_articulos()
self.consulta_por_codigo()
self.listado_completo()
self.cuaderno1.grid(column=0, row=0, padx=10, pady=10)
self.ventana1.mainloop()
def agregar(self):
datos=(self.descripcioncarga.get(), self.preciocarga.get())
Luego llamamos al método alta del objeto 'articulo1' y le pasamos la tupla con los
datos a añadir:
self.articulo1.alta(datos)
mb.showinfo("Información", "Los datos fueron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
En este momento nos conviene analizar el método 'alta' de la clase 'Articulos' que
se encuentra en el otro módulo:
def abrir(self):
conexion=sqlite3.connect("c:/programaspython/bd1.db")
return conexión
def consultar(self):
datos=(self.codigo.get(), )
respuesta=self.articulo1.consulta(datos)
if len(respuesta)>0:
self.descripcion.set(respuesta[0][0])
self.precio.set(respuesta[0][1])
else:
self.descripcion.set('')
self.precio.set('')
mb.showinfo("Información", "No existe un artículo con dicho código")
Creamos una tubla con un solo dato (es obligatoria la coma para que Python lo
considere una tupla:
datos=(self.codigo.get(), )
• Listado completo
Para mostrar todas las filas de la tabla 'articulos' hemos dispuesto un objeto de la
clase 'scrolledtext':
def listar(self):
respuesta=self.articulo1.recuperar_todos()
self.scrolledtext1.delete("1.0", tk.END)
for fila in respuesta:
self.scrolledtext1.insert(tk.END, "código:"+str(fila[0])+
"\ndescripción:"+fila[1]+
"\nprecio:"+str(fila[2])+"\n\n")
def recuperar_todos(self):
try:
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio from articulos"
cursor.execute(sql)
return cursor.fetchall()
finally:
cone.close()
Veamos con un ejemplo cual es la sintaxis para implementar los f-strings en Python.
89.1. Problema:
Ingresar por teclado dos enteros, calcular su suma y luego mostrar un mensaje de
los dos valores ingresados y su suma.
Programa: ejercicio308.py
Para indicar que un string en Python contendrá variables a ser sustituidas debemos
anteceder el caracter "f":
Las variables a ser sustituidas por su valor deben estar encerradas entre llaves.
El resultado de la ejecución es:
No olvidar el caracter "f" previo a la declaración del string sino el resulta será:
La suma de {valor1} y {valor2} es {suma}
89.2. Problema:
Definir una lista con 5 valores enteros. Mostrar los 5 valores formateados a derecha
junto a su suma.
• Programa: ejercicio309.py
Cuando disponemos entre llaves la variable a sustituir podemos agregar luego dos
puntos y la cantidad de espacios que ocupará la variable:
print(f"{elemento:10}")
También otra posibilidad es indicar entre llaves la llamada a una función (la función
sum retorna la suma de toda la lista):
print(f"{sum(lista):10}")
89.3. Problema:
Definir una lista con 5 valores flotantes con distintas cantidades de decimales.
Mostrar los números solo con dos decimales.
• Programa: ejercicio310.py
Acotaciones
Podemos utilizar tanto el caracter "f" minúscula como el caracter "F" mayúscula para
indicar que se trata de un f-strings.
valor1=10
print(F"{{valor1}} tiene el valor {valor1}")
valor1=1000
valor2=340
suma=valor1+valor2
cadena=f"""
{valor1:5}
{valor2:5}
-----
{suma:5}
"""
print(cadena)
1000
340
-----
1340
Anteriormente sin la sintaxis de los f-strings debíamos convertir todos los datos a
string y concatenarlos:
Con la llegada de los f-strings el código fuente de nuestro programa es mucho más
legible.
90.1. Problema 1:
• Programa: ejercicio311.py
def repetir():
repetir()
repetir()
Se llama la función repetir. Hay que tener en cuenta que cada vez que se llama a
una función se reservan un conjunto de bytes de la memoria que se liberarán
cuando finalice su ejecución.
90.2. Problema 2:
• Programa: ejercicio312.py
def imprimir(x):
print(x)
imprimir(x-1)
imprimir(5)
90.3. Problema 3:
• Programa: ejercicio313.py
def imprimir(x):
if x>0:
print(x)
imprimir(x-1)
imprimir(5)
Analice lo que sucede cuando el if x>0: se evalúa como falso, ¿a qué línea del
programa retorna?
90.4. Problema 4:
• Programa: ejercicio314.py
def imprimir(x):
if x>0:
imprimir(x-1)
print(x)
imprimir(5)
Con este ejemplo se presenta una situación donde debe analizarse línea a línea la
ejecución del programa y el porque de estos resultados.
def imprimir(x):
if x>0:
imprimir(x-1)
print(x)
Cuando x vale 0 la condición del if se valúa como falsa y sale de la función imprimir.
¿Qué línea ahora se ejecuta?
imprimir(x-1)
print(x)
print(x)
Es importante tener en cuenta que siempre en una función recursiva debe haber un
if para finalizar la recursividad ( en caso contrario la función recursiva será infinita y
provocará que el programa se bloquee generando una excepción)
90.5. Problema 5:
• Programa: ejercicio315.py
def factorial(fact):
if fact>0:
valor=fact*factorial(fact-1)
return valor
else:
return 1;
fact recibe el valor 4 y valor se cargará con el valor que se obtenga con el producto
de fact por el valor devuelto por la función factorial (llamada recursiva)
Cuando fact recibe un cero la condición del if se valúa como falsa y ejecuta el else
retornando un 1, la variable local de la llamada anterior a la función queda de la
siguiente manera:
Por último el bloque principal recibe "valor", en este caso el valor 24.
90.6. Problema 6:
• Programa: ejercicio316.py
datos=[60,44,22,33,2]
print(datos)
ordenar(datos, len(datos))
print(datos)
Hasta ahora hemos visto problemas que se pueden resolver tanto con recursividad
como con estructuras repetitivas.
Es muy importante tener en cuenta que siempre que podamos emplear un algoritmo
no recursivo será mejor (ocupa menos memoria de ram y se ejecuta más
rápidamente)
Pero hay casos donde el empleo de recursividad hace mucho más sencillo el
algoritmo (tener en cuenta que no es el caso de los problemas vistos previamente)
91.1. Problema 1:
• Programa: ejercicio317.py
import os
def leer(directorio):
lista = os.listdir(directorio)
for elemento in lista:
if os.path.isfile(directorio+elemento):
print(elemento+" [archivo]")
if os.path.isdir(directorio+elemento):
print(elemento+" [directorio]")
leer(directorio+elemento+"/")
leer("c:/programaspython/")
Cuando ejecutamos este programa tenemos como resultado un listado de todos los
archivos contenidos en la carpeta c:/programaspython/ y todas sus subcarpetas:
import os
Lo primero que hacemos dentro de la función leer es llamar a la función 'listdir' del
módulo 'os' que lo que hace es retornar una lista con todos los nombres de archivos
y directorios contenidos en la carpeta que le pasamos como parámetro (la primera
vez que se llama la función leer recibe la carpeta 'c:/programaspython/'):
def leer(directorio):
lista = os.listdir(directorio)
if os.path.isdir(directorio+elemento):
print(elemento+" [directorio]")
leer(directorio+elemento+"/")
91.2. Problema 2:
El valor:
0 Representa pasillo
1 Representa pared
9 Persona
5 Salida
• Programa: ejercicio318.py
import tkinter as tk
from tkinter import ttk
import random
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.ventana1.title("Laberinto")
self.salida=False
self.generar_laberinto()
self.boton1=ttk.Button(self.ventana1, text="Recorrer", command=self.analizar)
self.boton1.grid(column=0, row=10, columnspan=5, padx=10, pady=10)
self.boton2=ttk.Button(self.ventana1, text="Generar otro",
command=self.generar_otro)
self.boton2.grid(column=5, row=10, columnspan=5, padx=10, pady=10)
self.ventana1.mainloop()
def generar_laberinto(self):
self.tablero=[]
listafila=[]
for fila in range(0,10):
for columna in range(0,10):
label=ttk.Label(self.ventana1, text=self.retornar_aleatorio(),
foreground="red")
label.grid(column=columna, row=fila, padx=10, pady=10)
listafila.append(label)
self.tablero.append(listafila)
listafila=[]
self.tablero[0][0].configure(text=0)
self.tablero[9][9].configure(text=5)
def generar_otro(self):
for fila in range(0,10):
for columna in range(0,10):
self.tablero[fila][columna].configure(text=self.retornar_aleatorio(),background="#f0f
0f0")
self.tablero[0][0].configure(text=0)
self.tablero[9][9].configure(text=5)
def retornar_aleatorio(self):
valor=random.randint(1,4)
if valor==1:
return 1
else:
return 0
def analizar(self):
self.salida=False
self.recorrer(0,0)
if self.salida:
self.ventana1.title("Tiene salida el laberinto")
else:
self.ventana1.title("No tiene salida el laberinto")
aplicacion1=Aplicacion()
def generar_laberinto(self):
self.tablero=[]
listafila=[]
for fila in range(0,10):
for columna in range(0,10):
label=ttk.Label(self.ventana1, text=self.retornar_aleatorio(),
foreground="red")
label.grid(column=columna, row=fila, padx=10, pady=10)
listafila.append(label)
self.tablero.append(listafila)
listafila=[]
Fuera de los for configuramos el inicio del laberinto con un valor 0 (pasillo) y el valor
5 para la salida del laberinto:
self.tablero[0][0].configure(text=0)
self.tablero[9][9].configure(text=5)
def analizar(self):
self.salida=False
self.recorrer(0,0)
if self.salida:
self.ventana1.title("Tiene salida el laberinto")
else:
self.ventana1.title("No tiene salida el laberinto")
if self.tablero[fil][col].cget("text")==5:
self.salida=True
else:
if self.tablero[fil][col].cget("text")==0:
self.tablero[fil][col].configure(text=9)
self.tablero[fil][col].configure(background="yellow")
self.recorrer(fil,col+1)
self.recorrer(fil+1,col)
self.recorrer(fil-1,col)
self.recorrer(fil,col-1)
91.3. Problema 3:
Desarrollar el juego del Buscaminas. Definir una lista de 10 elementos de tipo lista
y en estas listas internas almacenar las referencias a botones.
El juego consiste en destapar todas las casillas que no tiene bombas. Si se presiona
la casilla que tiene bomba finaliza el juego. En las casillas que están en el perímetro
de una bomba aparece un número que indica la cantidad de bombas a su alrededor.
Por ejemplo si una casilla tiene el 2 significa que de las 8 casillas a su alrededor hay
2 bombas.
Cuando se inicia el juego debe aparecer el tablero con las 100 casillas:
• Programa: ejercicio319.py
import tkinter as tk
from tkinter import ttk
import random
from tkinter import messagebox as mb
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.destapadas=0
self.enjuego=True
self.ventana1.geometry("500x500")
self.ventana1.title("Buscaminas")
self.ventana1.configure(background="#BEF781")
self.generar_tablero()
self.generar_bombas()
self.generar_bombas_proximas()
menubar1 = tk.Menu(self.ventana1)
Ing. Álvaro Galeano Martínez 497
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1)
opciones1.add_command(label="Reiniciar", command=self.reiniciar)
opciones1.add_command(label="Salir", command=self.ventana1.destroy)
menubar1.add_cascade(label="Opciones", menu=opciones1)
self.ventana1.mainloop()
def generar_tablero(self):
self.tablero=[]
listafila=[]
for fila in range(0,10):
for columna in range(0,10):
boton=ttk.Button(self.ventana1, text="", command=lambda fi=fila,
co=columna: self.presion(fi,co))
boton.place(x=columna*50,y=fila*50,width=50,height=50)
listafila.append(boton)
self.tablero.append(listafila)
listafila=[]
def generar_bombas(self):
self.bombas=[]
listafila=[]
for fila in range(0,10):
for columna in range(0,10):
listafila.append("0")
self.bombas.append(listafila)
listafila=[]
cantidad=10
while cantidad!=0:
fila=random.randint(0,9)
columna=random.randint(0,9)
if self.bombas[fila][columna]!="b":
self.bombas[fila][columna]="b"
#self.tablero[fila][columna].configure(text="b")
cantidad=cantidad-1
def generar_bombas_proximas(self):
for f in range(0,10):
for c in range(0,10):
if self.bombas[f][c]=="0":
cant=self.contar_lado(f,c)
self.bombas[f][c]=str(cant)
if int(self.bombas[fila][columna])>=1 and
int(self.bombas[fila][columna])<=8 and self.tablero[fila][columna].cget("text")=="":
self.tablero[fila][columna].configure(text=self.bombas[fila][columna])
self.destapadas=self.destapadas+1
if self.destapadas==90:
self.enjuego=False
mb.showinfo("Información", "Ganaste")
def reiniciar(self):
self.destapadas=0
self.eliminar_botones()
self.generar_tablero()
self.generar_bombas()
self.generar_bombas_proximas()
self.enjuego=True
def eliminar_botones(self):
for fila in range(0,10):
for columna in range(0,10):
if self.tablero[fila][columna]!=None:
self.tablero[fila][columna].destroy()
self.tablero[fila][columna]=None
def destapar(self):
for fila in range(0,10):
for columna in range(0,10):
if self.tablero[fila][columna]!=None:
if self.bombas[fila][columna]!="0":
self.tablero[fila][columna].configure(text=self.bombas[fila][columna])
aplicacion1=Aplicacion()
La recursividad en este problema se utiliza cuando hay que destapar casillas libres
a su alrededor en el método recorrer.
Las funciones de orden superior son funciones que pueden recibir como parámetros
otras funciones y/o devolverlas como resultados.
Veremos una serie de ejemplos muy sencillos para ver como Python implementa el
concepto de funciones de orden superior y a medida que avancemos en el curso
podremos ver las ventajas de este paradigma.
92.1. Problema 1
Definir una función de orden superior llamada operar. Llegan como parámetro dos
enteros y una función. En el bloque de la función llamar a la función que llega como
parámetro y enviar los dos primeros parámetros.
• Programa: ejercicio320.py
def operar(v1,v2,fn):
return fn(v1,v2)
def sumar(x1,x2):
return x1+x2
def restar(x1,x2):
return x1-x2
def multiplicar(x1,x2):
return x1*x2
def dividir(x1,x2):
return x1/x2
resu1=operar(10,3,sumar)
print(resu1)
resu2=operar(10,3,restar)
print(resu2)
print(operar(30,10,multiplicar))
print(operar(10,2,dividir))
def operar(v1,v2,fn):
return fn(v1,v2)
return fn(v1,v2)
Como la función operar retorna un valor debemos indicar con la palabra clave return
que devuelva el dato que a su vez retorna la función "fn".
Las cuatro funciones que calculan la suma, resta, multiplicación y división no tienen
nada nuevo a lo visto en conceptos anteriores:
def sumar(x1,x2):
return x1+x2
def restar(x1,x2):
return x1-x2
def multiplicar(x1,x2):
return x1*x2
def dividir(x1,x2):
return x1/x2
resu1=operar(10,3,sumar)
print(resu1)
Como vemos para pasar la referencia de una función solo indicamos su nombre.
La función operar retorna un entero y lo almacenamos en la variable resu1 que
mostramos luego por pantalla:
print(resu1)
resu2=operar(10,3,restar)
print(resu2)
print(operar(30,10,multiplicar))
print(operar(10,2,dividir))
Tener en cuenta que para sumar dos valores es mejor llamar directamente a la
función sumar y pasar los dos valores, pero el objetivo de este problema es conocer
la sintaxis de las funciones de orden superior presentando el problema más sencillo
posible.
92.2. Problema 2
Declarar una clase que almacene el nombre y la edad de una persona. Definir un
método que retorne True o False según si la persona es mayor de edad o no. Este
método debe recibir como parámetro una función que al llamarla pasando la edad
de la persona retornará si es mayor o no de edad.
Tener en cuenta que una persona es mayor de edad en Estados Unidos si tiene 21
o más años y en Argentina si tiene 18 o más años.
• Programa: ejercicio321.py
class Persona:
def init (self,nombre,edad):
self.nombre=nombre
self.edad=edad
def es_mayor(self,fn):
return fn(self.edad)
def mayor_estadosunidos(edad):
if edad>=21:
return True
else:
return False
def mayor_argentina(edad):
if edad>=18:
return True
else:
return False
persona1=Persona("juan", 18)
if persona1.es_mayor(mayor_argentina):
print(f"{persona1.nombre} es mayor si vive en Argentina")
else:
print(f"{persona1.nombre} no es mayor si vive en Argentina")
if persona1.es_mayor(mayor_estadosunidos):
print(f"{persona1.nombre} es mayor si vive en Estados Unidos")
else:
print(f"{persona1.nombre} no es mayor si vive en Estados Unidos")
class Persona:
def init (self,nombre,edad):
self.nombre=nombre
self.edad=edad
def es_mayor(self,fn):
return fn(self.edad)
Tenemos dos funciones que al pasar una edad nos retornan si es mayor de edad o
no:
def mayor_estadosunidos(edad):
if edad>=21:
return True
else:
return False
def mayor_argentina(edad):
if edad>=18:
return True
else:
return False
persona1=Persona("juan", 18)
if persona1.es_mayor(mayor_argentina):
print(f"{persona1.nombre} es mayor si vive en Argentina")
else:
print(f"{persona1.nombre} no es mayor si vive en Argentina")
if persona1.es_mayor(mayor_estadosunidos):
print(f"{persona1.nombre} es mayor si vive en Estados Unidos")
else:
print(f"{persona1.nombre} no es mayor si vive en Estados Unidos")
Es más común enviar una expresión lambda en lugar de enviar la referencia de una
función como vimos en el concepto anterior.
93.1. Problema 1
Definir una función de orden superior llamada operar. Llegan como parámetro dos
enteros y una función. En el bloque de la función llamar a la función que llega como
parámetro y enviar los dos primeros parámetros.
• Programa: ejercicio322.py
def operar(v1,v2,fn):
return fn(v1,v2)
def operar(v1,v2,fn):
return fn(v1,v2)
Una expresión lambda comienza por la palabra clave 'lambda' y está compuesta por
una serie de parámetros (en este caso x1 y x2), el signo ':' y el cuerpo de la función:
x1+x2
93.2. Problema 2
Confeccionar una función de orden superior que reciba una lista que almacena
valores enteros y una función con un parámetro entero y que retorne un boolean.
La función debe analizar cada elemento de la lista llamando a la función que recibe
como parámetro, si retorna un True se pasa a mostrar el elemento.
En el bloque principal definir una lista de enteros.
Imprimir de la lista:
En forma muy sencilla si queremos imprimir todo el arreglo retornamos para cada
elemento que analiza nuestra expresión lambda el valor True:
93.3. Problema 3
Confeccionar una función de orden superior que reciba un String y una función con
un parámetro de tipo String que retorna un Boolean.
La función debe analizar cada elemento del String llamando a la función que recibe
como parámetro, si retorna un True se agrega dicho caracter al String que se
retornará.
def filtrar(cadena,fn):
cad=""
for caracter in cadena:
if fn(caracter):
cad=cad+caracter
return cad
Nuestra función de orden superior se llama filtrar y recibe un String y una función:
def filtrar(cadena,fn):
cad=""
for caracter in cadena:
if fn(caracter):
cad=cad+caracter
return cad
print("String original")
print(cadena)
Para generar un String solo con las letras minúsculas debemos verificar si el
parámetro de la función anónima se encuentra en el rango 'a' y 'z':
Por último para recuperar todos los símbolos que no sean letras expresamos la
siguiente condición:
Con este problema podemos seguir apreciando las grandes ventajas que nos
proveen las expresiones lambdas para la resolución de algoritmos.
La comprensión de listas es una construcción en Python que nos permite crear listas
a partir de otras listas, tuplas y cualquier iterable.
Nos permite escribir en forma más concisa un algoritmo. Veamos con un ejemplo
como lo resolvemos con y sin comprensión de listas.
94.1. Problema 1
Definir una lista con 5 valores enteros, luego a partir de la primer lista generar una
segunda lista con los valores elevados al cuadrado.
• Programa: ejercicio325.py
lista1=[8, 5, 4, 10, 2]
lista2=[]
for elemento in lista1:
lista2.append(elemento*elemento)
print("Lista 1")
print(lista1)
print("Nueva lista")
print(lista2)
• Programa: ejercicio326.py
lista1=[8, 5, 4, 10, 2]
lista2=[elemento*elemento for elemento in lista1]
print("Lista 1")
print(lista1)
print("Nueva lista")
print(lista2)
Como vemos lo resolvemos en una sola línea:
lista2=[elemento*elemento for elemento in lista1]
Lo que hacíamos en 3 líneas:
lista2=[]
Esta construcción para el recorrido de iterables se ejecuta más rápido que la forma
tradicional. Requiere un poco de tiempo para adaptar nuestro razonamiento a la
nueva sintaxis.
94.2. Problema 2
Se tiene una lista con un conjunto de tuplas con los nombres y edades de personas:
personas=[('pedro',33),('ana',3),('juan',13),('carla',45)]
• Programa: ejercicio327.py
personas=[('pedro',33),('ana',3),('juan',13),('carla',45)]
personas_mayores=[per for per in personas if per[1]>=18]
print(personas_mayores)
94.3. Problema 3
Generar una lista con todos los valores múltiplos de 8 comprendidos entre 1 y 500.
• Programa: ejercicio328.py
Disponemos un for que recorre los valores del 1 al 500 inclusive, cada vez que el
resto de dividir dicho valor por 8 se verifica verdadero procedemos a guardar dicho
valor en la lista 'multiplos8'.
Varios for
94.4. Problema 4
Se tiene una lista de nombres de personas. Generar otra lista cuyos elementos sean
a su vez listas con dos nombres cada uno.
Tener en cuenta que nunca se debe combinar el mismo nombre dos veces.
• Programa: ejercicio329.py
nombres=['juan','pablo','luis','mauro','hector']
nombres_compuestos=[[nombre1,nombre2] for nombre1 in nombres for
nombre2 in nombres if nombre1!=nombre2]
print(nombres_compuestos)
Si analizamos:
Como tenemos dos estructuras for cada vez que de ejecuta el for interno
completamente avanza uno el for externo: 'for nombre1 in nombres for nombre2 in
nombres'.
nombres=['juan','pablo','luis','mauro','hector']
nombres_compuestos=[]
for nombre1 in nombres:
for nombre2 in nombres:
if nombre1!=nombre2:
nombres_compuestos.append([nombre1,nombre2])
print(nombres_compuestos)
Requiere tiempo para habituarse a las 'List Comprehensions', pero una vez que le
tomamos la mano podemos obtener grandes ventajas en la definición de algoritmos
muy breves.
94.5. Problema 5
• Programa: ejercicio330.py
• Programa: ejercicio330.py
Con una única línea tenemos tenemos una lista con la secuencia que pide el
problema:
Hemos visto en conceptos anteriores las estructuras de datos que vienen por
defecto en Python y hacen a la esencia de este lenguaje:
• Listas
• Tuplas
• Diccionarios
Para crear un conjunto por asignación debemos indicar sus elementos encerrados
entre llaves y separados por coma.
lenguajes.add("Ruby")
lenguajes.add("PHP")
95.1. Problema 1
Definir dos conjuntos que almacenen cada uno una serie de lenguajes de
programación. Efectuar las cuatro operaciones básicas con dichos conjuntos.
• Programa: ejercicio331.py
x=lenguajes1.symmetric_difference(lenguajes2)
print("lenguajes del conjunto lenguajes1 o del conjunto lenguajes2 pero no
en ambos")
print(x)
Conjuntos disjuntos.
La clase set dispone del método 'isdisjoint' que retorna True si los conjuntos no
tienen elementos en común:
dias_feriados={"sábado","domingo"}
dias_laborables={"lunes", "martes", "miércoles","jueves","viernes"};
if dias_laborables.isdisjoint(dias_feriados):
print("dias_laborables no tiene elementos en común con dias_feriados")
• conjunto1==conjunto2
• conjunto1!=conjunto2
• conjunto1<conjunto2 (si el conjunto1 es un subconjunto de conjunto2)
• conjunto1<=conjunto2 (si el conjunto1 es un subconjunto o es igual que
conjunto2)
• conjunto1>conjunto2 (si el conjunto1 es un superconjunto de conjunto2)
• conjunto1>=conjunto2 (si el conjunto1 es un superconjunto o es igual que
conjunto2)
dias_semana={"lunes", "martes",
"miércoles","jueves","viernes","sábado","domingo"}
dias_feriados={"sábado","domingo"}
dias_laborables={"lunes", "martes", "miércoles","jueves","viernes"}
if dias_feriados<dias_semana:
print("dias_feriados es un subconjunto de dias_semana")
if dias_feriados!=dias_laborables:
Ing. Álvaro Galeano Martínez 525
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
Acotaciones.
productos={}
productos["manzanas"]=39
productos["peras"]=32
productos["lechuga"]=17
print(productos)
Un uso común de los conjuntos es eliminar los valores repetidos de listas y tuplas:
Se crea un conjunto llamando a set y pasando como parámetro una lista, luego el
conjunto no almacena los valores repetidos de la lista.
Hay otra clase llamada 'frozenset' que permite crear conjuntos inmutables, es decir
que no se le pueden agregar o eliminar elementos una vez creado.
95.2. Problema 2
Realizar la carga de valores enteros y sumarlos, cada vez que se ingresa un valor
preguntar al operador si desea ingresar otro valor.
• Programa: ejercicio332.py
opciones_salir=frozenset(["no","NO"])
suma=0
while True:
valor=int(input("Ingrese un valor:"))
suma=suma+valor
op=input("Desea ingresar otro valor: [si/no]")
if op in opciones_salir:
break
print(f"La suma de los valores es {suma}")
Creamos un conjunto inmutable con las dos opciones que finalizarán la carga de
valores:
opciones_salir=frozenset(["no","NO"])
Tenga en cuenta que debe tener instalado el motor de base de datos PostgreSQL
para poder seguir este concepto. En el tutorial de PostgreSQL están todos los pasos
para su instalación.
Para crear una base de datos presionamos el botón derecho del mouse donde dice
"Databases" y seleccionamos la opción "Create"->"Database...":
Para poder ejecutar comandos SQL debemos presionar el botón derecho del mouse
sobre el nombre de la base de datos "bd1" y seleccionar la opción "Query Tool..":
Luego de ejecutar el programa pip podemos ver que nos informa que la instalación
del paquete se efectuó correctamente:
• Programa: ejercicio333.py
import psycopg2
conexion1.commit()
conexion1.close()
Ejecutemos este programa para que se efectúe la carga de las tres filas en la tabla
'articulos' de la base de datos 'bd1'.
Por el momento si queremos controlar que se han cargado las tres filas en la tabla
'articulos' podemos abrir el 'pgAdmin' que viene com PostgreSQL y ver el contenido
de la tabla:
Lo primero que hacemos es importar el módulo que nos permite conectarnos con
PostgreSQL:
import psycopg2
cursor1=conexion1.cursor()
La variable datos es una tupla que contiene los datos que se utilizarán en la
sustitución %s:
datos=("naranjas", 23.50)
cursor1.execute(sql, datos)
Es fundamental llamar al final al método 'commit' para que queden firmes los
comandos SQL 'insert':
conexion1.commit()
• Programa: ejercicio334.py
import psycopg2
print(fila)
conexion1.close()
Cuando ejecutamos el programa podemos ver que se recuperan todas las filas de
la tabla 'articulos':
cursor1=conexion1.cursor()
cursor1.execute("select codigo, descripcion, precio from articulos")
for fila in cursor1:
print(fila)
Las otras dos actividades fundamentales que podemos hacer con una tabla es
borrar filas y modificar datos.
• Programa: ejercicio335.py
import psycopg2
Cuando ejecutamos el programa podemos ver que se eliminó el artículo cuyo código
es 1 y se modificó el precio del artículo con código 3:
Luego de crear el cursor podemos llamar al método 'execute' varias veces y pasar
distintos comando SQL:
cursor1=conexion1.cursor()
cursor1.execute("delete from articulos where codigo=1")
cursor1.execute("update articulos set precio=50 where codigo=3")
Siempre que pasemos un comando SQL: insert, delete o update debemos llamar al
método commit para que quede firme los cambios en la base de datos:
conexion1.commit()
97.1. Problema:
Desarrollar una aplicación visual con la librería tkinter que permita implementar los
algoritmos de carga de artículos, consulta por código y listado completo.
El primer paso será crear una carpeta llamada 'proyecto5' y dentro de esta
crearemos los dos módulos:
• módulo: formularioarticulos.py
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
from tkinter import scrolledtext as st
import articulos
class FormularioArticulos:
def init (self):
self.articulo1=articulos.Articulos()
self.ventana1=tk.Tk()
self.ventana1.title("Mantenimiento de artículos")
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.carga_articulos()
self.consulta_por_codigo()
self.listado_completo()
self.cuaderno1.grid(column=0, row=0, padx=10, pady=10)
self.ventana1.mainloop()
def carga_articulos(self):
self.pagina1 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina1, text="Carga de artículos")
self.labelframe1=ttk.LabelFrame(self.pagina1, text="Artículo")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, text="Descripción:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.descripcioncarga=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labelframe1,
textvariable=self.descripcioncarga)
self.entrydescripcion.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, text="Precio:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.preciocarga=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelframe1, textvariable=self.preciocarga)
self.entryprecio.grid(column=1, row=1, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe1, text="Confirmar",
command=self.agregar)
self.boton1.grid(column=1, row=2, padx=4, pady=4)
def agregar(self):
datos=(self.descripcioncarga.get(), self.preciocarga.get())
self.articulo1.alta(datos)
mb.showinfo("Información", "Los datos fueron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
def consulta_por_codigo(self):
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Consulta por código")
self.labelframe1=ttk.LabelFrame(self.pagina2, text="Artículo")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, text="Código:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.codigo=tk.StringVar()
self.entrycodigo=ttk.Entry(self.labelframe1, textvariable=self.codigo)
self.entrycodigo.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, text="Descripción:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.descripcion=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labelframe1,
textvariable=self.descripcion, state="readonly")
self.entrydescripcion.grid(column=1, row=1, padx=4, pady=4)
self.label3=ttk.Label(self.labelframe1, text="Precio:")
self.label3.grid(column=0, row=2, padx=4, pady=4)
self.precio=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelframe1, textvariable=self.precio,
state="readonly")
self.entryprecio.grid(column=1, row=2, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe1, text="Consultar",
command=self.consultar)
self.boton1.grid(column=1, row=3, padx=4, pady=4)
def consultar(self):
datos=(self.codigo.get(), )
respuesta=self.articulo1.consulta(datos)
if len(respuesta)>0:
self.descripcion.set(respuesta[0][0])
self.precio.set(respuesta[0][1])
else:
self.descripcion.set('')
self.precio.set('')
mb.showinfo("Información", "No existe un artículo con dicho código")
def listado_completo(self):
self.pagina3 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina3, text="Listado completo")
self.labelframe1=ttk.LabelFrame(self.pagina3, text="Artículo")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.boton1=ttk.Button(self.labelframe1, text="Listado completo",
command=self.listar)
self.boton1.grid(column=0, row=0, padx=4, pady=4)
self.scrolledtext1=st.ScrolledText(self.labelframe1, width=30, height=10)
self.scrolledtext1.grid(column=0,row=1, padx=10, pady=10)
def listar(self):
respuesta=self.articulo1.recuperar_todos()
self.scrolledtext1.delete("1.0", tk.END)
for fila in respuesta:
self.scrolledtext1.insert(tk.END,
"código:"+str(fila[0])+"\ndescripción:"+fila[1]+"\nprecio:"+str(fila[2])+"\n\n")
aplicacion1=FormularioArticulos()
• módulo: articulos.py
import psycopg2
class Articulos:
def abrir(self):
conexion = psycopg2.connect(database="bd1", user="postgres",
password="123456")
return conexion
def recuperar_todos(self):
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio from articulos"
cursor.execute(sql)
return cursor.fetchall()
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
from tkinter import scrolledtext as st
import artículos
class FormularioArticulos:
def init (self):
self.articulo1=articulos.Articulos()
También en el método init llamamos a una serie de métodos para crear cada
una de las páginas del objeto de la clase 'Notebook':
self.ventana1=tk.Tk()
self.ventana1.title("Mantenimiento de artículos")
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.carga_articulos()
self.consulta_por_codigo()
self.listado_completo()
self.cuaderno1.grid(column=0, row=0, padx=10, pady=10)
self.ventana1.mainloop()
def agregar(self):
datos=(self.descripcioncarga.get(), self.preciocarga.get())
Luego llamamos al método alta del objeto 'articulo1' y le pasamos la tupla con los
datos a añadir:
self.articulo1.alta(datos)
mb.showinfo("Información", "Los datos fueron cargados")
self.descripcion.set("")
self.precio.set("")
En este momento nos conviene analizar el método 'alta' de la clase 'Articulos' que
se encuentra en el otro módulo:
def consultar(self):
datos=(self.codigo.get(), )
respuesta=self.articulo1.consulta(datos)
if len(respuesta)>0:
self.descripcion.set(respuesta[0][0])
self.precio.set(respuesta[0][1])
else:
self.descripcion.set('')
self.precio.set('')
mb.showinfo("Información", "No existe un artículo con dicho código")
Creamos una tubla con un solo dato (es obligatoria la coma para que Python lo
considere una tupla:
datos=(self.codigo.get(), )
• Listado completo
Para mostrar todas las filas de la tabla 'articulos' hemos dispuesto un objeto de la
clase 'scrolledtext':
def listar(self):
respuesta=self.articulo1.recuperar_todos()
self.scrolledtext1.delete("1.0", tk.END)
for fila in respuesta:
self.scrolledtext1.insert(tk.END, "código:"+str(fila[0])+
"\ndescripción:"+fila[1]+
"\nprecio:"+str(fila[2])+"\n\n")
def recuperar_todos(self):
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio from articulos"
cursor.execute(sql)
return cursor.fetchall()
Desarrollar una aplicación visual que muestre dos botones. Al presionar el primero
mostrar otra ventana para el login, y al presionar el segundo mostrar una ventana
de mensajes.
El archivo ' init .py' generalmente se encuentra vacío y tiene por objetivo indicar
al intérprete de Python que dicha carpeta es un paquete.
Es decir que debemos tener los siguientes archivos y carpeta en nuestra aplicación:
• módulo: login.py
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.labelframe1=ttk.LabelFrame(self.ventana1, text="Login:")
self.labelframe1.grid(column=0, row=0, padx=5, pady=10)
self.login()
def login(self):
self.label1=ttk.Label(self.labelframe1, text="Nombre de usuario:")
self.label1.grid(column=0, row=0, padx=4, pady=4)
self.entry1=ttk.Entry(self.labelframe1)
self.entry1.grid(column=1, row=0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, text="Ingrese clave:")
self.label2.grid(column=0, row=1, padx=4, pady=4)
self.entry2=ttk.Entry(self.labelframe1, show="*")
self.entry2.grid(column=1, row=1, padx=4, pady=4)
self.boton1=ttk.Button(self.labelframe1,
text="Ingresar",command=self.ingresar)
self.boton1.grid(column=1, row=2, padx=4, pady=4)
def ingresar(self):
self.ventana1.destroy()
def mostrar():
aplicacion1=Aplicacion()
• módulo: mensaje.py
from tkinter import messagebox as mb
def mostrar(mensaje):
mb.showerror("Cuidado",mensaje)
Recordar de crear el archivo ' init .py' en la carpeta 'formularios' y sin contenido
(luego veremos que podemos disponer código en su interior que se ejecutará
cuando importemos algún módulo del paquete)
Por otro lado creamos en la carpeta superior el script que contendrá la aplicación
principal de nuestro programa que lo llamaremos 'principal.py'
• principal.py
import tkinter as tk
from tkinter import ttk
import formularios.login
import formularios.mensaje
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.ventana1.title("Hola Mundo")
self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje",
command=self.mostrar_mensaje)
self.boton1.grid(column=0, row=0)
self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de login",
command=self.mostrar_login)
self.boton2.grid(column=0, row=1)
self.ventana1.mainloop()
def mostrar_mensaje(self):
formularios.mensaje.mostrar("Es una prueba de acceder a módulos de un
paquete")
def mostrar_login(self):
formularios.login.mostrar()
aplicacion1=Aplicacion()
import formularios.login
import formularios.mensaje
formularios.login.mostrar()
Acotaciones.
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.ventana1.title("Hola Mundo")
self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje",
command=self.mostrar_mensaje)
self.boton1.grid(column=0, row=0)
self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de
login", command=self.mostrar_login)
self.boton2.grid(column=0, row=1)
self.ventana1.mainloop()
def mostrar_mensaje(self):
formmensaje.mostrar("Es una prueba de acceder a módulos de un
paquete")
def mostrar_login(self):
formlogin.mostrar()
aplicacion1=Aplicacion()
formlogin.mostrar()
También podemos hacer uso de la sintaxis del 'from' para importar
módulos de un determinado paquete:
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def init (self):
self.ventana1=tk.Tk()
self.ventana1.title("Hola Mundo")
self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje",
command=self.mostrar_mensaje)
self.boton1.grid(column=0, row=0)
self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de
login", command=self.mostrar_login)
self.boton2.grid(column=0, row=1)
self.ventana1.mainloop()
def mostrar_mensaje(self):
mensaje.mostrar("Es una prueba de acceder a módulos de un
paquete")
def mostrar_login(self):
login.mostrar()
aplicacion1=Aplicacion()
import formularios.modales.login
import formularios.modales.mensaje
import formularios.nomodales.ayuda
El primer módulo que veremos del paquete 'urllib' se llama 'request' y tiene por
objetivo permitir acceder a cualquier recurso alojado en Internet.
El primer ejemplo nos mostrará la facilidad que tenemos en Python para recuperar
un archivo html localizado en Internet.
http://www.scratchya.com.ar/pythonya/ejercicio336/pagina1.html
• Programa: ejercicio336.py
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336
/pagina1.html")
datos=pagina.read()
print(datos)
La ejecución del script nos muestra el contenido del archivo 'pagina1.html' que se
encuentra en el servidor antes mencionado:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336
/pagina1.html")
datos=pagina.read()
print(datos)
El método 'read' recupera los datos como un bloque de bytes, si vemos la imagen
anterior donde imprimimos la variable 'datos' podemos comprobar que aparece
entre comillas y antecedido por el caracter 'b':
• Programa: ejercicio336.py
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
gina1.html")
datos=pagina.read()
datosutf8=datos.decode("utf-8")
print(datosutf8)
Lectura de una página HTML u otro recurso y posterior grabación del archivo en
forma local.
http://www.scratchya.com.ar/pythonya/ejercicio336/pagina1.html
http://www.scratchya.com.ar/pythonya/ejercicio336/imagen1.jpg
luego grabar los dos archivos en forma local en el equipo donde se está ejecutando
el script de Python.
• Programa: ejercicio337.py
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
gina1.html")
datos=pagina.read()
archivo1=open("pagina1.html","wb")
archivo1.write(datos)
archivo1.close()
imagen=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/i
magen1.jpg")
datos=imagen.read()
archivo2=open("imagen1.jpg","wb")
archivo2.write(datos)
archivo2.close()
Procedemos primero a importar el módulo 'request' del paquete 'ulrlib':
from urllib import request
Recuperamos del servidor el recurso 'pagina1.html' en formato binario:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
gina1.html")
datos=pagina.read()
archivo1=open("pagina1.html","wb")
archivo1.write(datos)
archivo1.close()
Los mismos pasos damos para recuperar el archivo 'imagen1.jpg' y crear el archivo
en nuestro equipo:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336
/pagina1.html")
datos=pagina.read()
archivo1=open("pagina1.html","wb")
archivo1.write(datos)
archivo1.close()
http://www.scratchya.com.ar/pythonya/ejercicio336/paginax.html
• Programa: ejercicio338.py
try:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
ginax.html")
datos=pagina.read().decode("utf-8")
print(datos)
except error.HTTPError as err:
print(f"Código de respuesta HTTP devuelto por el servidor {err.code}")
print(f"No existe el recurso {err.filename}")
Lo primero que hacemos además de importar el módulo 'request', es importar el
módulo 'error' también almacenado en el paquete 'urllib':
from urllib import request
from urllib import error
Al método 'urlopen' lo debemos disponer dentro de un bloque try:
try:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
ginax.html")
datos=pagina.read().decode("utf-8")
Ing. Álvaro Galeano Martínez 560
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
print(datos)
99.1.1 Confeccionar una aplicación visual con tkinter que permita ingresar en un
control de tipo 'Entry' la URL de un sitio web y al presionar un botón recuperar
los datos y mostrarlos en un control de tipo 'ScrolledText':
La Biblioteca estándar de Python cuenta con un módulo que nos facilita trabajar con
archivos JSON.
cadena="""
{
"codigo":"1",
"descripcion":"papas",
"precio":"13.45"
}
"""
print(cadena) # imprimimos un string
diccionario=json.loads(cadena)
print(diccionario) # imprimimos un diccionario
import json
cadena="""
[
{
"codigo":"1",
"descripcion":"papas",
"precio":"13.45"
},
{
"codigo":"2",
"descripcion":"manzanas",
"precio":"45"
}
]
Ing. Álvaro Galeano Martínez 564
CARTILLA DE APRENDIZAJE LENGUAJE DE PROGRAMACIÓN PYTHON
"""
100.1. Problema 1
Implementar un sitio WEB en PHP que retorne un archivo con formato JSON con
los datos de diferentes artículos.
Para resolver el problema debemos tener un conocimiento del lenguaje PHP y del
gestor de base de datos MySQL.
Cree una base de datos llamada 'pythonya' y una tabla 'articulos' con los siguientes
datos:
• Programa: retornararticulos.php
<?php
header('Content-Type: application/json');
$server="localhost";
$usuario="root";
$clave="";
$base="pythonya";
$conexion=mysqli_connect($server,$usuario,$clave,$base) or die("problemas")
;
mysqli_set_charset($conexion,'utf8');
Ahora implementaremos una aplicación en Python que recupere y muestre los datos
del archivo JSON generado en un servidor de Internet accediendo a una base de
datos MySQL a través de PHP:
• Programa: ejercicio340.py
pagina=request.urlopen("http://localhost/pythonya/retornararticulos.php")
datos=pagina.read().decode("utf-8")
print(datos) # imprimimos un string
print("_"*100)
lista=json.loads(datos) # convertimos el string a una lista
print(lista) # imprimimos una lista
print("_"*100)
for elemento in lista:
print(f"{elemento['codigo']} {elemento['descripcion']:50}
{elemento['precio']:>12}")
El resultado de ejecutar la aplicación (recuerde tener activo el servidor web con PHP
y MySQL):
pagina=request.urlopen("http://localhost/pythonya/retornararticulos.php")
datos=pagina.read().decode("utf-8")
Mediante el método 'loads' del módulo 'json' transformamos el contenido del string
en una lista con elementos de tipo diccionario:
Hacemos una impresión de cada elemento de la lista con un formato más legible
para el usuario:
100.2. Problema 2
La aplicación en PHP que recupera los datos de un determinado artículo que llega
como parámetro es:
• Programa: retornararunarticulo.php
<?php
header('Content-Type: application/json');
$server="localhost";
$usuario="root";
$clave="";
$base="pythonya";
$conexion=mysqli_connect($server,$usuario,$clave,$base) or
die("problemas") ;
mysqli_set_charset($conexion,'utf8');
Es importante notar que ahora recuperamos solo una fila de la tabla 'articulos', es
decir aquel que coincide con el código de artículo pasado en la llamada:
• Programa: ejercicio341.py
lista=json.loads(datos)
if len(lista)>0:
print(f"Descripción:{lista[0]['descripcion']}")
print(f"Precio:{lista[0]['precio']}")
else:
print("No existe un artículo con el código ingresado")
Una vez que recuperamos los datos del servidor procedemos a convertir el string
devuelto:
lista=json.loads(datos)
Si la lista no está vacía procedemos a mostrar la descripción y precio del
artículo consultado:
if len(lista)>0:
print(f"Descripción:{lista[0]['descripcion']}")
print(f"Precio:{lista[0]['precio']}")
100.3.1 Confeccionar una aplicación visual con tkinter que permita mostrar todos
los artículos. Recuperar del servidor web llamando al recurso
'retornararticulos.php'.
Disponer dos botones para poder navegar entre los distintos registros recuperados.
La interfaz visual debe ser similar a:
• El sitio web
• https://jsonplaceholder.typicode.com/
se puede utilizar para recuperar datos con diferentes formatos (JSON por ejemplo)
y probar nuestros algoritmos.
https://jsonplaceholder.typicode.com/posts
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio
reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et
cum\nreprehenderit
molestiae ut ut quas totam\nnostrum rerum est autem sunt rem
eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor
beatae ea dolores
neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut
reiciendis\nqui
aperiam non debitis possimus qui neque nisi nulla"
}]
Convertir los datos recuperados a una lista y mediante un for mostrar los atributos
"userID", "id", "title" y "body".
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "[email protected]",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "[email protected]",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
}
Convertir los datos recuperados a una lista y mediante un for mostrar todos los
atributos.
Definiciones básicas.
Como vemos son los dos caminos posibles para transformar una estructura de datos
en otra estructura.
101.1. Problema 1
• Programa: ejercicio345.py
import json
cadena1="""
[
{
"codigo":"1",
"descripcion":"papas",
"precio":"12"
},
{
"codigo":"2",
"descripcion":"naranjas",
"precio":"25"
}
]
"""
print(type(cadena1))
print(cadena1)
print("_"*80)
lista=json.loads(cadena1)
print(type(lista))
print(lista)
print("_"*80)
cadena2=json.dumps(lista)
print(type(cadena2))
print(cadena2)
cadena1="""
[
{
"codigo":"1",
"descripcion":"papas",
"precio":"12"
},
{
"codigo":"2",
"descripcion":"naranjas",
"precio":"25"
}
]
"""
print(type(cadena1))
Ahora mediante la función 'loads' del módulo 'json' que vimos en el concepto anterior
deserializamos el string:
lista=json.loads(cadena1)
Si imprimimos el tipo de la variable 'lista' podemos verificar que se trata de tipo 'list':
print(type(lista))
print(lista)
Para convertir una lista a tipo string debemos utilizar la función 'dumps' del módulo
'json':
cadena2=json.dumps(lista)
print(type(cadena2))
print(cadena2)
Los tipos de datos en JSON son muy similares a los tipos de datos en Python, pero
no son exactamente iguales.
Python JSON
dic object
str string
True true
False false
None null