-
-
Save matburnham/b29790039e158ee9de3cb6e65c8ec20c to your computer and use it in GitHub Desktop.
callsigns.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm not convinced the syllables are perfect, and I think the morse 'syllables' are somewhat off.