Skip to content

Instantly share code, notes, and snippets.

@ckuhl
Last active January 31, 2018 03:07
Show Gist options
  • Save ckuhl/5deff586dc07db6272b918cab83b4bee to your computer and use it in GitHub Desktop.
Save ckuhl/5deff586dc07db6272b918cab83b4bee to your computer and use it in GitHub Desktop.
Generate an ASCII punchcard from a series of timestamps
#!/usr/bin/env python3
'''
punchcard - generate a punchcard from a series of timestamps
Example:
$ git --no-pager log | punchcard
╔═════╦════════════════════════════════════════════════════════════════════════╗
║ Sun ║ ║
║ Mon ║ o . ║
║ Tue ║ . . .║
║ Wed ║ * o * . . . . . . ║
║ Thu ║ . 0 * ║
║ Fri ║ . . * * . . . . ║
║ Sat ║ . * . . ║
╠═════╬════════════════════════════════════════════════════════════════════════╣
║ ║ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23║
╚═════╩════════════════════════════════════════════════════════════════════════╝
Optional arguments:
-h, --help show this help message and exit
--version print version and exit
--week-start WEEK_START
specify the first day of the week
<Sun|Mon|Tue|...|Sat>
--colour, --color toggle optional heatmap
'''
import argparse
import sys
# metadata
__author__ = 'Christian Kuhl'
__licence__ = 'GPLv3'
__version__ = (1, 0, 0)
# take input
parser = argparse.ArgumentParser(
prog='punchcard',
description='produce an ASCII punchcard from datestamped logs')
parser.add_argument(
'--version',
action='store_true',
help='print version and exit')
parser.add_argument(
'--week-start',
action='store',
default='Sun',
dest='week_start',
help='specify the first day of the week <Sun|Mon|Tue|...|Sat>')
parser.add_argument(
'--colour', '--color',
action='store_true',
help='toggle optional heatmap')
args = parser.parse_args()
# handle version request
if args.version:
print('punchcard {}.{}.{}'.format(*__version__))
sys.exit(0)
# set up global vars
hours = ['%02d' % x for x in range(0, 24)]
days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
if args.week_start in days:
if args.week_start != 'Sun':
ws = days.index(args.week_start)
days = days[ws:] + days[:ws]
else:
print('ERROR: %s not a valid day of the week' % args.week_start,
file=sys.stderr)
sys.exit(1)
occur = {(x, y): 0 for x in days for y in hours}
# main operation functions
def print_ascii(value):
if value >= 1: # should be at most == 1
print(' 0', end='')
elif value >= 0.80:
print(' 8', end='')
elif value >= 0.60:
print(' O', end='')
elif value >= 0.40:
print(' o', end='')
elif value >= 0.20:
print(' *', end='')
elif value:
print(' .', end='')
else:
print(' ', end='')
def print_colour(value):
'''
Print a given colour and space
'''
BASE = '\033[48;05;'
BASE_END = ';m'
END_COL = '\033[0m'
start = 232
end = 255
c = str(int((start - end) * value) + end)
print(BASE + c + BASE_END + ' ' + END_COL, end='')
def draw_card(occur):
'''
Draw the punchcard
'''
most = 0
for k in occur:
if occur[k] > most:
most = occur[k]
print('╔', '═' * 5, '╦', '═' * (3 * 24), '╗', sep='')
for d in days:
print('║', d, '║', end='')
for h in hours:
if args.colour:
print_colour(occur[(d, h)] / most)
else:
print_ascii(occur[(d, h)] / most)
print('║')
print('╠', '═' * 5, '╬', '═' * (3 * 24), '╣', sep='')
print('║', ' ' * 5 , '║', sep='', end='')
for h in hours:
print(' ', h, sep='', end='')
print('║')
print('╚', '═' * 5, '╩', '═' * 72, '╝', sep='')
sys.exit(0)
def read_input():
'''
Read in from stdin and create occurence dict
'''
log = sys.stdin.read()
for line in log.split('\n'):
if 'Date:' in line:
ts = line.split()
occur[(ts[1], ts[4].split(':')[0])] += 1
return occur
def main():
'''
Run script components
'''
draw_card(read_input())
sys.exit(0)
# run the script
main()
@ckuhl
Copy link
Author

ckuhl commented Nov 4, 2017

Example of git --no-pager log | punchcard --colour:

image

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