Питон берет мой словарь взят за кортеж или список - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь разработать программу личных финансов на 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.

Большое спасибо за любую помощь, которую кто-нибудь может мне предоставить.

1 Ответ

0 голосов
/ 10 октября 2018

Одна вещь, которая выглядит как проблема: вы определили глобальный categorias_gastos дважды.

Второе определение перезапишет первое, и это скорее список кортежей, а не диктат.Используйте другое имя для ваших кортежей радиокнопок и / или спрячьте его внутри (скажем) функции make_radiobuttons.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...