Skip to content
{{ message }}

Instantly share code, notes, and snippets.

# tadeoos/spot.py

Last active Sep 10, 2017
Script for calculating spotify's discover weekly probabilities
 from __future__ import print_function, division import itertools, sys, time # simple factorial function def fact(n, acc=1): return acc if n == 0 else fact(n - 1, n * acc) # binomial coefficient def newton(n, k): return 0 if k > n else fact(n) / (fact(k) * fact(n - k)) # our function! def discover_weekly_prob(n, x, y): if x * y < n: return 0 sigma_sum = sum([((-1)**(i - 1)) * newton(n, i) * (((newton((n - i), y) * fact(y) * fact(n - y)) / (fact(n)))**x) for i in range(1, n - y + 1)]) return 1 - sigma_sum def filter_heads(p, head): # This function flattens a tuple of tuples into list of gotten heads # filter_heads(((1,4,2,3), (3,1,2,4)), 2) => [1,4,3,1] return [y for x in p for y in x[:head]] def brute_prob(n, x, y): # all possible permutations of our initial set permuts = [p for p in itertools.permutations(range(n))] # list of every possible outcome of our experiment. Shrinked to y-long heads. space = [filter_heads(prdct, y) for prdct in itertools.product(permuts, repeat=x)] # the number of outcomes in which we got all elements of our initial set good = sum([1 for outcome in space if len(set(outcome)) == n]) return (good / len(space)) def tests(n=5): for x in range(1, n+1): for h in range(1, n): for t in range(1, 4): w = brute_prob(x, t, h) # if w>0: # print('for n:{} x:{} y:{} prob is {}'.format(x,t,h,w)) assert (abs(w - discover_weekly_prob(x,t,h)) < 0.01) print('--tests passed--') def best_ratio(sngtme=5, hours=7, scale=1, prnt=False, tmlimit=False): TIME_LIMIT = hours*60/sngtme res = [] data_dict = {'x':[], 'y':[], 'ratio':[]} # dict used for creating a scatter plot for x in range(1,31): for y in range(1,31): prob = discover_weekly_prob(30, x, y) filtered_prob = 0 if prob <= 0.5 else prob if tmlimit: if prob == 0 or (x*y > TIME_LIMIT): continue ratio = (30*scale*filtered_prob) / (y * x) res.append((ratio,x,y)) data_dict['x'].append(x) data_dict['y'].append(y) rt_to_add = ratio*2 if ratio!=1 else ratio+0.1 # scaling for scatter plot data_dict['ratio'].append(rt_to_add) res.sort(reverse=True) if prnt: for x in res: print('y: {} x: {} ratio: {:.6}'.format(x,x, x)) return res, data_dict if __name__ == "__main__": # tests() try: assert len(sys.argv)==4 n, x, y = int(sys.argv), int(sys.argv), int(sys.argv) res = discover_weekly_prob(n,x,y) ratio = (30*res) / (y * x) print('With n={}, x={} & y={}\nThe probability of listening to every song is ~{:.0%}\nProbability/time ratio is {:.4}'.format(n,x,y,res,ratio)) except Exception as e: print("Something went wrong...") if len(sys.argv)!=4: print("It looks like you haven't passed three arguments!") elif y>n: print('y cannot be bigger then n!') else: print('Your error is: ', e) print('Correct syntax looks like this: "python spot.py 30 14 5"')

### tadeoos commented Feb 15, 2017 • edited

For context see my post.

## USAGE

You need to have Python installed. Both 2.7+ and 3+ versions are supported.

If you are on mac - don't worry you should have Python 2.7 already installed. Otherwise - read this.

Once you have Python installed, download the above file. Then open Terminal and go to the folder where you saved the file.

Example for mac users:

If you downloaded the file to your "Downloads" folder, you should simply type `cd ~/Downloads` in Terminal and you should be good to go.

Once you're there you just run the script and pass the values for n, x and y by typing for example:

`python spot.py 30 14 6`

this will print the probability for n=30 x=14 and y=6 as well as it's ratio measure.

Have fun! :)

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