Tutorial Es Program Ac I On Ya Python
Tutorial Es Program Ac I On Ya Python
Tutorial Es Program Ac I On Ya Python
Este curso esta 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.
¿Qué es un programa?
Programa: Conjunto de instrucciones que entiende una computadora para
realizar una actividad.
Todo programa tiene un objetivo bien definido: un procesador de texto es un
programa que permite cargar, modificar e imprimir textos, un programa de
ajedrez permite jugar al ajedrez contra el ordenador u otro contrincante
humano.
La actividad fundamental del programador es resolver problemas empleando el
ordenador como herramienta fundamental.
Para la resolución de un problema hay que plantear un algoritmo.
Algoritmo: Son los pasos a seguir para resolver un problema.
Diagrama de flujo
Un diagrama de flujo es la representación gráfica de un ALGORITMO.
Los símbolos gráficos principales a utilizar para el planteo de diagramas de
flujo son:
Estos son los elementos gráficos esenciales para el desarrollo de un diagrama
de flujo.
Retornar
Retornar
Problema
Hallar la superficie de un cuadrado conociendo el valor de un lado.
Diagrama de flujo:
lado=int(lado)
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(superficie)
Algunas consideraciones
Python es sensible a mayúsculas y minúsculas, no es lo mismo llamar a la
función input con la sintaxis: Input.
Los nombres de variables también son sensibles a mayúsculas y minúsculas.
Son dos variables distintas si en un lugar iniciamos a la variable "superficie" y
luego hacemos referencia a "Superficie"
Los nombres de variable no pueden tener espacios en blanco, caracteres
especiales y empezar con un número.
Todo el código debe escribirse en la misma columna, estará incorrecto si
escribimos:
Hay más restricciones que iremos aprendiendo a medida que avance el curso.
Retornar
Problema
Hallar la superficie de un cuadrado conociendo el valor de un lado.
Diagrama de flujo:
superficie=lado*lado*lado
Retornar
5 - Estructura de programación
secuencial
Cuando en un problema sólo participan operaciones, entradas y salidas se la
denomina una estructura secuencial.
Los problemas diagramados y codificados previamente emplean solo
estructuras secuenciales.
La programación requiere una práctica ininterrumpida de diagramación y
codificación de problemas.
Problema:
Realizar la carga de dos números enteros por teclado e imprimir su suma y su
producto.
Diagrama de flujo:
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:
Ver video
Ver video
Ver video
Ver video
Solución
Retornar
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:
Se hace la entrada de num1 y num2 por teclado. Para saber cual 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.
Como podemos observar nunca se imprimen num1 y num2 simultáneamente.
Estamos en presencia de una ESTRUCTURA CONDICIONAL COMPUESTA
ya que tenemos actividades por la rama del verdadero y del falso.
Programa: ejercicio10.py
Ver video
Operadores
En una condición deben disponerse únicamente variables, valores constantes y
operadores relacionales.
Operadores Relacionales:
== Igualdad
!= Desigualdad
< menor
> mayor
Operadores Matemáticos
+ suma
- resta
* multiplicación
/ división de flotantes
// división de enteros
% resto de una división
** exponenciación
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.
Problemas propuestos
• Realizar un programa que solicite la carga por teclado de dos números,
si el primero es mayor al segundo informar su suma y diferencia, en caso
contrario informar el producto y la división del primero respecto al
segundo.
Ver video
Ver video
Ver video
Solución
Retornar
7 - Estructuras condicionales
anidadas
Estamos en presencia de una estructura condicional anidada cuando por la
rama del verdadero o el falso de una estructura condicional hay otra estructura
condicional.
El diagrama de flujo que se presenta contiene dos estructuras condicionales.
La principal se trata de una estructura condicional compuesta y la segunda es
una estructura condicional simple y está contenida por la rama del falso de la
primer estructura.
Es común que se presenten estructuras condicionales anidadas aún más
complejas.
Problema:
Confeccionar un programa que pida por teclado tres notas de un alumno,
calcule el promedio e imprima alguno de estos mensajes:
Si el promedio es >=7 mostrar "Promocionado".
Si el promedio es >=4 y <7 mostrar "Regular".
Si el promedio es <4 mostrar "Reprobado".
Diagrama de flujo:
Problemas propuestos
• Se cargan por teclado tres números distintos. Mostrar por pantalla el
mayor de ellos.
Ver video
• Se ingresa por teclado un valor entero, mostrar una leyenda que indique
si el número es positivo, negativo o nulo (es decir cero)
Ver video
• Confeccionar un programa que permita cargar un número entero positivo
de hasta tres cifras y muestre un mensaje indicando si tiene 1, 2, o 3
cifras. Mostrar un mensaje de error si el número de cifras es mayor.
Ver video
Ver video
Solución
Retornar
Operador and
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 mas simple la solución.
La primera estructura condicional es una ESTRUCTURA CONDICIONAL
COMPUESTA con una CONDICION COMPUESTA.
Podemos leerla de la siguiente forma:
Si el contenido de la variable num1 es mayor al contenido de la variable num2
"Y" si el contenido de la variable num1 es mayor al contenido de la variable
num3 entonces la CONDICION COMPUESTA resulta Verdadera.
Si una de las condiciones simples da falso la CONDICION COMPUESTA da
Falso y continúa por la rama del falso.
Es decir que se mostrará el contenido de num1 si y sólo si num1 > num2 y
num1 > num3.
En caso de ser Falsa la condición, analizamos el contenido de num2 y num3
para ver cual tiene un valor mayor.
En esta segunda estructura condicional no se requieren operadores lógicos al
haber una condición simple.
Programa: ejercicio19.py
Ver video
Operador or
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: dia: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.
En la condición no participan las variables dia y año.
Programa: ejercicio20.py
Ver video
Problemas propuestos
• Realizar un programa que pida cargar una fecha cualquiera, luego
verificar si dicha fecha corresponde a Navidad.
Ver video
Ver video
Ver video
Ver video
Ver video
Ver video
Ver video
Solución
Retornar
Problema 1:
Realizar un programa que imprima en pantalla los números del 1 al 100.
Sin conocer las estructuras repetitivas podemos resolver el problema
empleando una estructura secuencial. Iniciamos una variable con el valor 1,
luego imprimimos la variable, incrementamos nuevamente la variable y así
sucesivamente.
Diagrama de flujo:
x
1
2
3
4
.
.
100
101 Cuando x vale 101 la condición de la estructura repetitiva retorna
falso,
en este caso finaliza el diagrama.
x=1
while x<=100:
print(x)
x=x+1
Recordemos que un problema no estará 100% solucionado si no codificamos
el programa en nuestro caso en Python que muestre los resultados buscados.
Es importante notar que seguido de la palabra clave while disponemos la
condición y finalmente los dos puntos. Todo el código contenido en la
estructura repetitiva debe estar indentado (normalmente a cuatro espacios)
Probemos algunas modificaciones de este programa y veamos que cambios se
deberían hacer para:
Respuestas:
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:
n x
5 1 (Se imprime el contenido de x)
2 " "
3 " "
4 " "
5 " "
6 (Sale del while porque 6 no es menor o igual a 5)
Programa: ejercicio29.py
Ver video
Problema 3:
Desarrollar un programa que permita la carga de 10 valores por teclado y nos
muestre posteriormente la suma de los valores ingresados y su promedio.
Diagrama de flujo:
promedio=suma//10
Problema 4:
Una planta que fabrica perfiles de hierro posee un lote de n piezas.
Confeccionar un programa que pida ingresar por teclado la cantidad de piezas
a procesar y luego ingrese la longitud de cada perfil; sabiendo que la pieza
cuya longitud esté comprendida en el rango de 1.20 y 1.30 son aptas. Imprimir
por pantalla la cantidad de piezas aptas que hay en el lote.
Diagrama de flujo:
Programa: ejercicio31.py
Ver video
cantidad=0
x=1
n=int(input("Cuantas piezas cargara:"))
while x<=n:
largo=float(input("Ingrese la medida de la pi
eza:"))
if largo>=1.2 and largo<=1.3:
cantidad=cantidad+1
x=x+1
print("La cantidad de piezas aptas son")
print(cantidad)
Veamos algunas cosas nuevas:
Cuando queremos cargar por teclado un valor con decimales debemos utilizar
la función float en lugar de int:
Ver video
Ver video
Ver video
Ver video
Ver video
Ver video
• if valor%2==0:
Ver video
Solución
Retornar
10 - Estructura repetitiva for
Cualquier problema que requiera una estructura repetitiva se puede resolver
empleando la estructura while, pero hay otra estructura repetitiva cuyo planteo
es más sencillo en ciertas situaciones que tenemos que recorrer una lista de
datos.
En general, la estructura repetitiva for se usa en aquellas situaciones en las
cuales queremos que una variable vaya tomando un valor de una lista definida
de valores.
Veremos con una serie de ejemplos el empleo del for.
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
Ver video
for x in range(101):
print(x)
Tenemos primero la palabra clave for y seguidamente el nombre de la variable
que almacenará en cada vuelta del for el valor entero que retorna la función
range.
La función range retorna la primera vez el valor 0 y se almacena en x, luego el
1 y así sucesivamente hasta que retorna el valor que le pasamos a range
menos uno (es decir en nuestro ejemplo al final retorna un 100)
Tengamos en cuenta que este mismo problema resuelto con la estructura while
debería ser:
Programa: ejercicio40.py
x=0
while x<101:
print(x)
x=x+1
Problema 2:
Realizar un programa que imprima en pantalla los números del 20 al 30.
Programa: ejercicio41.py
for x in range(20,31):
print(x)
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.
Problema 3:
Imprimir todos los números impares que hay entre 1 y 100.
Programa: ejercicio42.py
for x in range(1,100,2):
print(x)
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.
Problema 4:
Desarrollar un programa que permita la carga de 10 valores por teclado y nos
muestre posteriormente la suma de los valores ingresados y su promedio. Este
problema ya lo desarrollamos, lo resolveremos empleando la estructura for
para repetir la carga de los diez valores por teclado.
Programa: ejercicio43.py
Ver video
suma=0
for f in range(10):
valor=int(input("Ingrese valor:"))
suma=suma+valor
print("La suma es")
print(suma)
promedio=suma/10
print("El promedio es:")
print(promedio)
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)
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
Ver video
aprobados=0
reprobados=0
for f in range(10):
nota=int(input("Ingrese la nota:"))
if nota>=7:
aprobados=aprobados+1
else:
reprobados=reprobados+1
print("Cantidad de aprobados")
print(aprobados)
print("Cantidad de reprobados")
print(reprobados)
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.
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
Ver video
mul3=0
mul5=0
for f in range(10):
valor=int(input("Ingrese un valor:"))
if valor%3==0:
mul3=mul3+1
if valor%5==0:
mul5=mul5+1
print("Cantidad de valores ingresados múltiplos d
e 3")
print(mul3)
print("Cantidad de valores ingresados múltiplos d
e 5")
print(mul5)
Si ejecutamos el programa tenemos una salida similar a esta:
Problema 7:
Codificar un programa que lea n números enteros y calcule la cantidad de
valores mayores o iguales a 1000 (n se carga por teclado)
Este tipo de problemas también se puede resolver empleando la estructura
repetitiva for. Lo primero que se hace es cargar una variable que indique la
cantidad de valores a ingresar. Dicha variable se carga antes de entrar a la
estructura repetitiva for.
Programa: ejercicio46.py
Ver video
cantidad=0
n=int(input("Cuantos valores ingresará:"))
for f in range(n):
valor=int(input("Ingrese el valor:"))
if valor>=1000:
cantidad=cantidad+1
print("La cantidad de valores ingresados mayores
o iguales a 1000 son")
print(cantidad)
Problemas propuestos
Ha llegado nuevamente la parte fundamental, que es el momento donde uno
desarrolla individualmente un algoritmo para la resolución de un problema.
Ver video
Ver video
• Desarrollar un programa que muestre la tabla de multiplicar del 5 (del 5
al 50)
Ver video
Ver video
Ver video
Ver video
Ver video
Retornar
11 - Definición de comentarios en el
código fuente
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:
• conta1=0
• conta2=0
• conta3=0
• conta1=0
• conta2=0
• conta3=0
Se deben utilizar tres comillas simples o dobles seguidas al principio y al
final del comentario.
Problema 1:
Mostrar la tabla de multiplicar del 5 empleando primero el while y seguidamente
de nuevo empleando el for.
Programa: ejercicio55.py
Ver video
"""
Mostrar la tabla de 5 con las estructuras repetit
ivas:
while
y
for
"""
#utilizando el while
print("Tabla del 5 empleando el while")
x=5
while x<=50:
print(x)
x=x+5
#utilizando el for
print("Tabla del 5 empleando el for")
for x in range(5,51,5):
print(x)
Problemas propuestos
• 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.
Ver video
Ver video
Solución
Retornar
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:
nombre=input("ingrese su nombre:")
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
Ver video
edad1=int(input("Ingrese la edad:"))
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:
nombre1=input("Ingrese nombre:")
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
Ver video
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.
Mostrar la suma de los valores ingresados.
Programa: ejercicio60.py
Ver video
opcion="si"
suma=0
while opcion=="si":
valor=int(input("Ingrese un valor:"))
suma=suma+valor
opcion=input("Desea cargar otro numero (si/no
):")
print("La suma de valores ingresados es")
print(suma)
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.
El ciclo se corta cuando el operador carga un string distinto a "si".
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)
Problema propuesto
• Realizar la carga de dos nombres de personas distintos. Mostrar por
pantalla luego ordenados en forma alfabética.
Ver video
Solución
Retornar
nombre=input("Ingrese su nombre:")
== Igualdad
!= Desigualdad
< menor
> mayor
nombre='juan'
print(nombre[0]) #se imprime una j
if nombre[0]=="j": #verificamos si el primer caracter del string es una j
print(nombre)
print("comienza con la letra j")
nombre='juan'
print(len(nombre))
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
nombre=input("Ingrese su nombre:")
print("Primer caracter")
print(nombre[0])
print("Cantidad de letras del nombre:")
print(len(nombre))
Problema 2:
Solicitar la carga del nombre de una persona en minúsculas. Mostrar un
mensaje si comienza con vocal dicho nombre.
Programa: ejercicio63.py
Ver video
nombre=input("Ingrese su nombre:")
if nombre[0]=="a" or nombre[0]=="e" or nombre[0]=
="i" or nombre[0]=="o" or nombre[0]=="u":
print("El nombre ingresado comienza con vocal
")
else:
print("El nombre ingresado no comienza con vo
cal")
Con que una de las condiciones del if sea verdadera luego se ejecuta el bloque
del verdadero.
Problema 3:
Ingresar un mail por teclado. Verificar si el string ingresado contiene solo un
caracter "@".
Programa: ejercicio64.py
Ver video
mail=input("Ingrese un mail:")
cantidad=0
x=0
while x<len(mail):
if mail[x]=="@":
cantidad=cantidad+1
x=x+1
if cantidad==1:
print("Contiene solo un caracter @ el mail in
gresado")
else:
print("Incorrecto")
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)
Métodos propios de las cadenas de caracteres.
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.
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
Ver video
nombre1="mAriA"
print(nombre1)
nombre2=nombre1.upper()
print(nombre2)
nombre3=nombre1.lower()
print(nombre3)
nombre4=nombre1.capitalize()
print(nombre4)
El resultado de ejecutar este programa es:
Para llamar a un método del string debemos disponer entre el nombre del
string y el método el caracter punto:
nombre2=nombre1.upper()
Es importante decir que el string nombre1 no se modifica su contenido
(recordar que un string es inmutable) pero el método upper() retorna el
contenido de la variable nombre1 pera convertida a mayúsculas. El dato
devuelto se almacena en la variable nombre2.
Problemas propuestos
• 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 ""
Ver video
• 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.
Ver video
Ver video
Solución
Retornar
edad=12
altura=1.79
nombre="juan"
Problema 1:
Definir una lista que almacene 5 enteros. Sumar todos sus elementos y mostrar
dicha suma.
Programa: ejercicio69.py
Ver video
lista=[10,7,3,7,2]
suma=0
x=0
while x<len(lista):
suma=suma+lista[x]
x=x+1
print("Los elementos de la lista son")
print(lista)
print("La suma de todos sus elementos es")
print(suma)
lista=[10,7,3,7,2]
suma=0
x=0
while x<len(lista):
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:
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
Ver video
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
Ver video
lista=["ana", 7, 9]
print("Nombre del alumno:")
print(lista[0])
promedio=(lista[1]+lista[2])//2
print("Promedio de sus dos notas:")
print(promedio)
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.
Problemas propuestos
• Definir por asignación una lista con 8 elementos enteros. Contar cuantos
de dichos valores almacenan un valor superior a 100.
Ver video
• Definir una lista por asignación con 5 enteros. Mostrar por pantalla solo
los elementos con valor iguales o superiores a 7.
Ver video
Ver video
Solución
Retornar
print(len(lista)) # imprime un 3
lista.append(100)
print(len(lista)) # imprime un 4
print(lista[0]) # imprime un 10
print(lista[3]) # imprime un 100
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
Ver video
#imprimimos la lista
print(lista)
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)
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
Ver video
lista=[]
valor=int(input("Ingresar valor (0 para finalizar
):"))
while valor!=0:
lista.append(valor)
valor=int(input("Ingresar valor (0 para final
izar):"))
print("Tamano de la lista:")
print(len(lista))
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))
Problemas propuestos
• Almacenar en una lista los sueldos (valores float) de 5 operarios.
Imprimir la lista y el promedio de sueldos.
Ver video
Ver video
• 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.
Ver video
Solución
Retornar
Problema 1:
Crear y cargar una lista con 5 enteros. Implementar un algoritmo que
identifique el mayor valor de la lista.
Ver video
Programa: ejercicio80.py
lista=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
mayor=lista[0]
for x in range(1,5):
if lista[x]>mayor:
mayor=lista[x]
print("Lista completa")
print(lista)
print("Mayor de la lista")
print(mayor)
Primero procedemos a cargar por teclado los 5 valores en la lista:
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
mayor=lista[0]
for x in range(1,5):
Dentro del for mediante una estructura condicional verificamos si el elemento
de la posición x de la lista es mayor al que hemos considerado hasta este
momento como mayor:
if lista[x]>mayor:
mayor=lista[x]
print("Mayor de la lista")
print(mayor)
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
Ver video
lista=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
menor=lista[0]
posicion=0
for x in range(1,5):
if lista[x]<menor:
menor=lista[x]
posicion=x
print("Lista completa")
print(lista)
print("Menor de la lista")
print(menor)
print("Posicion del menor en la lista")
print(posicion)
Iniciamos una lista vacía y cargamos 5 elementos enteros:
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
print("Lista completa")
print(lista)
print("Menor de la lista")
print(menor)
print("Posicion del menor en la lista")
print(posicion)
Problemas propuestos
• Ingresar por teclado los nombres de 5 personas y almacenarlos en una
lista. Mostrar el nombre de persona menor en orden alfabético.
Ver video
Ver video
Solución
Retornar
17 - Listas paralelas
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.
Esta relación la conoce únicamente el programador y se hace para facilitar el
desarrollo de algoritmos que procesen los datos almacenados en las
estructuras de datos.
Problema 1:
Desarrollar un programa que permita cargar 5 nombres de personas y sus
edades respectivas. Luego de realizar la carga por teclado de todos los datos
imprimir los nombres de las personas mayores de edad (mayores o iguales a
18 años)
Programa: ejercicio84.py
Ver video
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 person
a:"))
edades.append(ed)
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])
Problemas propuestos
• 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.
Ver video
Ver video
Ver video
Solución
Retornar
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.
La primera aproximación para llegar en el próximo problema al ordenamiento
completo de una lista tiene por objetivo analizar los intercambios de elementos
dentro de la lista y dejar el mayor en la última posición.
El algoritmo consiste en comparar si la primera componente es mayor a la
segunda, en caso que la condición sea verdadera, intercambiamos los
contenidos de las componentes.
Vamos a suponer que se ingresan los siguientes valores por teclado:
1200
750
820
550
490
Cuando x = 0 x = 1 x = 2 x = 3
sueldos=[]
for x in range(5):
valor=int(input("Ingrese sueldo:"))
sueldos.append(valor)
for x in range(4):
if sueldos[x]>sueldos[x+1]:
aux=sueldos[x]
sueldos[x]=sueldos[x+1]
sueldos[x+1]=aux
750
820
550
490
1200
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.
Realicemos una prueba del siguiente algoritmo:
Cuando k = 0
x = 0 x = 1 x = 2 x = 3
750 750 750 750
1200 820 820 820
820 1200 550 550
550 550 1200 490
490 490 490 1200
Cuando k = 1
x = 0 x = 1 x = 2 x = 3
750 750 750 750
820 550 550 550
550 820 490 490
490 490 820 820
1200 1200 1200 1200
Cuando k = 2
x = 0 x = 1 x = 2 x = 3
550 550 550 550
750 490 490 490
490 750 750 750
820 820 820 820
1200 1200 1200 1200
Cuando k = 3
x = 0 x = 1 x = 2 x = 3
490 490 490 490
550 550 550 550
750 750 750 750
820 820 820 820
1200 1200 1200 1200
Programa: ejercicio89.py
Ver video
sueldos=[]
for x in range(5):
valor=int(input("Ingrese sueldo:"))
sueldos.append(valor)
for k in range(4):
for x in range(4):
if sueldos[x]>sueldos[x+1]:
aux=sueldos[x]
sueldos[x]=sueldos[x+1]
sueldos[x+1]=aux
print("Lista ordenada")
print(sueldos)
¿Porque repetimos 4 veces el for externo?
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)
Una última consideración a este ALGORITMO de ordenamiento es que los
elementos que se van ordenando continuamos comparándolos.
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
Problemas propuestos
• Crear una lista y almacenar los nombres de 5 países. Ordenar
alfabéticamente la lista e imprimirla.
Ver video
Ver video
Ver video
Solución
Retornar
Problema 1:
Confeccionar un programa que permita cargar los nombres de 5 alumnos y sus
notas respectivas. Luego ordenar las notas de mayor a menor. Imprimir las
notas y los nombres de los alumnos.
Debe quedar claro que cuando intercambiamos las notas para dejarlas
ordenadas de mayor a menor debemos intercambiar los nombres para que las
listas continúen paralelas (es decir que en los mismos subíndices de cada lista
continúe la información relacionada)
Programa: ejercicio93.py
Ver video
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
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])
Ver video
Solución
Retornar
20 - Listas: componentes de tipo lista
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.
Problema 1:
Crear una lista por asignación. La lista tiene que tener cuatro elementos. Cada
elemento debe ser una lista de 3 enteros.
Imprimir sus elementos accediendo de diferentes modos.
Programa: ejercicio95.py
Ver video
[1,2,3]
[4,5,6]
print(lista)
Aparece:
print(lista[0])
[1, 2, 3]
print(lista[0][0])
Nos muestra:
for x in range(len(lista[0])):
print(lista[0][x])
for k in range(len(lista)):
for x in range(len(lista[k])):
print(lista[k][x])
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
Ver video
lista=[[1,1,1,1,1], [2,2,2,2,2]]
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)
print("----------")
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)
print("----------")
for k in range(len(lista)):
suma=0
for x in range(len(lista[k])):
suma=suma+lista[k][x]
print(suma)
Hemos resuelto el problema de tres formas.
La primer forma es acceder a cada elemento en forma secuencial, esto se
resuelve de esta forma si tenemos que acceder a un pequeño número de
elementos, es decir si la lista es pequeña:
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)
for k in range(len(lista)):
suma=0
for x in range(len(lista[k])):
suma=suma+lista[k][x]
print(suma)
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
Ver video
suma=0
for k in range(len(lista)):
for x in range(len(lista[k])):
suma=suma+lista[k][x]
print(suma)
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]
Problemas propuestos
• Se tiene la siguiente lista:
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.
Ver video
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.
Ver video
• 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.
Ver video
Solución
Retornar
En muchas situaciones debemos crear una nueva lista ingresando los datos
por teclado o por operaciones del mismo programa.
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.
Si cargáramos los datos por asignación sería algo parecido a esto:
nombres=[]
notas=[]
for x in range(3):
nom=input("Ingrese el nombre del alumno:")
nombres.append(nom)
no1=int(input("Ingrese la primer nota:"))
no2=int(input("Ingrese la segunda nota:"))
notas.append([no1,no2])
for x in range(3):
print(nombres[x],notas[x][0],notas[x][1])
La ejecución del programa tiene una salida por pantalla similar a:
La creación de las dos listas no difiere una de otra:
nombres=[]
notas=[]
for x in range(3):
nom=input("Ingrese el nombre del alumno:")
nombres.append(nom)
Lo nuevo se presenta cuando queremos añadir elementos a la lista notas, lo
hacemos con el mismo método append pero le pasamos como parámetro una
lista con dos elementos:
for x in range(3):
print(nombres[x],notas[x][0],notas[x][1])
Problema 2:
Se tiene que cargar la siguiente información:
· Nombres de 3 empleados
· Ingresos en concepto de sueldo, cobrado por cada empleado, en los últimos 3
meses.
Confeccionar el programa para:
a) Realizar la carga de los nombres de empleados y los tres sueldos por cada
empleado.
b) Generar una lista que contenga el ingreso acumulado en sueldos en los
últimos 3 meses para cada empleado.
c) Mostrar por pantalla el total pagado en sueldos a cada empleado en los
últimos 3 meses
d) Obtener el nombre del empleado que tuvo el mayor ingreso acumulado
En este problema definiremos tres listas:
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:
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
Ver video
nombres=[]
sueldos=[]
totalsueldos=[]
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)
for x in range(3):
print(nombres[x], totalsueldos[x])
posmayor=0
mayor=totalsueldos[0]
for x in range(1,3):
if totalsueldos[x]>mayor:
mayor=totalsueldos[x]
posmayor=x
print("Empleado con mayores ingresos en los ultim
os tres meses")
print(nombres[posmayor])
print("con un ingreso de",mayor)
Definimos 3 listas:
nombres=[]
sueldos=[]
totalsueldos=[]
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)
for x in range(3):
print(nombres[x], totalsueldos[x])
posmayor=0
mayor=totalsueldos[0]
for x in range(1,3):
if totalsueldos[x]>mayor:
mayor=totalsueldos[x]
posmayor=x
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
Ver video
lista=[]
elementos=int(input("Cuantos elementos tendra la
lista:"))
sub=int(input("Cuantos elementos tendran las list
as internas:"))
for k in range(elementos):
lista.append([])
for x in range(sub):
valor=int(input("Ingrese valor:"))
lista[k].append(valor)
print(lista)
suma=0
for k in range(len(lista)):
for x in range(len(lista[k])):
suma=suma+lista[k][x]
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.
Problema 4:
Definir dos listas de 3 elementos.
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.
Imprimir los nombres del padre, la madre y sus hijos.
También imprimir solo el nombre del padre y la cantidad de hijos que tiene
dicho padre.
Un ejemplo si se define por asignación:
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
Ver video
padres=[]
hijos=[]
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 fam
ilia:"))
hijos.append([])
for x in range(cant):
nom=input("Ingrese el nombre del hijo:")
hijos[k].append(nom)
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)
Problemas propuestos
• Se desea saber la temperatura media trimestral de cuatro paises. Para
ello se tiene como dato las temperaturas medias mensuales de dichos
paises.
Se debe ingresar el nombre del país y seguidamente las tres
temperaturas medias mensuales.
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.
b - Imprimir los nombres de las paises y las temperaturas medias
mensuales de las mismas.
c - Calcular la temperatura media trimestral de cada país.
c - Imprimir los nombres de los paises y las temperaturas medias
trimestrales.
b - Imprimir el nombre del pais con la temperatura media trimestral
mayor.
Ver video
Ver video
• Desarrollar un programa que cree una lista de 50 elementos. El primer
elemento es una lista con un elemento entero, el segundo elemento es
una lista de dos elementos etc.
La lista debería tener esta estructura y asignarle esos valores a medida
que se crean los elementos:
Ver video
Solución
Retornar
lista.append(120)
lista.pop(0)
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
Ver video
print(lista)
lista.pop(0)
lista.pop(1)
lista.pop(2)
print(lista)
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.
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
Ver video
lista=[]
for x in range(10):
valor=int(input("Ingrese valor:"))
lista.append(valor)
print(lista)
posicion=0
while posicion<len(lista):
if lista[posicion]==5:
lista.pop(posicion)
else:
posicion=posicion+1
print(lista)
Mediante un for cargamos 10 elementos en la lista:
lista=[]
for x in range(10):
valor=int(input("Ingrese valor:"))
lista.append(valor)
posicion=0
while posicion<len(lista):
if lista[posicion]==5:
lista.pop(posicion)
else:
posicion=posicion+1
del(lista[0])
del(lista[1])
del(lista[2])
print(lista) # 20 40
Problemas propuestos
• 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)
Ver video
Ver video
Solución
Retornar
23 - Concepto de funciones -
Programación estructurada
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)
Cuando los problemas a resolver tienden a ser más grandes la metodología de
programación lineal se vuelve ineficiente y compleja.
El segundo paradigma de programación que veremos es la programación
estructurada.
La programación estructurada busca dividir o descomponer un problema
complejo en pequeños problemas. La solución de cada uno de esos pequeños
problemas nos trae la solución del problema complejo.
En Python el planteo de esas pequeñas soluciones al problema complejo se
hace dividiendo el programa en funciones.
Una función es un conjunto de instrucciones en Python que resuelven un
problema específico.
El lenguaje Python ya tiene incorporada algunas funciones básicas. Algunas de
ellas ya las utilizamos en conceptos anteriores como son las funciones: print,
len y range.
Veamos ahora como crear nuestras propias funciones.
El tema de funciones en un principio puede presentar dificultades para
entenderlo y ver sus ventajas ante la metodología de programación lineal que
veníamos trabajando en conceptos anteriores.
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.
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.
Implementar estas actividades en tres funciones.
Programa: ejercicio112.py
Ver video
def presentacion():
print("Programa que permite cargar dos valore
s por teclado.")
print("Efectua la suma de los valores")
print("Muestra el resultado de la suma")
print("*******************************")
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)
def finalizacion():
print("*******************************")
print("Gracias por utilizar este programa")
# programa principal
presentacion()
carga_suma()
finalizacion()
La forma de organizar nuestro programa cambia en forma radical.
El programa ahora no empieza a ejecutarse en la línea 1.
El programa principal comienza a ejecutarse luego del comentario "programa
principal":
# programa principal
presentacion()
carga_suma()
finalizacion()
def presentacion():
print("Programa que permite cargar dos valores por teclado.")
print("Efectua la suma de los valores")
print("Muestra el resultado de la suma")
print("*******************************")
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)
def finalizacion():
print("*******************************")
print("Gracias por utilizar este programa")
Luego de definir las funciones tenemos al final de nuestro archivo *.py las
llamadas de las funciones:
# programa principal
presentacion()
carga_suma()
finalizacion()
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:
# programa principal
# programa principal
finalizacion()
carga_suma()
presentacion()
print("*******************************")
print("Gracias por utilizar este programa")
Problema 2:
Confeccionar una aplicación que solicite la carga de dos valores enteros y
muestre su suma.
Repetir la carga e impresion de la suma 5 veces.
Mostrar una línea separadora después de cada vez que cargamos dos valores
y su suma.
Programa: ejercicio113.py
Ver video
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)
def separacion():
print("*******************************")
# programa principal
for x in range(5):
carga_suma()
separacion()
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()
Problemas propuestos
• Desarrollar un programa con dos funciones. La primer solicite el ingreso
de un entero y muestre el cuadrado de dicho valor. La segunda que
solicite la carga de dos valores y muestre el producto de los mismos.
LLamar desde el bloque del programa principal a ambas funciones.
Ver video
Ver video
Solución
Retornar
24 - Funciones: parámetros
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.
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
Ver video
def mostrar_mensaje(mensaje):
print("**************************************
***********")
print(mensaje)
print("**************************************
***********")
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)
# programa principal
def mostrar_mensaje(mensaje):
print("*************************************************")
print(mensaje)
print("*************************************************")
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
Ver video
def mostrar_mayor(v1,v2,v3):
print("El valor mayor de los tres numeros es"
)
if v1>v2 and v1>v3:
print(v1)
else:
if v2>v3:
print(v2)
else:
print(v3)
def cargar():
valor1=int(input("Ingrese el primer valor:"))
valor2=int(input("Ingrese el segundo valor:")
)
valor3=int(input("Ingrese el tercer valor:"))
mostrar_mayor(valor1,valor2,valor3)
# programa principal
cargar()
Es importante notar que un programa en Python no ejecuta en forma lineal las
funciones definidas en el archivo *.py sino que arranca en la zona del bloque
principal. En nuestro ejemplo se llama primero a la función "cargar()", esta
función no tiene parámetros.
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.
La función mostrar_mayor recibe en sus parámetros v1, v2 y v3 los valores
cargados en las variables valor1, valor2 y valor3.
Los parámetros son la forma que nos permite comunicar la función cargar con
la función mostrar_mayor.
Dentro de la función mostrar_mayor no podemos acceder a las variable valor1,
valor2 y valor3 ya que son variables locales de la función cargar.
La definición mostrar_mayor debe estar escrita antes de la definición de la
función cargar que es donde la llamamos.
Otra cosa importante notar que en la sección del programa principal solo
llamamos a la función cargar, es decir que en esta zona no es obligatorio
llamar a cada una de las funciones que definimos.
Problema 3:
Desarrollar un programa que permita ingresar el lado de un cuadrado. Luego
preguntar si quiere calcular y mostrar su perímetro o su superficie.
Programa: ejercicio118.py
Ver video
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/superfi
cie]?")
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.
Problemas propuestos
• Desarrollar una funcion que reciba un string como parametro y nos
muestre la cantidad de vocales. Llamarla desde el bloque principal del
programa 3 veces con string distintos.
Ver video
Ver video
Solución
Retornar
25 - Funciones: retorno de datos
Hemos comenzado a pensar con la metodología de programación
estructurada. Buscamos dividir un problema en subproblemas y plantear
algoritmos en Python que los resuelvan.
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)
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
Ver video
def retornar_superficie(lado):
sup=lado*lado
return sup
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.
Hay un cambio importante cuando llamamos o invocamos a una función que
devuelve un dato:
superficie=retornar_superficie(va)
retornar_superficie(va)
Problema 2:
Confeccionar una función que le enviemos como parámetros dos enteros y nos
retorne el mayor.
Programa: ejercicio121.py
Ver video
def retornar_mayor(v1,v2):
if v1>v2:
mayor=v1
else:
mayor=v2
return mayor
# bloque principal
valor1=int(input("Ingrese el primer valor:"))
valor2=int(input("Ingrese el segundo valor:"))
print(retornar_mayor(valor1,valor2))
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
Cuando una función encuentra la palabra return no sigue ejecutando el resto
de la función sino que sale a la línea del programa desde donde llamamos a
dicha función.
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
Ver video
def largo(cadena):
return len(cadena)
# bloque principal
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")
Problemas propuestos
• Elaborar una función que reciba tres enteros y nos retorne el valor
promedio de los mismos.
Ver video
Ver video
• Confeccionar una función que calcule la superficie de un rectángulo y la
retorne, la función recibe como parámetros los valores de dos de sus
lados:
• def retornar_superficie(lado1,lado2):
Ver video
Solución
Retornar
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
Ver video
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
# bloque principal del programa
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
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
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
Ver video
def mayormenor(lista):
may=lista[0]
men=lista[0]
for x in range(1,len(lista)):
if lista[x]>may:
may=lista[x]
else:
if lista[x]<men:
men=lista[x]
print("El valor mayor de la lista es", may)
print("El valor menor de la lista es", men)
# bloque principal
lista=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
mayormenor(lista)
En el bloque principal de nuestro programa cargamos dentro de un for 5
valores enteros y los añadimos a la estructura de datos "lista".
Fuera del for procedemos a llamar a la función mayormenor y procedemos a
enviarle la lista para que pueda consultar sus datos.
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.
Problemas propuestos
• 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)
Ver video
• 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:
Ver video
Ver video
Solución
Retornar
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
Ver video
def carga_lista():
li=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
li.append(valor)
return li
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])
lista=carga_lista()
imprimir_mayor10(lista)
Recordemos que el programa empieza a ejecutarse desde el bloque principal y
no se ejecutan cada función en forma lineal. Lo primero que hacemos en el
bloque principal del programa es llamar a la función carga_lista y se la
asignamos a una variable que recibirá la referencia de la función que se creará
en carga_lista:
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
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])
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
Ver video
def carga_lista():
li=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
li.append(valor)
return li
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]
return [ma,me]
lista=carga_lista()
rango=retornar_mayormenor(lista)
print("Mayor elemento de la lista:",rango[0])
print("Menor elemento de la lista:",rango[1])
Lo interesante que tenemos que sacar de este ejemplo es que cuando
tenemos que retornar varios valores podemos utilizar una lista. La función
retornar_mayormenor debe devolver dos enteros, y la forma de hacerlo en
Python es mediante una lista.
En la función retornar_mayormenor definimos dos variables locales donde
almacenamos el primer elemento de la lista que recibimos como parámetro:
def retornar_mayormenor(li):
ma=li[0]
me=li[0]
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)
Problema 3:
Desarrollar un programa que permita cargar 5 nombres de personas y sus
edades respectivas. Luego de realizar la carga por teclado de todos los datos
imprimir los nombres de las personas mayores de edad (mayores o iguales a
18 años)
Imprimir la edad promedio de las personas.
Programa: ejercicio134.py
Ver video
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]
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:",promed
io)
# bloque principal
nombres,edades=cargar_datos()
mayores_edad(nombres,edades)
promedio_edades(edades)
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()
# bloque principal
nombres,edades=cargar_datos()
mayores_edad(nombres,edades)
promedio_edades(edades)
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)
Problemas propuestos
• En una empresa se almacenaron los sueldos de 10 personas.
Desarrollar las siguientes funciones y llamarlas desde el bloque principal:
1) Carga de los sueldos en una lista.
2) Impresión de todos los sueldos.
3) Cuántos tienen un sueldo superior a $4000.
4) Retornar el promedio de los sueldos.
5) Mostrar todos los sueldos que están por debajo del promedio.
Ver video
• Desarrollar una aplicación que permita ingresar por teclado los nombres
de 5 artículos y sus precios.
Definir las siguientes funciones:
1) Cargar los nombres de articulos y sus precios.
2) Imprimir los nombres y precios.
3) Imprimir el nombre de artículo con un precio mayor
4) Ingresar por teclado un importe y luego mostrar todos los artículos con
un precio menor igual al valor ingresado.
Ver video
Ver video
Solución
Retornar
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
Ver video
def titulo_subrayado(titulo,caracter="*"):
print(titulo)
print(caracter*len(titulo))
# bloque principal
titulo_subrayado("Sistema de Administracion")
titulo_subrayado("Ventas","-")
Cuando ejecutamos esta aplicación podemos observar el siguiente resultado:
titulo_subrayado("Sistema de Administracion")
titulo_subrayado("Ventas","-")
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:
Problema propuesto
• Confeccionar una función que reciba entre 2 y 5 enteros. La misma nos
debe retornar la suma de dichos valores. Debe tener tres parámetros por
defecto.
Ver video
Solución
Retornar
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
Ver video
def calcular_sueldo(nombre,costohora,cantidadhora
s):
sueldo=costohora*cantidadhoras
print(nombre,"trabajo",cantidadhoras,"y cobra
un sueldo de",sueldo)
# bloque principal
calcular_sueldo("juan",10,120)
calcular_sueldo(costohora=12,cantidadhoras=40,nom
bre="ana")
calcular_sueldo(cantidadhoras=90,nombre="luis",co
stohora=7)
def calcular_sueldo(nombre,costohora,cantidadhoras):
sueldo=costohora*cantidadhoras
print(nombre,"trabajo",cantidadhoras,"y cobra un sueldo de",sueldo)
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.
Por ejemplo si ejecutamos
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="-")
Problema 2:
Cargar una lista de 10 enteros, luego mostrarlos por pantalla a cada elemento
separados por una coma.
Programa: ejercicio141.py
Ver video
def cargar():
lista=[]
for x in range(10):
valor=int(input("Ingrese valor:"))
lista.append(valor)
return lista
def imprimir(lista):
for x in range(len(lista)):
print(lista[x], end=",")
# bloque principal
lista=cargar()
imprimir(lista)
Lo nuevo en este problema aparece cuando imprimimos los elementos de la
lista, como necesitamos que se muestren todos en la misma línea y separados
por coma cargamos en el parámetro end la cadena ",":
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
Problema propuesto
• 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.
Ver video
Solución
Retornar
30 - Funciones: con cantidad variable
de parámetros
Otra variante en la declaración de una función en Python es la definición de
una cantidad variable de parámetros.
Para definir una cantidad variable de parámetros debemos anteceder el
caracter asterísco (*) al último parámetro de la función.
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
Ver video
def sumar(v1,v2,*lista):
suma=v1+v2
for x in range(len(lista)):
suma=suma+lista[x]
return suma
# bloque principal
def sumar(v1,v2,*lista):
suma=v1+v2
for x in range(len(lista)):
suma=suma+lista[x]
return suma
print(sumar(1,2))
print(sumar(1,2,3,4))
print(sumar(1,2,3,4,5,6,7,8,9,10))
li=[2, 4, 5]
su=sumar(*li)
print(su)
La función 'sumar' tiene 3 parámetro y la llamamos con la sintaxis:
su=sumar(*li)
Problema propuesto
• 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)
Ver video
Solución
Retornar
tupla=(1, 2, 3)
fecha=(25, "Diciembre", 2016)
punto=(10, 2)
persona=("Rodriguez", "Pablo", 43)
print(tupla)
print(fecha)
print(punto)
print(persona)
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.
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
Ver video
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)
def imprimir_fecha(fecha):
print(fecha[0],fecha[1],fecha[2],sep="/")
# bloque principal
fecha=cargar_fecha()
imprimir_fecha(fecha)
En la función cargar_fecha cargamos tres enteros por teclado y procedemos a
crear una tupla indicando entre paréntesis los nombres de las tres variables y
procedemos a retornarla:
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()
Definimos una función que recibe la tupla y procede a mostrar el contenido
separado por el caracter "/":
def imprimir_fecha(fecha):
print(fecha[0],fecha[1],fecha[2],sep="/")
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
Ver video
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
Problemas propuestos
• Confeccionar un programa con las siguientes funciones:
1)Cargar una lista de 5 enteros.
2)Retornar el mayor y menor valor de la lista mediante una tupla.
Desempaquetar la tupla en el bloque principal y mostrar el mayor y
menor.
Ver video
• # bloque principal
•
• empleado1=cargar_empleado()
• empleado2=cargar_empleado()
• mayor_sueldo(empleado1,empleado2)
Ver video
Solución
Retornar
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)
Problema 1:
Almacenar en una lista de 5 elementos tuplas que guarden el nombre de un
pais y la cantidad de habitantes.
Definir tres funciones, en la primera cargar la lista, en la segunda imprimirla y
en la tercera mostrar el nombre del país con mayor cantidad de habitantes.
Programa: ejercicio152.py
Ver video
def cargar_paisespoblacion():
paises=[]
for x in range(5):
nom=input("Ingresar el nombre del pais:")
cant=int(input("Ingrese la cantidad de ha
bitantes:"))
paises.append((nom,cant))
return paises
def imprimir(paises):
print("Paises y su poblacion")
for x in range(len(paises)):
print(paises[x][0],paises[x][1])
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])
# bloque principal
paises=cargar_paisespoblacion()
imprimir(paises)
pais_maspoblacion(paises)
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 paises
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])
Problemas propuestos
• 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)
El programa debe tener las siguientes funciones:
1)Carga de los nombres de empleados y sus últimos tres sueldos.
2)Imprimir el monto total cobrado por cada empleado.
3)Imprimir los nombres de empleados que tuvieron un ingreso trimestral
mayor a 10000 en los últimos tres meses.
Tener en cuenta que la estructura de datos si se carga por asignación
debería ser similar a:
Ver video
• 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.
Retornar
33 - Variantes de la estructura
repetitiva for para recorrer tuplas y
listas
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.
Problema 1:
Confeccionar un programa que permita la carga de una lista de 5 enteros por
teclado.
Luego en otras funciones:
1) Imprimirla en forma completa.
2) Obtener y mostrar el mayor.
3) Mostrar la suma de todas sus componentes.
Utilizar la nueva sintaxis de for vista en este concepto.
Programa: ejercicio155.py
Ver video
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",sum
a)
# bloque principal
lista=cargar()
imprimir(lista)
mayor(lista)
sumar_elementos(lista)
En la carga planteamos un for que se repita cinco veces y es imposible recorrer
la lista con el for ya que antes de entrar al for la lista se define vacía:
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)
Problema 2:
Almacenar en una lista de 5 elementos las tuplas con el nombre de empleado y
su sueldo.
Implementar las funciones:
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
Ver video
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
def imprimir(empleados):
print("Listado de los nombres de empleados y
sus sueldos")
for nombre,sueldo in empleados:
print(nombre,sueldo)
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 me
nor a 1000 son:",cant)
# bloque principal
empleados=cargar()
imprimir(empleados)
mayor_sueldo(empleados)
sueldos_menor1000(empleados)
La carga de la lista con elementos de tipo tupla ya la conocemos de conceptos
anteriores:
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)
Problemas propuestos
• 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.
Ver video
Ver video
Solución
Retornar
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.
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
Ver video
def imprimir(paises):
for clave in paises:
print(clave, paises[clave])
# bloque principal
paises={"argentina":40000000, "españa":46000000,
"brasil":190000000, "uruguay": 3400000}
imprimir(paises)
En el bloque principal de nuestro programa inicializamos un diccionario con
cuatro elementos y lo pasamos a la función imprimir:
def imprimir(paises):
for clave in paises:
print(clave, paises[clave])
Problema 2:
Crear un diccionario que permita almacenar 5 artículos, utilizar como clave el
nombre de productos y como valor el precio del mismo.
Desarrollar además las funciones de:
1) Imprimir en forma completa el diccionario
2) Imprimir solo los artículos con precio superior a 100.
Programa: ejercicio160.py
Ver video
def cargar():
productos={}
for x in range(5):
nombre=input("Ingrese el nombre del produ
cto:")
precio=int(input("Ingrese el precio:"))
productos[nombre]=precio
return productos
def imprimir(productos):
print("Listado de todos los articulos")
for nombre in productos:
print(nombre, productos[nombre])
def imprimir_mayor100(productos):
print("Listado de articulos con precios mayor
es a 100")
for nombre in productos:
if productos[nombre]>100:
print(nombre)
# bloque principal
productos=cargar()
imprimir(productos)
imprimir_mayor100(productos)
Para agregar elementos a un diccionario procedemos a asignar el valor e
indicamos como subíndice la clave:
if clave in diccionario:
print(diccionario[clave])
print(diccionario[clave])
Problema 3:
Desarrollar una aplicación que nos permita crear un diccionario
ingles/castellano. La clave es la palabra en ingles y el valor es la palabra en
castellano.
Crear las siguientes funciones:
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
Ver video
def cargar():
diccionario={}
continua="s"
while continua=="s":
caste=input("Ingrese palabra en castellan
o:")
ing=input("Ingrese palabra en ingles:")
diccionario[ing]=caste
continua=input("Quiere cargar otra palabr
a:[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 con
sultar:")
if pal in diccionario:
print("En castellano significa:",dicciona
rio[pal])
# bloque principal
diccionario=cargar()
imprimir(diccionario)
consulta_palabra(diccionario)
La función de cargar crea el diccionario y va solicitando la palabra en
castellano y su traducción. Luego de agregar un elementos se solicita el
ingrese de una variable string pidiendo que confirme si quiere cargar otra
palabra en el diccionario o finalizar:
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])
Problema propuesto
• Crear un diccionario en Python que defina como clave el número de
documento de una persona y como valor un string con su nombre.
Desarrollar las siguientes funciones:
1) Cargar por teclado los datos de 4 personas.
2) Listado completo del diccionario.
3) Consulta del nombre de una persona ingresando su número de
documento.
Ver video
Solución
Retornar
Problema 1:
Confeccionar un programa que permita cargar un código de producto como
clave en un diccionario. Guardar para dicha clave el nombre del producto, su
precio y cantidad en stock.
Implementar las siguientes actividades:
1) Carga de datos en el diccionario.
2) Listado completo de productos.
3) Consulta de un producto por su clave, mostrar el nombre, precio y stock.
4) Listado de todos los productos que tengan un stock con valor cero.
Programa: ejercicio163.py
Ver video
def cargar():
productos={}
continua="s"
while continua=="s":
codigo=int(input("Ingrese el codigo del p
roducto:"))
descripcion=input("Ingrese la descripcion
:")
precio=float(input("Ingrese el precio:"))
stock=int(input("Ingrese el stock actual:
"))
productos[codigo]=(descripcion,precio,sto
ck)
continua=input("Desea cargar otro product
o[s/n]?")
return productos
def imprimir(productos):
print("Listado completo de productos:")
for codigo in productos:
print(codigo,productos[codigo][0],product
os[codigo][1],productos[codigo][2])
def consulta(productos):
codigo=int(input("Ingrese el codigo de articu
lo a consultar:"))
if codigo in productos:
print(productos[codigo][0],productos[codi
go][1],productos[codigo][2])
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],pro
ductos[codigo][1],productos[codigo][2])
# bloque principal
productos=cargar()
imprimir(productos)
consulta(productos)
listado_stock_cero(productos)
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[cod
igo][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)
Implementar las siguientes funciones:
1) Carga de datos en la agenda.
2) Listado completo de la agenda.
3) Consulta de una fecha.
Programa: ejercicio164.py
Ver video
def cargar():
agenda={}
continua1="s"
while continua1=="s":
fecha=input("ingrese la fecha con formato
dd/mm/aa:")
continua2="s"
lista=[]
while continua2=="s":
hora=input("Ingrese la hora de la act
ividad con formato hh:mm ")
actividad=input("Ingrese la descripco
n de la actividad:")
lista.append((hora,actividad))
continua2=input("Ingresa otra activid
ad para la misma fecha[s/n]:")
agenda[fecha]=lista
continua1=input("Ingresa otra fecha[s/n]:
")
return agenda
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)
def consulta_fecha(agenda):
fecha=input("Ingrese la fecha que desea consu
ltar:")
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)
Un ejemplo de ejecutar este programa tenemos la siguiente pantalla:
La carga de la agenda se compone de dos estructuras repetitivas anidadas.
Previo a comenzar la primer estructura repetitiva creamos el diccionario
llamado agenda:
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]:")
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)
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)
Problema propuesto
• 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.
Retornar
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.
Problema 1:
Confeccionar un programa que contenga las siguientes funciones:
1) Carga de una lista y retorno al bloque principal.
2) Fijar en cero todos los elementos de la lista que tengan un valor menor a 10.
3) Imprimir la lista
Programa: ejercicio166.py
Ver video
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
def fijar_cero(li):
for x in range(len(li)):
if li[x]<10:
li[x]=0
def imprimir(lista):
for elemento in lista:
print(elemento,"-",sep="",end="")
print("")
# bloque principal
lista=cargar()
print("Lista antes de modificar")
imprimir(lista)
fijar_cero(lista)
print("Lista despues de modificar")
imprimir(lista)
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
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
def imprimir(nombres):
for x in range(len(nombres)):
print(nombres[x]," ",end="")
# bloque principal
nombres=cargar()
ordenar(nombres)
imprimir(nombres)
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)
Problema 3:
Confeccionar un programa que almacene en un diccionario como clave el
nombre de un contacto y como valor su número telefónico:
1) Carga de contactos y su número telefónico.
2) Pemitir modificar el número telefónico. Se ingresa el nombre del contacto
para su búsqueda.
3) Imprimir la lista completa de contactos con sus números telefónicos.
Programa: ejercicio168.py
Ver video
def cargar():
contactos={}
continua="s"
while continua=="s":
nombre=input("Ingrese el nombre del conta
cto:")
telefono=input("Ingrese el numero de tele
fono:")
contactos[nombre]=telefono
continua=input("Ingresa otro contacto[s/n
]?:")
return contactos
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 t
elefonico")
contactos[nombre]=telefono
else:
print("No existe un contacto con el nombr
e ingresado")
def imprimir(contactos):
print("Listado de todos los contactos")
for nombre in contactos:
print(nombre,contactos[nombre])
# bloque principal
contactos=cargar()
modificar_telefono(contactos)
imprimir(contactos)
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)
Problema propuesto
• Crear un diccionario en Python para almacenar los datos de empleados
de una empresa. La clave será su número de legajo y en su valor
almacenar una lista con el nombre, profesión y sueldo.
Retornar
lista1=[0,1,2,3,4,5,6]
lista2=lista1[2:5]
print(lista2) # 2,3,4
lista3=lista1[1:3]
print(lista3) # 1,2
lista4=lista1[:3]
print(lista4) # 0,1,2
lista5=lista1[2:]
print(lista5) # 2,3,4,5,6
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.
Por ejemplo con la sintaxis:
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
Problema 1:
Confeccionar una función que le enviemos un número de mes como parámetro
y nos retorne una tupla con todos los nombres de meses que faltan hasta fin de
año.
Programa: ejercicio171.py
Ver video
def meses_faltantes(numeromes):
meses=('enero','febrero','marzo','abril','may
o','junio','julio','agosto','septiembre','octubre
','noviembre','diciembre')
return meses[numeromes:]
# bloque principal
def meses_faltantes(numeromes):
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','se
ptiembre','octubre','noviembre','diciembre')
return meses[numeromes:]
Como vemos generamos una tupla a partir del valor "numeromes" hasta el final
de la tupla:
return meses[numeromes:]
En el bloque principal del programa cargamos el número de mes, llamamos a
la función e imprimimos la tupla devuelta por la función:
# bloque principal
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
Ver video
def primeros_tres(cadena):
return cadena[:3];
# bloque principal
meses=('enero','febrero','marzo','abril','mayo','
junio','julio','agosto','septiembre','octubre','n
oviembre','diciembre')
for x in meses:
print(primeros_tres(x))
La función primeros_tres recibe un string y retorna los tres primeros caracteres:
def primeros_tres(cadena):
return cadena[:3];
meses=('enero','febrero','marzo','abril','mayo','junio','julio','agosto','septie
mbre','octubre','noviembre','diciembre')
for x in meses:
print(primeros_tres(x))
Acotaciones
El comando "del" de Python para la eliminación de componentes de una lista
también funcionan con la sintaxis de porciones:
Problemas propuestos
• Realizar un programa que contenga las siguientes funciones:
1) Carga de una lista de 10 enteros.
2) Recibir una lista y retornar otra con la primer mitad (se sabe que
siempre llega una lista con una cantidad par de elementos)
3) Imprimir una lista.
Ver video
Ver video
Solución
Retornar
lista1=[0,1,2,3,4,5,6]
print(lista1[-1]) # 6
print(lista1[-2]) # 5
En Python podemos acceder fácilmente al último elemento de la secuencia
indicando un subíndice -1:
print(lista1[-1]) # 6
print(lista1[-2]) # 5
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
Ver video
def capicua(cadena):
indice=-1
iguales=0
for x in range(0,len(cadena)//2):
if cadena[x]==cadena[indice]:
iguales=iguales+1
indice=indice-1
print(cadena)
if iguales==(len(cadena)//2):
print("Es capicua")
else:
print("No es capicua")
# bloque principal
capicua("neuquen")
capicua("casa")
Disponemos un contador que comience en -1 llamado indice y otro contador
para las coincidencias:
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")
Problemas propuestos
• Cargar una cadena de caracteres por teclado. Mostrar la cadena del final
al principio utilizando subíndices negativos.
Ver video
Solución
Retornar
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
Ver video
import random
dado1=random.randint(1,6)
dado2=random.randint(1,6)
print("Primer dado:",dado1)
print("Segundo dado:",dado2)
suma=dado1+dado2
if suma==7:
print("Gano")
else:
print("Perdio")
import random
import random
def cargar():
lista=[]
for x in range(10):
lista.append(random.randint(0,1000))
return lista
def imprimir(lista):
print(lista)
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)
No hay ningún problema de llamar a las funciones de un módulo dentro de una
función propia siempre y cuando indiquemos el import respectivo:
import random
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)
Problemas propuestos
• Confeccionar un programa que genere un número aleatorio entre 1 y 100
y no se muestre.
El operador debe tratar de adivinar el número ingresado.
Cada vez que ingrese un número mostrar un mensaje "Gano" si es igual
al generado o "El número aleatorio es mayor" o "El número aleatorio es
menor".
Mostrar cuando gana el jugador cuantos intentos necesitó.
Ver video
Ver video
Solución
Retornar
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)
Problema 1:
Confeccionar un programa que solicite la carga de un valor entero por teclado y
luego nos muestre la raíz cuadrada del número y el valor elevado al cubo.
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
Ver video
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)
r1=raiz(valor)
r2=elevar(valor,3)
Problema propuesto
• Calcular el factorial de un número ingresado por teclado.
El factorial de un número es la cantidad que resulta de la multiplicación
de determinado número natural por todos los números naturales que le
anteceden excluyendo el cero. Por ejemplo el factorial de 4 es 24, que
resulta de multiplicar 4*3*2*1.
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.
Solo importar la funcionalidad factorial del módulo math de la biblioteca
estándar de Python.
Ver video
Solución
Retornar
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
def cargar():
lista=[]
for x in range(5):
valor=int(input("Ingrese valor:"))
lista.append(valor)
return lista
def imprimir_mayor(lista):
may=lista[0]
for x in range(1,5):
if lista[x]>may:
may=lista[x]
print("Mayor de la lista",may)
def imprimir_suma(lista):
suma=0
for elemento in lista:
suma=suma+elemento
print("Suma de todos sus elementos",suma)
El segundo archivo y desde donde realmente arrancará nuestro programa es el
módulo principal.py
módulo: principal.py
import operacioneslista
lista=operacioneslista.cargar()
operacioneslista.imprimir_mayor(lista)
operacioneslista.imprimir_suma(lista)
Es importante indicar que cuando queremos ejecutar nuestro programa
tenemos que abrir el archivo principal.py y elegir la opción "Run Module" o
presionar la tecla "F5".
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)
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
def menor(x1,x2):
if x1<x2:
return x1
else:
return x2
Por otro lado el programa principal que importa solo la función mayor es:
módulo: principal.py
Retornar
42 - Conceptos de programación
orientada a objetos
Python nos permite utilizar distintas metodologías de programación. Hemos
implementado inicialmente programas utilizando la programación lineal, luego
vimos funciones y trabajamos con programación estructurada.
Ahora introduciremos los conceptos de programación orientada a objetos. A
partir de este concepto mostraremos en forma sencilla la metodología de
Programación Orientada a Objetos.
Se irán introduciendo conceptos de objeto, clase, atributo, método etc. y de
todos estos temas se irán planteando problemas resueltos.
Prácticamente todos los lenguajes desarrollados en los últimos 25 años
implementan la posibilidad de trabajar con POO (Programación Orientada a
Objetos)
El lenguaje Python tiene la característica de permitir programar con las
siguientes metodologías:
Retornar
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.
Ver video
Programa: ejercicio186.py
class Persona:
def inicializar(self,nom):
self.nombre=nom
def imprimir(self):
print("Nombre",self.nombre)
# bloque principal
persona1=Persona()
persona1.inicializar("Pedro")
persona1.imprimir()
persona2=Persona()
persona2.inicializar("Carla")
persona2.imprimir()
Siempre conviene buscar un nombre de clase lo más próximo a lo que
representa. La palabra clave para declarar la clase es class, seguidamente el
nombre de la clase y luego dos puntos.
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
# bloque principal
persona1=Persona()
persona1.inicializar("Pedro")
persona1.imprimir()
persona2=Persona()
persona2.inicializar("Carla")
persona2.imprimir()
persona1.inicializar("Pedro")
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
Ver video
class Alumno:
def inicializar(self,nombre,nota):
self.nombre=nombre
self.nota=nota
def imprimir(self):
print("Nombre:",self.nombre)
print("Nota:",self.nota)
def mostrar_estado(self):
if self.nota>=4:
print("Regular")
else:
print("Libre")
# bloque principal
alumno1=Alumno()
alumno1.inicializar("diego",2)
alumno1.imprimir()
alumno1.mostrar_estado()
alumno2=Alumno()
alumno2.inicializar("ana",10)
alumno2.imprimir()
alumno2.mostrar_estado()
Declaramos la clase Alumno y definimos sus tres métodos, en el método
inicializar llegan como parámetros a parte del self el nombre y nota del alumno:
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
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()
Problemas propuestos
• 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)
Ver video
Ver video
Solución
Retornar
44 - Método __init__ de la clase
El método __init__ es un método especial de una clase en Python. El objetivo
fundamental del método __init__ es inicializar los atributos del objeto que
creamos.
Básicamente el método __init__ remplaza al método inicializar que habíamos
hecho en el concepto anterior.
Las ventajas de implementar el método __init__ en lugar del método inicializar
son:
def __init__([parámetros]):
[algoritmo]
Problema 1:
Confeccionar una clase que represente un empleado. Definir como atributos su
nombre y su sueldo. En el método __init__ cargar los atributos por teclado y
luego en otro método imprimir sus datos y por último uno que imprima un
mensaje si debe pagar impuestos (si el sueldo supera a 3000)
Programa: ejercicio190.py
Ver video
class Empleado:
def __init__(self):
self.nombre=input("Ingrese el nombre del
empleado:")
self.sueldo=float(input("Ingrese el sueld
o:"))
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")
# bloque principal
empleado1=Empleado()
empleado1.imprimir()
empleado1.paga_impuestos()
Definimos el método __init__ donde cargamos por teclado el nombre del
empleado y su sueldo:
def __init__(self):
self.nombre=input("Ingrese el nombre del empleado:")
self.sueldo=float(input("Ingrese el sueldo:"))
empleado1=Empleado()
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()
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
Ver video
class Punto:
def __init__(self,x,y):
self.x=x
self.y=y
def imprimir(self):
print("Coordenada del punto")
print("(",self.x,",",self.y,")")
def imprimir_cuadrante(self):
if self.x>0 and self.y>0:
print("Primer cuadrange")
else:
if self.x<0 and self.y>0:
print("Segundo cuadrante")
else:
if self.x<0 and self.y<0:
print("Tercer cuadrante")
else:
if self.x>0 and self.y<0:
print("Cuarto cuadrante")
# bloque principal
punto1=Punto(10,-2)
punto1.imprimir()
punto1.imprimir_cuadrante()
En este problema el método __init__ aparte del parámetro self que siempre va
tenemos otros dos parámetros:
def __init__(self,x,y):
self.x=x
self.y=y
punto1=Punto(10,-2)
Problemas propuestos
• 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.
Ver video
Ver video
Solución
Retornar
empleado1=Empleado("diego",2000)
empleado1.paga_impuestos()
Utilizamos la sintaxis:
Es importante tener en cuenta que esto solo se puede hacer cuando estamos
dentro de la misma clase.
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
Ver video
class Operacion:
def __init__(self):
self.valor1=int(input("Ingrese primer val
or:"))
self.valor2=int(input("Ingrese segundo va
lor:"))
self.sumar()
self.restar()
self.multiplicar()
self.dividir()
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()
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.
La llamada de los métodos de la misma clase se hace antecediendo al nombre
del método la palabra self:
def __init__(self):
self.valor1=int(input("Ingrese primer valor:"))
self.valor2=int(input("Ingrese segundo valor:"))
self.sumar()
self.restar()
self.multiplicar()
self.dividir()
def sumar(self):
suma=self.valor1+self.valor2
print("La suma es",suma)
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()
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
Ver video
class Alumnos:
def __init__(self):
self.nombres=[]
self.notas=[]
def menu(self):
opcion=0
while opcion!=4:
print("1- Cargar alumnos")
print("2- Listar alumnos")
print("3- Listado de alumnos con nota
s 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()
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)
def listar(self):
print("Listado completo de alumnos")
for x in range(5):
print(self.nombres[x],self.notas[x])
print("_____________________")
def notas_altas(self):
print("Alumnos con notas superiores o igu
ales a 7")
for x in range(5):
if self.notas[x]>=7:
print(self.nombres[x],self.notas[
x])
print("_____________________")
# bloque principal
alumnos=Alumnos()
alumnos.menu()
Si ejecutamos el programa podemos ver como aparece un menú de opciones y
podemos seleccionar para cargar, listar etc.:
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:
def __init__(self):
self.nombres=[]
self.notas=[]
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()
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("_____________________")
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("_____________________")
Problema propuesto
• 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:
1- Carga de un contacto en la agenda.
2- Listado completo de la agenda.
3- Consulta ingresando el nombre de la persona.
4- Modificación de su teléfono y mail.
5- Finalizar programa.
Ver video
Solución
Retornar
46 - Colaboración de clases
Normalmente un problema resuelto con la metodología de programación
orientada a objetos no interviene una sola clase, sino que hay muchas clases
que interactúan y se comunican.
Plantearemos un problema separando las actividades en dos clases.
Problema 1:
Un banco tiene 3 clientes que pueden hacer depósitos y extracciones. También
el banco requiere que al final del día calcule la cantidad de dinero que hay
depositado.
Lo primero que hacemos es identificar las clases:
Podemos identificar la clase Cliente y la clase Banco.
Luego debemos definir los atributos y los métodos de cada clase:
Cliente
atributos
nombre
monto
métodos
__init__
depositar
extraer
retornar_monto
Banco
atributos
3 Cliente (3 objetos de la clase Cliente)
métodos
__init__
operar
depositos_totales
Programa: ejercicio197.py
Ver video
class Cliente:
def __init__(self,nombre):
self.nombre=nombre
self.monto=0
def depositar(self,monto):
self.monto=self.monto+monto
def extraer(self,monto):
self.monto=self.monto-monto
def retornar_monto(self):
return self.monto
def imprimir(self):
print(self.nombre,"tiene depositado la su
ma de",self.monto)
class Banco:
def __init__(self):
self.cliente1=Cliente("Juan")
self.cliente2=Cliente("Ana")
self.cliente3=Cliente("Diego")
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.cliente3.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()
Primero hacemos la declaración de la clase Cliente, en el método __init__
inicializamos los atributos nombre con el valor que llega como parámetro y el
atributo monto con el valor cero:
class Cliente:
def __init__(self,nombre):
self.nombre=nombre
self.monto=0
self.nombre=nombre
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)
class Banco:
def __init__(self):
self.cliente1=Cliente("Juan")
self.cliente2=Cliente("Ana")
self.cliente3=Cliente("Diego")
def operar(self):
self.cliente1.depositar(100)
self.cliente2.depositar(150)
self.cliente3.depositar(200)
self.cliente3.extraer(150)
# bloque principal
banco1=Banco()
banco1.operar()
banco1.depositos_totales()
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ó".
Lo primero que hacemos es identificar las clases:
Podemos identificar la clase Dado y la clase JuegoDeDados.
Luego los atributos y los métodos de cada clase:
Dado
atributos
valor
métodos
tirar
imprimir
retornar_valor
JuegoDeDados
atributos
3 Dado (3 objetos de la clase Dado)
métodos
__init__
jugar
Programa: ejercicio198.py
Ver video
import random
class Dado:
def tirar(self):
self.valor=random.randint(1,6)
def imprimir(self):
print("Valor del dado:",self.valor)
def retornar_valor(self):
return self.valor
class JuegoDeDados:
def __init__(self):
self.dado1=Dado()
self.dado2=Dado()
self.dado3=Dado()
def jugar(self):
self.dado1.tirar()
self.dado1.imprimir()
self.dado2.tirar()
self.dado2.imprimir()
self.dado3.tirar()
self.dado3.imprimir()
if self.dado1.retornar_valor()==self.dado
2.retornar_valor() and self.dado1.retornar_valor(
)==self.dado3.retornar_valor():
print("Gano")
else:
print("Perdio")
juego_dados=JuegoDeDados()
juego_dados.jugar()
Importamos el módulo "random" de la biblioteca estándar de Python ya que
requerimos utilizar la función randint:
import random
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:
def __init__(self):
self.dado1=Dado()
self.dado2=Dado()
self.dado3=Dado()
def jugar(self):
self.dado1.tirar()
self.dado1.imprimir()
self.dado2.tirar()
self.dado2.imprimir()
self.dado3.tirar()
self.dado3.imprimir()
if self.dado1.retornar_valor()==self.dado2.retornar_valor() and self.dad
o1.retornar_valor()==self.dado3.retornar_valor():
print("Gano")
else:
print("Perdio")
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():
Ver video
Solución
Retornar
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.
La herencia significa que se pueden crear nuevas clases partiendo de clases
existentes, que tendrá todas los atributos y los métodos de su 'superclase' o
'clase padre' y además se le podrán añadir otros atributos y métodos propios.
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 la clase
padre.
Subclase
Clase descendiente de otra. Hereda automáticamente los atributos y métodos
de su superclase. Es una especialización de otra clase.
Admiten la definición de nuevos atributos y métodos para aumentar la
especialización de la clase.
Veamos algunos ejemplos teóricos de herencia:
1) Imaginemos la clase Vehículo. Qué clases podrían derivar de ella?
Vehiculo
Software
DeAplicacion DeBase
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)
También en el bloque principal del programa crear un objeto de la clase
Empleado.
Programa: ejercicio200.py
Ver video
class Persona:
def __init__(self):
self.nombre=input("Ingrese el nombre:")
self.edad=int(input("Ingrese la edad:"))
def imprimir(self):
print("Nombre:",self.nombre)
print("Edad:",self.edad)
class Empleado(Persona):
def __init__(self):
super().__init__()
self.sueldo=float(input("Ingrese el sueld
o:"))
def imprimir(self):
super().imprimir()
print("Sueldo:",self.sueldo)
def paga_impuestos(self):
if self.sueldo>3000:
print("El empleado debe pagar impuest
os")
else:
print("No paga impuestos")
# bloque principal
persona1=Persona()
persona1.imprimir()
print("____________________________")
empleado1=Empleado()
empleado1.imprimir()
empleado1.paga_impuestos()
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 __init__(self):
self.nombre=input("Ingrese el nombre:")
self.edad=int(input("Ingrese la edad:"))
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.
La clase Empleado define un nuevo atributo que es el sueldo y tres
funcionalidades __init__, imprimir y paga_impuestos.
En el método __init__ de la clase Empleado primero llamamos al método
__init__ de la clase padre y luego cargamos el sueldo:
def __init__(self):
super().__init__()
self.sueldo=float(input("Ingrese el sueldo:"))
def imprimir(self):
super().imprimir()
print("Sueldo:",self.sueldo)
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()
Problema 2:
Ahora plantearemos otro problema empleando herencia. Supongamos que
necesitamos implementar dos clases que llamaremos Suma y Resta. Cada
clase tiene como atributo valor1, valor2 y resultado. Los métodos a definir son
cargar1 (que inicializa el atributo valor1), carga2 (que inicializa el atributo
valor2), operar (que en el caso de la clase "Suma" suma los dos atributos y en
el caso de la clase "Resta" hace la diferencia entre valor1 y valor2), y otro
método mostrar_resultado.
Si analizamos ambas clases encontramos que muchos atributos y métodos son
idénticos. En estos casos es bueno definir una clase padre que agrupe dichos
atributos y responsabilidades comunes.
La relación de herencia que podemos disponer para este problema es:
Operacion
Suma Resta
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
Ver video
class Operacion:
def __init__(self):
self.valor1=0
self.valor2=0
self.resultado=0
def cargar1(self):
self.valor1=int(input("Ingrese primer val
or:"))
def cargar2(self):
self.valor2=int(input("Ingrese segundo va
lor:"))
def mostrar_resultado(self):
print(self.resultado)
def operar(self):
pass
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()
En este problema la clase Operación tiene por objetivo agrupar atributos y
funcionalidades que se heredarán en otras clases.
La clase Operación inicializa en el metodo __init__ tres atributos:
class Operacion:
def __init__(self):
self.valor1=0
self.valor2=0
self.resultado=0
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()
Problema propuesto
• 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.
Una caja de ahorro y un plazo fijo tienen un nombre de titular y un
monto. Un plazo fijo añade un plazo de imposición en días y una tasa de
interés. Hacer que la caja de ahorro no genera intereses.
En el bloque principal del programa definir un objeto de la clase
CajaAhorro y otro de la clase PlazoFijo.
Ver video
Solución
Retornar
48 - Variables de clase
Hemos visto como definimos atributos en una clase anteponiendo la palabra
clave self:
class Persona:
def __init__(self,nombre):
self.nombre=nombre
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:
class Persona:
def __init__(self,nombre):
self.nombre=nombre
# bloque principal
persona1=Persona("Juan")
persona2=Persona("Ana")
persona3=Persona("Luis")
print(persona1.nombre) # Juan
print(persona2.nombre) # Ana
print(persona3.nombre) # Luis
class Persona:
variable=20
def __init__(self,nombre):
self.nombre=nombre
# bloque principal
persona1=Persona("Juan")
persona2=Persona("Ana")
persona3=Persona("Luis")
print(persona1.nombre) # Juan
print(persona2.nombre) # Ana
print(persona3.nombre) # Luis
print(persona1.variable) # 20
Persona.variable=5
print(persona2.variable) # 5
Persona.variable=5
Problema 1:
Definir una clase Cliente que almacene un código de cliente y un nombre.
En la clase Cliente definir una variable de clase de tipo lista que almacene
todos los clientes que tienen suspendidas sus cuentas corrientes.
Imprimir por pantalla todos los datos de clientes y el estado que se encuentra
su cuenta corriente.
Programa: ejercicio203.py
Ver video
class Cliente:
suspendidos=[]
def __init__(self,codigo,nombre):
self.codigo=codigo
self.nombre=nombre
def imprimir(self):
print("Codigo:",self.codigo)
print("Nombre:",self.nombre)
self.esta_suspendido()
def esta_suspendido(self):
if self.codigo in Cliente.suspendidos:
print("Esta suspendido")
else:
print("No esta suspendido")
print("_____________________________")
def suspender(self):
Cliente.suspendidos.append(self.codigo)
# bloque principal
cliente1=Cliente(1,"Juan")
cliente2=Cliente(2,"Ana")
cliente3=Cliente(3,"Diego")
cliente4=Cliente(4,"Pedro")
cliente3.suspender()
cliente4.suspender()
cliente1.imprimir()
cliente2.imprimir()
cliente3.imprimir()
cliente4.imprimir()
print(Cliente.suspendidos)
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("_____________________________")
# bloque principal
cliente1=Cliente(1,"Juan")
cliente2=Cliente(2,"Ana")
cliente3=Cliente(3,"Diego")
cliente4=Cliente(4,"Pedro")
cliente3.suspender()
cliente4.suspender()
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.
Problema propuesto
• Plantear una clase llamada Jugador.
Definir en la clase Jugador los atributos nombre y puntaje, y los métodos
__init__, imprimir y pasar_tiempo (que debe reducir en uno la variable de
clase).
Declarar dentro de la clase Jugador una variable de clase que indique
cuantos minutos falta para el fin de juego (iniciarla con el valor 30)
Definir en el bloque principal dos objetos de la clase Jugador.
Reducir dicha variable hasta llegar a cero.
Ver video
Solución
Retornar
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape
persona1=Persona("Jose","Rodriguez")
print(persona1)
Python nos permite redefinir el método que se debe ejecutar. Esto se hace
definiendo en la clase el método especial __str__
En el ejemplo anterior si queremos que se muestre el nombre y apellido
separados por coma cuando llamemos a la función print el código que
debemos implementar es el siguiente:
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape
def __str__(self):
cadena=self.nombre+","+self.apellido
return cadena
persona1=Persona("Jose","Rodriguez")
print(persona1)
def __str__(self):
cadena=self.nombre+","+self.apellido
return cadena
class Persona:
def __init__(self,nom,ape):
self.nombre=nom
self.apellido=ape
def __str__(self):
cadena=self.nombre+","+self.apellido
return cadena
# bloque principal
persona1=Persona("Jose","Rodriguez")
persona2=Persona("Ana","Martinez")
print(str(persona1)+"-"+str(persona2)) # Jose,Rodriguez-Ana,Martinez
Problema 1:
Definir una clase llamada Punto con dos atributos x e y.
Crearle el método especial __str__ para retornar un string con el formato (x,y).
Programa: ejercicio205.py
Ver video
class Punto:
def __str__(self):
return "("+str(self.x)+","+str(self.y)+")
"
# bloque principal
punto1=Punto(10,3)
punto2=Punto(3,4)
print(punto1)
print(punto2)
La clase Punto define dos métodos especiales. El método __init__ donde
inicializamos los atributos x e y:
class Punto:
def __init__(self, x, y):
self.x=x
self.y=y
def __str__(self):
return "("+str(self.x)+","+str(self.y)+")"
# 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.
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
Ver video
class Familia:
def __init__(self,padre,madre,hijos=[]):
self.padre=padre
self.madre=madre
self.hijos=hijos
def __str__(self):
cadena=self.padre+","+self.madre
for hi in self.hijos:
cadena=cadena+","+hi
return cadena
# bloque principal
familia1=Familia("Pablo","Ana",["Pepe","Julio"])
familia2=Familia("Jorge","Carla")
familia3=Familia("Luis","Maria",["marcos"])
print(familia1)
print(familia2)
print(familia3)
Para resolver este problema el método __init__ recibe en forma obligatoria el
nombre del padre, madre y en forma opcional una lista con los nombres de los
hijos:
class Familia:
def __init__(self,padre,madre,hijos=[]):
self.padre=padre
self.madre=madre
self.hijos=hijos
def __str__(self):
cadena=self.padre+","+self.madre
for hi in self.hijos:
cadena=cadena+","+hi
return cadena
# bloque principal
familia1=Familia("Pablo","Ana",["Pepe","Julio"])
familia2=Familia("Jorge","Carla")
familia3=Familia("Luis","Maria",["marcos"])
print(familia1)
print(familia2)
print(familia3)
Problema propuesto
• Desarrollar un programa que implemente una clase llamada Jugador.
Definir como atributos su nombre y puntaje.
Codificar el método especial __str__ que retorne el nombre y si es
principiante (menos de 1000 puntos) o experto (1000 o más puntos)
Ver video
Solución
Retornar
__add__(self,objeto2)
Para el operador -:
__sub__(self,objeto2)
Para el operador *:
__mul__(self,objeto2)
__floordiv__(self,objeto2)
Para el operador /:
__truediv__(self,objeto2)
Problema 1:
Veamos con un ejemplo la sintaxis para redefinir el operador +.
Crearemos una clase Cliente de un banco y redefiniremos el operador + para
que nos retorne la suma de los depósitos de los dos clientes que estamos
sumando.
Programa: ejercicio208.py
Ver video
class Cliente:
def __init__(self,nombre,monto):
self.nombre=nombre
self.monto=monto
def __add__(self,objeto2):
s=self.monto+objeto2.monto
return s
cli1=Cliente('Ana',1200)
cli2=Cliente('Luis',1500)
print("El total depositado por los dos clientes e
s")
print(cli1+cli2)
print(cli1+cli2)
def __add__(self,objeto2):
s=self.monto+objeto2.monto
return s
Es muy importante tener en cuenta que debemos redefinir un operador
matemático siempre y cuando haga nuestro programa más legible.
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.
Problema 2:
Desarrollar una clase llamada Lista, que permita pasar al método __init__ una
lista de valores enteros.
Redefinir los operadores +,-,* y // con respecto a un valor entero.
Programa: ejercicio209.py
Ver video
class Lista:
def imprimir(self):
print(self.lista)
def __add__(self,entero):
nueva=[]
for x in range(len(self.lista)):
nueva.append(self.lista[x]+entero)
return nueva
def __sub__(self,entero):
nueva=[]
for x in range(len(self.lista)):
nueva.append(self.lista[x]-entero)
return nueva
def __mul__(self,entero):
nueva=[]
for x in range(len(self.lista)):
nueva.append(self.lista[x]*entero)
return nueva
def __floordiv__(self,entero):
nueva=[]
for x in range(len(self.lista)):
nueva.append(self.lista[x]//entero)
return nueva
# bloque principal
lista1=Lista([3,4,5])
lista1.imprimir()
print(lista1+10)
print(lista1-10)
print(lista1*10)
print(lista1//10)
Al método __init__ llega la lista de enteros:
class Lista:
def __init__(self, lista):
self.lista=lista
def __add__(self,entero):
nueva=[]
for x in range(len(self.lista)):
nueva.append(self.lista[x]+entero)
return nueva
Retornar
__eq__(self,objeto2)
__ne__(self,objeto2)
__gt__(self,objeto2)
__ge__(self,objeto2)
Para el operador <:
__lt__(self,objeto2)
__le__(self,objeto2)
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
Ver video
class Persona:
def __eq__(self,objeto2):
if self.edad==objeto2.edad:
return True
else:
return False
def __ne__(self,objeto2):
if self.edad!=objeto2.edad:
return True
else:
return False
def __gt__(self,objeto2):
if self.edad>objeto2.edad:
return True
else:
return False
def __ge__(self,objeto2):
if self.edad>=objeto2.edad:
return True
else:
return False
def __lt__(self,objeto2):
if self.edad<objeto2.edad:
return True
else:
return False
def __le__(self,objeto2):
if self.edad<=objeto2.edad:
return True
else:
return False
# bloque principal
persona1=Persona('juan',22)
persona2=Persona('ana',22)
if persona1==persona2:
print("Las dos personas tienen la misma edad.
")
else:
print("No tienen la misma edad.")
Como podemos observar planteamos un método por cada operador relacional:
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.
Problema 2:
Plantear una clase Rectangulo. Definir dos atributos (ladomenor y ladomayor).
Redefinir el operador == de tal forma que tengan en cuenta la superficie del
rectángulo. Lo mismo hacer con todos los otros operadores relacionales.
Programa: ejercicio211.py
Ver video
class Rectangulo:
def __init__(self,lmenor,lmayor):
self.lmenor=lmenor
self.lmayor=lmayor
def retornar_superficie(self):
return self.lmenor*self.lmayor
def __eq__(self,objeto2):
if self.retornar_superficie()==objeto2.re
tornar_superficie():
return True
else:
return False
def __ne__(self,objeto2):
if self.retornar_superficie()!=objeto2.re
tornar_superficie():
return True
else:
return False
def __gt__(self,objeto2):
if self.retornar_superficie()>objeto2.ret
ornar_superficie():
return True
else:
return False
def __ge__(self,objeto2):
if self.retornar_superficie()>=objeto2.re
tornar_superficie():
return True
else:
return False
def __lt__(self,objeto2):
if self.retornar_superficie()<objeto2.ret
ornar_superficie():
return True
else:
return False
def __le__(self,objeto2):
if self.retornar_superficie()<=objeto2.re
tornar_superficie():
return True
else:
return False
# bloque principal
rectangulo1=Rectangulo(10,10)
rectangulo2=Rectangulo(5,20)
if rectangulo1==rectangulo2:
print("Los rectangulos tienen la misma superf
icie")
else:
print("Los rectangulos no tienen la misma sup
erficie")
Similar al concepto anterior redefinimos los métodos especiales e
implementamos un algoritmo para verificar las superficies de dos objetos
rectángulos (llamamos al método retornar_superficie de cada objeto):
def __eq__(self,objeto2):
if self.retornar_superficie()==objeto2.retornar_superficie():
return True
else:
return False
Retornar
Retornar
• Depuradores
Retornar
54 - Depuración de programas en
VSCode
La depuración de programas es el proceso de identificar y corregir errores de
programación. VSCode nos trae dentro del editor y junto a extensiones este
proceso.
Dentro de la "Barra de actividades" de VSCode podemos identificar el ícono
que nos abre el diálogo de depuración:
lista=[10,7,3,7,2]
suma=0
x=0
while x<len(lista):
suma=suma+lista[x]
x=x+1
print("Los elementos de la lista son")
print(lista)
print("La suma de todos sus elementos es")
print(suma)
Podemos ejecutar la aplicación desde la consola y comprobaremos su
resultado:
• Detener (Shift+F5)
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.
Retornar
Instalación de un paquete
Para conocer los pasos en la instalación de un paquete almacenado en pypi
elegiremos el paquete 'wxPython' (tengamos en cuenta que es uno solo entre
más de 191000 disponibles) que tiene por objetivo facilitar la implementación
de interfaces visuales en Python.
Desde la línea de comandos debemos ejecutar:
import wx
aplicacion = wx.App()
ventana = wx.Frame(parent=None,title="Hola Mundo"
)
ventana.Show()
aplicacion.MainLoop()
Si lo ejecutamos al programa podemos comprobar que nuestra aplicación no
se ejecuta en la consola del sistema operativo sino que aparece una interfaz
visual:
Siempre que utilizamos paquetes desarrollados por la comunidad debemos
visitar su documentación para poder utilizarlos en nuestros proyectos, por
ejemplo la documentación del paquete wxPython se encuentra aquí
Problema:
Mostrar una ventana con un botón en su interior. Al ser presionado mostrar un
mensaje.
El programa en Python haciendo uso del paquete wxPython requiere el
siguiente algoritmo:
Programa: ejercicio214.py
import wx
class Ventana(wx.Frame):
def presion_boton(self,evento):
wx.MessageBox("Hola mundo")
aplicacion = wx.App()
frm = Ventana(None, title='Prueba')
frm.Show()
aplicacion.MainLoop()
La ejecución de este programa nos muestra una ventana con un botón en su
interior:
Si se presiona el botón se muestra la ventana con el mensaje:
Conclusión
El objetivo de este concepto es aprender a instalar un paquete y su posterior
uso y no aprender las particularidades de la librería wxPython que instalamos.
Si quiere aprender todas las funcionalidades de wxPython visite el
sitio wxpython.org, en los próximos conceptos veremos otra librería de Python
para trabajar con GUI.
Retornar
56 - pip : funcionalidades
La aplicación pip es la herramienta fundamental que trae Python para la
instalación de paquetes para poder utilizarlos en nuestros proyectos.
• Vimos en el concepto anterior la sintaxis que se requiere para instalar un
paquete que se encuentra publicado en el sitio pypi.org:
• 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):
Para profundizar y tener todas las actualizaciones del programa 'pip' debemos
visitar la guía de referencia oficial.
Retornar
Problema:
Mostrar una ventana y que en su título aparezca el mensaje 'Hola Mundo'.
El programa en Python haciendo uso del módulo 'tkinter' requiere el siguiente
algoritmo:
Programa: ejercicio215.py
Ver video
import tkinter as tk
ventana1=tk.Tk()
ventana1.title("Hola Mundo")
ventana1.mainloop()
Lo primero que hacemos es importar el módulo tkinter y le definimos un alias
luego de la palabra clave as. Es más fácil luego escribir 'tk' en lugar de 'tkinter':
import tkinter as tk
ventana1=tk.Tk()
ventana1.title("Hola Mundo")
ventana1.mainloop()
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.ventana1.title("Hola Mundo")
self.ventana1.mainloop()
aplicacion1=Aplicacion()
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()
Retornar
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.valor=1
self.ventana1=tk.Tk()
self.ventana1.title("Controles Button y L
abel")
self.label1=tk.Label(self.ventana1, text=
self.valor)
self.label1.grid(column=0, row=0)
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)
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()
Definimos un atributo en la clase Aplicacion y almacenamos el valor 1:
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)
self.label1.configure(foreground="red")
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()
self.label1.config(text=self.valor)
O mediante la sintaxis:
self.label1["text"]=self.valor
Problema:
Mostrar dos Label, en una se muestra el nombre del programa y en la segunda
el año de creación. Disponer un botón para finalizar el programa.
No permitir al usuario redimensionar la ventana.
Programa: ejercicio217.py
Ver video
import tkinter as tk
import sys
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.ventana1.title("Prueba")
self.label1=tk.Label(self.ventana1, text=
"Sistema de facturación")
self.label1.grid(column=0, row=0)
self.label2=tk.Label(self.ventana1, text=
"2018")
self.label2.grid(column=0, row=1)
self.boton1=tk.Button(self.ventana1, text
="Finalizar", command=self.finalizar)
self.boton1.grid(column=0, row=2)
self.ventana1.resizable(False, False)
self.ventana1.mainloop()
def finalizar(self):
sys.exit(0)
aplicacion1=Aplicacion()
En esta aplicación para no permitir redimensionar ni el ancho ni el alto del la
ventana debemos llamar al método resizable y pasar el valor False a cada
parámetro.
Cuando queremos finalizar un programa en Python debemos llamar a la
función exit que se encuentra en el módulo sys, por ello hemos importado
dicho módulo al principio:
import sys
Problemas propuestos
• 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.
Ver video
Retornar
Problema:
Confeccionar una aplicación que permita ingresar un entero por teclado y al
presionar un botón muestre dicho valor elevado al cuadrado en una Label.
Programa: ejercicio220.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=tk.Label(self.ventana1,text="
Ingrese un número:")
self.label1.grid(column=0, row=0)
self.dato=tk.StringVar()
self.entry1=tk.Entry(self.ventana1, width
=10, textvariable=self.dato)
self.entry1.grid(column=0, row=1)
self.boton1=tk.Button(self.ventana1, text
="Calcular Cuadrado", command=self.calcularcuadra
do)
self.boton1.grid(column=0, row=2)
self.label2=tk.Label(self.ventana1,text="
resultado")
self.label2.grid(column=0, row=3)
self.ventana1.mainloop()
def calcularcuadrado(self):
valor=int(self.dato.get())
cuadrado=valor*valor
self.label2.configure(text=cuadrado)
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
Veamos lo nuevo que aparece para definir un objeto de la clase Entry:
self.dato=tk.StringVar()
self.entry1=tk.Entry(self.ventana1, widt=10, textvariable=self.dato)
self.entry1.grid(column=0, row=1)
def calcularcuadrado(self):
valor=int(self.dato.get())
cuadrado=valor*valor
self.label2.configure(text=cuadrado)
Problema:
Confeccionar un programa que permita ingresar el nombre de usuario en un
control Entry y cuando se presione un botón mostrar el valor ingresado en la
barra de títulos de la ventana.
Programa: ejercicio221.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=tk.Label(self.ventana1,text="
Ingrese nombre de usuario:")
self.label1.grid(column=0, row=0)
self.dato=tk.StringVar()
self.entry1=tk.Entry(self.ventana1, width
=20, textvariable=self.dato)
self.entry1.grid(column=1, row=0)
self.boton1=tk.Button(self.ventana1, text
="Ingresar", command=self.ingresar)
self.boton1.grid(column=1, row=1)
self.ventana1.mainloop()
def ingresar(self):
self.ventana1.title(self.dato.get())
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
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())
Problemas propuestos
• Confeccionar un programa que permita ingresar dos números en
controles de tipo Entry, luego sumar los dos valores ingresados y
mostrar la suma en una Label al presionar un botón.
Ver video
Ver video
Solución
Retornar
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.seleccion=tk.IntVar()
self.seleccion.set(2)
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.boton1=tk.Button(self.ventana1, text
="Mostrar seleccionado", command=self.mostrarsele
ccionado)
self.boton1.grid(column=0, row=2)
self.label1=tk.Label(self.ventana1,text="
opcion seleccionada")
self.label1.grid(column=0, row=3)
self.ventana1.mainloop()
def mostrarseleccionado(self):
if self.seleccion.get()==1:
self.label1.configure(text="opcion se
leccionada=Varon")
if self.seleccion.get()==2:
self.label1.configure(text="opcion se
leccionada=Mujer")
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
Definimos dos objetos de la clase Radiobutton e iniciamos el parámetro
variable con la referencia de un objeto de la clase IntVar:
self.radio1=tk.Radiobutton(self.ventana1,text="Varon", variable=self.sel
eccion, value=1)
self.radio1.grid(column=0, row=0)
self.radio2=tk.Radiobutton(self.ventana1,text="Mujer", variable=self.sel
eccion, 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")
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=tk.Label(self.ventana1,text="
Ingrese primer valor:")
self.label1.grid(column=0, row=0)
self.dato1=tk.StringVar()
self.entry1=tk.Entry(self.ventana1, width
=20, textvariable=self.dato1)
self.entry1.grid(column=1, row=0)
self.label2=tk.Label(self.ventana1,text="
Ingrese segundo valor:")
self.label2.grid(column=0, row=1)
self.dato2=tk.StringVar()
self.entry2=tk.Entry(self.ventana1, width
=20, textvariable=self.dato2)
self.entry2.grid(column=1, row=1)
self.seleccion=tk.IntVar()
self.radio1=tk.Radiobutton(self.ventana1,
text="Sumar", variable=self.seleccion, value=1)
self.radio1.grid(column=1, row=2)
self.radio2=tk.Radiobutton(self.ventana1,
text="Restar", variable=self.seleccion, value=2)
self.radio2.grid(column=1, row=3)
self.boton1=tk.Button(self.ventana1, text
="Operar", command=self.operar)
self.boton1.grid(column=1, row=4)
self.label3=tk.Label(self.ventana1,text="
resultado")
self.label3.grid(column=1, row=5)
self.ventana1.mainloop()
def operar(self):
if self.seleccion.get()==1:
suma=int(self.dato1.get())+int(self.d
ato2.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)
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
Cuando se presiona el botón se dispara el método 'operar':
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)
Problema propuesto
• 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.
Si consideramos que la variable ventana1 es un objeto de la clase Tk,
luego si queremos que el fondo sea de color rojo debemos llamar al
método configure y en el parámetro bg indicar un string con el color a
activar ("red", "green" o "blue"):
• self.ventana1.configure(bg="red")
Ver video
Solución
Retornar
Problema:
Mostrar una ventana y en su interior tres controles de tipo Checkbutton cuyas
etiquetas correspondan a distintos lenguajes de programación. Cuando se
presione un botón mostrar en una Label la cantidad de Checkbutton que se
encuentran chequeados.
Programa: ejercicio227.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.seleccion1=tk.IntVar()
self.check1=tk.Checkbutton(self.ventana1,
text="Python", variable=self.seleccion1)
self.check1.grid(column=0, row=0)
self.seleccion2=tk.IntVar()
self.check2=tk.Checkbutton(self.ventana1,
text="C++", variable=self.seleccion2)
self.check2.grid(column=0, row=1)
self.seleccion3=tk.IntVar()
self.check3=tk.Checkbutton(self.ventana1,
text="Java", variable=self.seleccion3)
self.check3.grid(column=0, row=2)
self.boton1=tk.Button(self.ventana1, text
="Verificar", command=self.verificar)
self.boton1.grid(column=0, row=4)
self.label1=tk.Label(self.ventana1,text="
cantidad:")
self.label1.grid(column=0, row=5)
self.ventana1.mainloop()
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:"+st
r(cant))
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
A cada control de tipo Checkbutton lo asociamos con un objeto de la clase
IntVar (por defecto el objeto de la clase IntVar almacena un cero indicando que
el Checkbutton debe aparecer no seleccionado):
self.seleccion1=tk.IntVar()
self.check1=tk.Checkbutton(self.ventana1,text="Python", variable=self.se
leccion1)
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))
Problema:
Disponer un control Checkbutton que muestre el siguiente mensaje: ¿Está de
acuerdo con los términos y condiciones?, además agregar un Button desactivo.
Cuando se tilde el Checkbutton inmediatamente activar el botón.
Programa: ejercicio228.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.seleccion=tk.IntVar()
self.check1=tk.Checkbutton(self.ventana1,
text="¿Está de acuerdo con los términos y condici
ones?", variable=self.seleccion, command=self.cam
biarestado)
self.check1.grid(column=0, row=0)
self.boton1=tk.Button(self.ventana1, text
="Entrar", state="disabled", command=self.ingresa
r)
self.boton1.grid(column=0, row=1)
self.ventana1.mainloop()
def cambiarestado(self):
if self.seleccion.get()==1:
self.boton1.configure(state="normal")
if self.seleccion.get()==0:
self.boton1.configure(state="disabled
")
def ingresar(self):
self.ventana1.title("Ingresando...")
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
def cambiarestado(self):
if self.seleccion.get()==1:
self.boton1.configure(state="normal")
if self.seleccion.get()==0:
self.boton1.configure(state="disabled")
Problema propuesto
• Disponer varios objetos de la clase Checkbutton con nombres de
navegadores web. En el título de la ventana mostrar todos los nombres
de navegadores seleccionados.
Ver video
Solución
Retornar
62 - tkinter : control Listbox
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.
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.listbox1=tk.Listbox(self.ventana1)
self.listbox1.grid(column=0,row=0)
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")
self.boton1=tk.Button(self.ventana1, text=
"Recuperar", command=self.recuperar)
self.boton1.grid(column=0, row=1)
self.label1=tk.Label(self.ventana1,text="S
eleccionado:")
self.label1.grid(column=0, row=2)
self.ventana1.mainloop()
def recuperar(self):
if len(self.listbox1.curselection())!=0:
self.label1.configure(text=self.listbo
x1.get(self.listbox1.curselection()[0]))
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
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.curselect
ion()[0]))
Problema:
Disponer un Listbox con una serie de nombres de frutas. Permitir la selección
de varias frutas. Cuando se presione un botón recuperar todas las frutas
seleccionadas y mostrarlas en una Label.
Programa: ejercicio231.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.listbox1=tk.Listbox(self.ventana1, se
lectmode=tk.MULTIPLE)
self.listbox1.grid(column=0,row=0)
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")
self.boton1=tk.Button(self.ventana1, text=
"Recuperar", command=self.recuperar)
self.boton1.grid(column=0, row=1)
self.label1=tk.Label(self.ventana1,text="S
eleccionado:")
self.label1.grid(column=0, row=2)
self.ventana1.mainloop()
def recuperar(self):
if len(self.listbox1.curselection())!=0:
todas=''
for posicion in self.listbox1.curselec
tion():
todas+=self.listbox1.get(posicion)
+"\n"
self.label1.configure(text=todas)
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
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.
El mismo programa anterior pero con la barra de scroll queda:
Programa: ejercicio232.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.scroll1 = tk.Scrollbar(self.ventana1,
orient=tk.VERTICAL)
self.listbox1=tk.Listbox(self.ventana1, se
lectmode=tk.MULTIPLE, yscrollcommand=self.scroll1.
set)
self.listbox1.grid(column=0,row=0)
self.scroll1.configure(command=self.listbo
x1.yview)
self.scroll1.grid(column=1, row=0, sticky=
'NS')
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")
self.listbox1.insert(6,"limon")
self.listbox1.insert(7,"kiwi")
self.listbox1.insert(5,"banana")
self.listbox1.insert(5,"uva")
self.listbox1.insert(5,"papaya")
self.listbox1.insert(5,"mandarina")
self.listbox1.insert(5,"frutilla")
self.boton1=tk.Button(self.ventana1, text=
"Recuperar", command=self.recuperar)
self.boton1.grid(column=0, row=1)
self.label1=tk.Label(self.ventana1,text="S
eleccionado:")
self.label1.grid(column=0, row=2)
self.ventana1.mainloop()
def recuperar(self):
if len(self.listbox1.curselection())!=0:
todas=''
for posicion in self.listbox1.curselec
tion():
todas+=self.listbox1.get(posicion)
+"\n"
self.label1.configure(text=todas)
aplicacion1=Aplicacion()
Creamos un objeto de la clase Scrollbar que se encuentra declarado en el
módulo tkinter:
self.scroll1.configure(command=self.listbox1.yview)
Finalmente ubicamos el Scrollbar en la segunda columna y hacemos que se
expanda de 'N' North a 'S' South configurando sticky:
Problema propuesto
• Solicitar el ingreso del nombre de una persona y seleccionar de un
control Listbox un país. Al presionar un botón mostrar en la barra de la
ventana el nombre ingresado y el país seleccionado.
Ver video
Solución
Retornar
63 - módulo ttk
Tk hemos dicho que es una biblioteca de controles visuales que los podemos
acceder desde Python y desde otros lenguajes de programación.
En la versión Tk 8.5 sumó una nueva serie de controles visuales ( Notebook,
Combobox etc.) y modernizó los que hemos visto en los conceptos anteriores.
Para hacer uso de esta nueva versión de la biblioteca en Python se
implementó un nuevo módulo y se lo agregó al paquete tkinter.
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.
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.valor=1
self.ventana1=tk.Tk()
self.ventana1.title("Controles Button y L
abel")
self.label1=ttk.Label(self.ventana1, text
=self.valor)
self.label1.grid(column=0, row=0)
self.label1.configure(foreground="red")
self.boton1=ttk.Button(self.ventana1, tex
t="Incrementar", command=self.incrementar)
self.boton1.grid(column=0, row=1)
self.boton2=ttk.Button(self.ventana1, tex
t="Decrementar", command=self.decrementar)
self.boton2.grid(column=0, row=2)
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()
Como los tres controles (Label y Button) son de este nuevo módulo podemos
ver que su representación visual es distinta:
Recordemos como se veían utilizando el módulo tkinter:
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.i
ncrementar)
...
self.boton2=ttk.Button(self.ventana1, text="Decrementar", command=self.d
ecrementar)
self.label1=tk.Label(self.ventana1, text=self.valor)
Problema:
Ingresar el nombre de usuario y clave en controles de tipo Entry. Si se ingresa
las cadena (usuario: juan, clave="abc123") luego mostrar en el título de la
ventana el mensaje "Correcto" en caso contrario mostrar el mensaje
"Incorrecto". Utilizar Widget del módulo ttk.
Programa: ejercicio235.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=ttk.Label(text="Ingrese nombr
e de usuario:")
self.label1.grid(column=0, row=0)
self.dato1=tk.StringVar()
self.entry1=ttk.Entry(self.ventana1, widt
h=30, textvariable=self.dato1)
self.entry1.grid(column=1, row=0)
self.label2=ttk.Label(text="Ingrese clave
:")
self.label2.grid(column=0, row=1)
self.dato2=tk.StringVar()
self.entry2=ttk.Entry(self.ventana1, widt
h=30, textvariable=self.dato2, show="*")
self.entry2.grid(column=1, row=1)
self.boton1=ttk.Button(self.ventana1, tex
t="Ingresar", command=self.ingresar)
self.boton1.grid(column=1, row=2)
self.ventana1.mainloop()
def ingresar(self):
if self.dato1.get()=="juan" and self.dato
2.get()=="abc123":
self.ventana1.title("Correcto")
else:
self.ventana1.title("Incorrecto")
aplicacion1=Aplicacion()
La interfaz visual queda:
self.dato1=tk.StringVar()
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.seleccion=tk.IntVar()
self.seleccion.set(2)
self.radio1=ttk.Radiobutton(self.ventana1
,text="Varon", variable=self.seleccion, value=1)
self.radio1.grid(column=0, row=0)
self.radio2=ttk.Radiobutton(self.ventana1
,text="Mujer", variable=self.seleccion, value=2)
self.radio2.grid(column=0, row=1)
self.boton1=ttk.Button(self.ventana1, tex
t="Mostrar seleccionado", command=self.mostrarsel
eccionado)
self.boton1.grid(column=0, row=2)
self.label1=ttk.Label(text="opcion selecc
ionada")
self.label1.grid(column=0, row=3)
self.ventana1.mainloop()
def mostrarseleccionado(self):
if self.seleccion.get()==1:
self.label1.configure(text="opcion se
leccionada=Varon")
if self.seleccion.get()==2:
self.label1.configure(text="opcion se
leccionada=Mujer")
aplicacion1=Aplicacion()
La interfaz visual con el módulo ttk queda:
Problema:
Mostrar una ventana y en su interior tres controles de tipo Checkbutton cuyas
etiquetas correspondan a distintos lenguajes de programación. Cuando se
presione un botón mostrar en una Label la cantidad de Checkbutton que se
encuentran chequeados. Utilizar Widget del módulo ttk.
Programa: ejercicio237.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.seleccion1=tk.IntVar()
self.check1=ttk.Checkbutton(self.ventana1
,text="Python", variable=self.seleccion1)
self.check1.grid(column=0, row=0)
self.seleccion2=tk.IntVar()
self.check2=ttk.Checkbutton(self.ventana1
,text="C++", variable=self.seleccion2)
self.check2.grid(column=0, row=1)
self.seleccion3=tk.IntVar()
self.check3=ttk.Checkbutton(self.ventana1
,text="Java", variable=self.seleccion3)
self.check3.grid(column=0, row=2)
self.boton1=ttk.Button(self.ventana1, tex
t="Verificar", command=self.verificar)
self.boton1.grid(column=0, row=4)
self.label1=ttk.Label(text="cantidad:")
self.label1.grid(column=0, row=5)
self.ventana1.mainloop()
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:"+st
r(cant))
aplicacion1=Aplicacion()
La interfaz visual con el módulo ttk queda:
Acotaciones
El módulo ttk no implementa el Widget Listbox, pero podemos mezclar en una
aplicación controles visuales de los dos paquetes.
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.listbox1=tk.Listbox(self.ventana1)
self.listbox1.grid(column=0,row=0)
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")
self.boton1=ttk.Button(self.ventana1, tex
t="Recuperar", command=self.recuperar)
self.boton1.grid(column=0, row=1)
self.label1=ttk.Label(text="Seleccionado:
")
self.label1.grid(column=0, row=2)
self.ventana1.mainloop()
def recuperar(self):
if len(self.listbox1.curselection())!=0:
self.label1.configure(text=self.listb
ox1.get(self.listbox1.curselection()[0]))
aplicacion1=Aplicacion()
Notemos que la clase Listbox la recuperamos del módulo tkinter a través de su
alias tk:
self.listbox1=tk.Listbox(self.ventana1)
Retornar
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=ttk.Label(self.ventana1, text
="Seleccione un día de la semana")
self.label1.grid(column=0, row=0)
self.opcion=tk.StringVar()
diassemana=("lunes","martes","miércoles",
"jueves","viernes","sábado","domingo")
self.combobox1=ttk.Combobox(self.ventana1
,
width=10,
textvariable=se
lf.opcion,
values=diassema
na)
self.combobox1.current(0)
self.combobox1.grid(column=0, row=1)
self.boton1=tk.Button(self.ventana1, text
="Recuperar", command=self.recuperar)
self.boton1.grid(column=0, row=2)
self.label2=ttk.Label(self.ventana1, text
="Día seleccionado:")
self.label2.grid(column=0, row=3)
self.ventana1.mainloop()
def recuperar(self):
self.label2.configure(text=self.opcion.ge
t())
aplicacion1=Aplicacion()
La ejecución de esta aplicación muestra una interfaz visual similar a esta:
self.opcion=tk.StringVar()
diassemana=("lunes","martes","miércoles","jueves","viernes","sábado","do
mingo")
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.
Si ejecutamos la aplicación y escribimos dentro del Combobox podemos ver
que nos deja ingresar cualquier string. Para desactivar la edición del
Combobox debemos iniciar el parámetro state con el valor 'readonly':
self.combobox1=ttk.Combobox(self.ventana1,
width=10,
textvariable=self.opcion,
values=diassemana,
state='readonly')
Problema propuesto
• Solicitar el ingreso del nombre de una persona y seleccionar de un
control Combobox un país. Al presionar un botón mostrar en la barra de
la ventana el nombre ingresado y el país seleccionado.
Ver video
Solución
Retornar
Problema:
Confeccionar una aplicación que muestre dos opciones en el menú de barra
superior. La primer opción despliega un submenú que permita cambiar el color
de fondo del formulario y la segunda permita cambiar el tamaño de formulario:
Programa: ejercicio241.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1)
opciones1.add_command(label="Rojo", comma
nd=self.fijarrojo)
opciones1.add_command(label="Verde", comm
and=self.fijarverde)
opciones1.add_command(label="Azul", comma
nd=self.fijarazul)
menubar1.add_cascade(label="Colores", men
u=opciones1)
opciones2 = tk.Menu(menubar1)
opciones2.add_command(label="640x480", co
mmand=self.ventanachica)
opciones2.add_command(label="1024x800", c
ommand=self.ventanagrande)
menubar1.add_cascade(label="Tamaños", men
u=opciones2)
self.ventana1.mainloop()
def fijarrojo(self):
self.ventana1.configure(background="red")
def fijarverde(self):
self.ventana1.configure(background="green
")
def fijarazul(self):
self.ventana1.configure(background="blue"
)
def ventanachica(self):
self.ventana1.geometry("640x480")
def ventanagrande(self):
self.ventana1.geometry("1024x800")
aplicacion1=Aplicacion()
Importamos solo el módulo tkinter ya que no utilizamos controles del módulo
tkinter.ttk:
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)
• opciones1 = tk.Menu(menubar1)
• opciones1.add_command(label="Rojo", command=self.fijarrojo)
• opciones1.add_command(label="Verde", command=self.fijarverde)
• opciones1.add_separator()
• opciones1.add_command(label="Azul", command=self.fijarazul)
• import tkinter as tk
•
• class Aplicacion:
• def __init__(self):
• self.ventana1=tk.Tk()
• menubar1 = tk.Menu(self.ventana1)
• self.ventana1.config(menu=menubar1)
• opciones1 = tk.Menu(menubar1, tearoff
=0)
• opciones1.add_command(label="Rojo", c
ommand=self.fijarrojo, accelerator="Ctrl+R")
• opciones1.add_command(label="Verde",
command=self.fijarverde, accelerator="Ctrl+V"
)
• opciones1.add_separator()
• opciones1.add_command(label="Azul", c
ommand=self.fijarazul, accelerator="Ctrl+A")
• self.ventana1.bind_all("<Control-r>",
self.cambiar)
• self.ventana1.bind_all("<Control-v>",
self.cambiar)
• self.ventana1.bind_all("<Control-a>",
self.cambiar)
• 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)
• self.ventana1.mainloop()
•
• def fijarrojo(self):
• self.ventana1.configure(background="r
ed")
•
• def fijarverde(self):
• self.ventana1.configure(background="g
reen")
•
• def fijarazul(self):
• self.ventana1.configure(background="b
lue")
•
• def ventanachica(self):
• self.ventana1.geometry("640x480")
•
• def ventanagrande(self):
• self.ventana1.geometry("1024x800")
•
• aplicacion1=Aplicacion()
El método cambiar se ejecuta cuando presionamos al mismo tiempo la
tecla Ctrl y alguna de las otras teclas "R", "V" o "A":
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1)
opciones1.add_command(label="Rojo", c
ommand=self.fijarrojo)
opciones1.add_command(label="Verde",
command=self.fijarverde)
opciones1.add_command(label="Azul", c
ommand=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)
submenu1=tk.Menu(menubar1)
submenu1.add_command(label="1024x1024
", command=self.tamano1)
submenu1.add_command(label="1280x1024
", command=self.tamano2)
opciones2.add_cascade(label="Otros ta
maños", menu= submenu1)
menubar1.add_cascade(label="Tamaños",
menu=opciones2)
self.ventana1.mainloop()
def fijarrojo(self):
self.ventana1.configure(background="r
ed")
def fijarverde(self):
self.ventana1.configure(background="g
reen")
def fijarazul(self):
self.ventana1.configure(background="b
lue")
def ventanachica(self):
self.ventana1.geometry("640x480")
def ventanagrande(self):
self.ventana1.geometry("1024x800")
def tamano1(self):
self.ventana1.geometry("1024x1024")
def tamano2(self):
self.ventana1.geometry("1280x1024")
aplicacion1=Aplicacion()
Problema propuesto
• 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
Ver video
Solución
Retornar
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.ventana1.title("Prueba del control N
otebook")
self.cuaderno1 = ttk.Notebook(self.ventan
a1)
self.pagina1 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina1, text="Bu
tton")
self.label1=ttk.Label(self.pagina1, text=
"La clase Button nos permite capturar el clic y l
anzar un método.")
self.label1.grid(column=0, row=0)
self.boton1=ttk.Button(self.pagina1, text
="Ejemplo de botón")
self.boton1.grid(column=0, row=1)
self.boton2=ttk.Button(self.pagina1, text
="Ejemplo de botón inactivo", state="disabled")
self.boton2.grid(column=0, row=2)
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="La
bel")
self.label2=ttk.Label(self.pagina2, text=
"La clase Label permite mostrar un mensaje en la
ventana")
self.label2.grid(column=0, row=0)
self.label3=ttk.Label(self.pagina2, text=
"con los caracteres \\n podemos hacer un salto de
línea dentro de la Label")
self.label3.grid(column=0, row=1)
self.pagina3 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina3, text="En
try")
self.label4=ttk.Label(self.pagina3, text=
"""En tkinter el control de entrada de datos por
teclado se llama Entry.\n
Con este control aparece el típico recuadro que c
uando se le da foco aparece el cursor en forma in
termitente\n
esperando que el operador escriba algo por teclad
o.""")
self.label4.grid(column=0, row=0)
self.entry1=tk.Entry(self.pagina3, width=
30)
self.entry1.grid(column=0, row=1)
self.cuaderno1.grid(column=0, row=0)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
Creamos un objeto de la clase Notebook y le pasamos como referencia la
ventana donde se mostrará:
self.cuaderno1 = ttk.Notebook(self.ventana1)
self.pagina1 = ttk.Frame(self.cuaderno1)
Añadimos el objeto de la clase Frame que acabamos de crear con el nombre
'pagina1' en el objeto 'cuaderno1' y en la propiedad 'text' indicamos el texto que
debe mostrar la pestaña:
self.cuaderno1.add(self.pagina1, text="Button")
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:
De forma similar creamos las otras dos pestañas con sus respectivos 'Frame':
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Label")
self.label2=ttk.Label(self.pagina2, text="La clase Label permite mostrar
un mensaje en la ventana")
self.label2.grid(column=0, row=0)
self.label3=ttk.Label(self.pagina2, text="con los caracteres \\n podemos
hacer un salto de línea dentro de la Label")
self.label3.grid(column=0, row=1)
self.pagina3 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina3, text="Entry")
self.label4=ttk.Label(self.pagina3, text="""En tkinter el control de ent
rada de datos por teclado se llama Entry.\n
Con este control aparece el típico recuadro que cuando se le da foco aparece el
cursor en forma intermitente\n
esperando que el operador escriba algo por teclado.""")
self.label4.grid(column=0, row=0)
self.entry1=tk.Entry(self.pagina3, width=30)
self.entry1.grid(column=0, row=1)
self.cuaderno1.grid(column=0, row=0)
Retornar
Problema:
Confeccionar una aplicación que muestre dos controles de tipo LabelFrame. En
la primera disponer 2 Label, 2 Entry y un Button, en el segundo LabelFrame
disponer 3 botones.
La representación visual debe ser:
Programa: ejercicio244.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.labelframe1=ttk.LabelFrame(self.vent
ana1, text="Login:")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.login()
self.labelframe2=ttk.LabelFrame(self.vent
ana1, text="Operaciones")
self.labelframe2.grid(column=0, row=1, pa
dx=5, pady=10)
self.operaciones()
self.ventana1.mainloop()
def login(self):
self.label1=ttk.Label(self.labelframe1, t
ext="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, t
ext="Ingrese clave:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.entry2=ttk.Entry(self.labelframe1, s
how="*")
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)
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)
aplicacion1=Aplicacion()
En el método __init__ inmediatamente luego de crear el objeto de la clase Tk
procedemos a crear el primer LabelFrame y ubicarlo dentro de la ventana:
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.
De forma similar en el método __init__ creamos el segundo LabelFrame y
llamamos al método operaciones:
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.
Si tenemos luego que hacer cambios de ubicación de los LabelFrame es muy
sencillo, solo cambiamos los valores que le pasamos a grid. Si queremos que
primero se muestre la barra de botones y luego el login:
Problema propuesto
• Mediante dos controles de tipo LabelFrame implementar la siguiente
interfaz visual:
Ver video
Solución
Retornar
68 - tkinter : Layout Manager
(administrador de diseño)
Una de las herramientas fundamentales cuando armamos interfaces visuales
es la metodología que utilizamos para disponer los controles dentro del
formulario. Hasta ahora hemos utilizado el administrador de diseño Grid.
En la librería GUI tkinter disponemos de tres Layout Manager para disponer
controles dentro de una ventana:
1. Grid
2. Pack
3. Place
Problema:
Disponer una serie de botones utilizando el Layout Manager de tipo Pack.
La representación visual debe ser:
Programa: ejercicio246.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.boton1=ttk.Button(self.ventana1, tex
t="Boton 1")
self.boton1.pack(side=tk.TOP, fill=tk.BOT
H)
self.boton2=ttk.Button(self.ventana1, tex
t="Boton 2")
self.boton2.pack(side=tk.TOP, fill=tk.BOT
H)
self.boton3=ttk.Button(self.ventana1, tex
t="Boton 3")
self.boton3.pack(side=tk.TOP, fill=tk.BOT
H)
self.boton4=ttk.Button(self.ventana1, tex
t="Boton 4")
self.boton4.pack(side=tk.LEFT)
self.boton5=ttk.Button(self.ventana1, tex
t="Boton 5")
self.boton5.pack(side=tk.RIGHT)
self.boton6=ttk.Button(self.ventana1, tex
t="Boton 6")
self.boton6.pack(side=tk.RIGHT)
self.boton7=ttk.Button(self.ventana1, tex
t="Boton 7")
self.boton7.pack(side=tk.RIGHT)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
Para ubicar los controles empleando el administrador de diseños Pack
utilizamos el método 'pack' que cuenta con una serie de parámetros.
El boton1 se ubica en la parte superior de la ventana ya que en el parámetro
side hemos pasado la contante tk.TOP:
• 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:
Para lograr ese resultado debemos hacer los siguientes cambios:
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.boton1=ttk.Button(self.ventana1, tex
t="Boton 1")
self.boton1.pack(side=tk.TOP, fill=tk.BOT
H, padx=5, pady=5)
self.boton2=ttk.Button(self.ventana1, tex
t="Boton 2")
self.boton2.pack(side=tk.TOP, fill=tk.BOT
H, padx=15, pady=15)
self.boton3=ttk.Button(self.ventana1, tex
t="Boton 3")
self.boton3.pack(side=tk.TOP, fill=tk.BOT
H, padx=25, pady=25)
self.boton4=ttk.Button(self.ventana1, tex
t="Boton 4")
self.boton4.pack(side=tk.LEFT)
self.boton5=ttk.Button(self.ventana1, tex
t="Boton 5")
self.boton5.pack(side=tk.RIGHT, padx=10)
self.boton6=ttk.Button(self.ventana1, tex
t="Boton 6")
self.boton6.pack(side=tk.RIGHT)
self.boton7=ttk.Button(self.ventana1, tex
t="Boton 7")
self.boton7.pack(side=tk.RIGHT)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
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.
Problema:
Disponer una serie de botones utilizando el Layout Manager de tipo Grid.
La representación visual debe ser:
Programa: ejercicio247.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.boton1=ttk.Button(self.ventana1, tex
t="Boton 1")
self.boton1.grid(column=0, row=0)
self.boton2=ttk.Button(self.ventana1, tex
t="Boton 2")
self.boton2.grid(column=1, row=0)
self.boton3=ttk.Button(self.ventana1, tex
t="Boton 3")
self.boton3.grid(column=2, row=0, rowspan
=2, sticky="ns")
self.boton4=ttk.Button(self.ventana1, tex
t="Boton 4")
self.boton4.grid(column=0, row=1)
self.boton5=ttk.Button(self.ventana1, tex
t="Boton 5")
self.boton5.grid(column=1, row=1)
self.boton6=ttk.Button(self.ventana1, tex
t="Boton 6")
self.boton6.grid(column=0, row=2, columns
pan=3, sticky="we")
self.ventana1.mainloop()
aplicacion1=Aplicacion()
Los dos primeros botones como ocupan una celda única no varía con lo que
hemos visto hasta ahora:
Problema:
Disponer dos botones en la parte inferior derecha de la ventana utilizando el
Layout Manager de tipo Place. El ancho y alto de la ventana debe ser de 800
por 600 píxeles.
La representación visual debe ser:
Programa: ejercicio248.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.ventana1.geometry("800x600")
self.ventana1.resizable(0,0)
self.boton1=ttk.Button(self.ventana1, tex
t="Confirmar")
self.boton1.place(x=680, y=550, width=90,
height=30)
self.boton2=ttk.Button(self.ventana1, tex
t="Cancelar")
self.boton2.place(x=580, y=550, width=90,
height=30)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
Creamos una ventana de 800x600 píxeles:
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)
self.boton2=ttk.Button(self.ventana1, text="Cancelar")
self.boton2.place(x=580, y=550, width=90, height=30)
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.
Retornar
69 - tkinter.messagebox : ventanas de
mensajes
Las aplicaciones de escritorio es muy común la necesidad de abrir otras
ventanas emergentes con el objetivo de informar, advertir de errores etc.
La librería tkinter provee un paquete llamado messagebox con una serie de
funciones para la apertura de diálogos de información.
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.
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.
Agregar además un menú de opciones que al ser seleccionado nos muestre
información del programa.
La representación visual cuando se presiona el botón "sumar" y no se ingresa
alguno de los dos números debe ser:
La representación visual cuando se abre el diálogo que informa sobre el
programa desde el menú de opciones es:
Programa: ejercicio249.py
Ver video
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.labelframe1=ttk.LabelFrame(self.vent
ana1, text="Suma de números")
self.labelframe1.grid(column=0, row=0, pa
dx=10, pady=10)
self.agregar_componentes()
self.agregar_menu()
self.ventana1.mainloop()
def agregar_componentes(self):
self.label1=ttk.Label(self.labelframe1, t
ext="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, t
extvariable=self.dato1)
self.entry1.grid(column=1, row=0, padx=5,
pady=5)
self.label2=ttk.Label(self.labelframe1, t
ext="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, t
extvariable=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, t
earoff=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 deja
r los cuadros de entrada de números vacíos")
else:
suma=int(self.dato1.get())+int(self.d
ato2.get())
self.ventana1.title("La suma es "+str
(suma))
def acerca(self):
mb.showinfo("Información", "Este programa
fue desarrollado para el aprendizaje de Python y
tkinter.")
aplicacion1=Aplicacion()
Creamos un objeto de la clase LabelFrame para disponer los controles de
entrada de dato y el botón de sumar:
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.suma
r)
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úm
eros vacíos")
else:
suma=int(self.dato1.get())+int(self.dato2.get())
self.ventana1.title("La suma es "+str(suma))
def acerca(self):
mb.showinfo("Información", "Este programa fue desarrollado para el apren
dizaje de Python y tkinter.")
Problema:
Confeccionar un programa que tenga solo un menú de opciones que al ser
presionado nos muestre un cuadro de mensaje que informe si queremos
finalizar la ejecución del programa. Si se presiona "si" se finaliza el programa
en caso contrario no se hace nada.
La representación visual luego de seleccionar la opción del menú es:
Programa: ejercicio250.py
Ver video
import tkinter as tk
from tkinter import messagebox as mb
import sys
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.agregar_menu()
self.ventana1.mainloop()
def agregar_menu(self):
self.menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=self.menubar1)
self.opciones1 = tk.Menu(self.menubar1, t
earoff=0)
self.opciones1.add_command(label="Salir",
command=self.salir)
self.menubar1.add_cascade(label="Opciones
", menu=self.opciones1)
def salir(self):
respuesta=mb.askyesno("Cuidado", "¿Quiere
salir del programa?")
if respuesta==True:
sys.exit()
aplicacion1=Aplicacion()
Cuando se selecciona la opción "Salir" del menú se ejecuta el método 'salir':
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()
Retornar
Problema:
Confeccionar una aplicación que muestre un diálogo cuando se seleccione una
opción de un menú.
El dialogo debe solicitar el ingreso de dos enteros que se utilizarán en la
ventana principal para redimensionarla.
La representación visual de la ventana principal es muy sencilla:
Cuando se abre el diálogo tenemos la siguiente imagen:
Programa: ejercicio251.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.agregar_menu()
self.ventana1.mainloop()
def agregar_menu(self):
self.menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=self.menubar1)
self.opciones1 = tk.Menu(self.menubar1, t
earoff=0)
self.opciones1.add_command(label="Configu
rar ventana", command=self.configurar)
self.menubar1.add_cascade(label="Opciones
", menu=self.opciones1)
def configurar(self):
dialogo1 = DialogoTamano(self.ventana1)
s=dialogo1.mostrar()
self.ventana1.geometry(s[0]+"x"+s[1])
class DialogoTamano:
def mostrar(self):
self.dialogo.wait_window()
return (self.dato1.get(), self.dato2.get(
))
def confirmar(self):
self.dialogo.destroy()
aplicacion1=Aplicacion()
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()
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.conf
igurar)
self.menubar1.add_cascade(label="Opciones", menu=self.opciones1)
def configurar(self):
dialogo1 = DialogoTamano(self.ventana1)
Inmediatamente luego de crear el diálogo llamamos al método 'mostrar' donde
se quedará ejecutando la aplicación hasta que el operador cierre el diálogo:
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])
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())
def confirmar(self):
self.dialogo.destroy()
Retornar
Programa: ejercicio252.py
Ver video
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb
import random
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.label1=ttk.Label(self.ventana1, text
="Seleccione la cantidad de bultos:")
self.label1.grid(column=0, row=0, padx=10
, pady=10)
self.spinbox1=ttk.Spinbox(self.ventana1,
from_=0, to=100, width=10, state='readonly')
self.spinbox1.set(0)
self.spinbox1.grid(column=1, row=0, padx=
10, pady=10)
self.boton1=ttk.Button(self.ventana1, tex
t="Sortear", command=self.sortear)
self.boton1.grid(column=0, row=1, padx=10
, pady=10)
self.label2=ttk.Label(self.ventana1, text
="", width=20)
self.label2.grid(column=1, row=1, padx=10
, pady=10)
self.ventana1.mainloop()
def sortear(self):
if int(self.spinbox1.get())==0:
mb.showerror("Cuidado","Debe seleccio
nar un valor distinto a cero en bultos")
else:
valor=random.randint(1,3)
if valor==1:
self.label2.configure(text="Se de
ben revisar")
self.label2.configure(background=
"red")
else:
self.label2.configure(text="No se
revisan")
self.label2.configure(background=
"green")
aplicacion1=Aplicacion()
Cuando creamos el Spinbox pasamos el parámetro 'from_' con el valor inicial y
el parámetro 'to' con el valor final (el nombre tan extraño de 'from_' se debe a
que Python tiene una palabra reservada con dicho nombre):
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
• Si queremos llenar el Spinbox con valores no consecutivos, sino de 3 en
3 podemos utilizar la siguiente sintaxis:
• self.spinbox1=ttk.Spinbox(self.ventana1, increment=3, from_=1, to=10, sta
te='readonly')
• self.spinbox1.set(dias[0])
Retornar
72 - tkinter.ScrolledText : editor
multilínea
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):
Problema:
Confeccionar un programa que contenga dos controles de tipo ScrolledText. En
el primero ingresamos por teclado cualquier texto. Mediante 4 controles de tipo
Entry indicar desde que fila y columna hasta que fila y columna extraer
caracteres del primer ScrolledText y copiarlos al segundo ScrolledText cuando
se presione un botón.
La interfaz visual debe ser similar a esta:
Programa: ejercicio253.py
Ver video
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext as st
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.scrolledtext1=st.ScrolledText(self.v
entana1, width=50, height=10)
self.scrolledtext1.grid(column=0,row=0, p
adx=10, pady=10)
self.framecopia()
self.scrolledtext2=st.ScrolledText(self.v
entana1, width=50, height=10)
self.scrolledtext2.grid(column=0,row=2, p
adx=10, pady=10)
self.ventana1.mainloop()
def framecopia(self):
self.labelframe1=ttk.LabelFrame(self.vent
ana1, text="Region")
self.labelframe1.grid(column=0, row=1, pa
dx=5, pady=5, sticky="w")
self.label1=ttk.Label(self.labelframe1, t
ext="Desde fila:")
self.label1.grid(column=0, row=0, padx=5,
pady=5, sticky="e")
self.dato1=tk.StringVar()
self.entry1=ttk.Entry(self.labelframe1, t
extvariable=self.dato1)
self.entry1.grid(column=1, row=0, padx=5,
pady=5, sticky="e")
self.label2=ttk.Label(self.labelframe1, t
ext="Desde columna:")
self.label2.grid(column=0, row=1, padx=5,
pady=5, sticky="e")
self.dato2=tk.StringVar()
self.entry2=ttk.Entry(self.labelframe1, t
extvariable=self.dato2)
self.entry2.grid(column=1, row=1, padx=5,
pady=5, sticky="e")
self.label3=ttk.Label(self.labelframe1, t
ext="Hasta fila:")
self.label3.grid(column=0, row=2, padx=5,
pady=5, sticky="e")
self.dato3=tk.StringVar()
self.entry3=ttk.Entry(self.labelframe1, t
extvariable=self.dato3)
self.entry3.grid(column=1, row=2, padx=5,
pady=5, sticky="e")
self.label4=ttk.Label(self.labelframe1, t
ext="Hasta columna:")
self.label4.grid(column=0, row=3, padx=5,
pady=5, sticky="e")
self.dato4=tk.StringVar()
self.entry4=ttk.Entry(self.labelframe1, t
extvariable=self.dato4)
self.entry4.grid(column=1, row=3, padx=5,
pady=5, sticky="e")
self.boton1=ttk.Button(self.labelframe1,
text="Copiar", command=self.copiar)
self.boton1.grid(column=1, row=4, padx=10
, pady=10)
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)
aplicacion1=Aplicacion()
Lo primero que hacemos es importar el módulo scrolledtext del paquete tkinter
y definir un alias:
def __init__(self):
self.ventana1=tk.Tk()
self.scrolledtext1=st.ScrolledText(self.ventana1, width=50, height=10)
self.scrolledtext1.grid(column=0,row=0, padx=10, pady=10)
self.framecopia()
self.scrolledtext2=st.ScrolledText(self.ventana1, width=50, height=10)
self.scrolledtext2.grid(column=0,row=2, padx=10, pady=10)
self.ventana1.mainloop()
Separamos en el método framecopia la creación de la interfaz visual donde se
cargan los 4 valores.
El método fundamental es el 'copiar':
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+"."+f
incolumna)
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.
Para borrar todo el contenido de un ScrolledText debemos llamar al método
delete y pasar estos dos parámetros:
self.scrolledtext2.delete("1.0", tk.END)
self.scrolledtext2.insert("1.0", datos)
Retornar
73 - tkinter : control Canvas
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:
Confeccionar un programa que cree un objeto de la clase Canvas y muestre la
funcionalidad de las principales primitivas gráficas.
La interfaz visual debe ser similar a esta:
Programa: ejercicio254.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0, row=0)
self.canvas1.create_line(0, 0, 100,50, fi
ll="white")
self.canvas1.create_rectangle(150,10, 250
,110, fill="white")
self.canvas1.create_oval(300,10,400,150,
fill="red")
self.canvas1.create_arc(420,10,550,110, f
ill="yellow", start=180, extent=90)
self.canvas1.create_rectangle(150,210, 25
0,310, outline="white")
self.canvas1.create_oval(300,210,400,350,
outline="red")
self.canvas1.create_arc(420,210,550,310,
outline="yellow", start=180, extent=90)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
La clase Canvas se encuentra en el módulo 'tkinter':
import tkinter as tk
self.canvas1.grid(column=0, row=0)
self.canvas1.create_oval(300,10,400,150, fill="red")
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.entradadatos()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0, row=1)
self.ventana1.mainloop()
def entradadatos(self):
self.lf1=ttk.LabelFrame(self.ventana1,tex
t="Partidos políticos")
self.lf1.grid(column=0, row=0, sticky="w"
)
self.label1=ttk.Label(self.lf1, text="Par
tido A:")
self.label1.grid(column=0,row=0, padx=5,
pady=5)
self.dato1=tk.StringVar()
self.entry1=ttk.Entry(self.lf1, textvaria
ble=self.dato1)
self.entry1.grid(column=1, row=0, padx=5,
pady=5)
self.label2=ttk.Label(self.lf1, text="Par
tido B:")
self.label2.grid(column=0,row=1, padx=5,
pady=5)
self.dato2=tk.StringVar()
self.entry2=ttk.Entry(self.lf1, textvaria
ble=self.dato2)
self.entry2.grid(column=1, row=1, padx=5,
pady=5)
self.label3=ttk.Label(self.lf1, text="Par
tido C:")
self.label3.grid(column=0,row=2, padx=5,
pady=5)
self.dato3=tk.StringVar()
self.entry3=ttk.Entry(self.lf1, textvaria
ble=self.dato3)
self.entry3.grid(column=1, row=2, padx=5,
pady=5)
self.boton1=ttk.Button(self.lf1, text="Ge
nerar gráfico", command=self.grafico_barra)
self.boton1.grid(column=0, row=3, columns
pan=2, padx=5, pady=5, sticky="we")
self.entry1.focus()
def grafico_barra(self):
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
largo1=valor1/mayor*400
largo2=valor2/mayor*400
largo3=valor3/mayor*400
self.canvas1.create_rectangle(10,10,10+la
rgo1,90,fill="red")
self.canvas1.create_rectangle(10,120,10+l
argo2,200,fill="blue")
self.canvas1.create_rectangle(10,230,10+l
argo3,310,fill="green")
self.canvas1.create_text(largo1+70, 50, t
ext="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")
aplicacion1=Aplicacion()
En el método __init__ llamamos al método 'entradadatos' que crea el
LabelFrame con los 3 controles Entry, 3 controles Label y el botón:
def __init__(self):
self.ventana1=tk.Tk()
self.entradadatos()
self.canvas1=tk.Canvas(self.ventana1, width=600, height=400, background=
"black")
self.canvas1.grid(column=0, row=1)
self.ventana1.mainloop()
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.
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':
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:.
La interfaz visual debe ser similar a esta:
Programa: ejercicio256.py
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.entradadatos()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0, row=1)
self.ventana1.mainloop()
def entradadatos(self):
self.lf1=ttk.LabelFrame(self.ventana1,tex
t="Partidos políticos")
self.lf1.grid(column=0, row=0, sticky="w"
)
self.label1=ttk.Label(self.lf1, text="Par
tido A:")
self.label1.grid(column=0,row=0, padx=5,
pady=5)
self.dato1=tk.StringVar()
self.entry1=ttk.Entry(self.lf1, textvaria
ble=self.dato1)
self.entry1.grid(column=1, row=0, padx=5,
pady=5)
self.label2=ttk.Label(self.lf1, text="Par
tido B:")
self.label2.grid(column=0,row=1, padx=5,
pady=5)
self.dato2=tk.StringVar()
self.entry2=ttk.Entry(self.lf1, textvaria
ble=self.dato2)
self.entry2.grid(column=1, row=1, padx=5,
pady=5)
self.label3=ttk.Label(self.lf1, text="Par
tido C:")
self.label3.grid(column=0,row=2, padx=5,
pady=5)
self.dato3=tk.StringVar()
self.entry3=ttk.Entry(self.lf1, textvaria
ble=self.dato3)
self.entry3.grid(column=1, row=2, padx=5,
pady=5)
self.boton1=ttk.Button(self.lf1, text="Ge
nerar gráfico", command=self.grafico_tarta)
self.boton1.grid(column=0, row=3, columns
pan=2, padx=5, pady=5, sticky="we")
self.entry1.focus()
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
grados1=valor1/suma*360
grados2=valor2/suma*360
grados3=valor3/suma*360
self.canvas1.create_arc(10,10,400,400,fil
l="red", start=0, extent=grados1)
self.canvas1.create_arc(10,10,400,400,fil
l="blue", start=grados1, extent=grados2)
self.canvas1.create_arc(10,10,400,400,fil
l="yellow", start=grados1+grados2, extent=grados3
)
self.canvas1.create_text(500, 50, text="p
artido A:"+str(valor1), fill="red", font="Arial")
self.canvas1.create_text(500, 100, text="
partido B:"+str(valor2), fill="blue", font="Arial
")
self.canvas1.create_text(500, 150, text="
partido C:"+str(valor3), fill="yellow", font="Ari
al")
aplicacion1=Aplicacion()
En el método grafico_tarta lo primero que hacemos es borrar el contenido del
control Canvas:
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
Problema propuesto
• Implementar un gráfico estadístico de tipo "Barra Porcentual":
Ver video
Solución
Retornar
74 - Canvas : captura de eventos del
mouse
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.
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.bind("<Motion>", self.mover_
mouse)
self.canvas1.bind("<Button-1>", self.pres
ion_mouse)
self.canvas1.grid(column=0, row=1)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
Luego de crear el objeto de la clase Canvas procedemos a llamar al método
bind e indicar el nombre de evento a capturar y el método que lo capturará:
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>
self.canvas1.bind("<Enter>", self.entrada)
self.canvas1.bind("<Leave>", self.salida)
• self.canvas1.bind("<Double-Button-1>", self.presion_mouse)
Problema:
Confeccionar un programa que cree un objeto de la clase Canvas y nos
permita dibujar a mano alzada dentro del mismo.
La interfaz visual debe ser similar a esta luego de dibujar unos trazos:
Programa: ejercicio259.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0,row=0)
self.canvas1.bind("<ButtonPress-1>",self.
boton_presion)
self.canvas1.bind("<Motion>", self.mover_
mouse)
self.canvas1.bind("<ButtonRelease-1>",sel
f.boton_soltar)
self.presionado=False
self.ventana1.mainloop()
def boton_soltar(self,evento):
self.presionado=False
aplicacion1=Aplicacion()
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("<ButtonRelease-1>", self.boton_soltar)
def boton_soltar(self,evento):
self.presionado=False
Retornar
75 - Canvas : borrar figuras mediante
Ids y Tags
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.
Problema:
Confeccionar un programa que cree un objeto de la clase Canvas y luego
dibuje una línea, un réctángulo y un óvalo, almacenar el Id de cada dibujo en
un atributo.
Crear también 3 cuadrados y definir el parámetro tag con el mismo valor para
cada uno de ellos.
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
Ver video
import tkinter as tk
from tkinter import ttk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.crear_botones()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0, row=1)
self.linea=self.canvas1.create_line(0, 0,
100,50, fill="white")
self.rectangulo=self.canvas1.create_recta
ngle(150,10, 300,110, fill="white")
self.ovalo=self.canvas1.create_oval(400,1
0,500,150, fill="red")
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")
self.ventana1.mainloop()
def crear_botones(self):
self.labelframe1=ttk.LabelFrame(self.vent
ana1,text="opciones")
self.labelframe1.grid(column=0, row=0, st
icky="w", padx=5, pady=5)
self.boton1=ttk.Button(self.labelframe1,
text="borrar linea", command=self.borrar_linea)
self.boton1.grid(column=0, row=0, padx=5)
self.boton2=ttk.Button(self.labelframe1,
text="borrar rectángulo", command=self.borrar_rec
tangulo)
self.boton2.grid(column=1, row=0, padx=5)
self.boton3=ttk.Button(self.labelframe1,
text="borrar óvalo", command=self.borrar_ovalo)
self.boton3.grid(column=2, row=0, padx=5)
self.boton4=ttk.Button(self.labelframe1,
text="borrar todos los cuadrados", command=self.b
orrar_cuadrados)
self.boton4.grid(column=3, row=0, padx=5)
self.boton5=ttk.Button(self.labelframe1,
text="borrar todos", command=self.borrar_todos)
self.boton5.grid(column=4, row=0, padx=5)
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)
def borrar_cuadrados(self):
self.canvas1.delete("cuadrado")
def borrar_todos(self):
self.canvas1.delete(tk.ALL)
aplicacion1=Aplicacion()
Las tres primeras figuras que creamos almacenamos en atributos de la clase la
referencia a las mismas:
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="cuadr
ado")
self.canvas1.create_rectangle(200,300,250,350,fill="#555555", tag="cuadr
ado")
self.canvas1.create_rectangle(300,300,350,350,fill="#cccccc", tag="cuadr
ado")
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)
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')
Retornar
Programa: ejercicio261.py
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=600, height=400, background="black")
self.canvas1.grid(column=0, row=0)
self.cuadrado=self.canvas1.create_rectang
le(150,10,200,60, fill="red")
self.ventana1.bind("<KeyPress>", self.pre
sion_tecla)
self.ventana1.mainloop()
aplicacion1=Aplicacion()
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)
Problema propuesto
• 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':
Ver video
Solución
Retornar
Problema:
Se cuenta con tres archivos de tipo png con las imágenes de distintas cartas.
Mostrarlas a cada una dentro de una componente de tipo Canvas.
Puede descargar estas tres imágenes y copiarlas en la carpeta donde codifica
sus programas en Python:
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=700, height=500, background="black")
self.canvas1.grid(column=0, row=0)
archi1=tk.PhotoImage(file="carta1.png")
self.canvas1.create_image(30, 100, image=
archi1, anchor="nw")
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")
self.ventana1.mainloop()
aplicacion1=Aplicacion()
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")
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")
Problema propuesto
• 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.
Ver video
Solución
Retornar
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
Ver video
import tkinter as tk
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.canvas1=tk.Canvas(self.ventana1, wid
th=900, height=500, background="black")
self.canvas1.grid(column=0, row=0)
archi1=tk.PhotoImage(file="carta1.png")
self.canvas1.create_image(30, 100, image=
archi1, anchor="nw", tags="movil")
archi2=tk.PhotoImage(file="carta2.png")
self.canvas1.create_image(400, 100, image
=archi2, anchor="nw", tags="movil")
self.canvas1.tag_bind("movil", "<ButtonPr
ess-1>", self.presion_boton)
self.canvas1.tag_bind("movil", "<Button1-
Motion>", self.mover)
self.carta_seleccionada = None
self.ventana1.mainloop()
aplicacion1=Aplicacion()
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
Problema propuesto
• Crear 100 cuadrados de color rojo y disponerlos en el control Canvas en
posiciones aleatorias. Permitir desplazar con el mouse cualquiera de los
cuadrados.
Ver video
Solución
Retornar
Archivo de texto
Un archivo de texto contiene un conjunto de caracteres estructurados en
distintas líneas. Es un formato de archivo ampliamente utilizado como pueden
ser:
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
Ver video
archi1=open("datos.txt","w")
archi1.write("Primer línea.\n")
archi1.write("Segunda línea.\n")
archi1.write("Tercer línea.\n")
archi1.close()
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.")
archi1.close()
Problema:
Leer el contenido del archivo de texto 'datos.txt'.
Programa: ejercicio268.py
archi1=open("datos.txt","r")
contenido=archi1.read()
print(contenido)
archi1.close()
Luego de ejecutar este programa:
Llamamos a la función 'open' y le pasamos el nombre del archivo a leer y un
string con el caracter "r" (read):
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()
Problema:
Leer el contenido del archivo de texto 'datos.txt' línea a línea.
Programa: ejercicio269.py
archi1=open("datos.txt","r")
linea=archi1.readline()
while linea!='':
print(linea, end='')
linea=archi1.readline()
archi1.close()
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()
archi1=open("datos.txt","r")
for linea in archi1:
print(linea, end='')
archi1.close()
Es una forma más compacta de recorrer cada una de las líneas del archivo de
texto.
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
archi1=open("datos.txt","r")
lineas=archi1.readlines()
print('El archivo tiene', len(lineas), 'líneas')
print('El contenido del archivo')
for linea in lineas:
print(linea, end='')
archi1.close()
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']
Problema:
Abrir el archivo de texto 'datos.txt' y luego agregar 2 líneas. Imprimir luego el
archivo completo.
Programa: ejercicio272.py
Ver video
archi1=open("datos.txt","a")
archi1.write("nueva línea 1\n")
archi1.write("nueva línea 2\n")
archi1.close()
archi1=open("datos.txt","r")
contenido=archi1.read()
print(contenido)
archi1.close()
Abrimos el archivo 'datos.txt' en modo agregar:
archi1=open("datos.txt","a")
archi1.close()
archi1=open("datos.txt","r")
contenido=archi1.read()
print(contenido)
archi1.close()
Problema:
Abrir un archivo de texto con el parámetro "r+", imprimir su contenido actual y
agregar luego dos líneas al final.
Programa: ejercicio273.py
archi1=open("datos.txt","r+")
contenido=archi1.read()
print(contenido)
archi1.write("Otra línea 1\n")
archi1.write("Otra línea 2\n")
archi1.close()
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
Ver video
archi1=open("datos.txt","w", encoding="utf-8")
archi1.write("Primer línea.\n")
archi1.write("Segunda línea.\n")
archi1.write("Tercer línea.\n")
archi1.close()
Si ahora abrimos el archivo de texto creado con un editor que permite trabajar
con archivos con codificación utf-8 el resultado es:
Retornar
Problema:
Confeccionar una interfaz visual que contenga un menú de opciones que
permitan "Guardar archivo", "Recuperar archivo" y "Salir del programa".
En la ventana principal debe aparecer un control de tipo 'scrolledtext' donde el
operador pueda escribir un texto para luego grabarlo en un archivo de texto.
También el control 'scrolledtext' debe cargarse con el contenido de un archivo
existente en el disco duro.
La interfaz visual debe ser:
import tkinter as tk
from tkinter import scrolledtext as st
import sys
from tkinter import filedialog as fd
from tkinter import messagebox as mb
class Aplicacion:
def __init__(self):
self.ventana1=tk.Tk()
self.agregar_menu()
self.scrolledtext1=st.ScrolledText(self.v
entana1, width=80, height=20)
self.scrolledtext1.grid(column=0,row=0, p
adx=10, pady=10)
self.ventana1.mainloop()
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 arch
ivo", command=self.guardar)
opciones1.add_command(label="Recuperar ar
chivo", command=self.recuperar)
opciones1.add_separator()
opciones1.add_command(label="Salir", comm
and=self.salir)
menubar1.add_cascade(label="Archivo", men
u=opciones1)
def salir(self):
sys.exit()
def guardar(self):
nombrearch=fd.asksaveasfilename(initialdi
r = "/",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","*.*")
))
if nombrearch!='':
archi1=open(nombrearch, "r", encoding
="utf-8")
contenido=archi1.read()
archi1.close()
self.scrolledtext1.delete("1.0", tk.E
ND)
self.scrolledtext1.insert("1.0", cont
enido)
aplicacion1=Aplicacion()
La parte de la interfaz visual la dividimos por un lado en la creación del
'ScrolledText':
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
.")
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)
Retornar
Instalación de MySQL.
Para facilitar la administración del MySQL utilizaremos el programa XAMPP
que entre otros instala:
• MySQL
• PHPMyAdmin (que nos permitirá administrar las bases de datos
existentes en 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.
En el siguiente diálogo debemos definir el nombre de nuestra base de datos, la
llamaremos "bd1":
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:
Almacenaremos en la tabla articulos el codigo, descripcion y precio.
El campo 'codigo' será int'clave primaria' y auto_increment.
El campo 'descripcion' será varchar de 50.
El campo 'precio' será float.
Los datos a ingresar para cada campo para la creación de la tabla articulos
son:
Ya tenemos creada la base de datos: "bd1" y en ésta la tabla "articulos":
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
", user="root", passwd="")
cursor1=conexion1.cursor()
cursor1.execute("show databases")
for base in cursor1:
print(base)
conexion1.close()
El resultado de ejecutar este programa es:
import mysql.connector
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()
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
cursor1.execute("show tables")
for tabla in cursor1:
print(tabla)
conexion1.close()
El resultado de ejecutar este programa es:
conexion1=mysql.connector.connect(host="localhost",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
cursor1.execute("show tables")
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
sql="insert into articulos(descripcion, precio) v
alues (%s,%s)"
datos=("naranjas", 23.50)
cursor1.execute(sql, datos)
datos=("peras", 34)
cursor1.execute(sql, datos)
datos=("bananas", 25)
cursor1.execute(sql, datos)
conexion1.commit()
conexion1.close()
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)
Finalmente llamamos al método 'execute' y le pasamos las dos variables que
acabamos de crear:
cursor1.execute(sql, datos)
Es fundamental llamar al final al método 'commit' para que queden firmes los
comandos SQL 'insert':
conexion1.commit()
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
cursor1.execute("select codigo, descripcion, prec
io from articulos")
for fila in cursor1:
print(fila)
conexion1.close()
Cuando ejecutamos el programa podemos ver que se recuperan todas las filas
de la tabla 'articulos':
Luego de conectarnos y crear un cursor procedemos a ejecutar el comando
'select', recorremos con un for el 'cursor1':
cursor1=conexion1.cursor()
cursor1.execute("select codigo, descripcion, precio from articulos")
for fila in cursor1:
print(fila)
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
cursor1.execute("delete from articulos where codi
go=1")
cursor1.execute("update articulos set precio=50 w
here codigo=3")
conexion1.commit()
cursor1.execute("select codigo, descripcion, prec
io from articulos")
for fila in cursor1:
print(fila)
conexion1.close()
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")
conexion1.commit()
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.
Seguiremos trabajando con la tabla 'articulos' que creamos en el concepto
anterior.
Las interfaz visual para la carga debe ser:
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.ventan
a1)
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="Ca
rga de artículos")
self.labelframe1=ttk.LabelFrame(self.pagi
na1, text="Artículo")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, t
ext="Descripción:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.descripcioncarga=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe1, textvariable=self.descripcioncarga)
self.entrydescripcion.grid(column=1, row=
0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, t
ext="Precio:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.preciocarga=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e1, textvariable=self.preciocarga)
self.entryprecio.grid(column=1, row=1, pa
dx=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 fue
ron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
def consulta_por_codigo(self):
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Co
nsulta por código")
self.labelframe2=ttk.LabelFrame(self.pagi
na2, text="Artículo")
self.labelframe2.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe2, t
ext="Código:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.codigo=tk.StringVar()
self.entrycodigo=ttk.Entry(self.labelfram
e2, textvariable=self.codigo)
self.entrycodigo.grid(column=1, row=0, pa
dx=4, pady=4)
self.label2=ttk.Label(self.labelframe2, t
ext="Descripción:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.descripcion=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe2, textvariable=self.descripcion, state="re
adonly")
self.entrydescripcion.grid(column=1, row=
1, padx=4, pady=4)
self.label3=ttk.Label(self.labelframe2, t
ext="Precio:")
self.label3.grid(column=0, row=2, padx=4,
pady=4)
self.precio=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e2, textvariable=self.precio, state="readonly")
self.entryprecio.grid(column=1, row=2, pa
dx=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="Li
stado completo")
self.labelframe3=ttk.LabelFrame(self.pagi
na3, text="Artículo")
self.labelframe3.grid(column=0, row=0, pa
dx=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.l
abelframe3, width=30, height=10)
self.scrolledtext1.grid(column=0,row=1, p
adx=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]+"\np
recio:"+str(fila[2])+"\n\n")
aplicacion1=FormularioArticulos()
El módulo 'articulos.py' contiene toda la lógica de acceso a datos.
módulo: articulos.py
import mysql.connector
class Articulos:
def abrir(self):
conexion=mysql.connector.connect(host="lo
calhost",
use
r="root",
pas
swd="",
dat
abase="bd1")
return conexion
def recuperar_todos(self):
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, precio f
rom articulos"
cursor.execute(sql)
cone.close()
return cursor.fetchall()
Tener en cuenta que el módulo principal se encuentra en el archivo
'formularioarticulos.py' y es el que debemos ejecutar:
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()
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("")
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()
Problema propuesto
• Agregar dos pestañas al programa de administración de artículos que
permitan borrar un artículo ingresando su código y otra opción que
permita consultar y modificar la descripción y precio de un artículo.
La interfaces visuales a implementar son:
Ver video
Solución
Retornar
83 - MySQL : otras funcionalidades del
paquete mysql-connector
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.
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
sql="insert into articulos(descripcion, precio) v
alues (%s,%s)"
datos=("naranjas", 23.50)
cursor1.execute(sql, datos)
conexion1.commit()
print("Valor del último codigo de artículo genera
do:", cursor1.lastrowid)
conexion1.close()
Luego de efectuar la inserción de una fila en la tabla 'articulos' procedemos a
acceder al atributo 'lastrowid' que almacena el código de artículo que se acaba
de generar.
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd1")
cursor1=conexion1.cursor()
sql="insert into articulos(descripcion, precio) v
alues (%s,%s)"
filas=[ ("naranjas", 23.50),
("bananas", 34),
("peras", 21),
("sandía", 19.60) ]
cursor1.executemany(sql, filas)
conexion1.commit()
conexion1.close()
El método 'executemany' debe recibir en el segundo parámetro una lista cuyos
elementos sean una tupla por cada fila:
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="")
cursor1=conexion1.cursor()
sql="create database bd2"
cursor1.execute(sql)
sql="use bd2"
cursor1.execute(sql)
conexion1.commit()
conexion1.close()
Lo primero que debemos notar que en la conexión al servidor de base de datos
MySQL no indicamos una "base de datos":
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)
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="")
cursor1=conexion1.cursor()
sql="use bd2"
cursor1.execute(sql)
conexion1.commit()
conexion1.close()
Este programa es una variante del anterior donde primero verificamos si existe
la base de datos 'bd2' y en caso afirmativo la eliminamos:
import mysql.connector
conexion1=mysql.connector.connect(host="localhost
",
user="root",
passwd="",
database="bd2")
cursor1=conexion1.cursor()
sql="drop table if exists usuarios"
cursor1.execute(sql)
conexion1.commit()
conexion1.close()
Para eliminar la tabla 'usuarios' si existe ejecutamos el siguiente comando
SQL:
Retornar
Problema:
Realizar la carga de dos números enteros por teclado e imprimir su suma,
luego preguntar si quiere seguir sumando valores.
Codificar dos programas uno que capture la excepción de ingreso de datos no
numéricos y el otro que no tenga en cuenta el tipo de entrada de datos.
Primero codificaremos sin la captura de excepciones.
Ver video
Programa: ejercicio296.py
while True:
valor1=int(input("Ingrese primer valor:"))
valor2=int(input("Ingrese segundo valor:"))
suma=valor1+valor2
print("La suma es", suma)
respuesta=input("Desea ingresar otro par de v
alores?[s/n]")
if respuesta=="n":
break
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.
El algoritmo planteado funciona correctamente en casi todos los casos,
siempre y cuando el operador ingrese por teclado valores numéricos. En el
caso que el operador ingrese un valor no numérico el programa se interrumpe
mostrando la excepción generada:
Como podemos comprobar el programa finaliza si ingresamos la cadena 'juan'
en lugar de un número. Es un tipo de error que según el tipo de programa que
estamos desarrollando capturaremos ésta excepción, por ejemplo si es un
pequeño script que utilizaremos nosotros mismos es posible que este algoritmo
nos alcance y tengamos cuidado de cargar siempre valores enteros por
teclado.
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
while True:
try:
valor1=int(input("Ingrese primer valor:")
)
valor2=int(input("Ingrese segundo valor:"
))
suma=valor1+valor2
print("La suma es",suma)
except ValueError:
print("debe ingresar números.")
respuesta=input("Desea ingresar otro par de v
alores?[s/n]")
if respuesta=="n":
break
En el caso que el operador ingrese un valor no numérico el programa no se
interrumpe mostrando la excepción generada sino que se ejecuta un algoritmo
alternativo:
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.")
Retornar
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
try:
valor1=int(input("Ingrese dividendo:"))
valor2=int(input("Ingrese divisor:"))
division=valor1/valor2
print("El resultado de la división es", divis
ion)
except ZeroDivisionError:
print("No se puede dividir por cero.")
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","n
oviembre","diciembre")
try:
nromes=int(input("Ingrese un número de mes [1
-12]:"))
print(meses[nromes-1])
except IndexError:
print("En número de mes debe ir entre 1 y 12"
)
Con este algoritmo si el operador ingresa un valor superior a 12 luego se
captura la excepción IndexError. Pero tenemos el problema si carga un valor 0
o inferior a 0 luego las tuplas pueden disponer valores negativos, por lo que
estos casos lo podemos resolver con un if:
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")
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
try:
valor1=int(input("Ingrese dividendo:"))
valor2=int(input("Ingrese divisor:"))
division=valor1/valor2
print("El resultado de la división es", divis
ion)
except ZeroDivisionError:
print("No se puede dividir por cero.")
except ValueError:
print("Los valores a ingresar deben ser enter
os")
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")
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
try:
valor1=int(input("Ingrese dividendo:"))
valor2=int(input("Ingrese divisor:"))
division=valor1/valor2
print("El resultado de la división es", divis
ion)
except:
print("Problemas con la entrada u operación")
Como podemos ver no disponemos un nombre de excepción después de la
palabra clave 'except':
except:
print("Problemas con la entrada u operación")
Retornar
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]
Problema:
Almacenar una serie de string en un archivo de texto. Tratar de llamar al
método 'write' pasando un entero.
Programa: ejercicio301.py
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)
except TypeError:
print("No se puede grabar un entero con write
")
finally:
archi1.close()
print("Se cerró el archivo")
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")
archi1.close()
print("Se cerró el archivo")
Problema:
Conectarse a una base de datos de MySQL y ejecutar un comando SQL
incorrecto.
Programa: ejercicio302.py
import mysql.connector
try:
conexion1=mysql.connector.connect(host="local
host", user="root", passwd="")
cursor1=conexion1.cursor()
cursor1.execute("show databasesqqqqqqqq")
for base in cursor1:
print(base)
except mysql.connector.errors.ProgrammingError:
print("Error en el comando SQL")
finally:
conexion1.close()
print("Se cerró la conexión a la base de dato
s")
Hemos definido un comando SQL incorrecto al llamar al método 'execute':
cursor1.execute("show databasesqqqqqqqq")
except mysql.connector.errors.ProgrammingError:
print("Error en el comando SQL")
finally:
conexion1.close()
print("Se cerró la conexión a la base de datos")
Retornar
• Firefox usa SQLite para almacenar los favoritos, el historial, las cookies
etc.
import sqlite3
conexion=sqlite3.connect("bd1.db")
try:
conexion.execute("""create table articulos (
codigo integer prim
ary key autoincrement,
descripcion text,
precio real
)""")
print("se creo la tabla articulos")
except sqlite3.OperationalError:
print("La tabla articulos ya existe")
conexion.close()
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:
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()
import sqlite3
conexion=sqlite3.connect("bd1.db")
conexion.execute("insert into articulos(descripci
on,precio) values (?,?)", ("naranjas", 23.50))
conexion.execute("insert into articulos(descripci
on,precio) values (?,?)", ("peras", 34))
conexion.execute("insert into articulos(descripci
on,precio) values (?,?)", ("bananas", 25))
conexion.commit()
conexion.close()
Llamamos a execute y le pasamos como primer parámetro un comando SQL
'insert' con el caracter '?' indicamos las posiciones donde se van a sustituir. El
segundo parámetro es una tupla con los datos que se utilizarán en la
sustitución:
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()
import sqlite3
conexion=sqlite3.connect("bd1.db")
cursor=conexion.execute("select codigo,descripcio
n,precio from articulos")
for fila in cursor:
print(fila)
conexion.close()
Si ejecutamos este programa luego de haber cargado las tres filas del ejercicio
anterior el resultado será el siguiente:
El método execute retorna un objeto de la clase Cursor:
import sqlite3
conexion=sqlite3.connect("bd1.db")
codigo=int(input("Ingrese el código de un artícul
o:"))
cursor=conexion.execute("select descripcion,preci
o from articulos where codigo=?", (codigo, ))
fila=cursor.fetchone()
if fila!=None:
print(fila)
else:
print("No existe un artículo con dicho código
.")
conexion.close()
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.")
import sqlite3
conexion=sqlite3.connect("bd1.db")
precio=float(input("Ingrese un precio:"))
cursor=conexion.execute("select descripcion from
articulos where precio<?", (precio, ))
filas=cursor.fetchall()
if len(filas)>0:
for fila in filas:
print(fila)
else:
print("No existen artículos con un precio men
or al ingresado.")
conexion.close()
En este caso el resultado del comando 'select' pueden ser muchas filas:
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.")
Retornar
Problema:
Ver video
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:
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.ventan
a1)
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="Ca
rga de artículos")
self.labelframe1=ttk.LabelFrame(self.pagi
na1, text="Artículo")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, t
ext="Descripción:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.descripcioncarga=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe1, textvariable=self.descripcioncarga)
self.entrydescripcion.grid(column=1, row=
0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, t
ext="Precio:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.preciocarga=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e1, textvariable=self.preciocarga)
self.entryprecio.grid(column=1, row=1, pa
dx=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 fue
ron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
def consulta_por_codigo(self):
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Co
nsulta por código")
self.labelframe2=ttk.LabelFrame(self.pagi
na2, text="Artículo")
self.labelframe2.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe2, t
ext="Código:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.codigo=tk.StringVar()
self.entrycodigo=ttk.Entry(self.labelfram
e2, textvariable=self.codigo)
self.entrycodigo.grid(column=1, row=0, pa
dx=4, pady=4)
self.label2=ttk.Label(self.labelframe2, t
ext="Descripción:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.descripcion=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe2, textvariable=self.descripcion, state="re
adonly")
self.entrydescripcion.grid(column=1, row=
1, padx=4, pady=4)
self.label3=ttk.Label(self.labelframe2, t
ext="Precio:")
self.label3.grid(column=0, row=2, padx=4,
pady=4)
self.precio=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e2, textvariable=self.precio, state="readonly")
self.entryprecio.grid(column=1, row=2, pa
dx=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="Li
stado completo")
self.labelframe3=ttk.LabelFrame(self.pagi
na3, text="Artículo")
self.labelframe3.grid(column=0, row=0, pa
dx=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.l
abelframe3, width=30, height=10)
self.scrolledtext1.grid(column=0,row=1, p
adx=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]+"\np
recio:"+str(fila[2])+"\n\n")
aplicacion1=FormularioArticulos()
El módulo 'articulos.py' contiene toda la lógica de acceso a SQLite.
módulo: articulos.py
import sqlite3
class Articulos:
def abrir(self):
conexion=sqlite3.connect("c:/programaspyt
hon/bd1.db")
return conexion
def alta(self, datos):
cone=self.abrir()
cursor=cone.cursor()
sql="insert into articulos(descripcion, p
recio) values (?,?)"
cursor.execute(sql, datos)
cone.commit()
cone.close()
def recuperar_todos(self):
try:
cone=self.abrir()
cursor=cone.cursor()
sql="select codigo, descripcion, prec
io from articulos"
cursor.execute(sql)
return cursor.fetchall()
finally:
cone.close()
Tener en cuenta que el módulo principal se encuentra en el archivo
'formularioarticulos.py' y es el que debemos ejecutar:
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()
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("")
def abrir(self):
conexion=sqlite3.connect("c:/programaspython/bd1.db")
return conexion
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()
Problema propuesto
• Agregar dos pestañas al programa de administración de artículos que
permitan borrar un artículo ingresando su código y otra opción que
permita consultar y modificar la descripción y precio de un artículo.
La interfaces visuales a implementar son:
Ver video
Solución
Retornar
89 - Python: f-strings para formateo
de cadenas de caracteres
Ver video
En las últimas versiones se ha agregado al lenguaje Python la posibilidad de
definir string y dentro hacer la sustitución de variables.
Veamos con un ejemplo cual es la sintaxis para implementar los f-strings en
Python.
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
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á:
Problema:
Definir una lista con 5 valores enteros. Mostrar los 5 valores formateados a
derecha junto a su suma.
Programa: ejercicio309.py
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}")
Problema:
Definir una lista con 5 valores flotantes con distintas cantidades de decimales.
Mostrar los números solo con dos decimales.
Programa: ejercicio310.py
• valor1=10
• valor1=10
• valor1=1000
• valor2=340
• suma=valor1+valor2
• cadena=f"""
• {valor1:5}
• {valor2:5}
• -----
• {suma:5}
• """
• print(cadena)
1000
340
-----
1340
• suma=valor1+valor2
Retornar
Problema 1:
Implementación de una función recursiva.
Programa: ejercicio311.py
def repetir():
repetir()
repetir()
La función repetir es recursiva porque dentro de la función se llama a sí misma.
Cuando ejecuta este programa se bloqueará y generará una excepción:
"RecursionError: maximum recursion depth exceeded"
Analicemos como funciona:
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.
La primera línea de la función llama a la función repetir, es decir que se
reservan más bytes nuevamente. Se ejecuta nuevamente una instancia de la
función repetir y así sucesivamente hasta que la pila estática se colme y se
cuelgue el programa.
Problema 2:
Implementación de una función recursiva que reciba un parámetro de tipo
entero y luego llame en forma recursiva con el valor del parámetro menos 1.
Programa: ejercicio312.py
def imprimir(x):
print(x)
imprimir(x-1)
imprimir(5)
Desde el bloque principal del programa se llama a la función imprimir y se le
envía el valor 5. El parámetro x recibe el valor 5. Se ejecuta el algoritmo de la
función, imprime el contenido del parámetro (5) y seguidamente se llama a una
función, en este caso a sí misma (por eso decimos que es una función
recursiva), enviándole el valor 4.
El parámetro x recibe el valor 4 y se imprime en pantalla el cuatro, llamando
nuevamente a la función imprimir enviándole el valor 3.
Si continuamos este algoritmo podremos observar que en pantalla se imprime:
5 4 3 2 1 0 -1 -2 -3 . . . . . . . . .
Problema 3:
Implementar una función recursiva que imprima en forma descendente de 5 a 1
de uno en uno.
Programa: ejercicio313.py
def imprimir(x):
if x>0:
print(x)
imprimir(x-1)
imprimir(5)
Ahora si podemos ejecutar este programa y observar los resultados en
pantalla. Se imprimen los números 5 4 3 2 1 y no se bloquea el programa.
Analice lo que sucede cuando el if x>0: se evalúa como falso, ¿a qué línea del
programa retorna?
Problema 4:
Imprimir los números de 1 a 5 en pantalla utilizando recursividad.
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.
¿Por qué se imprime en pantalla 1 2 3 4 5 ?
Veamos como se apilan las llamadas recursivas:
En la primera llamada desde el bloque principal del programa el parámetro x
recibe el valor 5.
def imprimir(x):
if x>0:
imprimir(x-1)
print(x)
imprimir(x-1)
print(x)
print(x)
Problema 5:
Otro problema típico que se presenta para analizar la recursividad es el
obtener el factorial de un número.
Recordar que el factorial de un número es el resultado que se obtiene de
multiplicar dicho número por el anterior y así sucesivamente hasta llegar a uno.
Ej. el factorial de 4 es 4 * 3 * 2 * 1 es decir 24.
Programa: ejercicio315.py
Ver video
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)
Problema 6:
Implementar un método recursivo para ordenar los elementos de una lista.
Programa: ejercicio316.py
Ver video
def ordenar(lista, cant):
if cant>1:
for f in range(0, cant-1):
if lista[f]>lista[f + 1]:
aux=lista[f]
lista[f]=lista[f + 1]
lista[f + 1] = aux
ordenar(lista, cant - 1)
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)
Retornar
Problema 1:
Recorrer un árbol de directorios en forma recursiva. Mostrar de cada directorios
los archivos y directorios, luego descender a cada directorio y hacer la misma
actividad.
Programa: ejercicio317.py
Ver video
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:
La función leer es recursiva ya que dentro de la misma se llama a leer.
Importamos el módulo 'os':
import os
def leer(directorio):
lista = os.listdir(directorio)
if os.path.isdir(directorio+elemento):
print(elemento+" [directorio]")
leer(directorio+elemento+"/")
leer("c:/programaspython/")
Problema 2:
Desarrollar un programa que permita recorrer un laberinto e indique si tiene
salida o no empleando la librería tkinter.
Para resolver este problema al laberinto lo representaremos con una lista de 10
elementos de tipo lista que en casa una hay 10 Label.
El valor:
0 Representa pasillo
1 Representa pared
9 Persona
5 Salida
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, tex
t="Recorrer", command=self.analizar)
self.boton1.grid(column=0, row=10, column
span=5, padx=10, pady=10)
self.boton2=ttk.Button(self.ventana1, tex
t="Generar otro", command=self.generar_otro)
self.boton2.grid(column=5, row=10, column
span=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, te
xt=self.retornar_aleatorio(), foreground="red")
label.grid(column=columna, row=fi
la, 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].confi
gure(text=self.retornar_aleatorio(),background="#
f0f0f0")
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()
Cuando ejecutamos el programa se genera un laberinto en forma aleatoria:
Cuando presionamos el botón "Recorrer" comenzamos a avanzar desde la fila
0 y columna 0:
En el método generar_laberinto mediante dos for anidados procedemos a crear
cada uno de los objetos de tipo Label y almacenarlos en una lista:
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(), f
oreground="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)
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.
Si se selecciona una casilla que no tiene bombas a su alrededor se libera esta
y todas las que se encuentran próximas a ella.
Permitir volver a jugar mediante un menú de opciones.
Cuando se inicia el juego debe aparecer el tablero con las 100 casillas:
Luego de destapar algunas casillas:
Programa: ejercicio319.py
Ver video
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="#BEF7
81")
self.generar_tablero()
self.generar_bombas()
self.generar_bombas_proximas()
menubar1 = tk.Menu(self.ventana1)
self.ventana1.config(menu=menubar1)
opciones1 = tk.Menu(menubar1)
opciones1.add_command(label="Reiniciar",
command=self.reiniciar)
opciones1.add_command(label="Salir", comm
and=self.ventana1.destroy)
menubar1.add_cascade(label="Opciones", me
nu=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, t
ext="", command=lambda fi=fila, co=columna: self.
presion(fi,co))
boton.place(x=columna*50,y=fila*5
0,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].conf
igure(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)
def eliminar_botones(self):
for fila in range(0,10):
for columna in range(0,10):
if self.tablero[fila][columna]!=N
one:
self.tablero[fila][columna].d
estroy()
self.tablero[fila][columna]=N
one
def destapar(self):
for fila in range(0,10):
for columna in range(0,10):
if self.tablero[fila][columna]!=N
one:
if self.bombas[fila][columna]
!="0":
self.tablero[fila][column
a].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.
Retornar
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.
La función retorna un entero.
Programa: ejercicio320.py
Ver video
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))
Tenemos definidas 5 funciones en este problema. La única función de orden
superior es la llamada "operar":
def operar(v1,v2,fn):
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)
print(resu1)
resu2=operar(10,3,restar)
print(resu2)
De forma similar llamamos a operar y le pasamos las referencias a las otras
funciones:
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.
Las funciones de orden superior se pueden utilizar perfectamente en los
métodos de una clase.
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
Ver video
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")
Declaramos la clase Persona con dos propiedades llamadas nombre y edad:
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")
Retornar
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.
Desde el bloque principal llamar a operar y enviar distintas expresiones
lambdas que permitan sumar, restar, multiplicar y dividir .
Programa: ejercicio322.py
Ver video
def operar(v1,v2,fn):
return fn(v1,v2)
def operar(v1,v2,fn):
return fn(v1,v2)
x1+x2
Programa: ejercicio323.py
Ver video
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á.
En el bloque principal definir un String con una cadena cualquiera.
Llamar a la función de orden superior y pasar expresiones lambdas para filtrar
y generar otro String con las siguientes restricciones:
def filtrar(cadena,fn):
cad=""
for caracter in cadena:
if fn(caracter):
cad=cad+caracter
return cad
def filtrar(cadena,fn):
cad=""
for caracter in cadena:
if fn(caracter):
cad=cad+caracter
return cad
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.
Retornar
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)
Mediante la construcción de comprensión de listas tenemos:
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=[]
for elemento in lista1:
lista2.append(elemento*elemento)
personas=[('pedro',33),('ana',3),('juan',13),('carla',45)]
personas=[('pedro',33),('ana',3),('juan',13),('ca
rla',45)]
personas_mayores=[per for per in personas if per[
1]>=18]
print(personas_mayores)
Mediante el for recuperamos cada persona en la nueva lista si su edad es
mayor o igual a 18:
Problema 3
Generar una lista con todos los valores múltiplos de 8 comprendidos entre 1 y
500.
Programa: ejercicio328.py
Varios for
Podemos utilizar más de un for cuando empleamos la característica de 'List
Comprehensions' de Python.
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
Ver video
nombres=['juan','pablo','luis','mauro','hector']
nombres_compuestos=[[nombre1,nombre2] for nombre1
in nombres for nombre2 in nombres if nombre1!=nom
bre2]
print(nombres_compuestos)
Podemos comprobar que conciso ha quedado el algoritmo para generar pares
de nombres:
Si analizamos:
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.
Vamos a resolver un problema clásico que a muchos programadores le han
hecho en su primer entrevista para un puesto de programador.
Problema 5
Codificar un programa que muestre en pantalla los números del 1 al 100,
sustituyendo los múltiplos de 3 por el palabra "Fizz" y, a su vez, los múltiplos de
5 por "Buzz". Para los números que, al tiempo, son múltiplos de 3 y 5, mostrar
el mensaje "FizzBuzz".
Programa: ejercicio330.py
Ver video
• Listas
• Tuplas
• Diccionarios
lenguajes.add("Ruby")
lenguajes.add("PHP")
• Unión
• Intersección
• Diferencia
• Diferencia simétrica
Gráficamente estas operaciones con dos conjuntos las podemos graficar:
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
Ver video
| (unión)
& (Intersección)
- (Diferencia)
^ (Diferencia simétrica)
Conjuntos disjuntos.
Dos conjuntos son disjuntos si no tienen elementos en común entre ellos. Su
intersección es el conjunto vacío.
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
Acotaciones.
• Para conocer la cantidad de elementos de un conjunto disponemos de la
función 'len':
• print(len(lenguajes)) # imprime un 4
• lenguajes=set()
• lenguajes.add("C")
• lenguajes.add("Pascal")
• lenguajes.add("PHP")
• lenguajes.add("Python")
• print(len(lenguajes)) # imprime un 4
productos={}
productos["manzanas"]=39
productos["peras"]=32
productos["lechuga"]=17
print(productos)
• print(edades)
• conjunto=set(edades)
• print(dia)
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
Ver video
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"])
Retornar
Para crear una base de datos presionamos el botón derecho del mouse donde
dice "Databases" y seleccionamos la opción "Create"->"Database...":
Aparece un diálogo donde debemos ingresar el nombre de la base de datos a
crear, la llamaremos "bd1":
Luego de ejecutar el programa pip podemos ver que nos informa que la
instalación del paquete se efectuó correctamente:
import psycopg2
import psycopg2
cursor1=conexion1.cursor()
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()
import psycopg2
cursor1=conexion1.cursor()
cursor1.execute("select codigo, descripcion, precio from articulos")
for fila in cursor1:
print(fila)
import psycopg2
conexion1.commit()
Retornar
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.
Seguiremos trabajando con la tabla 'articulos' que creamos en el concepto
anterior.
Las interfaz visual para la carga debe ser:
Las interfaz visual para la consulta:
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.ventan
a1)
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="Ca
rga de artículos")
self.labelframe1=ttk.LabelFrame(self.pagi
na1, text="Artículo")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, t
ext="Descripción:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.descripcioncarga=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe1, textvariable=self.descripcioncarga)
self.entrydescripcion.grid(column=1, row=
0, padx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, t
ext="Precio:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.preciocarga=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e1, textvariable=self.preciocarga)
self.entryprecio.grid(column=1, row=1, pa
dx=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 fue
ron cargados")
self.descripcioncarga.set("")
self.preciocarga.set("")
def consulta_por_codigo(self):
self.pagina2 = ttk.Frame(self.cuaderno1)
self.cuaderno1.add(self.pagina2, text="Co
nsulta por código")
self.labelframe1=ttk.LabelFrame(self.pagi
na2, text="Artículo")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.label1=ttk.Label(self.labelframe1, t
ext="Código:")
self.label1.grid(column=0, row=0, padx=4,
pady=4)
self.codigo=tk.StringVar()
self.entrycodigo=ttk.Entry(self.labelfram
e1, textvariable=self.codigo)
self.entrycodigo.grid(column=1, row=0, pa
dx=4, pady=4)
self.label2=ttk.Label(self.labelframe1, t
ext="Descripción:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.descripcion=tk.StringVar()
self.entrydescripcion=ttk.Entry(self.labe
lframe1, textvariable=self.descripcion, state="re
adonly")
self.entrydescripcion.grid(column=1, row=
1, padx=4, pady=4)
self.label3=ttk.Label(self.labelframe1, t
ext="Precio:")
self.label3.grid(column=0, row=2, padx=4,
pady=4)
self.precio=tk.StringVar()
self.entryprecio=ttk.Entry(self.labelfram
e1, textvariable=self.precio, state="readonly")
self.entryprecio.grid(column=1, row=2, pa
dx=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="Li
stado completo")
self.labelframe1=ttk.LabelFrame(self.pagi
na3, text="Artículo")
self.labelframe1.grid(column=0, row=0, pa
dx=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.l
abelframe1, width=30, height=10)
self.scrolledtext1.grid(column=0,row=1, p
adx=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]+"\np
recio:"+str(fila[2])+"\n\n")
aplicacion1=FormularioArticulos()
El módulo 'articulos.py' contiene toda la lógica de acceso a datos.
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 f
rom articulos"
cursor.execute(sql)
return cursor.fetchall()
Tener en cuenta que el módulo principal se encuentra en el archivo
'formularioarticulos.py' y es el que debemos ejecutar:
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()
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("")
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()
Problema propuesto
• Agregar dos pestañas al programa de administración de artículos que
permitan borrar un artículo ingresando su código y otra opción que
permita consultar y modificar la descripción y precio de un artículo.
La interfaces visuales a implementar son:
Ver video
Solución
Retornar
Problema:
Ver video
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.
Crear un paquete llamado 'formularios' que contenga en su interior dos
módulos llamados 'login.py' y 'mensaje.py'.
La aplicación principal llamarla 'principal.py'
Debemos crear una carpeta llamada 'formularios' y en su interior tres archivos:
'login.py', 'mensaje.py' y '__init__.py'.
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.vent
ana1, text="Login:")
self.labelframe1.grid(column=0, row=0, pa
dx=5, pady=10)
self.login()
def login(self):
self.label1=ttk.Label(self.labelframe1, t
ext="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, t
ext="Ingrese clave:")
self.label2.grid(column=0, row=1, padx=4,
pady=4)
self.entry2=ttk.Entry(self.labelframe1, s
how="*")
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
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, tex
t="Mostrar Mensaje", command=self.mostrar_mensaje
)
self.boton1.grid(column=0, row=0)
self.boton2=ttk.Button(self.ventana1, tex
t="Mostrar formulario de login", command=self.mos
trar_login)
self.boton2.grid(column=0, row=1)
self.ventana1.mainloop()
def mostrar_mensaje(self):
formularios.mensaje.mostrar("Es una prueb
a de acceder a módulos de un paquete")
def mostrar_login(self):
formularios.login.mostrar()
aplicacion1=Aplicacion()
Si ejecutamos la aplicación desde el script 'principal.py' tenemos como
resultado en pantalla al presionar el botón "Mostrar formulario de login":
formularios.login.mostrar()
Acotaciones.
1. Recordemos que podemos crear un alias cuando importamos un módulo
con el fin de escribir menos cada vez que lo accedemos:
2. import tkinter as tk
3. from tkinter import ttk
4.
5. import formularios.login as formlogin
6. import formularios.mensaje as formmensaje
7.
8. class Aplicacion:
9. def __init__(self):
10. self.ventana1=tk.Tk()
11. self.ventana1.title("Hola Mundo")
12. self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje", com
mand=self.mostrar_mensaje)
13. self.boton1.grid(column=0, row=0)
14. self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de
login", command=self.mostrar_login)
15. self.boton2.grid(column=0, row=1)
16. self.ventana1.mainloop()
17.
18. def mostrar_mensaje(self):
19. formmensaje.mostrar("Es una prueba de acceder a módulos de un paq
uete")
20.
21. def mostrar_login(self):
22. formlogin.mostrar()
23.
24. aplicacion1=Aplicacion()
formlogin.mostrar()
25. También podemos hacer uso de la sintaxis del 'from' para importar
módulos de un determinado paquete:
import formularios.modales.login
import formularios.modales.mensaje
import formularios.nomodales.ayuda
Retornar
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/pagina
1.html")
datos=pagina.read()
print(datos)
pagina=request.urlopen("http://www.scratchya.com.
ar/pythonya/ejercicio336/pagina1.html")
datos=pagina.read()
datosutf8=datos.decode("utf-8")
print(datosutf8)
Si ejecutamos ahora nuevamente la aplicación podemos ver el contenido
convertido a texto con formato 'utf-8' (formato de codificación de caracteres
más común empleado en Internet para representar múltiples idiomas):
Lectura de una página HTML u otro recurso y posterior
grabación del archivo en forma local.
Recuperar la página html 'pagina1.html' y el archivo 'imagen1.jpg' que se
encuentran localizados en:
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
imagen=request.urlopen("http://www.scratchya.com.
ar/pythonya/ejercicio336/imagen1.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':
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pagina
1.html")
datos=pagina.read()
archivo1=open("pagina1.html","wb")
archivo1.write(datos)
archivo1.close()
http://www.scratchya.com.ar/pythonya/ejercicio336/paginax.html
try:
pagina=request.urlopen("http://www.scratchya.
com.ar/pythonya/ejercicio336/paginax.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':
try:
pagina=request.urlopen("http://www.scratchya.com.ar/pythonya/ejercicio336/pa
ginax.html")
datos=pagina.read().decode("utf-8")
print(datos)
Ver video
Solución
Retornar
import json
cadena="""
{
"codigo":"1",
"descripcion":"papas",
"precio":"13.45"
}
"""
print(cadena) # imprimimos un string
diccionario=json.loads(cadena)
print(diccionario) # imprimimos un diccionario
De forma similar si disponemos de un vector, luego la transformación será a
una lista con elementos de tipo diccionario:
import json
cadena="""
[
{
"codigo":"1",
"descripcion":"papas",
"precio":"13.45"
},
{
"codigo":"2",
"descripcion":"manzanas",
"precio":"45"
}
]
"""
print(cadena) # imprimimos un string
lista=json.loads(cadena)
print(lista) # imprimimos una lista
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:
<?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');
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['desc
ripcion']:50} {elemento['precio']:>12}")
El resultado de ejecutar la aplicación (recuerde tener activo el servidor web con
PHP y MySQL):
Importamos los módulos request y json:
pagina=request.urlopen("http://localhost/pythonya/retornararticulos.php")
datos=pagina.read().decode("utf-8")
Problema 2
Ingresar por teclado el código de un artículo, seguidamente recuperar los datos
de dicho artículo del servidor local. Pasar el código del artículo como parámetro
'GET' en la llamada.
La aplicación en PHP que recupera los datos de un determinado artículo que
llega como parámetro es:
Programa: retornararunarticulo.php
Ver video
<?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');
Una vez que recuperamos los datos del servidor procedemos a convertir el
string devuelto:
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")
Problemas propuestos
• 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:
Ver video
• El sitio web
• https://jsonplaceholder.typicode.com/
https://jsonplaceholder.typicode.com/posts
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi opti
o 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 dolo
r 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".
Ver video
• Hacer la misma actividad que el problema anterior con el recurso que
devuelve la dirección:
• https://jsonplaceholder.typicode.com/users
[
{
"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"
}
}
]
Retornar
Definiciones básicas.
• Serialización: Consiste en convertir un objeto de Python (normalmente
una lista o diccionario) en un string.
Como vemos son los dos caminos posibles para transformar una estructura de
datos en otra estructura.
Problema 1
Definir un string en Python con la estructura interna de un archivo JSON.
Deserializar el string y convertirlo a una lista de Python. Luego volver a
serializar la lista a un string.
Programa: ejercicio345.py
Ver video
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)
El resultado de ejecutar el siguente script en Python es:
Definimos e inicializamos una variable string:
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)
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)
Python JSON
dic object
str string
True true
False false
None null
Retornar