For your first steps in Python, I have prepared a small project, that you can follow and change the code one step at a time. Take your time, you don’t need to do this in one go, always run the code at every step, and observe how the program evolves.
I want to manage my shopping list. I will have a list of categories (like Fruit, Meat, Fish, etc) so when I add an item to my list I can assign a category. I want to be able to save the list to a file and retrieve it, sort the list by category, remove items, change quantities.
Do you prefer to watch a video?
Variables
For the first part of the project you will just create some variables to understand how they work. There are three basic types of variables
- Numbers, like 3, 65 or 7.23
- Strings, sequences of characters enclosed in single or double quotes, like ‘hello’, “B”, “isn’t it funny?”
- Boolean, a special value that can be either True or False (upper case initial)
Start coding your project by declaring some variables and assigning their initial value, then execute the following piece of code.
budget = 100 ## no matter the currency
store = "Kwik-e-Mart"
finish = False
# print out the values, but remove this part as you
# progress with the project
print(budget)
print(store)
print(finish)
In the next step you will define the set of possible categories to choose from. You will use a special type of variable, the list. It can contain an arbitrary number of values, including other lists.
categories = ['Meat/Fish','Fruit/Veg','Canned','Cooking']
print(categories)
Note how the function print can visually show any kind of data. Once you executed the program and checked that it works correctly, remove the unnecessary prints once they are no longer needed.
Functions
The program will display a main menu allowing the user to make a choice. This menu is displayed many times and it would be awkward to type the same exact code every time. Functions are very useful to solve the problem. You can define a piece of code inside a function and call the function as many times as you like simply by its name.
Add the following code immediately after the variable declaration, then execute the program.
def main_menu():
print("-----")
print("1. Add an item")
print("2. Display the list")
print("3. Exit")
main_menu() ## this calls the function main_menu
The program now displays the menu and terminates. To collect the option you will select, use the function input, which stores the value you type in a variable. Add this line after the last print (remember to indent it correctly)
print("3. Exit")
resp = input("What's your choice? ")
When you execute the program, it stops and waits for your input. Amazing, but nothing happens after you have typed a number (followd by [enter]). You must return the value to the main program, and for now just print it. Change the code as shown below. Since input returns a string, you must convert to an integer before returning its value.
resp = ...
return int(resp)
option = main_menu()
print(option)
Basic loops
Every time the program has nothing better to do, it will display the main menu. You defined the variable finish with a default value of False. You will add a loop that will execute the code inside its block while a certain condition remains True.
while not finish:
option = main_menu()
print(option)
Now the program will run forever, because there’s nothing insed the loop that makes the condition switch to False. You will make it happen when you select option 3 in the menu.
Basic flow control
Add the following code to your program.
option = main_menu()
if option == 3:
print("Exiting")
finish = True ## not the most elegant way to exit a loop :-)
You would normally use break to exit a loop, but for our demonstrative purposes this is just fine. Run the program and see what happens when you insert the value 3. Also check what happens if you insert any other number, or even some text. Since this is an introduction to the basic structures, I’m skipping all the checks on the validity of the input, but in a real program, you must check every possible condition that may cause the program to behave incorrectly, or crash.
Now change the program to print a warning if you input a number that is not in the menu.
if option == 3:
print("Exiting")
finish = True
else:
print("You selected an invalid option")
Adding more functionalities
You will now implement option number 1, and add an item to the shopping list. First you will need a variable that will contain the items, so declare an empty list. Then create a new function to manage the activity, finally add the code to call this function when you select option 1.
finish = False
shopping_list = [] ## empty list
def add_item_to_shopping_list():
name = input("Enter the item name: ")
quantity = input("Enter the quantity: ")
.
.
.
if option == 3:
print("Exiting")
finish = True
elif option == 1:
add_item_to_shopping_list()
If you run the program now, it will ask you to input the values for name and quantity. You still need to request a valid category. You will ask for the ID of the category, that is the index of the category within the list.
Looping through iterables
An iterable is a kind of data you can walk through using a loop. In other words, the elements of an iterable can be enumerated. The simplest one is the list that you already know. They automatically have an index, which starts from zero. You can access each item in the list by its index. In this section you will add the code to print the list of categories with their indexes, and request to insert the index of your desired one.
quantity = input("Enter the quantity: ")
print("Select the category by typing the corresponding number")
for index, category in enumerate(categories):
print(f"{index}. {category}")
category_index = int(input("Enter the category number: "))
category = categories[category_index]
print(f"You selected {category}")
...
Note how you are converting the input value to integer on the fly. This causes a run-time error if you type something that is not an integer. Another error will occur if you type an index that does not exist in the list. Again, for simplicity, you are not making a bomb proof user interface.
Dictionaries
A dictionary is a collection of key-value pairs, where each key is unique and is used to access its corresponding value. It is defined using curly braces {} with keys and values separated by a colon. For example (do not add this to your program):
item = {'name': 'Potatoes', 'quantity': 25, 'category': 2}
With the example in mind, add the code to append an item to the shopping list.
category = categories[category_index]
item = {
'name': name,
'quantity': quantity,
'category': category
}
shopping_list.append(item)
If you run the program now, you will notice no difference. This is because you are not using the content of the shopping list. To print the list, implement option 2. You could write a specific function for the task, but since it’s very short, you can add it directly in the main block.
if option == 3:
...
elif option == 2:
print("Shopping List:")
for item in shopping_list: ## walk through the list
print(f"{item['quantity']} of {item['name']} ({item['category']})")
Now run the program and select option 2 before adding anything to the list 🙂 then use the program for a while and add 5 or 6 elements. Then select option 3 and terminate the program. What happens when you restart the program? Your list is empty!!!! The memory used by our program is released when the program exits, so in the current state it’s not very useful.
Filo I/O
There are very efficient ways to implement the so-called data persistence. These include using libraries like pandas or duckdb which allow the management of data in various formats, including Excel. In this example you will keep it very basic and save the data in a comma separated text file.
Start with defining a global variable to store the file name, then define a new function to be called as part of the exit procedure when you select option 3. The function walks through the shopping list, generates a string for each item and writes the string to the file.
data_file = "shopping.txt"
def save_shopping_list_to_file():
with open(data_file, 'w') as file: # open the file in write mode
for item in shopping_list: # walk through the list
line = f"{item['name']},{item['quantity']},{item['category']}\n"
file.write(line)
print(f"Shopping list saved to {data_file}.")
...
...
if option == 3:
print("Exiting")
save_shopping_list_to_file()
finish = True
Now run the program, insert some items in the list and when you exit, check for a file named shopping.txt in the same directory. You can open it with any text editor.
Saving the list is not very useful if you can’t read it back into the program. Add the code to read the list at every execution of the program. There’s no need to create a function, since this is part of the main block. Write the following code before the loop.
with open(data_file, 'r') as file: # open the file in read mode
for line in file: ## for each line in the file (possibly none)
name, quantity, category = line.strip().split(',')
# pythonic way to split a string and put the slices in 3 different variables
# now rebuild the dictionary and add to the shopping list
item = {
'name': name,
'quantity': quantity,
'category': category
}
shopping_list.append(item)
print(f"Shopping list loaded from {data_file}.")
while not finish:
...
From now you can proceed on your own. The possibilities are endless … literally.
Try for example
- add a function to empty the shopping list
- remove a single item
- edit the quantity of an item
- handle the following errors
- the txt file does not exist (you may have deleted it, or it’s the first time you run the program in a specific directory)
- you input text instead of a number in the main menu or when selecting a category
- you input the index of a category that does not exist
