Video Demo: https://youtu.be/6ASX71jNGB0
My grocery tracker uses tkinter to allow users to edit an inventory and shopping list. People can use this to track what and when they need to buy food. It keeps track of dates when the food was last updated, and the design is mostly user friendly. The food.txt stores the currently inventory of the user in the format "Food": # servings (Last Updated Year-M-D). It is used to carry over the data between uses and is updated with the default python read and write functions, open("food.txt", 'r'). During the program, the data is storing in a dictionary in the format of {Food: [#, date]}. To convert to a user friendly date, I used the dateutil library. Shoppinglist.txt has a similar function, but is much simpler than food.txt. It only stores the food that needs to be bought, not dates or servings. Adding and removing foods is fairly simple as you just input the name, which will be removed if it already exists and vice versa. During the program, all the foods are stored in a list, which is easily updated as lists are mutable. Main.py is the main function of the file. The first 3 lines are simply importing libraries I used to make the program more user friendly. Lines 5-21 set up the empty shopping lists, invetories, and calculate today's date. It also creates a tkinter window called "Grocery Tracker". Lines 23-35 read the data from food.txt and shoppinglist.txt, which are stored in their respective dictionaries or lists. The displayFood function creates a window using tk.Toplevel() that shows the current inventory of the user, including the food, servings, and date last updated. A button to close the window is packed at the bottom of the window. The addToDict function is called after the "Save" button is pressed to add a food to the inventory. It takes the food and quantity as parameters to process. First of all, it makes sure that the food doesn't already exist, as data may be overriden in this case. If it does exist, it returns the function, preventing the rest of the function from executing. On the other hand, if it doesn't exist, the food is added to the inventory dictionary and the add window is closed. The addFood function makes a new window using tk.Toplevel() called addWindow. The window has an entry box for the grocery name and quantity, as the date can be calculated by the computer. All of the labels and entries are packed, and the save button leads to the addToDict function when clicked. The displayGroceryList function iterates through every item in the shopping list list and displays it with a tk.Label, which are all packed. The close button is packed at the bottom, and it closes the window when clicked with the window.destroy() function. The updateGroceryList() function, which takes the food item as a parameter, capitlizes the name of the food and adds the food to the shopping list if it doesn't exist and removes it if it doesn't exist. The groceryList() function displays, from top to bottom, a button allowing the user to view the shopping list, an entry box for entering a grocery, a save button to save the added grocery, and a close button to close the window. The view shopping list button opens a new window with the displayGroceryList() function explained earlier. When save is clicked, the updateGroceryList() function is called, either adding or removing the grocery. Finally, a lambda function is used to destroy the window when close is clicked. The updateEditedFood() function, which takes the food and quantity, simply changes the food in the dictionary to the quantity inputted, and updates the date to today. The editFood() function launches a new window with tk.Toplevel(). It uses a frame containing a StringVar and dropdown menu to allow the user to pick a food to edit. This is to make sure the user isn't editing a food that doesn't exist. Under the dropdown, the user can input a new integer quantity. The save button calls the updateEditedFood() function. The close button destroys the window. Finally, saveAndExit() erases both food.txt and shoppinglist.txt, writing the data from the dictionary and shopping list to the files. It writes the data in the same format. At the end, the code for the default window is opened. It has a welcome message containing today's date, and buttons to see the inventory, add to the inventory, view and edit the shopping list, edit the inventory, and save and write the data to the files. All of these messages and buttons are packed and appear in order from top to bottom. The mainloop() function is used to make sure the window doesn't disappear.