Skip to content

Instantly share code, notes, and snippets.

@sztanko
Last active December 5, 2021 11:10
Show Gist options
  • Save sztanko/d9ae1b4e7143cc77b05fbf52a0e76261 to your computer and use it in GitHub Desktop.
Save sztanko/d9ae1b4e7143cc77b05fbf52a0e76261 to your computer and use it in GitHub Desktop.
Role of luck in top selection

This was inspired by the video called "Is Success Luck or Hard Work?" by Veritasium https://www.youtube.com/watch?v=3LopI4YeC4I There he runs simulation of selecting 11 austronauts out of 18,300. If we say there is up to 5% luck contribution in their total score, then how strong the weakest person out of 11 should be?

My simulation shows that the weakest candidate still should be at least in the top 120 candidates, and out of those 11 initially selected 9 got there because of sheer luck.

Here is the code:

from typing import Generator, Tuple
import random
import typer


def generate_random_scores(num: int, random_factor: int) -> Generator[Tuple[float, float], None, None]:
    for i in range(0, num):
        skill_score = random.uniform(0, 100 - random_factor)
        luck_score = random.uniform(0, random_factor)
        t = (skill_score, luck_score)
        yield t


def main(num: int, random_factor: int, top: int):
    candidates = list(generate_random_scores(num, random_factor))
    top_n_combined = sorted(candidates, key=lambda t: t[0] + t[1], reverse=True)[0:top]
    top_n_skill = sorted(candidates, key=lambda t: t[0], reverse=True)[0:top]
    min_skill = min([t[0] for t in top_n_skill])
    min_luck = min([t[1] for t in top_n_combined])
    min_top_skill = min([t[0] for t in top_n_combined])
    canidates_above_min_top_skill = len(list(filter(lambda t: t[0]>=min_top_skill, candidates)))
    lucky_count = 0
    for t in top_n_combined:
        if t[0] >= min_skill:
            top_skill = "*"
        else:
            top_skill = ""
            lucky_count += 1
        total_score = t[0] + t[1]
        print(f"{t[0]:.2f}{top_skill}\t{t[1]:.2f}\t{total_score:.2f}")
    print("=====================")
    print(f"Min luck score: {min_luck:.2f} ({(min_luck*100/random_factor):.2f}%)")
    print(f"Min skill score: {min_skill:.2f} ({(min_skill*100/(100-random_factor)):.2f}%)")
    print(f"Min skill score in combined top: {min_top_skill:.2f} ({(min_top_skill*100/(100-random_factor)):.2f}%)")
    print(f"Lucky candidates: {lucky_count}")
    print(f"Count of candidates stronger then the weakest lucky_candidate: {canidates_above_min_top_skill}")


if __name__ == "__main__":
    typer.run(main)

If luck contributes only to 5% of your performance, and only 10 out of 1000 candidates will be selected, then 4 out of top 10 candidates will get there because of luck. They still will be in the top 28 strongest performers among those 1000

With top 10 out of 100,000 candidates, you still have to be in top 261 to have a chance to be selected in top 10. And all top 10 candidates are not the strongest top 10.

But, if we need to chose top 10 among 100 candidates, then luck will not be that important (you still need to be in top 12)

So I guess the morale is, if you don't try hard, luck won't help. But you also need luck to succeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment