[Math][Python][Bash] Printing reminders picked using lorarithmic scale

Preivously: 1, 2.

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.

(the post first published at 20230225.)


List of my other blog posts.

Subscribe to my news feed

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.