Skip to content

Instantly share code, notes, and snippets.

@alexwlchan
Last active August 29, 2015 14:11
Show Gist options
  • Save alexwlchan/b4554a6703e1be914a6b to your computer and use it in GitHub Desktop.
Save alexwlchan/b4554a6703e1be914a6b to your computer and use it in GitHub Desktop.
A command-line tool for managing acronyms
#!/usr/bin/python
"""A script for managing a dictionary of acronyms. For context, see the
associated blog post: http://alexwlchan.net/2014/12/acronyms/
Invoke with the -h or --help flag for a usage message:
$ ./acronyms.py -h
Invoke with the -a or --add flag to add an acronym:
$ ./acronyms.py -a NASA
$ ./acronyms.py --add IETF
You will then be prompted to fill in some details.
Invoke with the -l or --lookup flag to look up an existing acronym:
$ ./acronyms.py -l CLI
$ ./acronyms.py --lookup GUI
"""
import argparse
import json
import os
import re
import sys
import textwrap
ACRONYMS_FILE = 'acronyms.json'
#-----------------------------------------------------------------------------
# Set up the options for argparse
#-----------------------------------------------------------------------------
parser = argparse.ArgumentParser(description="A script for looking up acronyms.")
parser.add_argument('-a', '--add', dest='new_acronym',
help="add a new acronym")
parser.add_argument('-l', '--lookup', metavar='ACRONYM',
help="look up an existing acronym")
args = parser.parse_args()
#-----------------------------------------------------------------------------
# Utility functions
#-----------------------------------------------------------------------------
def read_acronyms_file(acronym_file=ACRONYMS_FILE):
"""Get a list of existing acronyms from a JSON file, or create the file if
it does not exist.
"""
if not os.path.isfile(acronym_file):
with open(acronym_file, 'w') as outfile:
outfile.write('[]')
with open(acronym_file, 'r') as json_data:
data = json.load(json_data)
return data
def write_acronyms_file(data, acronym_file=ACRONYMS_FILE):
"""Write the list of acronyms to a JSON file."""
with open(acronym_file, 'w') as outfile:
outfile.write(json.dumps(data))
def get_new_acronym(acronym=None):
"""Ask the user for information about the new acronym."""
if acronym is None:
acronym = raw_input("What is the new acronym?\n")
else:
print("Creating an entry for acronym \"%s\"." % acronym)
expansion = raw_input("\nWhat does %s stand for?\n" % acronym)
description = raw_input("\nAnd what does this mean? (optional)\n")
new_acronym = {
"acronym": acronym,
"expansion": expansion
}
if description:
new_acronym["description"] = description
return new_acronym
def add_new_acronym(acronym):
"""Ask the user for the new acronym, and write it to file."""
new_acronym = get_new_acronym(acronym)
data = read_acronyms_file()
data.append(new_acronym)
write_acronyms_file(data)
class color:
BOLD = '\033[1m'
END = '\033[0m'
def print_acronym(entry):
"""Pretty print an acronym to the console."""
print(color.BOLD + entry["acronym"] + ": " + entry["expansion"] + color.END)
if "description" in entry:
wrapper = textwrap.TextWrapper(initial_indent=" " * 4, width=70,
subsequent_indent=" " * 4)
print(wrapper.fill(entry["description"]))
print("")
#-----------------------------------------------------------------------------
# Mainline program function
#-----------------------------------------------------------------------------
def main():
# If no arguments are supplied, print the help message and exit
if len(sys.argv) == 1:
parser.print_help()
sys.exit(0)
# If the --add flag is supplied, create a new acronym and write it out to
# the database
if args.new_acronym is not None:
add_new_acronym(args.new_acronym)
# If we're looking up an existing acronym, do a search on the list of
# existing acronyms
if args.lookup is not None:
data = read_acronyms_file()
matches = []
for entry in data:
# We include both a perfect match, and a match on just the letters
# so 'abc' matches 'A-BC'. It doesn't coerce Unicode chars to their
# ASCII counterparts, but I also don't use any acronyms that include
# accented characters.
possible_matches = [
entry["acronym"].lower(),
re.sub('[^a-z]', '', entry["acronym"].lower())
]
if args.lookup.lower() in possible_matches:
matches.append(entry)
for entry in sorted(matches, key=lambda entry: entry["expansion"]):
print_acronym(entry)
# If we haven't found the acronym, offer to create it
if not matches:
create = raw_input("I didn't find that acronym. "
"Would you like to create it? [y/N]\n")
if create.lower() in ['y', 'yes']:
add_new_acronym(args.lookup)
else:
print("Okay, never mind.")
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment