Dizonario

Stato
Discussione chiusa ad ulteriori risposte.

Pythoner

Utente Silver
25 Dicembre 2009
0
0
0
52
Sto imparando a utilizzare le Tkinter. Volevo creare un semplice dizionario En - It, l'ho implementato a classi. Il problema è che non funziona! :mad:
Funziona tutto tranne l'aggiornamento dei dizionari!!! :mad:
Per piacere potete guardare? Grazie
Codice:
# -*- coding: cp1252 -*-
from Tkinter import *
import tkMessageBox as tkm
import tkSimpleDialog as tks


class GUI:
	def __init__(self, master):
		self.APPTITLE = "My dictionary It - En/En - It 2.01"
		self.enit = {}
		self.iten = {}
		self.master = master
		self.master.title(self.APPTITLE)

		# Widgets
		f = Frame(self.master)
		ff = Frame(self.master)
		fff = Frame(self.master)
		e = Entry(f)
		l = Label(f, text = "English", fg = "black")
		ee = Entry(ff)
		ll = Label(ff, text = "Italiano", fg = "black")
		b1 = Button(fff, text = "Aggiungi a En - It")
		b2 = Button(fff, text = "Aggiungi a It - En")
		b4 = Button(fff, text = "Dizionari", command = lambda: self.visualizza())
		b5 = Button(fff, text = "Ricerca", command = lambda: self.ricerca())
		b3 = Button(fff, text = "Uscita", command = lambda: self.uscita())

		# Packing
		f.pack()
		ff.pack()
		fff.pack()
		e.grid(row = 0, column = 1)
		l.grid(row = 0, column = 0)
		ee.grid(row = 0, column = 1)
		ll.grid(row = 0, column = 0)
		b1.grid(row = 0, column = 0)
		b2.grid(row = 0, column = 1)
		b4.grid(row = 1, column = 0)
		b5.grid(row = 1, column = 1)
		b3.grid(row = 1, column = 2)

	def addEn(self):
		self.enit[e.get()] = ee.get()

	def addIt(self):
		self.iten[ee.get()] = e.get()

	def visualizza(self):
		# Creating a new window
		# Widgets
		top = Tk()
		f = Frame(top)
		ff = Frame(top)
		t = Text(f, fg = "black", bg = "white")
		b = Button(ff, text = "Ok", command = top.destroy)

		# Packing
		f.pack()
		ff.pack()
		t.pack()
		b.pack()

		# View dictionaries
		t.insert(END, "Dizionario En - It:\n")
		t.insert(END, self.enit)
		t.insert(END, "\n")
		t.insert(END, "Dizionario It - En:\n")
		t.insert(END, self.iten)

	def ricerca(self):
		# Start a new search
		try:
			tkm.showinfo(self.APPTITLE, str(self.enit[tks.askstring("Ricerca", "Parola da cercare:")]))
		except KeyError:
			tkm.showinfo(self.APPTITLE, "La parola non è stata trovata nel dizionario En - It.\nOra sarà effettuata una ricerca in quello It - En")
			try:
				tkm.showinfo(self.APPTITLE, str(self.iten[tks.askstring("Ricerca", "Parola da cercare:")]))
			except KeyError:
				tkm.showwarning(self.APPTITLE, "La parola non è stata trovata nemmeno nel dizionario It - En")

	def uscita(self):
		# Exit
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero uscire?"):
			self.master.destroy()


if __name__ == "__main__":
	root = Tk()
	app = GUI(root)
	root.mainloop()
 
Uhm... ricordo poco e niente delle Tkinter...
Per aggiornamento intendi aggiungere le parole nel dizionario? Se è cosi, non c'è alcuna funzione collegata ai relativi bottoni.
 
Ah si quello l'ho visto, ho messo a posto, ma come mi consigliate di fare per salvare le parole? Perché se no i dizionari sono vuoti ad ogni riavvio....
 
Uhm, forse la risposta che ho dato è un mezzo fail, trattandosi di un dizionario forse non è molto comodo usare un semplice file txt.
 
shura ha detto:
usare un db mysql mi sembra esagerato
In effetti un pochino si xD.. Però dipende anche dal progetto che uno ha in mente.. E poi così magari impara anche la lib sql (se non la sa già)

EDIT: ripensandoci meglio in relazione al progetto mi sa che in effetti un sql è esagerato...
 
stavo per dire SHELVE, o, meglio (sebbene nn lo conosca) presente anchesso nella lib standard, dbm.

Cmq, tralasciando il design della classe che mi abbastanza escramentare:
1) togli quel cavalo di di if __name__=="__main__" che non serve a niente, non in programmi normali quantomeno, e che cmq risulta deprecato da quel che mi risulta.
2) CHE CODIFICA STAI USANDO?????? please, replace with: # -*- coding: utf-8 -*-
3) anche perché in py3, a cui prima o poi sarai costretto a passare, c'è solo quella (io la scriverei in py3, e cmq dovrebbe funzionare anche così, coding a parte)
4) perché usi due dizionari? cioè, devi mettere alcune parole tradotte in inglese e non viceversa? siccome nn credo, opterei per un singolo dizionario e giocherellare un po' con la sua miriade di metodi e proprietà per risalire dal valore alla chiave
5) che senso ha generalmente utilizzare una classe che contiene interfaccia e programma? cioè, sistemi il master e gli elementi tutto nel costruttore della classe :S almeno un metodo a parte direi; poi io avrei usato una classe che contenesse i dizionari/o, ed una classe con la GUI. Inoltre: non è che *per caso/ hai dimenticato il parametro command hai bottoni di aggiunta?


Ora guardo il codice meglio e provo a vedere se si riesce ad aggiustare

EDIT: guardato e detto quello che dovevo dire, poi imho il codice è un po' malscritto e risulta poco leggibile. IMHO
 
(shelve usava proprio un dizionario, imho era meglio, potevi inoltre usare anche la mia semplicissima classe che gira in questa sezioni)

open("mio file",'w').write("")

dovrebbe andare bene
 
Modificato ancora. Non funziona import, qualcuno potrebbe provarlo?
Codice:
# -*- coding: cp1252 -*-
from Tkinter import *
import tkMessageBox as tkm
import tkSimpleDialog as tks
import tkFileDialog as tkf
import shelve


class GUI(object):
	def __init__(self, master):
		self.APPTITLE = "My dictionary 3.8"
		if tkm.askyesno(self.APPTITLE, "Devi ancora creare il database?"):
			shelve.open(str(tkf.asksaveasfile())[13:-26], "c", 2)
		else:
			tkm.showinfo(self.APPTITLE, "Apri il database")
			self.diz = shelve.open(str(tkf.askopenfile())[13:-26], "c", 2)
		self.master = master
		self.master.title(self.APPTITLE)

		# Widgets
		f = Frame(self.master)
		ff = Frame(self.master)
		fff = Frame(self.master)
		self.e = Entry(f)
		l = Label(f, text = "Lang 1", fg = "black")
		self.ee = Entry(ff)
		ll = Label(ff, text = "Lang 2", fg = "black")
		b1 = Button(fff, text = "Aggiungi", command = self.add)
		b2 = Button(fff, text = "Importa...", command = self.importa)
		b3 = Button(fff, text = "Dizionario", command = self.visualizza)
		b4 = Button(fff, text = "Ricerca", command = self.ricerca)
		b5 = Button(fff, text = "Reset", command = self.canc)
		b6 = Button(fff, text = "Uscita", command = self.uscita)

		# Packing
		f.pack()
		ff.pack()
		fff.pack()
		self.e.grid(row = 0, column = 1)
		l.grid(row = 0, column = 0)
		self.ee.grid(row = 0, column = 1)
		ll.grid(row = 0, column = 0)
		b1.grid(row = 0, column = 0)
		b2.grid(row = 0, column = 1)
		b3.grid(row = 0, column = 2)
		b4.grid(row = 1, column = 0)
		b5.grid(row = 1, column = 1)
		b6.grid(row = 1, column = 2)

	def add(self):
		# Add words to dictionary
		self.diz[self.e.get()] = self.ee.get()

	def visualizza(self):
		# Creating a new window
		# Widgets
		top = Tk()
		f = Frame(top)
		ff = Frame(top)
		t = Text(f, fg = "black", bg = "white")
		b = Button(ff, text = "Ok", command = top.destroy)

		# Packing
		f.pack()
		ff.pack()
		t.pack()
		b.pack()

		# View dictionaries
		t.insert(END, "Dizionario:\n")
		t.insert(END, self.diz)

	def importa(self):
		# Import words from files
		try:
			file = open(str(tkf.askopenfile())[13:-26], "r")
		except TypeError:
			pass
		except IOError:
			tkm.showwarning(self.APPTITLE, "Il file non è stato trovato")
			return
		sep = tks.askstring(self.APPTITLE, "Inserisci il separatore usato (tab = \\t)")
		for line in file:
			r = line.strip().split(sep)
			self.diz[r[0]] = r[1]

	def ricerca(self):
		# Start a new search
		parola = tks.askstring("Ricerca", "Parola da cercare:")
		try:
			tkm.showinfo(self.APPTITLE, self.diz[parola])
		except KeyError:
			try:
				self._rev_dict()
				tkm.showinfo(self.APPTITLE, self.rev_dic[parola])
			except KeyError:
				tkm.showinfo(self.APPTITLE, "La parola non è stata trovata nel dizionario")

	def _rev_dict(self):
		self.rev_dic = dict(zip(self.diz.values(), self.diz.keys()))

	def canc(self):
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero resettare il dizionario?"):
			self.diz = {}
			self.rev_dic = {}

	def uscita(self):
		# Exit
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero uscire?"):
			self.master.destroy()


if __name__ == "__main__":
	root = Tk()
	app = GUI(root)
	root.mainloop()
 
1) vedo che hai ascoltato il mio consiglio riguardo all'if __name__, all'ecoding etc...
2) ogni tanto, dire che errore ti da sarebbe utile, oppure se nn ti da errori, prova un po' a togliere quell' except TypeError: pass che nn mi ispira per niente.. cmq in teoria askopenfile dovrebbe restituire un file già aperto, per verificare, al massimo, da un type(askopenfile())
 
Ho modificato così, ma l'import ancora non funziona. Qualcuno potrebbe provarlo?
Codice:
# -*- coding: utf-8 -*-

from Tkinter import *
import tkMessageBox as tkm
import tkSimpleDialog as tks
import tkFileDialog as tkf
import shelve


class GUI(object):
	def __init__(self, master):
		self.APPTITLE = "My dictionary 3.8"
		if tkm.askyesno(self.APPTITLE, "Devi ancora creare il database?"):
			shelve.open(str(tkf.asksaveasfile())[13:-26], "c", 2)
		else:
			tkm.showinfo(self.APPTITLE, "Apri il database")
			self.diz = shelve.open(str(tkf.askopenfile())[13:-26], "c", 2)
		self.master = master
		self.master.title(self.APPTITLE)

		# Widgets
		f = Frame(self.master)
		ff = Frame(self.master)
		fff = Frame(self.master)
		self.e = Entry(f)
		l = Label(f, text = "Lang 1", fg = "black")
		self.ee = Entry(ff)
		ll = Label(ff, text = "Lang 2", fg = "black")
		b1 = Button(fff, text = "Aggiungi", command = self.add)
		b2 = Button(fff, text = "Importa...", command = self.importa)
		b3 = Button(fff, text = "Dizionario", command = self.visualizza)
		b4 = Button(fff, text = "Ricerca", command = self.ricerca)
		b5 = Button(fff, text = "Reset", command = self.canc)
		b6 = Button(fff, text = "Uscita", command = self.uscita)

		# Packing
		f.pack()
		ff.pack()
		fff.pack()
		self.e.grid(row = 0, column = 1)
		l.grid(row = 0, column = 0)
		self.ee.grid(row = 0, column = 1)
		ll.grid(row = 0, column = 0)
		b1.grid(row = 0, column = 0)
		b2.grid(row = 0, column = 1)
		b3.grid(row = 0, column = 2)
		b4.grid(row = 1, column = 0)
		b5.grid(row = 1, column = 1)
		b6.grid(row = 1, column = 2)

	def add(self):
		# Add words to dictionary
		self.diz[self.e.get()] = self.ee.get()

	def visualizza(self):
		# Creating a new window
		# Widgets
		top = Tk()
		f = Frame(top)
		ff = Frame(top)
		t = Text(f, fg = "black", bg = "white")
		b = Button(ff, text = "Ok", command = top.destroy)

		# Packing
		f.pack()
		ff.pack()
		t.pack()
		b.pack()

		# View dictionaries
		t.insert(END, "Dizionario:\n")
		t.insert(END, self.diz)
		top.mainloop()

	def importa(self):
		# Import words from files
		try:
			file = open(str(tkf.askopenfile())[13:-26], "r")
		except IOError:
			tkm.showwarning(self.APPTITLE, "Il file non è stato trovato")
			return
		sep = tks.askstring(self.APPTITLE, "Inserisci il separatore usato (tab = \\t)")
		read = file.readlines()
		for line in read:
			r = line.strip().split(sep)
			tkm.showinfo("dsa", r)
			self.diz[r[0]] = r[1]

	def ricerca(self):
		# Start a new search
		parola = tks.askstring("Ricerca", "Parola da cercare:")
		try:
			tkm.showinfo(self.APPTITLE, self.diz[parola])
		except KeyError:
			try:
				self._rev_dict()
				tkm.showinfo(self.APPTITLE, self.rev_dic[parola])
			except KeyError:
				tkm.showinfo(self.APPTITLE, "La parola non è stata trovata nel dizionario")

	def _rev_dict(self):
		self.rev_dic = dict(zip(self.diz.values(), self.diz.keys()))

	def canc(self):
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero resettare il dizionario?"):
			self.diz = {}
			self.rev_dic = {}

	def uscita(self):
		# Exit
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero uscire?"):
			self.master.destroy()


root = Tk()
app = GUI(root)
root.mainloop()
 
Malex ha detto:
cmq in teoria askopenfile dovrebbe restituire un file già aperto, per verificare, al massimo, da un type(askopenfile())

ho l'impressione di parlare arabo..... cmq che diamine di errore ti restituisce????
 
!R~ ha detto:
La furia di Malex *_*

lol

è che se devo ripetere due volte la stessa cosa perché venga fatta; inoltre devo usare la funzione crystal_ball() [cit. blacklight] per capire cosa nn va nel suo codice...

cvd: "tkFileDialog.askopenfile, returns a file object" http://tk-happy.sourceforge.net/tk_dialogs.html

(che oltrettutto quel [13:-26] nn capisco cosa dovrebbe servire....)

EDIT: o mio dio, ora ho capito..... str(file) restiuisce una scritta del tipo: <open file "blabla", mode 'r' at 0xindirizzo>
quindi tu ottieni un oggetto file (già aperto dunque), lo converti a stringa, in modo da avere la scritta, ne estrai il nome; dopodiché con open ti crei un oggetto file ESATTAMENTE IDENTICO a quello di prima?!?!?!?!?!?!?!? potrebbe avere un minimo senso sul shelve.open, ma nell'open normale nn ne ha nessuno..

oltrettutto 'file' in py2 è una non-reserved keyword, sarebbe da evitare come nome di una var...

e guardando la doc: l'oggetto file ha un attribbuto name, quindi togli quello splittind di indici e metti asksaveas().name

e guarda un po' le documentazioni delle cose.....

EDIT2: perché usare la variabile temporanea read invece di fare direttamente:
Codice:
for line in file.readlines()
¿¿¿???
 
Le doc le guardo, ma non avevo trovato risposta!
Ora ho cambiato come hai detto, è solo che la funzione import non va! Utilizzo un file .txt e come separatore il tab.
Codice:
# -*- coding: utf-8 -*-

from Tkinter import *
import tkMessageBox as tkm
import tkSimpleDialog as tks
import tkFileDialog as tkf
import shelve


class GUI(object):
	def __init__(self, master):
		self.APPTITLE = "My dictionary 3.8"
		if tkm.askyesno(self.APPTITLE, "Devi ancora creare il database?"):
			self.new_db()
		tkm.showinfo(self.APPTITLE, "Apri il database")
		self.open_db()
		self.master = master
		self.master.title(self.APPTITLE)

		# Widgets
		f = Frame(self.master)
		ff = Frame(self.master)
		fff = Frame(self.master)
		self.e = Entry(f)
		l = Label(f, text = "Lang 1", fg = "black")
		self.ee = Entry(ff)
		ll = Label(ff, text = "Lang 2", fg = "black")
		b1 = Button(fff, text = "Aggiungi", command = self.add)
		b2 = Button(fff, text = "Importa...", command = self.importa)
		b3 = Button(fff, text = "Dizionario", command = self.visualizza)
		b4 = Button(fff, text = "Ricerca", command = self.ricerca)
		b5 = Button(fff, text = "Reset", command = self.canc)
		b6 = Button(fff, text = "Uscita", command = self.uscita)

		# Packing
		f.pack()
		ff.pack()
		fff.pack()
		self.e.grid(row = 0, column = 1)
		l.grid(row = 0, column = 0)
		self.ee.grid(row = 0, column = 1)
		ll.grid(row = 0, column = 0)
		b1.grid(row = 0, column = 0)
		b2.grid(row = 0, column = 1)
		b3.grid(row = 0, column = 2)
		b4.grid(row = 1, column = 0)
		b5.grid(row = 1, column = 1)
		b6.grid(row = 1, column = 2)

	def new_db(self):
		shelve.open(tkf.asksaveasfilename())

	def open_db(self):
		self.diz = shelve.open(tkf.askopenfile().name, "c", 2)

	def add(self):
		# Add words to dictionary
		self.diz[self.e.get()] = self.ee.get()

	def visualizza(self):
		# Creating a new window
		# Widgets
		top = Tk()
		f = Frame(top)
		ff = Frame(top)
		t = Text(f, fg = "black", bg = "white")
		b = Button(ff, text = "Ok", command = top.destroy)

		# Packing
		f.pack()
		ff.pack()
		t.pack()
		b.pack()

		# View dictionaries
		t.insert(END, "Dizionario:\n")
		t.insert(END, self.diz)
		top.mainloop()

	def importa(self):
		# Import words from files
		try:
			fileopen = tkf.askopenfile()
			file = open(fileopen.name, "r")
		except IOError:
			tkm.showwarning(self.APPTITLE, "Il file non è stato trovato")
			return
		sep = tks.askstring(self.APPTITLE, "Inserisci il separatore usato (tab = \\t)")
		for line in file.readlines():
			r = line.strip().split(sep)
			self.diz[r[0]] = r[1]

	def ricerca(self):
		# Start a new search
		parola = tks.askstring("Ricerca", "Parola da cercare:")
		try:
			tkm.showinfo(self.APPTITLE, self.diz[parola])
		except KeyError:
			try:
				self._rev_dict()
				tkm.showinfo(self.APPTITLE, self.rev_dic[parola])
			except KeyError:
				tkm.showinfo(self.APPTITLE, "La parola non è stata trovata nel dizionario")

	def _rev_dict(self):
		self.rev_dic = dict(zip(self.diz.values(), self.diz.keys()))

	def canc(self):
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero resettare il dizionario?"):
			self.diz = {}
			self.rev_dic = {}

	def uscita(self):
		# Exit
		if tkm.askyesno(self.APPTITLE, "Vuoi davvero uscire?"):
			self.diz.close()
			self.master.destroy()


root = Tk()
app = GUI(root)
root.mainloop()

E l'errore che mi dà è questo:
Codice:
Exception in Tkinter callback:
Traceback (most recent call last):
  File "C:\Programmi\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "C:\Documents and Settings\Miki - Administrator\Desktop\Dict.py", line 89, in importa
    self.diz[r[0]] = r[1]
IndexError: list index out of range
 
Stato
Discussione chiusa ad ulteriori risposte.