I have a list of reminders, TODOs, life goals, GTD items in the David Allen's style, etc. I want to print them when I run Linux shell, in the same manner as the 'fortune' utility does. I can do:
cat reminders.txt | shuf | head -1
But I want to print newest reminder lines more often and oldest -- less often. I want some PRNG function that is 'skewed'. This is my solution.
#!/usr/bin/env python3 import random, math #base=1.2 #base=1.3 base=2 total=30 for x in range(1000000): # sample size r=random.randint(1, int(base**total-1)) y=math.log(r, base) print ("%02d" % int(y))
If I run it...
% python3 1.py | sort | uniq -c 4 11 5 12 7 13 19 14 25 15 57 16 123 17 249 18 462 19 957 20 1873 21 3936 22 7829 23 15637 24 31430 25 62835 26 124932 27 250500 28 499120 29
You see -- a higher number printed as twice as often as a previous number (number minus 1). Because we use binary logarithm (AKA binlog, log2).
We can reduce log base to 1.3, for example:
base=1.3 ... 374 00 387 02 400 04 375 05 742 06 728 07 689 08 1059 09 1504 10 2270 11 2635 12 3297 13 4575 14 5779 15 7578 16 9927 17 13128 18 16940 19 21814 20 28105 21 36322 22 47422 23 62309 24 81244 25 105493 26 136949 27 177545 28 230410 29
Even to 1.2:
base=1.2 ... 4302 00 4271 03 4260 06 4295 07 4323 08 4251 09 4341 10 4291 11 8396 12 8377 13 12586 14 12588 15 17004 16 16932 17 21228 18 29644 19 34327 20 38331 21 46737 22 55134 23 67560 24 80613 25 97433 26 113964 27 139726 28 165086 29
This is better for my purpose. So here is a Python script that returns a random value skewed to higher values:
#!/usr/bin/env python3 import random, math, sys base=1.2 #base=1.3 #base=2 total=int(sys.argv[1]) r=random.randint(1, int(base**total-1)) y=math.log(r, base) result=int(y) #return result in [1..total] range #print ("result", result+1) exit(result+1)
Now the final script. It prints a random text file from a directory, but prints newest files more often and older files less often:
#!/usr/bin/env bash p=$HOME/reminders total=$(ls -1tr $p | wc -l) #echo $total ./my_PRNG.py $total random=$? #echo $random # https://stackoverflow.com/questions/6022384/bash-tool-to-get-nth-line-from-a-file fname=$(ls -1tr $p | tail -n+$random | head -1) echo "=" $fname cat "$p/$fname"
ls -1tr is used to get a list of files in directory sorted by timestamp.
I run this script instead of 'fortune', when bash (or zsh) shell starts.
Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.