Skip to content

Instantly share code, notes, and snippets.

@matburnham
Forked from kwirk/callsigns.py
Last active April 15, 2023 10:11
Show Gist options
  • Save matburnham/b29790039e158ee9de3cb6e65c8ec20c to your computer and use it in GitHub Desktop.
Save matburnham/b29790039e158ee9de3cb6e65c8ec20c to your computer and use it in GitHub Desktop.
callsigns.py
import csv
import string
import itertools
import re
def count_morse(callsign):
# Create a regular expression pattern that matches dots and dashes
morse_pattern = re.compile('[.-]+')
# Remove any non-alphabetic and non-Morse characters from the callsign
callsign = re.sub('[^a-zA-Z.-]', '', callsign)
# Convert the callsign to uppercase
callsign = callsign.upper()
# Split the callsign into individual letters
letters = list(callsign)
# Create a list of Morse code representations for each letter
morse = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.'}
# Create a list of Morse code representations for each letter in the callsign
morse_list = [morse.get(letter, '') for letter in letters]
# Join the Morse code representations into a single string
morse_string = ' '.join(morse_list)
# Split the Morse string into individual elements
elements = morse_pattern.findall(morse_string)
# Count the number of syllables in each element
syllable_counts = [len(element) for element in elements]
# Print the number of syllables in each element
#for i in range(len(elements)):
# print(f"{elements[i]}: {syllable_counts[i]} syllable(s)")
# Sum the syllable counts to get the total number of syllables
total_syllables = sum(syllable_counts)
return total_syllables
def count_syllables(callsign):
# Create a regular expression pattern that matches vowels
vowels = re.compile('[AEIOUY]')
# Remove any non-alphabetic characters from the callsign
callsign = re.sub('[^a-zA-Z]', '', callsign)
# Convert the callsign to uppercase
callsign = callsign.upper()
# Split the callsign into individual letters
letters = list(callsign)
# Create a list of phonetic pronunciations for each letter
phonetics = {'A': 'ALFA', 'B': 'BRAVO', 'C': 'CHARLIE', 'D': 'DELTA', 'E': 'ECHO', 'F': 'FOXTROT', 'G': 'GOLF', 'H': 'HOTEL', 'I': 'INDIA', 'J': 'JULIETT', 'K': 'KILO', 'L': 'LIMA', 'M': 'MIKE', 'N': 'NOVEMBER', 'O': 'OSCAR', 'P': 'PAPA', 'Q': 'QUEBEC', 'R': 'ROMEO', 'S': 'SIERRA', 'T': 'TANGO', 'U': 'UNIFORM', 'V': 'VICTOR', 'W': 'WHISKEY', 'X': 'XRAY', 'Y': 'YANKEE', 'Z': 'ZULU'}
# Create a list of phonetic pronunciations for each letter in the callsign
phonetic_list = [phonetics.get(letter, '') for letter in letters]
# Join the phonetic pronunciations into a single string
phonetic_string = ' '.join(phonetic_list)
# Split the phonetic string into individual words
words = phonetic_string.split()
# Count the number of syllables in each word
syllable_counts = [len(vowels.findall(word)) for word in words]
# Print the number of syllables in each word
#for i in range(len(words)):
# print(f"{words[i]}: {syllable_counts[i]} syllable(s)")
# Sum the syllable counts to get the total number of syllables
total_syllables = sum(syllable_counts)
return total_syllables
# Define valid prefixes and suffixes
valid_prefixes = ['M0', 'M1', 'M3', 'M5', 'M6', 'M7', '20', '21', 'G0', 'G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8']
valid_suffixes = [''.join(s) for s in itertools.product(string.ascii_uppercase, repeat=3) if s[0] not in {'Q', 'Z'} and ''.join(s) not in {'ADS', 'AID', 'ASS', 'AUT', 'BIG', 'BIT', 'BOG', 'BOL', 'BOM', 'BUM', 'CFM', 'CNT', 'COC', 'COK', 'COL', 'COW', 'CUM', 'DIC', 'DIE', 'DIK', 'DOR', 'DSC', 'ETA', 'FAG', 'FIC', 'FOC', 'FOF', 'FOO', 'FUC', 'FUK', 'FUX', 'GIT', 'GOD', 'HCQ', 'HIV', 'HOA', 'HON', 'HOR', 'IIR', 'IRA', 'IUD', 'JDX', 'JEW', 'JJJ', 'KKK', 'KOC', 'KOK', 'KTS', 'LIC', 'LIM', 'LOO', 'LPC', 'MIN', 'MOO', 'MSG', 'MSI', 'NIG', 'NIJ', 'NIL', 'NIP', 'NOB', 'OOG', 'PBL', 'PIG', 'PIM', 'PIN', 'PIS', 'POK', 'PON', 'POO', 'POR', 'POT', 'POX', 'PSE', 'RAF', 'RCC', 'REF', 'RID', 'RIM', 'ROD', 'ROG', 'RON', 'RPT', 'RSE', 'SAR', 'SEX', 'SIC', 'SIG', 'SLT', 'SOD', 'SOI', 'SOS', 'SOW', 'SVC', 'SYS', 'TFC', 'TIT', 'TOO', 'TOS', 'TTT', 'TXT', 'VDB', 'VIL', 'VIZ', 'WIP', 'WNG', 'WNK', 'WOG', 'WOP', 'WOR', 'XSC', 'XXX', 'YID'}]
# Generate all possible call signs
all_callsigns = []
for prefix in valid_prefixes:
for suffix in valid_suffixes:
call = prefix + suffix
all_callsigns.append(call)
# Read in allocated call signs from CSV file
allocated_callsigns = set()
with open('allocated_callsigns.csv', 'r', encoding='windows-1252') as f:
reader = csv.reader(f)
for row in reader:
call_sign = row[0].strip()
allocated_callsigns.add(call_sign)
# Find unallocated call signs
unallocated_callsigns = sorted(set(all_callsigns) - allocated_callsigns)
# Write out unallocated call signs to CSV file
with open('unallocated_callsigns.csv', 'w') as f:
for call in unallocated_callsigns:
syllables = count_syllables(call)
morse = count_morse(call)
f.write('"{}",{},{}\n'.format(call, syllables, morse))
@matburnham
Copy link
Author

I'm not convinced the syllables are perfect, and I think the morse 'syllables' are somewhat off.

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