RE: [Python-es] Mejorar este código
eber_ramirez en ltv.org.mx
eber_ramirez en ltv.org.mx
Jue Mayo 8 21:44:52 CEST 2008
> Este es el primer programa que hago en Python, así que agradeceré sugerencias para mejorar el código.
>
Pues está muy bien para ser tu primera aproximación al lenguaje.
Ya que los pides, aquí van algunos comentarios (la mayoría bastante
establecidos en la "tradición", otros puramente personales):
> # Version 0.1
> # Miercoles 7 de mayo de 2008
> # gerberito en gmail.com
>
En vez de comentarios, deberías usar las docstring del módulo:
"""
Programa XYZ: Hace esto y lo otro
...
"""
> from Tkinter import *
>
Es muy común importar los módulos de tkinter de este modo, pero el
principio general es no hacer "from xyz import *", ya que ensucia el
espacio de nombres. Podrías hacer esto:
import Tkinter as tk
tk.Button(...)
> #Creamos la clase que es la base del programa
> class Calcula_MR:
> def __init__(self):
> self.CreaObjetos()
>
> def CreaObjetos(self):
> self.programa = Tk( ) # 'Ventana principal' de Tkinter's
>
Las funciones vacías no deberían llevar espacio en los paréntesis: Tk()
> self.programa.title ('Momento Resistente - Sin acero a compresion')
No dejes un espacio entre la función y el paréntesis
self.programa.title(...)
> #MarcoPrincipal=Frame(self.programa)
>
> #Primero creamos el cuadro de dialogo para introducir datos.
> # FR = Factor de reduccion, por default 0.9
> # b = ancho de la seccion en cm
> # d = peralte efectivo de la seccion en cm
> # f'c = resistencia del concreto a la compresion a los 28 dias en kg/cm2
> # fy = Limite de fluencia del acero en kg/cm2
> # As = Area de acero en tension en cm2
>
Como antes: estos comentarios van en los docstrings del método/función.
De esta forma tu aplicación quedará perfectamente documentada.
> # Ahora creamos las zonas donde el usuario introduce datos
>
> # Primero ponemos las etiquetas de los datos que ocuparemos
> fila = 1
> for label in 'FR ', 'b ', 'd ', 'fc ', 'fy ', 'As ':
> Etiqueta=Label(self.programa, text=label+'=', borderwidth=6)
> Etiqueta.grid(row=fila,column=0)
> #Label(self.programa,text=label+'=', borderwidth=6).grid(row=fila, column=0)
> fila = fila + 1
>
Ese uso de "fila" es sospechoso. Usa enumerate:
for fila, label in ("label1", "label2"):
# fila empieza a contar por 0
Ver de paso Idiomatic Python:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
> #Ahora las unidades en las que se trabaja
> fila = 1
> for label in ' ', 'cm ', 'cm ', 'kg/cm2 ', 'kg/cm2 ', 'cm2 ':
> Etiqueta=Label(self.programa, text=label, borderwidth=6)
> Etiqueta.grid(row=fila,column=2)
> #Label(self.programa,text=label, borderwidth=6).grid(row=fila, column=2)
> fila = fila + 1
>
Está claro que los nombres y las unidades van unidas, ¿por qué hacer dos
bucles? puedes hacer
for index, (label, unit) in enumerate([("label1", "unit1"), (....)]):
o si quieres manter dos arrays separados, usa zip:
for index, (label, unit) in enumerate(zip(labels, units)):
> self.FR_t=StringVar()
> Entry(self.programa, width=10, textvariable=self.FR_t).grid(row=1, column=1)
> self.FR_t.set('0.9')
>
> self.b_t=StringVar()
> Entry(self.programa, width=10, textvariable=self.b_t).grid(row=2, column=1)
> self.b_t.set('20')
>
> self.d_t=StringVar()
> Entry(self.programa, width=10, textvariable=self.d_t).grid(row=3, column=1)
> self.d_t.set('40')
>
Aquí hay un patrón muy claro, deberías crear una lista e iterar en un bucle.
Quizá tengas algún problema al asignar la variable a self, ya que
tendrás el nombre de la variable en una cadena: dale un vistazo a
setattr. Otro tema sería que, en vez de meter esas variables
directamente en la instancia, crearas otra, para separar un poco las cosas:
class Container:
pass
variables = Container()
variables.d_t = 3
ó si tenemos el nombre de variable en una cadena... s = "d_t", hacemos:
setattr(variables, s, 3)
En este caso puedes acceder a las variables (como cadena) y su valor
pidiendo con "vars" el diccionario de la clase:
vars(variables)
También podrías meterla directamente en un diccionario, pero es
discutible si es estético:
variables["d_t"]
> def Calculos(self):
> #Extraemos los datos de los "entry's"
> FR=float(self.FR_t.get())
> b=float(self.b_t.get())
> d=float(self.d_t.get())
> fc=float(self.fc_t.get())
> fy=float(self.fy_t.get())
> As=float(self.As_t.get())
>
Mucha repetición: puedes abstraerlo en un bucle.
---
Esto en cuanto a lo que atañe al uso del lenguaje. Como concepto general
te recomendaría modularizar: separa la lógica de la presentación
(frontend). Si alguien quiere usar tu script (la parte de cálculo) desde
el suyo propio , o cambiar a gtk, por ejemplo, tendrá que retocarlo
bastante, ya que la interacción con Tk está por todas partes.
A este respecto, y uses el sistema operativo que uses, no dejes de darle
un vistazo a este repaso de la filosofía UNIX:
http://www.faqs.org/docs/artu/ch01s06.html
=========================================================
Wow!
Arnau, muchas gracias.
Voy a leer los documentos señalados e implementar los ajustes sugeridos.
Esto era justo lo que necesitaba para ir por el camino correcto con Python.
En cuanto tenga todo "listo" vuelvo a poner en la lista el código.
Nuevamente, muchas gracias.
Eber Ramírez
Este correo electrónico y cualquier archivo transmitido con él son confidenciales y son solamente para el uso del individuo o entidad a la que van dirigidos. Si recibió este correo electrónico por error por favor notifique al administrador del sistema. Este mensaje contiene información confidencial y es dirigido a la persona implicada. Si usted no es esa persona no debería diseminar, distribuir o copiar este mensaje de correo electrónico.
This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail.
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es