# Inequity Fini

There’s always a reasonable and intelligent way to approach any problem.

Then there’s the way I usually choose.

Yep. Trust me to do it the unreasonable and stoopid way.

The question I was asking in my previous blog post on this topic was pretty simple: *Will even a small amount of systemic unfairness have a measurable and significant impact on who wins and who loses in our little, random game?*

*Here’s me, being stoopid*: I decided to calculate the average *ID Number* of the winning cohort, to see how that was affected by injecting some unfairness into the game (i.e. 1% of the population refusing to give a pebble to a chunk of folks representing 10% of the overall population).

My method worked, but it finally dawned on me that I was taking a really *round about* way to look for my answer. I had the data - why not just look at the raw number of individuals in the affected population that actually made it into the winning cohort.

*Doh.*

Here’s the code to do just that. If it’s gibberish to you, feel free to ignore it… I’ll ‘splain below:

```
#!/usr/bin/env python3
import random
from datetime import datetime
# choose a random seed
random.seed(datetime.now())
people = {}
averages = []
winners = []
# we begin with 1000 people, each with 100 pebbles
for i in range(1000):
people[i] = 100
# let's play the game 100 times...
for k in range(100):
# every second, each individual picks a random person and gives them one pebble
for i in range(3600 * 8):
for p in range(len(people)):
r = p
while(r == p):
if p >= len(people) - (len(people) * 0.001):
r = random.randint(100,len(people) - 1)
else:
r = random.randint(0,len(people) - 1)
if people[p] > 0:
people[p] -= 1
people[r] += 1
# let's pull out the values so we can easily sort them...
values = []
for p in range(len(people)):
values.append(people[p])
# sort the results, lowest to highest
values.sort()
count = 0
total = 0
for p in range(100):
if people[p] >= 100:
count += 1
for p in range(len(people)):
if people[p] >= 100:
total += 1
print('Run #%3.3i count: %i winners: %i' % ((k + 1), count, total))
averages.append(count)
winners.append(total)
# now, let's do a little statistical math...
avg = sum(averages) / len(averages)
var = sum((x-avg)**2 for x in averages) / len(averages)
std = var**0.5
print('Overall (affected group): average:%f variance: %f std_deviation: %f' % (avg, var, std))
avg = sum(winners) / len(winners)
var = sum((x-avg)**2 for x in winners) / len(winners)
std = var**0.5
print('Overall (winners): average:%f variance: %f std_deviation: %f' % (avg, var, std))
```

So, once again, I’m playing the game 100 times. At the end of each game, I’m counting the number of folks in the affected group (the 10% of players with an ID Number in the range 0-99) that are *winners* (defined as having 100 or more pebbles at the end of the game). I’m also counting the overall number of *winners*.

In the original, completely fair version of the game, one would expect that our affected group - which makes up 10% of the overall population - would, on average, make up 10% of the winners. And yep, that’s what we find:

```
Overall (affected group): average:36.770000 variance: 24.357100 std_deviation: 4.935291
Overall (winners): average:367.810000 variance: 83.853900 std_deviation: 9.157178
```

But what happens with our *1% systemic unfairness* paradigm?

```
Overall (affected group): average:4.470000 variance: 4.169100 std_deviation: 2.041837
Overall (winners): average:358.460000 variance: 97.348400 std_deviation: 9.866529
```

The affected group goes from making up 10.00% of the *winners* to only making up 1.25%, because * only 1%* of the overall population refuses to allow them a fair chance in the game.

By now, you really should know what comes next…

Let’s go a little further. What if only 0.1% of the players (only * one* person in our population of 1000 players) decides that they won’t give a pebble to a specific group comprising 10% of the population? Surely, systemic unfairness on such a small scale can’t have a measurable impact…

```
Overall (affected group): average:30.290000 variance: 23.885900 std_deviation: 4.887320
Overall (winners): average:369.440000 variance: 89.066400 std_deviation: 9.437500
```

With only 0.1% of the population behaving unfairly, the marginalized group now makes up, on average, only 8.20% of the winning population (when, in a completely fair game, they made up 10.00%).

Apparently, even the smallest amount of built-in unfairness can have a profound impact.

-TL

Tom Liston

Owner, Principal Consultant

Bad Wolf Security, LLC

Mastodon: @tliston@infosec.exchange

Twitter: @tliston

April 28, 2021