Fundamentos de Python con Orientación a Objetos y Basado en Problemas Por Carlos Arturo Castro Castro 1. El Problema PROBLEMA EQUIPOS DE FUTBOL Problema diseñado por Carlos Arturo Castro Castro Temas: Arreglos Unidimensionales (vectores), Arreglos Bidimensionales (matrices). Se tiene un arreglo unidimensional (vector) con los nombres de N equipos de futbol. Un jemplo podría ser (ejemplo 6 equipos-> N=6): #1 #2 #3 #4 #5 #6 REAL LANÚS COLONIA LITEX BETIS NEC Se tiene una tabla (matriz) con los puntajes resultado del enfrentamiento entre N equipos de futbol. Cada celda (posición fila,columna) tiene un valor de 0 (cero), 3 (tres) ó 1 (uno). La primera columna tiene los puntajes resultado del enfrentamiento entre el equipo #1 con los demás equipos. La segunda columna tiene los puntajes resultado del enfrentamiento entre el equipo #2 con los demás equipos y así para las demás columnas. Los datos que están sobre la diagonal principal son todos cero (0) debido a que un equipo no se enfrenta con el mismo. Es decir en la celda en posición (2,1) (fila 2, columna 1) se encuentra el puntaje resultado del enfrentamiento entre el equipo #1 y el equipo #2. En la celda en posición (3,1) (fila 3, columna 1) se encuentra el puntaje resultado del enfrentamiento entre el equipo #1 y el equipo #3. En la celda en posición (i,j) (fila i, columna j) se encuentra el puntaje resultado del enfrentamiento entre el equipo #j y el equipo #i.Ver la tabla ejemplo a continuación (N=6 equipos): #1 #2 #3 #4 #5 #6 REAL LANÚS COLONIA LITEX BETIS NEC REAL 0 0 1 1 1 3 LANÚS 3 0 3 0 3 3 COLONIA 1 0 0 3 3 3 LITEX 1 3 0 0 0 0 BETIS 1 0 0 3 0 0 NEC 0 0 0 3 3 0 Se requiere un vector con los puntajes totales. Es decir un vector en el cual la primera posición
49
Embed
Fundamentos de Python con Orientación a Objetos y Basado en Problemas
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Fundamentos de Python con Orientación a Objetos y Basado en Problemas
Se tiene un arreglo unidimensional (vector) con los nombres de N equipos de futbol. Un jemplo podría ser (ejemplo 6 equipos-> N=6):
#1 #2 #3 #4 #5 #6
REAL LANÚS COLONIA LITEX BETIS NEC
Se tiene una tabla (matriz) con los puntajes resultado del enfrentamiento entre N equipos de futbol. Cada celda (posición fila,columna) tiene un valor de 0 (cero), 3 (tres) ó 1 (uno).
La primera columna tiene los puntajes resultado del enfrentamiento entre el equipo #1 con los
demás equipos. La segunda columna tiene los puntajes resultado del enfrentamiento entre el
equipo #2 con los demás equipos y así para las demás columnas. Los datos que están sobre la
diagonal principal son todos cero (0) debido a que un equipo no se enfrenta con el mismo. Es
decir en la celda en posición (2,1) (fila 2, columna 1) se encuentra el puntaje resultado del
enfrentamiento entre el equipo #1 y el equipo #2. En la celda en posición (3,1) (fila 3, columna
1) se encuentra el puntaje resultado del enfrentamiento entre el equipo #1 y el equipo #3. En la
celda en posición (i,j) (fila i, columna j) se encuentra el puntaje resultado del enfrentamiento
entre el equipo #j y el equipo #i.Ver la tabla ejemplo a continuación (N=6 equipos):
Se definió trabajar con dos paquetes de clases. El paquete Vista con los métodos que
implementan la interacción del programa con el usuario. Y el paquete Control, con los
métodos que poseen cálculos reutilizables e independientes de la forma como se
ingresan los datos y/o se muestran los resultados.
4.1 Crear una carpeta llamada proyectoEquipos
4.2 Paquete Control:
Se crea un archivo en blanco llamado __init__.py y se guarda en una carpeta llamada
control
Se crea un módulo con la clase Matriz y métodos reutilizables
# -*- coding: utf-8 -*- #La anterior Línea permite usar caracteres utf8 (tildes, eñes entre otros) #------------------------------------------------------------------------------- # Name: Matriz # Author: Carlos Arturo # Created: 29/11/2014 # Copyright: (c) Carlos Arturo 2014 # Licence: <your licence> #------------------------------------------------------------------------------- class Matriz: #atributos o propiedades mat=[] #se declara una arreglo numFilas=0 #se declara un entero numColumnas=0 #Métodos #Método para llenar matriz (Es decir asignar los datos en la matriz que se pasa como parámetro) def llenarMatriz(self,mat): self.mat=mat def obtenerNumFilas(self): self.numFilas=len(self.mat) return self.numFilas def obtenerNumColumnas(self):
self.numColumnas=len(self.mat[0]) return self.numColumnas #método para retornar un vector en el que se obtiene la suma de cada columna def obtenerSumaColumnas(self): sum=0 vec = [] nc=self.obtenerNumColumnas() #ciclo para. Inicializa el vector con nc ceros for i in range(nc): vec.append(0) #ciclos para anidados. Suma cada columna de la matriz y la lleva a un vector for j in range(self.obtenerNumColumnas()): sum=0 for i in range(self.obtenerNumFilas()): sum=sum+self.mat[i][j] vec[j]=sum return vec
Se crea un módulo con la clase Vector y métodos reutilizables
# Name: Vector # Author: Carlos Arturo # Created: 29/11/2014 # Copyright: (c) Carlos Arturo 2014 #------------------------------------------------------------------------------- #ver https://docs.python.org/2/library/functions.html import math class Vector: #atributos vec=[] def __init__(self,vec): #método para inicilaizar atributos self.vec=vec def obtenerNumElementos(self): return len(self.vec) def obtenerMedia(self): return float(sum(self.vec))/len(self.vec) #algoritmo tradicional de la media def obtenerMedia1(self): Acum=0 for i in range(len(self.vec)): Acum=Acum+self.vec[i] media=float(Acum)/self.obtenerNumElementos() #tambien media= media=float(Acum)/len(self.vec) return media def ordenarVectorAsc(self): self.vec.sort() return self.vec def ordenarVectorDesc(self): self.vec.sort() self.vec.reverse() return self.vec def ordenarVectorBurbuja(self): n=len(self.vec) for i in range(n-1): for j in range(i+1,n): if self.vec[i] > self.vec[j]: aux=self.vec[i] self.vec[i]=self.vec[j] self.vec[j]=aux return self.vec def obtenerMediana(self): self.vec.sort() n = len(self.vec) if len(self.vec) % 2 == 0: #si n es par
mediana = (self.vec[n/2-1]+ self.vec[n/2] )/2.0 #al dividirlo por 2.0 lo convierte a float else: mediana =self.vec[n/2] return mediana def obtenerModa1(self): n=len(self.vec) moda=self.vec[1] contModa=1 resultado=[contModa,moda] for i in range(n-1): cont=1 for j in range(i+1,n): if self.vec[i]==self.vec[j]: cont=cont+1 if cont >= contModa: contModa=cont moda=self.vec[i] resultado=[contModa,moda] if resultado[0]==1: moda=None else: moda=resultado[1]#aunque tenga varias modas. solo devuelve 1 return moda def obtenerVectorModas(self): n=len(self.vec) vecModas=[] for i in range(n): cont=1 for j in range(i+1,n): if self.vec[i]==self.vec[j]: cont=cont+1 #cuenta el número de veces que vec[i] se necuentra en el vector vecModas.append(cont) self.ordenarVectoresParalelos(0,vecModas,self.vec) return vecModas def obtenerDesviacionEstandarMuestral(self): media=self.obtenerMedia() n=len(self.vec) sumatoria=0.0 for i in range(n): sumatoria=sumatoria+(media-self.vec[i])**2 desVest = math.sqrt((sumatoria)/(n-1)) return desVest
def ordenarVectoresParalelos(self,fila,*parametros): mat=list(parametros) nfil=len(mat) ncol=len(mat[0]) if fila >= nfil: fila=nfil-1 elif fila < 0: fila=0 aux=[] #aux es un vector para intercambiar columnas for i in range(nfil): aux.append(None) for i in range(ncol-1): for j in range(i+1,ncol): if mat[fila][i] < mat[fila][j]: for k in range(nfil): aux[k]=mat[k][i] for k in range(nfil): mat[k][i]=mat[k][j] for k in range(nfil): mat[k][j]=aux[k] return mat
4.3 Paquete Vista:
Se crea un archivo en blanco llamado __init__.py y se guarda en una carpeta llamada
vista
Se crea un módulo llamado pryEquiposConsola.py y se guarda en la carpeta vista
Se importan las clases del paquete control
Se ingresan los datos por consola a un Vector de nombres de equipos y a una matriz de
puntajes.
Se Obtienen la medidas estadísticas invocando a los métodos correspondientes
# -*- coding: utf-8 -*- #------------------------------------------------------------------------------- # Name: pryEquiposConsola # Purpose: # # Author: Carlos Arturo # # Created: 30/11/2014 # Copyright: (c) Carlos Arturo 2014 # Licence: <your licence> #------------------------------------------------------------------------------- def main(): pass if __name__ == '__main__': main() from control.Matriz import * from control.Vector import * #vector de nombres vecNombres=[] continuar=True i=1 while (continuar == True): try: #Control de Excepciones nombreEquipo= raw_input("Ingrese Nombre del equipo # " + str(i)) i=i+1 vecNombres.append(nombreEquipo) except KeyboardInterrupt: continuar=False #Matriz de Puntajes matPuntajes=[] n= len(vecNombres) for i in range(n): matPuntajes.append( [0] * n ) #n filas for j in range(n): i=0 while i < n: #matPuntajes[i][j] = int(raw_input('Dame el componente (%i,%i): ' % (i, j))) if i>j: #por debajo de la diagonal principal matPuntajes[i][j] = int(input(" Puntaje del equipo " + vecNombres[j] + " al enfrentarse con el equipo " + vecNombres[i] + " :")) if matPuntajes[i][j]==3:
matPuntajes[j][i]=0; else: if matPuntajes[i][j]==0: matPuntajes[j][i]=3; else: if matPuntajes[i][j]==1: matPuntajes[j][i]=1; else: print("Debe ingresar 1, 3 o 0") i=i-1 i=i+1 #contador para el mientras #print matPuntajes for i in range(n): print matPuntajes[i] #crear un objeto de la clase Matriz objMatriz = Matriz() objMatriz.llenarMatriz(matPuntajes) #obtner el Vector de puntajes totales vectPunajesTolates=[] vectPunajesTolates = objMatriz.obtenerSumaColumnas() vectPunajesTolates1 = objMatriz.obtenerSumaColumnas() print '____________' print vectPunajesTolates #Crear un objeto de la clase Vector objVector = Vector(vectPunajesTolates) #Obtener Medidas estadísticas media = objVector.obtenerMedia() mediana = objVector.obtenerMediana() moda = objVector.obtenerModa1() desviacionEstandar = objVector.obtenerDesviacionEstandarMuestral() print 'Media =' + str(media) print 'mediana =' + str(mediana) print 'moda =' + str(moda) print 'desviación Estándar =' + str(desviacionEstandar) print '____________' print vectPunajesTolates print vectPunajesTolates1 print '____________'
#Ordenar el vector de Puntajes totales vectoresParalelos= objVector.ordenarVectoresParalelos(0,vectPunajesTolates1,vecNombres) print '____________' print vectoresParalelos print '____________' print vectoresParalelos[1] #nombres de los equipos print vectoresParalelos[0] #puntajes totales de los equipos
Puede usarse la función random.randint(1,3), para generar un aleatorio entero entre 1
y 3 y simular los puntajes ingresados por un usuario
Para esto se requiere importar el módulo random.
Se creó un nuevo proyecto denominado: pryEquiposConsolaRandom.py
main() from control.Matriz import * from control.Vector import * import random #vector de nombres vecNombres=[] continuar=True i=1 while (continuar == True): try: #Control de Excepciones nombreEquipo= raw_input("Ingrese Nombre del equipo # " + str(i)) i=i+1 vecNombres.append(nombreEquipo) except KeyboardInterrupt: continuar=False #Matriz de Puntajes matPuntajes=[] n= len(vecNombres) random.seed() #inicia generador de n{umeros aleatorios for i in range(n): matPuntajes.append( [0] * n ) #n filas for j in range(n): i=0 while i < n: #matPuntajes[i][j] = int(raw_input('Dame el componente (%i,%i): ' % (i, j))) if i>j: #por debajo de la diagonal principal #matPuntajes[i][j] = int(input(" Puntaje del equipo " + vecNombres[j] + " al enfrentarse con el equipo " + vecNombres[i] + " :")) matPuntajes[i][j]= random.randint(1,3) #aleatorio entre 1 y 3 if matPuntajes[i][j]==3: matPuntajes[j][i]=0; else: if matPuntajes[i][j]==0: matPuntajes[j][i]=3; else: if matPuntajes[i][j]==1: matPuntajes[j][i]=1; else: print("Debe ingresar 1, 3 o 0") i=i-1 i=i+1 #contador para el mientras #print matPuntajes for i in range(n): print matPuntajes[i]
#crear un objeto de la clase Matriz objMatriz = Matriz() objMatriz.llenarMatriz(matPuntajes) #obtner el Vector de puntajes totales vectPunajesTolates=[] vectPunajesTolates = objMatriz.obtenerSumaColumnas() vectPunajesTolates1 = objMatriz.obtenerSumaColumnas() print '____________' print vectPunajesTolates #Crear un objeto de la clase Vector objVector = Vector(vectPunajesTolates) #Obtener Medidas estadísticas media = objVector.obtenerMedia() mediana = objVector.obtenerMediana() moda = objVector.obtenerModa1() desviacionEstandar = objVector.obtenerDesviacionEstandarMuestral() print 'Media =' + str(media) print 'mediana =' + str(mediana) print 'moda =' + str(moda) print 'desviación Estándar =' + str(desviacionEstandar) print '____________' print vectPunajesTolates print vectPunajesTolates1 print '____________' #Ordenar el vector de Puntajes totales vectoresParalelos= objVector.ordenarVectoresParalelos(0,vectPunajesTolates1,vecNombres) print '____________' print vectoresParalelos print '____________' print vectoresParalelos[1] #nombres de los equipos print vectoresParalelos[0] #puntajes totales de los equipos
5. Clase Archivo
Se escribe el código para una clase con métodos que permitan manejar las operaciones básicas
con archivos planos: Abrir, Cerrar, Escribir una línea de texto en el archivo, leer una línea de
texto del archivo
# -*- coding: utf-8 -*- #------------------------------------------------------------------------------- # Name: Archivo # Purpose: # # Author: carlos.castro # # Created: 01/12/2014 # Copyright: (c) carlos.castro 2014 # Licence: <your licence> #------------------------------------------------------------------------------- #ver http://www.tutorialspoint.com/python/python_files_io.htm def main(): pass if __name__ == '__main__': main() import os class Archivo: f="" #Se declara la variable tipo archivo rutaYNombre="" mensaje="ok" def __init__(self,rutaYNombre): self.rutaYNombre =rutaYNombre def abirArchivo(self): try: if os.path.exists(self.rutaYNombre): self.f = open(self.rutaYNombre,'r+')#abre archivo para lectura escritura else: self.f = open(self.rutaYNombre,'a+')#crea archivo para lectura escritura except IOError as objIOError: self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje def cerrarArchivo(self): self.mensaje="ok" try: self.f.close() except IOError as objIOError:
self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje def contarNumLineasArchivo(self): self.mensaje="ok" n=0 try: for LineaTexto in self.f: n=n+1 except IOError as objIOError: self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje return n def leerUnaLinea(self): self.mensaje="ok" try: lineaTexto = self.f.readline() if lineaTexto[-1] == '\n': lineaTexto=lineaTexto[:-1] #elimina el \n except IOError as objIOError: self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje return lineaTexto def escribirUnaLineaDebajo(self,lineaTexto): self.mensaje="ok" print lineaTexto try: self.f.writelines(lineaTexto+"\n") except IOError as objIOError: self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje def escribirUnaLineaAlFrente(self,lineaTexto): self.mensaje="ok" print lineaTexto try: self.f.writelines(lineaTexto) except IOError as objIOError: self.mensaje= "Problemas con el archivo: Error #" + str(objIOError.errno) + " Mensaje : "+format(objIOError.strerror) return self.mensaje
6. Diseño de la Interfaz gráfica
Para la interfaz gráfica se seleccionó PYQY
6.1 ejecutar el diseñador que está en C:\Python27\Lib\site-packages\PyQt4
Seleccionar Main Window -> Crear
Dibujar: dos Label, un Text Edit , tres TableView, un ListView , un Push Button:
Guardar el archivo en la carpeta C:\Python27\Lib\site-packages\PyQt4 con el nombre
de:
pryEquiposConsolaRandomGUIPYQT4
Cerrar el Qt Designer
Crear el archivo pryEquiposConsolaRandomGUIPYQT4.py a partir del archivo
pryEquiposConsolaRandomGUIPYQT4.ui
En el PyScripter: Herramientas->Herramientas->Command Prompt
self.label_2.setText(_translate("MainWindow", "Número de equipos de fútbol", None)) self.pushButton.setText(_translate("MainWindow", "PushButton", None)) #****************************************************************************************************** #Se agrega la siguiente línea para programar el evento click sobre el botón e invoque qoe método btnCalcularClick QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.btnCalcularClick) #****************************************************************************************************** def btnCalcularClick(self): from control.Matriz import * from control.Vector import * from control.Archivo import * import random,os rta='s' rta2='s' #vector de nombres vecNombres=[] if rta =='s': objArchivo=Archivo("nombres.txt") sw=objArchivo.abirArchivo() if sw == 'ok': lineaTexto=objArchivo.leerUnaLinea() lineaTexto=lineaTexto[:-1] vecNombres=lineaTexto.split(",") objArchivo.cerrarArchivo() else: pass #Matriz de Puntajes matPuntajes=[] n= len(vecNombres) #****************************************************************************************************** #Se asigna el Cuadro de Texto con el valor de n self.textEdit.setText(str(n)) #******************************************************************************************************
#****************************************************************************************************** #muestra el Vector de nombres en el Primer TableView model1 = QtGui.QStandardItemModel (1, n) #se define el modelo 1 filas y n columnas for fila in range(1): for columna in range(n): item1 = QtGui.QStandardItem(vecNombres[columna]) model1.setItem(fila, columna, item1) self.tableView.setModel(model1) #****************************************************************************************************** random.seed() #inicia generador de números aleatorios for i in range(n): matPuntajes.append( [0] * n ) #n filas if rta2=='s': objArchivo=Archivo("puntajes.txt") sw=objArchivo.abirArchivo() for i in range(n): if sw == 'ok': lineaTexto=objArchivo.leerUnaLinea() if lineaTexto[-1]==',': lineaTexto=lineaTexto[:-1] lista=[int(numero) for numero in lineaTexto.split(",")] #convertir la lista a enteros # del(lista[-1]) #borra el último de la lista print lista matPuntajes[i]=lista objArchivo.cerrarArchivo() #****************************************************************************************************** #muestra La Matriz de puntajes en el segundo TableView model2 = QtGui.QStandardItemModel (n, n) #se define el modelo n filas y n columnas for fila in range(n): for columna in range(n): item2 = QtGui.QStandardItem(str(matPuntajes[fila][columna])) model2.setItem(fila, columna, item2) self.tableView_2.setModel(model2) #****************************************************************************************************** else: for j in range(n): i=0 while i < n: #matPuntajes[i][j] = int(raw_input('Dame el componente (%i,%i): ' % (i, j))) if i>j: #por debajo de la diagonal principal
#matPuntajes[i][j] = int(input(" Puntaje del equipo " + vecNombres[j] + " al enfrentarse con el equipo " + vecNombres[i] + " :")) matPuntajes[i][j]= random.randint(1,3) #aleatorio entre 1 y 3 if matPuntajes[i][j]==3: matPuntajes[j][i]=0; else: if matPuntajes[i][j]==0: matPuntajes[j][i]=3; else: if matPuntajes[i][j]==1: matPuntajes[j][i]=1; else: print("Debe ingresar 1, 3 o 0") i=i-1 i=i+1 #contador para el mientras #Guarda los puntajes en un archivo open('puntajes.txt', 'w').close() #borra el contenido del archivo y lo cierra objArchivo=Archivo("puntajes.txt") sw=objArchivo.abirArchivo() for j in range(n): for i in range(n): if sw == 'ok': objArchivo.escribirUnaLineaAlFrente(str(matPuntajes[i][j])+",") objArchivo.escribirUnaLineaDebajo("") objArchivo.cerrarArchivo() #Muest for i in range(n): print matPuntajes[i] #crear un objeto de la clase Matriz objMatriz = Matriz() objMatriz.llenarMatriz(matPuntajes) #obtner el Vector de puntajes totales vectPunajesTolates=[] vectPunajesTolates = objMatriz.obtenerSumaColumnas() vectPunajesTolates1 = objMatriz.obtenerSumaColumnas() print '____________' print vectPunajesTolates #****************************************************************************************************** #muestra el Vector de puntajes totales en el tercer TableView model3 = QtGui.QStandardItemModel (1, n) #se define el modelo 1 filas y n columnas for fila in range(1): for columna in range(n): item3 = QtGui.QStandardItem(str(vectPunajesTolates1[columna])) model3.setItem(fila, columna, item3)
self.tableView_3.setModel(model3) #****************************************************************************************************** #Crear un objeto de la clase Vector objVector = Vector(vectPunajesTolates) #Obtener Medidas estadísticas media = objVector.obtenerMedia() mediana = objVector.obtenerMediana() moda = objVector.obtenerModa1() desviacionEstandar = objVector.obtenerDesviacionEstandarMuestral() print 'Media =' + str(media) print 'mediana =' + str(mediana) print 'moda =' + str(moda) print 'desviación Estándar =' + str(desviacionEstandar) print '____________' print vectPunajesTolates print vectPunajesTolates1 print '____________' #Ordenar el vector de Puntajes totales vectoresParalelos= objVector.ordenarVectoresParalelos(0,vectPunajesTolates1,vecNombres) print '____________' print vectoresParalelos print '____________' print vectoresParalelos[1] #nombres de los equipos print vectoresParalelos[0] #puntajes totales de los equipos #****************************************************************************************************** #muestra Los Vectores de nombres y de Puntajes Ordenados (Vectores paralelos) en el listView. al igual que las estadísticas model4 = QtGui.QStandardItemModel(self.listView) for i in range(n): # create an item with a caption item4 = QtGui.QStandardItem(str(vecNombres[i])+"\t"+str(vectPunajesTolates1[i])) model4.appendRow(item4) item4 = QtGui.QStandardItem("") model4.appendRow(item4) item4 = QtGui.QStandardItem("") model4.appendRow(item4)