Jan-18-2018, 03:56 PM
I created this script for myself which I thought I would share for those interested in learning or improving their Morse Code skills. I have not included all possible tests, but if you follow the menu items, 1 than 2 than 3, you should be o.k. The script will create a group of 5 random characters per word depending on the file type selected. The number of 'words' is determined by line 45, in this case it is set for 10 words, though for myself, I set it for 500 or (range(2500)).
The 'Words per minute' (wpm) are based on the formula from the ARRL (American Radio Relay League) site located here:
http://www.arrl.org/files/file/Technology/x9004008.pdf.
I suggest not going above 70 wpm because, at least for my sound system, it becomes to distorted.
As for the frequency, I would suggest starting with 400 and adjusting from there to suit your tastes. This value must be given in Hertz.
The file 'code_file.txt' will be created in the working directory.
One final note, although I've included all characters in the standard Morse Code, there is one that I had to skip and that is the single 'close quote' or back slant quote. There is no equivalent on the keyboard, so I tried to use the Unicode equivalent, but this raises an error I can't figure out how to correct (see line 98).
EDIT: The error has been corrected in the included code posted here
Lastly, if you don't want to see the answer printed on screen, comment out line 168.
As always any comments, critisisms, improvements are appreciated.
Enjoy.
The 'Words per minute' (wpm) are based on the formula from the ARRL (American Radio Relay League) site located here:
http://www.arrl.org/files/file/Technology/x9004008.pdf.
I suggest not going above 70 wpm because, at least for my sound system, it becomes to distorted.
As for the frequency, I would suggest starting with 400 and adjusting from there to suit your tastes. This value must be given in Hertz.
The file 'code_file.txt' will be created in the working directory.
One final note, although I've included all characters in the standard Morse Code, there is one that I had to skip and that is the single 'close quote' or back slant quote. There is no equivalent on the keyboard, so I tried to use the Unicode equivalent, but this raises an error I can't figure out how to correct (see line 98).
EDIT: The error has been corrected in the included code posted here
Lastly, if you don't want to see the answer printed on screen, comment out line 168.
As always any comments, critisisms, improvements are appreciated.
Enjoy.
#! /usr/bin/env/ python3 import os import random import string import time from itertools import zip_longest from pysine import sine def words(words_per_minute): """ Calculates the proper duration and spacing based on the selected words per minute """ # For 18 wpm and greater, use: if words_per_minute >= 18: unit = 1.2 / words_per_minute dit = round(unit, 2) dah = round(unit * 3, 2) elem_space = round(unit, 2) char_space = round(unit * 3, 2) word_space = round(unit * 7, 2) wpm_settings = (dit, dah, elem_space, char_space, word_space) # For wpm less than 18, use: else: unit = 1.2 / 18 dit = round(unit, 2) dah = round(unit * 3, 2) elem_space = round(unit, 2) char_speed = 18 char_space = round(unit * 3, 2) word_space = round(unit * 7, 2) delay = ((60 * char_speed) - (37.2 * words_per_minute)) / (char_speed * words_per_minute) char_delay = 3 * delay / 19 word_delay = 7 * delay / 19 char_space += char_delay word_space += word_delay wpm_settings = (dit, dah, elem_space, round(char_space, 2), round(word_space, 2)) return wpm_settings def grouper(iterable, n=5, fillvalue=None): """ Creates 5 (n) letter 'words' from single string of characters""" big_iterable = [] for c in range(50): # Set the number of groups; 2500 characters = 500 groups. Characters must be divisible by 5 big_iterable.append(random.choice(iterable)) args = [iter(big_iterable)] * n return zip_longest(*args, fillvalue=fillvalue) def settings(): """ This function generates the settings for words-per-minute (wpm), play back frequency and character set """ print("Here you will be able to create settings for:") print("\t** Words per minute\n\t** Frequency of play back\n\t** Type of characters\n") setting = [] while True: try: wrds_p_min = int(input("How many words per minute would you like? (whole numbers only between 5 and 70): ")) if wrds_p_min < 5 or wrds_p_min > 70: print("Must be a positive whole number greater than or equal than 5 and less than or equal to 70.") continue else: break except ValueError as e: print("Must be a positive whole number greater than 0 and less than or equal to 70.", e) continue wpm = words(wrds_p_min) # Get the appropriate values based on words per minute setting.append(wpm) while True: try: freq = int(input("What play back frequency would you like? (whole numbers only): ")) if freq < 400: print("Must be a positive whole number greater than or equal to 400.") continue else: break except ValueError as e: print("Must be a positive whole number greater than or equal to 400.", e) continue setting.append(freq) while True: try: print("1 Alpha\n2 Numeric\n3 Punctuation\n4 Alpha and Numeric\n5 Alpha and Punctuation\n6 Numeric and " "Punctuation\n7 All") char_set = int(input("Which character set(s) would you like? (select one): ")) if char_set < 1 or char_set > 7: print("Must be a number 1 through 7") continue else: break except ValueError as e: print("Must be a positive whole number greater than or equal to 1.", e) continue punc = '.,?`!/()&:;=+-_$@\u00b4' # added close quote '\u00b4' if char_set == 1: char_set = string.ascii_lowercase elif char_set == 2: char_set = string.digits elif char_set == 3: char_set = punc elif char_set == 4: char_set = string.ascii_lowercase + string.digits elif char_set == 5: char_set = string.ascii_lowercase + punc elif char_set == 6: char_set = string.digits + punc elif char_set == 7: char_set = string.ascii_lowercase + string.digits + punc setting.append(char_set) print("Settings have been saved.") time.sleep(3) return setting def write_file(setting): """ Creates a text file of selected character set(s) """ groups = grouper(setting) content = list(groups) with open('code_file.txt', 'w', encoding='utf-8') as file: total = 0 w = 0 while total < len(content): for g in content[w]: file.write(g) w += 1 file.write(' ') total += 1 print('File code_file.txt has been created in the current working directory.') time.sleep(3) return def play_file(wpm, freq): """ Play back the file code_file.txt """ dit = wpm[0] dah = wpm[1] elem_space = wpm[2] char_space = wpm[3] word_space = wpm[4] 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': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', '.': '.-.-.-', ',': '--..--', '?': '..--..', '`': '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '$': '...-..-', '@': '.--.-.', '\u00b4': '.-..-.'} print('Commencing in 5 seconds ...') time.sleep(5) with open('code_file.txt', 'r', encoding='utf-8') as file: for line in file: for word in line.split(): for character in word: print('Character: ', character.capitalize()) # REMOVE IF YOU DON"T WANT TO CHEAT :-D letter = morse[character] for element in letter: if element == '.': sine(freq, dit) sine(0, elem_space) elif element == '-': sine(freq, dah) sine(0, elem_space) sine(0, char_space) sine(0, word_space) print("\nEnd of file reached\n") exit_prog() def exit_prog(): """ Function to exit the program """ print("You are now exiting the program ...") def main_mnu(): while True: os.system('cls' if os.name == 'nt' else 'clear') print('This is the Main Menu. Please make a selection.') print('\t1) Settings') print('\t2) Create Code File') print('\t3) Play Code') print('\n\t4) Exit') choice = input('\nEnter choice: ') try: if choice == '1': setting_list = list(settings()) continue if choice == '2': if not setting_list != []: print("You need to create the settings first, please enter '1' at the prompt") continue else: write_file(setting_list[2]) continue if choice == '3': exists = os.path.exists('code_file.txt') if exists: play_file(setting_list[0], setting_list[1]) break else: print("The file 'code_file.txt' does not exist") continue if choice == '4': exit_prog() break except KeyError as err: print('Not an option, try again.', err) if __name__ == '__main__': main_mnu()