Я пытаюсь разработать программу личных финансов на python.Мои расходы делятся на категории, которые в свою очередь делятся на подкатегории.Я использую вложенные архивы для хранения этих данных, как показано ниже:
categorias_gastos = {'alimentacao_limpeza':{'almoco':0,
'supermercado':0},
'carro': {'combustivel':0,
'manutencao':0,
'multas_cnh':0},
'criaturas_estimacao': {'animais':0,
'plantas':0},
'despesas_medicas': {'consultas':0,
'dentista':0,
'exames':0,
'material_permanente':0,
'remedios':0 },
'formacao': 0,
'impostos': 0,
'lazer': 0,
'manutencao_casa':0,
'seguros':0,
'servicos':0,
'outros':0}
Из того, что я понимаю, фигурных скобок достаточно, чтобы сообщить Python, что это - словарей.Затем я пытаюсь получить доступ к конкретным данным, используя вложенные индексы, такие как categoryorias_gastos [key1] [key2].Индексы key1 и key2 соответствуют именам ключей в категориях расходов и подкатегориях соответственно.Этот бит кода:
key1 = StringVar()
key1.set('alimentacao_limpeza')
key2 = StringVar()
key1.set('supermercado')
. Здесь проблема начинается, когда python вызывает следующую ошибку атрибута,
AttributeError: 'NoneType' object has no attribute '_root'
Если я вместо этого внесу следующее изменение
#key1 = StringVar()
#key1.set('alimentacao_limpeza')
key1 = 0
#key2 = StringVar()
#key1.set('supermercado')
key2 = 0
Я могу заставить Python запускать мой код.Я пытаюсь обновить данные в словаре с помощью функции обратного вызова в кнопке,
terminado_button = Button(somar_despesas_frame,
text="TERMINADO",
font=('arial', 10, 'bold'),
command=atualizar_categoria).grid(row=3,
column=0,
columnspan=4)
Функция обратного вызова:
def atualizar_categoria():
global categorias_gastos, despesas, valores
total_despesas = sum(valores)
categorias_gastos[key1][key2] = total_despesas
print("CATEGORIA ATUALIZADA =",categorias_gastos[key1][key2])
Затем возникает другая ошибка:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\ridim\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "<ipython-input-37-f7d458c1a385>", line 8, in atualizar_categoria
categorias_gastos[key1][key2] = total_despesas
TypeError: 'tuple' object does not support item assignment
Если я внесу незначительные изменения, python затем берет мой словарь для списка и вызывает аналогичную ошибку.
Кто-нибудь может мне сказать, что я делаю неправильно?
Полный код представлен ниже:
# ------------------------------------------------------------------------------
# import classes, attributes, and methods of TKinter into current workspace
from tkinter import *
# ttk is Python's binding to the "themed widgets"
from tkinter import ttk
# ------------------------------------------------------------------------------
# global variables
categoria=0
categorias_gastos = {'alimentacao_limpeza':{'almoco':0,
'supermercado':0},
'carro': {'combustivel':0,
'manutencao':0,
'multas_cnh':0},
'criaturas_estimacao': {'animais':0,
'plantas':0},
'despesas_medicas': {'consultas':0,
'dentista':0,
'exames':0,
'material_permanente':0,
'remedios':0 },
'formacao': 0,
'impostos': 0,
'lazer': 0,
'manutencao_casa':0,
'seguros':0,
'servicos':0,
'outros':0}
contador = 0
despesa = 0
despesas = []
#key1 = StringVar()
#key1.set('alimentacao_limpeza')
key1 = 0
#key2 = StringVar()
#key1.set('supermercado')
key2 = 0
valores = []
global categoria, categorias_gastos, contador, despesa, despesas, key1, key2, valores
# ------------------------------------------------------------------------------
# define accountancy calculation functions
def atualizar_categoria():
global categorias_gastos, despesas, valores
total_despesas = sum(valores)
categorias_gastos[key1][key2] = total_despesas
print("CATEGORIA ATUALIZADA =",categorias_gastos[key1][key2])
def atualizar_despesas():
global contador,despesa, valores
valor_despesa = float(despesa.get())
contador = contador + 1
filename = ''.join(["Despesa_", str(contador)])
despesas.append(filename)
valores.append(valor_despesa)
print()
print("ATUALIZAR DESPESAS")
print(filename," = ",despesa.get())
def exibir_categoria():
print(categoria.get())
def imprimir_despesa():
global despesa, despesas, valores
print("Despesa =",despesa.get())
def selecionar_rubrica():
global despesa, despesas, key1, key2, valores
print()
print("SELECIONAR RUBRICA")
print("rubrica key1 =", key1)
print("rubrica key2 =", key2)
rubricas = ['Supermercado',
'Almoço']
selecionar_rubrica_frame = Toplevel(root)
var = StringVar()
var.set(rubricas[0])
# create title label
Label_1 = Label(selecionar_rubrica_frame,
text='SELECIONAR RUBRICA',
font=('arial', 12, 'bold')).pack()
for item in rubricas:
rubrica = Radiobutton(selecionar_rubrica_frame,
text=item,
font=('arial', 12, 'bold'),
indicatoron=0,
variable=var,
value=item,
command=somar_despesas)
rubrica.pack(anchor=W,
fill=X)
def somar_despesas():
global despesa, despesas, key1, key2, valores
print("key1 =", key1)
print("key2 =", key2)
despesa = StringVar()
despesa.set("Inserir valor da despesa")
# create frame
somar_despesas_frame=Toplevel(root)
# create title label
Label_1 = Label(somar_despesas_frame,
text='SOMAR DESPESAS',
font=('arial', 12, 'bold')).grid(row=0,
column=0,
columnspan=4)
#create operation label
despesa_label = Label(somar_despesas_frame,
text='Despesa',
font=('arial', 10, 'bold')).grid(row=1,column=0)
#add entry widget to my_frame_1
despesa_entry = Entry(somar_despesas_frame,
textvariable=despesa,
font=('arial', 10, 'normal')).grid(row=1,column=1)
validar_button = Button(somar_despesas_frame,
text="Validar",
font=('arial', 10, 'bold'),
command=atualizar_despesas).grid(row=1,column=3)
terminado_button = Button(somar_despesas_frame,
text="TERMINADO",
font=('arial', 10, 'bold'),
command=atualizar_categoria).grid(row=3,
column=0,
columnspan=4)
# ------------------------------------------------------------------------------
# Ia - create the toplevel or root window (an instance of tkinter.class)
root = Tk()
root.geometry('1400x700')
root.title('INSERIR GASTOS')
# ------------------------------------------------------------------------------
# CATEGORIAS_GASTOS_FRAME (EXPENDITURE CATEGORIES) AND ITS CONTENTS
# IIa - create categorias_gastos_frame
categorias_gastos_frame = Frame(root,
bd=2,
relief=SUNKEN)
categorias_gastos_frame.pack(side=LEFT,
anchor=N)
# add label to to my_frame_1
Label(categorias_gastos_frame,
text='SELECIONAR CATEGORIA DE GASTOS:',
font=('arial', 14, 'bold')).pack(anchor=W)
categorias_gastos = [("Alimentação / Limpeza",1),
("Carro",2),
("Criaturas de Estimação",3),
("Despesas Médicas",4),
("Formação",5),
("Impostos",6),
("Lazer",7),
("Manutenção da Casa",8),
("Seguros",9),
("Serviços",10),
("Outros",11)]
for text, category in categorias_gastos:
global categoria
botao = Radiobutton(categorias_gastos_frame,
text=text,
font=('arial', 12, 'bold'),
width=20,
padx=20,
indicator=0,
variable=key1,
value=categoria,
command=selecionar_rubrica)
botao.pack(anchor=W,
fill=X)
orientation = Label(categorias_gastos_frame)
orientation.pack(anchor=W,fill=X)
# Ib - the mainloop method is what keeps the root window visible
root.mainloop()
Я понимаю, что использование глобальных переменных нехорошо, и что вместо этого я должен использовать классы.Но это только для меня, чтобы начать изучать Python.
Большое спасибо за любую помощь, которую кто-нибудь может мне предоставить.