Welcome to The Python Patisserie.
Quick question: how many round shortbread biscuits are there in this Taster Box?

Did you say two? Right, I see why you said that. And I agree. But does Python agree?
We'll get back to this conundrum later.
Back in The Python Patisserie, Mr Bakeman had just walked in. Angie, the owner, forced a smile.
"Morning, Mr Bakeman."
"Good morning, my dear. How are you" But that wasn't a question, and Mr Bakeman certainly didn't wait for an answer. "What a lovely day today. I was just chatting to Trevor down the road, and I was telling him about the…"
Angie had already zoned out, keeping her smile pinned somewhat reluctantly to her face.
She turned to Todd. It was his first day working at the shop. And as it turned out, he didn't know much about biscuits or cakes.
"Can you count how many of that biscuit we have", Angie muttered while pointing at the shortbread biscuit closer to her.
Mr Bakeman will ask for a box of ten round shortbread biscuits once he finishes his monologue, as he does every Sunday morning.
"…and I was so surprised to see two robins, side by side, on the wavy branch of the apple tree…"
"Er, that's the only one, Angie." Todd had spent a minute or so examining the biscuit display with a perplexed look on his face.
"What do you mean it's the only one? I can see more like it from here!"
"There are some similar biscuits, yes, but…but they're not the one you pointed to…"
"Er?!" Angie didn't want to lose her patience. There was already Mr Bakeman testing her limits. Not Todd, too!
"How many round shortbread biscuits are there, biscuits just like that one?" She jabbed her finger in the direction of the biscuit again. "As long as they're shortbread biscuits. And round. He doesn't want the rectangular ones."
"Ah, I see", said Todd. And he went back to the display.
"Thirteen", he said with a sense of proud satisfaction on his face. Angie nodded and thought to herself that Todd may not last long at her patisserie.
But at least they could give Mr Bakeman his ten round, shortbread biscuits and send him on his way. Finally.
Counting
Angie wasn't clear and precise when asking Todd to count all the round shortbread biscuits. Still, Todd should have figured it out. The context should have been clear.
Todd missed the context, lacked common sense. Let's see how Python deals with this question. Let's get back to the Taster Box–you'll need to define a basic Biscuit
class first:
The Biscuit
class doesn't have much in it. And since taster_box
is a list, you can use the .count()
method to count how many round shortbread biscuits there are. Here's the output:
There are 0 round shortbread biscuits
Mr Bakeman won't be pleased. Python says there aren't any left. But surely, there are two in the box, no?
Here's a small clue to the puzzle:
You create an instance of a round shortbread biscuit, the_biscuit_on_the_left
. This is a specific biscuit. The one on the left of the counter.
And this is why the box you create is the_impossible_box
. You place the same biscuit in the first and fourth slots of the box. That's impossible. But bear with me for a few more seconds. You also have two more round shortbread biscuits in the box, in the second and last slots.
Note that you pass the_biscuit_on_the_left
to .count()
this time. Here's the output from this code:
There are 2 round shortbread biscuits
The name the_biscuit_on_the_left
always refers to the same object, but the additional calls Biscuit("shortbread", "round")
create new objects. The .count()
method counts how many times the same object appears in the list.
But is that right? How about in this example:
The strings are different objects in this REPL session, as you can see from their different IDs. But a_list.count()
returns 2 when you check how often the string appears in the list, even though they're not the same object.
Back to the Taster Box
Here's the original Taster Box code:
Recall that this is the version that claims there are no round shortbread biscuits. You create a new Biscuit
instance as the argument for .count()
. Therefore, that instance can't also be in the Taster Box.
But surely, this is not how you expect .count()
to work. You want to know how many round shortbread biscuits there are in the box, not how many times one particular biscuit appears!
Python faces the same problem Todd faced when Angie pointed at the biscuit, asking, "How many are there of that biscuit?".
How can Python determine which objects are similar to each other to add them to the count? It doesn't know. It cannot know. So, when in doubt, Python looks for the same object–the exact same object.
But just as Angie later gave more explicit instructions to Todd on what to look for, you can also tell Python how to proceed:
Now that you defined what it means for two Biscuit
objects to be equal, Python doesn't need to fall back on its default of only treating references to the same object as being equal. Here's the output:
There are 2 round shortbread biscuits
Now Python can use your definition of equality–the one you defined in .__eq__()
. And if you prefer to treat all shortbread biscuits the same, irrespective of their shape, you can modify the .__eq__()
special method:
And now the output shows there are three biscuits:
There are 3 round shortbread biscuits
The printout still says round shortbread biscuits, which is now inaccurate. But that's beside the point.
Join the members’ forum by becoming a paid subscriber here on The Python Coding Stack.
Paid subscribers on The Python Coding Stack now get full access to the members’ forum at The Python Coding Place, with access to regular new content and discussions about all things Python.
And you’ll be supporting this publication…
It's All Connected
So, the .count()
list method relies on the Biscuit
object's .__eq__()
special method to determine how many equal objects there are in the list. If you don't find this surprising, good–you're mastering how Python works. If this was surprising, but now it makes sense, then you're on your way to master Python's behind-the-scenes.
You may recall that a couple of weeks ago here on The Stack, I republished an old article of mine about the £5 note analogy for objects–here it is again: The One About the £5 Note and the Trip to the Coffee Shop • The Difference Between `is` and `==` in Python. Today's topic follows on nicely from that introductory post about objects and their references. It's all connected.
Todd kept his job at The Python Patisserie. Angie learnt to be clearer and more precise when asking him to do things. And, as it turned out, he was pretty efficient at his job. He even seemed to get on well with Mr Bakeman.
As I planned and wrote this article, I kept a record of all the steps, ideas, decisions I took along the way. I wrote this up as a post in my other publication, Breaking the Rules, where I write about narrative technical writing. Here’s that post if you’re interested in reading about the process that let to this article: From Spark to Published
Code in this article uses Python 3.13
The code images used in this article are created using Snappify. [Affiliate link]
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com
Further reading related to this article’s topic:
Appendix: Code Blocks
Code Block #1
taster_box = [
Biscuit("shortbread", "round"),
Biscuit("bourbon", "rectangular"),
Biscuit("shortbread", "rectangular"),
Biscuit("custard cream", "rectangular"),
Biscuit("shortbread", "round"),
Biscuit("chocolate chip", "round"),
]
Code Block #2
class Biscuit:
def __init__(self, type_of_biscuit, shape):
self.type_of_biscuit = type_of_biscuit
self.shape = shape
taster_box = [
Biscuit("shortbread", "round"),
Biscuit("bourbon", "rectangular"),
Biscuit("shortbread", "rectangular"),
Biscuit("custard cream", "rectangular"),
Biscuit("shortbread", "round"),
Biscuit("chocolate chip", "round"),
]
n_biscuits = taster_box.count(
Biscuit("shortbread", "round")
)
print(
f"There are {n_biscuits} round shortbread biscuits"
)
Code Block #3
# ...
the_biscuit_on_the_left = Biscuit("shortbread", "round")
the_impossible_box = [
the_biscuit_on_the_left,
Biscuit("shortbread", "round"),
Biscuit("bourbon", "rectangular"),
the_biscuit_on_the_left,
Biscuit("shortbread", "round"),
]
n_biscuits = the_impossible_box.count(
the_biscuit_on_the_left
)
print(
f"There are {n_biscuits} round shortbread biscuits"
)
Code Block #4
a_string = "The Python Coding Stack"
another_string = "The Python Coding Stack"
id(a_string)
# 4407626608
id(another_string)
# 4407632928
a_list = [a_string, another_string]
a_list.count("The Python Coding Stack")
# 2
Code Block #5
class Biscuit:
def __init__(self, type_of_biscuit, shape):
self.type_of_biscuit = type_of_biscuit
self.shape = shape
taster_box = [
Biscuit("shortbread", "round"),
Biscuit("bourbon", "rectangular"),
Biscuit("shortbread", "rectangular"),
Biscuit("custard cream", "rectangular"),
Biscuit("shortbread", "round"),
Biscuit("chocolate chip", "round"),
]
n_biscuits = taster_box.count(
Biscuit("shortbread", "round")
)
print(
f"There are {n_biscuits} round shortbread biscuits"
)
Code Block #6
class Biscuit:
def __init__(self, type_of_biscuit, shape):
self.type_of_biscuit = type_of_biscuit
self.shape = shape
def __eq__(self, other):
return (
self.type_of_biscuit == other.type_of_biscuit
and self.shape == other.shape
)
taster_box = [
Biscuit("shortbread", "round"),
Biscuit("bourbon", "rectangular"),
Biscuit("shortbread", "rectangular"),
Biscuit("custard cream", "rectangular"),
Biscuit("shortbread", "round"),
Biscuit("chocolate chip", "round"),
]
n_biscuits = taster_box.count(
Biscuit("shortbread", "round")
)
print(
f"There are {n_biscuits} round shortbread biscuits"
)
Code Block #7
class Biscuit:
# ...
def __eq__(self, other):
return self.type_of_biscuit == other.type_of_biscuit
# ...
For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!
Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.
And you can find out more about me at stephengruppetta.com