Butter Berries, An Elusive Delicacy
How my quest to find butter berries at the supermarket led to musings about Python lists and dictionaries and more
My daughter has a swimming lesson every Saturday morning. My wife takes her. My son and I meet them directly at the supermarket after the lesson to get our weekly shopping done.
Last Saturday, my son and I were a bit early so we started going round the supermarket filling the trolley. I texted my wife to see what she needed:
Get butter berries and flour. Will be there soon.
Right, let's start with the fruit aisle.
I'm not as knowledgeable about fruit as I should be. I know the common types of berries—blueberries, blackberries, raspberries, strawberries—but I'm not quite sure I know the other fancier varieties. Did our local supermarket even stock butter berries?
If they did, they weren't in the obvious place next to the strawberries. "We should ask a staff member", my son suggested sensibly. No way! We'll find them. All by ourselves.
Ten long minutes later, my wife and daughter arrived, finally.
"Can't find the butter berries anywhere"
"The what?"
"The butter berries. What are they, anyway?"
My wife's quizzical look prompted me to flick my phone out of my pocket, and a few carefully crafted swipes later, I'm showing her the text message she had sent me earlier.
"So?" she asked. "I need butter and flour to make a cake, and any type of berry will do."
Oh!
Get butter berries and flour
The comma. The comma's missing:
Get butter, berries and flour
Well, if it were me, it'd be two commas missing since I'd use an Oxford comma, but that's another matter.
In shopping lists, just like Python lists, commas matter.
Weekly Shop, Python-Style
Let's re-imagine this trip to the supermarket through Python spectacles. In particular, I'll look at some of the fundamental data types and how we can map this real-life situation to Python data structures.
I'll start with the shopping list, and then move on to the supermarket aisles.
Here's the shopping list first. You already know the issue with the missing comma. I'll add it in later. But for now, spot the missing comma:
You use the unpacking operator *
with shopping_list
in print()
to print out the individual items within the list rather than the list as a whole. And here's the output from this code:
Time to start your shopping:
Biscuits
Bread
ButterBerries
Bananas
Bagels
I'll imagine a couple of different scenarios next. In the first one, you're shopping in an unfamiliar supermarket. You don't know where anything is. Later, you'll do the same shop in your local supermarket, which you know well. We'll explore Python's data structures while shopping.
Rambling Through The Aisles
You take your shopping list to a supermarket. But you haven't been to this supermarket before. Its layout is unfamiliar. You start going through your shopping list:
Time to start your shopping:
Biscuits
Bread
ButterBerries
Bananas
Bagels
Biscuits is first on the list. You start walking up the first aisle and down the second one. Then back up the third aisle, and so on. You scan every shelf until you find the biscuits. Great.
Now, start again. This time, you're looking for bread. You find it, eventually.
Butter berries are next on the list. I know you know how this story ends. But let's play along. You walk up and down every aisle in the supermarket. Then back again. And again. You scan every shelf, but there are no signs of butter berries.
You would have saved plenty of time if you hadn't missed the comma when you created the list. But that's not the whole problem. In this scenario, you have a list
of the items you want to buy. But this list has no information on whether the items are available and where they're located.
Let's combine this list
with another built-in Python data structure, the dictionary. We'll also use some generator expressions and named tuples for good measure.
An Efficient Trip to Your Local Supermarket
You didn't like the experience in the unfamiliar supermarket. You like to shop in your local one, which you know well. You know your local supermarket so well you created a Python dictionary to keep track of the aisle and section of each item that the supermarket stocks. The aisles are numbered, and letters are used for the sections.
Here's the first version of this dictionary:
The dictionary's keys are strings with the items' names. The value associated with each key is a tuple containing the aisle number and the section.
This works. However, fetching data from this dictionary can be a bit messy. Let's assume you want the aisle number where you can find bananas:
supermarket["Bananas"][0]
or
supermarket.get("Bananas")[0]
Both versions return 5
, the aisle number where you'll find the bananas.
There's nothing wrong with this dictionary with tuple values. However, especially for more complex use cases, the need to index using an integer can lead to code that's less readable and more susceptible to bugs. It's not immediately evident that the index [0]
refers to the aisle number.
I've been using named tuples instead of tuples recently in similar scenarios. You'll see why this makes the code more readable soon.