Мой словарь не работает должным образом - PullRequest
0 голосов
/ 04 мая 2018

Я работал над проектом tkinter. Это просто ресторанный кассир (как ни крути) проект. Это еще не сделано, но я застрял в проблеме.

Вот мой код:

from tkinter import *
from tkinter.ttk import Style

# The different type of items that the store is selling
drinks = {}
burgers = {}
french_fries = {}
ice_creams = {}

class Object:

    def __init__(self, name, price, type):
        self.name = name
        self.price = price
        self.type = type
        exec('{}["{}"] = [{}, {}]'.format(self.type, name, price, self.type))

    def return_price(self):
        return self.price

    def get_price(self, amount):
        return self.price * amount

# Creating the object
Object('Coco Cola', 1.50, 'drinks')
Object('Sprite', 1.50, 'drinks')
Object('Apple Juice', 2.50, 'drinks')
Object('Orange juice', 2.50, 'drinks')
Object('Grape Juice', 2.50, 'drinks')
Object('Cheese and Ham', 3.75, 'burgers')
Object('Cheese', 4.00, 'burgers')
Object('Cheese and Fish', 3.50, 'burgers')
Object('All Meat', 5.50, 'burgers')
Object('Waffle Fries', 2.50, 'french_fries')
Object('Chili Cheese Fries', 2.75, 'french_fries')
Object('Polenta Fries', 3.50, 'french_fries')
Object('Potato Wedges', 3.50, 'french_fries')
Object('Strawberry', 3.50, 'ice_creams')
Object('Blueberry', 3.75, 'ice_creams')
Object('Black Berry', 3.00, 'ice_creams')
Object('Vanilla', 3.00, 'ice_creams')
Object('Chocolate', 3.50, 'ice_creams')



# This code is what gives me the result i specified at the bottom of my question
print(drinks)

# All the tkinter stuff
root = Tk()
root.resizable(width=False, height=False)
root.style = Style()
root.style.theme_use('xpnative')


drink, burger, french_fry, ice_cream = StringVar(), StringVar(), StringVar(), StringVar()
drink_amount, burger_amount, french_fry_amount, ice_cream_amount = IntVar(), IntVar(), IntVar(), IntVar()
subtotal, tax, total, change = IntVar(), IntVar(), IntVar(), IntVar()
drink_amount.set(0)
burger_amount.set(0)
french_fry_amount.set(0)
ice_cream_amount.set(0)

Label(root, text='Restaraunt Cashier').grid(row=0, column=1, columnspan=5)
Label(root, text='Drinks:').grid(row=1, sticky=W)
Label(root, text='Burgers:').grid(row=2, sticky=W)
Label(root, text='French Fries:').grid(row=3, sticky=W)
Label(root, text='Ice cream:').grid(row=4, sticky=W)
Label(root, text='Amount:').grid(row=1, column=2, sticky=E)
Label(root, text='Amount:').grid(row=2, column=2, sticky=E)
Label(root, text='Amount:').grid(row=3, column=2, sticky=E)
Label(root, text='Amount:').grid(row=4, column=2, sticky=E)
Label(root, text='Subtotal:').grid(row=1, column=4, sticky=W)
Label(root, text='Tax:').grid(row=2, column=4, sticky=W)
Label(root, text='Total:').grid(row=3, column=4, sticky=W)
Label(root, text='Change:').grid(row=4, column=4, sticky=W)

# Entry types
drink_entry = OptionMenu(root, drink, *drinks)
burger_entry = OptionMenu(root, burger, *drinks)
french_fries_entry = OptionMenu(root, french_fry, *drinks)
ice_cream_entry = OptionMenu(root, ice_cream, *drinks)

# Entry amount
drink_entry_amount = Entry(root, width=50)
burger_entry_amount = Entry(root, width=50)
french_fry_entry_amount = Entry(root, width=50)
ice_cream_entry_amount = Entry(root, width=50)

# Subtotal, tax, total, change, entries
subtotal_entry = Entry(root, width=50)
tax_entry = Entry(root, width=50)
total_entry = Entry(root, width=50)
change_entry = Entry(root, width=50)

# Gridding
drink_entry.grid(row=1, column=1, ipady=5)
burger_entry.grid(row=2, column=1, ipady=5)
french_fries_entry.grid(row=3, column=1, ipady=5)
ice_cream_entry.grid(row=4, column=1, ipady=5)
drink_entry_amount.grid(row=1, column=3, ipady=5)
burger_entry_amount.grid(row=2, column=3, ipady=5)
french_fry_entry_amount.grid(row=3, column=3, ipady=5)
ice_cream_entry_amount.grid(row=4, column=3, ipady=5)
subtotal_entry.grid(row=1, column=5, ipady=5)
tax_entry.grid(row=2, column=5, ipady=5)
total_entry.grid(row=3, column=5, ipady=5)
change_entry.grid(row=4, column=5, ipady=5)

entry_list = [
    'drink_entry', 'burger_entry', 'french_fries_entry', 'ice_cream_entry', 'drink_entry_amount', 'burger_entry_amount',
    'french_fries_entry_amount', 'ice_cream_entry_amount'
]

item_selected = []

def submit_clicked(event=None):
    global item_selected
    drink_amount.set(drink_entry_amount.get())
    burger_amount.set(burger_entry_amount.get())
    french_fry_amount.set(french_fry_entry_amount.get())
    ice_cream_amount.set(ice_cream_entry_amount.get())
    item_selected.append(drink.get())
    item_selected.append(burger.get())
    item_selected.append(french_fry.get())
    item_selected.append(ice_cream.get())
    item_selected = list(filter(None, item_selected))



submit_button = Button(root, text='Submit', command=submit_clicked)
submit_button.grid(row=6, column=1, columnspan=5)
root.grid_rowconfigure(5, minsize=20)


root.mainloop()

Я проведу вас по коду:

  1. Объявлено, что товары магазина продаются как словари
  2. Создание класса для создания объектов для создания предметов каждого типа, продаваемых в магазине
  3. Объявление переменных, которые получают меню ввода и параметров в коде ниже.
  4. Создание записей
  5. Сетка
  6. Создание функции, которая получает меню ввода и параметров и устанавливает для него указанные выше переменные.

Я думаю, что выбранный здесь элемент не нужен.

Итак, проблема в том, что когда я бегу, это дает мне что-то вроде этого:

{'Coco Cola': [1.5, {...}], 'Sprite': [1.5, {...}], 'Apple Juice': [2.5, {...}], 'Orange juice': [2.5, {...}], 'Grape Juice': [2.5, {...}]}

Что я ожидал от кода:

{'Coca Cola': [1.5, 'drinks'], 'Sprite': [1.5, 'drinks'], 'Apple Juice': [2.5, 'drinks'], 'Orange juice': [2.5, 'drinks'], 'Grape Juice': [2.5, 'drinks']}

Я полагаю, что моя проблема не мешает коду tkinter, я могу ошибаться, но я просто хочу, чтобы люди точно определяли мои ошибки, потому что я не могу прямо сейчас.

1 Ответ

0 голосов
/ 04 мая 2018

Как я думаю, @ Аран-Фей поставил диагноз в комментариях, ваша проблема связана с вашим exec вызовом Object.__init__, который не выполняет то, что вы ожидаете. Когда делать:

exec('{}["{}"] = [{}, {}]'.format(self.type, name, price, self.type))

с self.type, равным названию одного из ваших словарей (например, "drinks"), вы выполняете этот оператор Python:

drinks[...] = [..., drinks]

То есть вы присваиваете ссылку на словарь как часть значения в словаре. Я подозреваю, что вы хотите, чтобы это значение включало строку "drinks" вместо ссылки на словарь с именем drinks. Для этого вам понадобится {!r} в строке формата.

Но, что еще лучше, покончите с вызовом exec полностью! Имена переменных не должны быть данными. Если у вас есть элемент данных, например строка "drinks", и вы хотите, чтобы он позволял вам искать словарь, используйте его в качестве ключа на другом уровне словаря.

Итак, вместо четырех переменных верхнего уровня:

drinks = {}
burgers = {}
french_fries = {}
ice_creams = {}

Сделайте только одну (которую я назвал data, вы можете придумать более подходящее имя):

data = {"drinks": {}, "burgers": {}, "french_fries": {}, "ice_creams": {}}

Тогда вместо необходимости exec вы можете просто индексировать словарь по мере необходимости:

data[self.type][name] = [price, self.type]

Есть и другие проблемы в вашем коде. Очень странно, что вы создаете Object экземпляров исключительно для их побочных эффектов (вы отбрасываете каждый экземпляр сразу после его создания). Это может иметь смысл, если конструктор вставляет объект в структуру данных (как, например, часто делают типы TKinter). Если вас интересуют только побочные эффекты, просто переместите код из Object.__init__ в функцию верхнего уровня и покончите с классом!

Некоторые из ваших Entry объектов, по-видимому, ссылаются на неправильный словарь: burger_entry = OptionMenu(root, burger, *drinks), вероятно, должно иметь *burgers в качестве последнего аргумента (или *data['burgers'], если вы измените структуры данных, как я предлагал выше).

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