El 14/10/12 09:40, kausdiv escribió:

> Efectivamente he realizado el programa para aprender Python y de paso
> dotarme de una utilidad para memorizar vocabulario ingles.
> 
> Dejo el código que he creado para que hagais las mejoras que veais
> oportunas y así pueda aprender más:

OK. Pues te voy a dar algunos consejos:

Lo primero es que sigas el modo "pythónico" de hacer las cosas. Intenta
usar compresiones de listas e iteradores donde sea más oportuno, como
es, por ejemplo, cuando leas un fichero secuencialmente.

Expresiones como:

  f=open(self.nfich,"r")
  for l in f:
    self.dic.append(l[:-1])
  f.close()

se pueden expresar mejor si consideramos que el objeto 'file' es un
iterador:

  for l in open(self.nfich,"r"):
    self.dic.append(l[:-1])

En el caso de fichero de salida (método guardar), se puede gestionar
mejor si usas "contextos":

  with open(self.nfich,"w") as f:
    for l in self.dic:
      f.write(l)
      f.write("\n")

El contexto se encarga de cerrar automáticamente el fichero.

Así mismo, existe un modo más directo de escribir en un fichero de texto
usando la sentencia 'print', con la cual se añade automáticamente el
retorno de línea '\n':

  with open(self.nfich,"w") as f:
    for l in self.dic:
      print >>f, l

Existe un modo de hacerlo todavía más compacto:

  open(self.nfich,"w").writelines(self.dic)

...pero no funciona bien ya que no añade los saltos de línea. Se puede
apañar con compresiones de lista; pero mejor lo dejo para más adelante.


En cuanto al estilo, se nota bastante que vienes de la programación
imperativa. Tu clase es un saco de funciones que realizan acciones,
evidente en que son "verbos" de una oración linguística. Deberías
intentar expresar la clase como "mensajes" que el objeto debe responder.
Desacoplando mejor los objetos de tu aplicación podrás reutilizarlos
mejor en otras aplicaciones. Al fin de cuentas, la reusabilidad es uno
de los grandes fines de la programación orientada a objeto.

Por ejemplo: separa el código en dos clases, la clase Diccionario,
encargada de manejar la lista de palabras, y la clase Menu, encargada
del menú de opciones.

El diccionario podría ser así:

class Diccionario():
    def __init__(self):
        self.eng=[]
        self.spa=[]

    def agregar(self, eng, spa):

        self.eng.append(eng)
        self.span.append(spa)

        return len(self.dic)  #idx

    def obtener(self, idx):

        if 0<=idx<len(self.eng):
            return (sel.eng(idx),sel.spa(idx))
        else:
            return None

    def aleatorio(self):

        idx=random.randrange(len(self.eng))
        return (self.eng[idx],self.spa[idx])

    def eng2spa(self, eng):

        if eng in self.eng:
            idx=self.eng.index(eng)
            return self.spa[idx]
        else:
            return ""

    def spa2eng(self, spa):

        if spa in self.spa:
            idx=self.spa.index(spa)
            return self.eng[idx]
        else:
            return ""

    def to_list(self):

        return zip(self.eng,self.spa)


Se puede ver que todos los métodos, excepto __init__, devuelven valores
e intentan ser lo más genéricos posibles para que el "consumidor" del
objeto lo use según sus necesidades.

Con el último método (.to_list()) permitirá hacer mejor el "writelines"
que había dejado antes apuntado:

    open(nfich,"w").writelines("%s;%s\n"%(a,b) for (a,b) in dic.to_list())

Como argumento del .writelines() va lo que se denomina un "generador"
(muy parecido a la compresión de listas).

Hay muchas más cosas para mejorar, como el admitir términos duplicados
según las distintas traducciones de una misma palabra y que sean
consideradas por la búsqueda.

En cuanto al menú, deberías seguir con el diccionario que tienes en el
comentario. Un modo muy común es usar un diccionario para menús es así:

  dic=Diccionario)
  menu=Menu(dic)

  fmenu={
    "1":("Agregar", menu.agregar),
    "2":("Guardar", menu.guardar),
    "3":("Ver Todo", menu.mostrar_todo),
    ...
  }

Para mostrar el menú:

  for k,v in fmenu.items():
    print k,"-",v[0]
  print "0 - **Salir**"

  op=raw_input("> ")

Para elegir una acción:

  fmenu[op][1]()



Espero que te sirva de ayuda.

Saludos,
Chema Cortés

-- 
Hyperreals *R: http://ch3m4.org/blog
Quarks, bits y otras criaturas infinitesimales
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a