“Got. Got. Need.” Despite the clamour for NFTs and digital collectibles, there’s nothing like getting Eric Dier in a physical pack for the 8th time this year.
If you are setting off on your collection journey for the delayed 2020 Euros, it might be wise to take a guess at how much it is going to cost in total.
How much could it possibly be? 70p for a pack of five… so 568 stickers needed… so maybe £150? £200? £1000?!
Fortunately, we can put our Python skills to good use and simulate how many stickers, packs and dollar bills you need to fill an album. It also provides us with a great opportunity to learn about logic and chance in simulations.
We’ll simulate opening a pack, saving the sticker numbers that we have, then repeating until we have a complete collection. We assume that all stickers appear equally in packs and that all conspiracies of super rare stickers are exactly that. This is Panini, not Qanoni.
Beginning our album
First things first, we need to get our album. We need to define the variables that will hold our sticker numbers, swaps, number of packs bought and so on.
stickerAlbum = []
stickersRemaining = 568 - len(stickerAlbum) #Less than the World Cup album!
swapsCollection = []
swapStickers = len(swapsCollection)
packetsBought = 0
From here, we now have places to deal with the stickers we’re going to get in our packs.
Opening a pack
The process of opening a pack is simple. We need to give ourselves 5 random numbers between 1 and 568 then check if we have them in our album already.
If we do not have them, they get ‘stuck in’ – appended to our album array. If not, they go into the swaps bin.
We are going to open lots of packs, so let’s wrap this up in a neat openPacket() function.
def openPacket(packSize = 5):
#Referencing values outside the function
global packetsBought, stickersRemaining, swapStickers
packetsBought += 1
stickers = np.random.randint(low = 1, high = 569, size = packSize) #High is non-inclusive
for sticker in stickers:
if sticker not in stickerAlbum:
stickerAlbum.append(sticker)
else:
swapsCollection.append(sticker)
stickersRemaining = 568 - len(stickerAlbum)
swapStickers = len(swapsCollection)
We can now open a pack and see what that does to our collection:
openPacket()
print('You have {a} stickers to go, from {b} pack(s)'.format(a=stickersRemaining, b=packetsBought))
Assuming no swaps in the first pack, this will say “You have 563 stickers to go, from 1 pack(s)”. Great job! Now we can run our simulations
Simulating the collection process
We have our album, we have unlimited packs, now we simply have to wrap this in a loop to run until we have a full collection. You may need to reset your album and collection variables from the first code window.
while stickersRemaining > 0:
openPacket()
print(packetsBought)
Drum roll please! In our first simulation, we bought 729 packs to finish the album. At 70p each, that gives us a grand total of £510.30. Of course, yours will very likely be different to this! Let’s run this a bunch of times to see what we should expect.
Results
We simulated opening a pack 100,000 times by wrapping it in a for loop. On average, you should expect to spend £550.20 on 786 packets to complete the album.
The luckier ones among you might be closer to the quickest album completion, coming in at 450 packs and £315. At the other end of the scale, the max pack count in the 100,000 simulations was a staggering 2,263… £1,584.10. Yikes.
Check out the overall distribution below with its super long tail.
To keep yourself away from the expensive side of the tail, we might need to collect with a friend or just collect to a set percentage and buy the remaining stickers individually. Let’s try and find a smart place to stop buying packs.
Collecting up to a certain percentage
Of course, nobody should continue collecting to the tune of 2,263 packs. There are two strategies to avoid this, collect with a friend and swap, or stop at a set completion level and purchase the stickers individually.
We can easily check how many packs are required to reach a certain percentage by changing the condition of our previous while loop. We can change the remaining sticker requirement from 0 to a % of the total.
while stickersRemaining > (538 - (538*.1)):
openPacket()
print(packetsBought)
In this example, we are running until remaining stickers goes below 484 – or 10% complete.
If we run this multiple times at each percentage point, we can get an estimation of how many packs we need to reach a certain threshold:
The exponential rise should be expected, as when you need 1 in 568, the odds are incredibly unlikely. Pick your happy point and buy the rest! 85% complete looks like a smart way to avoid continuous disappointment.
I hope this all helps you to understand the sticker market, but most importantly how we can run some simulations with logic and likelihood in Python!
Let us know your thoughts on the article on Twitter, where any shares, mentions or likes are hugely appreciated!
If you really enjoyed the content or found it helpful, consider funding more of it through the ‘Buy me a coffee’ button on the page!
This article is based on our answer to the World Cup 2018 sticker album, which takes a different approach. Our copy of the physical album remains half finished in a box somewhere.