Editor

Acronym Generator in Python

Beginner · Text and words · about 25 minutes to build · 92 lines

Type a phrase and get its acronym, with dots and without small words, plus a guess at whether people say it as a word or as letters.

The program

Press Run and answer its questions in the box that appears under the code.

acronym_generator.py
"""Acronym generator: turn "Portable Network Graphics" into PNG."""
import re
# Small words that acronyms usually leave out: "Bureau of Investigation" -> BI.
SMALL_WORDS = {"a", "an", "and", "the", "of", "for", "to", "in", "on", "at",
"by", "or", "with"}
# Letters and digits, maybe with an apostrophe. A hyphen splits words.
WORD_PATTERN = r"[A-Za-z0-9]+(?:'[A-Za-z]+)?"
# --- Building the acronym ---
def split_words(phrase):
"""Split a phrase into words at spaces, hyphens and punctuation."""
return re.findall(WORD_PATTERN, phrase)
def letter_flags(words, skip_small=True):
"""Return True for each word that gives a letter to the acronym."""
flags = [not skip_small or word.lower() not in SMALL_WORDS
for word in words]
if not any(flags): # the phrase was only small words, like "of the"
return [True] * len(words)
return flags
def make_acronym(words, flags):
"""Join the first letters of the words whose flag is True."""
return "".join(word[0].upper() for word, flag in zip(words, flags) if flag)
def show_letters(words, flags):
"""Show where each letter comes from: [N]ational [A]eronautics and ..."""
parts = []
for word, flag in zip(words, flags):
if flag:
parts.append(f"[{word[0].upper()}]{word[1:]}")
else:
parts.append(word.lower())
return " ".join(parts)
# --- Saying it out loud ---
def sounds_like_word(acronym):
"""Guess if an acronym is said as a word (NASA) or as letters (FBI)."""
if not acronym.isalpha() or len(acronym) < 3:
return False
if re.search(r"[B-DF-HJ-NP-TV-Z]{3}", acronym):
return False # three consonants in a row, like HTML, are hard to say
vowels = sum(1 for letter in acronym if letter in "AEIOU")
shape = re.fullmatch(r"[^AEIOU][AEIOU][^AEIOU]", acronym) # like GIF
return vowels >= 2 or shape is not None
# --- Talking to the user ---
def report(phrase):
"""Print the acronym of a phrase in a few useful forms."""
words = split_words(phrase)
if not words:
print("There are no words in that phrase.")
return
flags = letter_flags(words)
acronym = make_acronym(words, flags)
every_word = make_acronym(words, letter_flags(words, skip_small=False))
print(f" Letters from: {show_letters(words, flags)}")
print(f" Acronym: {acronym}")
print(f" With dots: {'.'.join(acronym)}.")
if sounds_like_word(acronym):
print(" Spoken as: one word")
else:
print(f" Spoken as: letters, {'-'.join(acronym)}")
if every_word != acronym:
print(f" Every word: {every_word}")
def main():
"""Make acronyms until the user presses Enter on an empty line."""
print("Acronym generator")
print("Small words such as 'of', 'and' and 'the' are left out.")
while True:
phrase = input("\nPhrase (or press Enter to quit): ").strip()
if not phrase:
print("Goodbye.")
break
report(phrase)
if __name__ == "__main__":
main()

Open it in the full editor to save it, share it and keep building.

Sample run

What the program printed, and what was typed (in yellow).

Acronym generator
Small words such as 'of', 'and' and 'the' are left out.

Phrase (or press Enter to quit): National Aeronautics and Space Administration
  Letters from:  [N]ational [A]eronautics and [S]pace [A]dministration
  Acronym:       NASA
  With dots:     N.A.S.A.
  Spoken as:     one word
  Every word:    NAASA

Phrase (or press Enter to quit): self-contained underwater breathing apparatus
  Letters from:  [S]elf [C]ontained [U]nderwater [B]reathing [A]pparatus
  Acronym:       SCUBA
  With dots:     S.C.U.B.A.
  Spoken as:     one word

Phrase (or press Enter to quit): Federal Bureau of Investigation
  Letters from:  [F]ederal [B]ureau of [I]nvestigation
  Acronym:       FBI
  With dots:     F.B.I.
  Spoken as:     letters, F-B-I
  Every word:    FBOI

Phrase (or press Enter to quit): !!!
There are no words in that phrase.

Phrase (or press Enter to quit): as soon as possible
  Letters from:  [A]s [S]oon [A]s [P]ossible
  Acronym:       ASAP
  With dots:     A.S.A.P.
  Spoken as:     one word

Phrase (or press Enter to quit): 
Goodbye.

How it is built

1. Splitting the phrase

re.findall() returns every run of letters and digits, so hyphens and punctuation split words: Self-Contained gives two letters, S and C.

def split_words(phrase):
    """Split a phrase into words at spaces, hyphens and punctuation."""
    return re.findall(WORD_PATTERN, phrase)

2. Which words count

Each word gets True or False, and small words like of and and get False. If the phrase is made only of small words, every word counts, so the acronym is never empty.

def letter_flags(words, skip_small=True):
    """Return True for each word that gives a letter to the acronym."""
    flags = [not skip_small or word.lower() not in SMALL_WORDS
             for word in words]
    if not any(flags):  # the phrase was only small words, like "of the"
        return [True] * len(words)
    return flags

3. Building the acronym

zip() walks the words and their flags together, and the first letter of each word with a True flag is upper-cased and joined.

def make_acronym(words, flags):
    """Join the first letters of the words whose flag is True."""
    return "".join(word[0].upper() for word, flag in zip(words, flags) if flag)

4. A word or letters

A rule of thumb: an acronym with two vowels (NASA) or a consonant, vowel, consonant shape (GIF) can be said as a word, while three consonants in a row (HTML) cannot. English has exceptions, so it is only a guess.

def sounds_like_word(acronym):
    """Guess if an acronym is said as a word (NASA) or as letters (FBI)."""
    if not acronym.isalpha() or len(acronym) < 3:
        return False
    if re.search(r"[B-DF-HJ-NP-TV-Z]{3}", acronym):
        return False  # three consonants in a row, like HTML, are hard to say
    vowels = sum(1 for letter in acronym if letter in "AEIOU")
    shape = re.fullmatch(r"[^AEIOU][AEIOU][^AEIOU]", acronym)  # like GIF
    return vowels >= 2 or shape is not None

5. The report

The Every word line is printed only when it differs from the acronym, which shows the reader what skipping small words changed.

def report(phrase):
    """Print the acronym of a phrase in a few useful forms."""
    words = split_words(phrase)
    if not words:
        print("There are no words in that phrase.")
        return
    flags = letter_flags(words)
    acronym = make_acronym(words, flags)
    every_word = make_acronym(words, letter_flags(words, skip_small=False))
    print(f"  Letters from:  {show_letters(words, flags)}")
    print(f"  Acronym:       {acronym}")
    print(f"  With dots:     {'.'.join(acronym)}.")
    if sounds_like_word(acronym):
        print("  Spoken as:     one word")
    else:
        print(f"  Spoken as:     letters, {'-'.join(acronym)}")
    if every_word != acronym:
        print(f"  Every word:    {every_word}")

Make it bigger

  • Let the user choose which small words to skip.
  • Make a backronym: for a word like CODE, pick a random word starting with each letter from a list.
  • Keep a dictionary of known acronyms and show the full form when the user types one.
  • Add a quiz that shows a phrase and asks for its acronym.

What it practises