Last active
November 7, 2018 01:43
-
-
Save ConorOBrien-Foxx/ac1a55a6f1982d533beb38d6e9c593dd to your computer and use it in GitHub Desktop.
morse code in powershell
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
Symbol | Sequence | |
---|---|---|
A | 01 | |
B | 1000 | |
C | 1010 | |
D | 100 | |
E | 0 | |
F | 0010 | |
G | 110 | |
H | 0000 | |
I | 00 | |
J | 0111 | |
K | 101 | |
L | 0100 | |
M | 11 | |
N | 10 | |
O | 111 | |
P | 0110 | |
Q | 1101 | |
R | 010 | |
S | 000 | |
T | 1 | |
U | 001 | |
V | 0001 | |
W | 011 | |
X | 1001 | |
Y | 1011 | |
Z | 1100 |
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
function ShowHelp() { | |
echo "Insufficient arguments passed." | |
echo "" | |
echo "Usage: " | |
echo " .\morse.ps1 ""words"" [path\to\table.csv]" | |
echo "" | |
echo "``morse`` takes a series of words as input through the first command line" | |
echo "parameter and causes the Caps Lock key to blink accordingly." | |
echo "" | |
echo " words the words to display" | |
echo " [path\to\table.csv] uses the referenced file as the morse table." | |
echo " default: $DefaultCsvPath" | |
echo "" | |
echo "Examples:" | |
echo " .\morse.ps1 ""SOS send help""" | |
echo " .\morse.ps1 ""wot is this???"" .\punct.csv" | |
} | |
# Definitions: | |
# - A `symbol` is one of $LongBlinkSymbol or $ShortBlinkSymbol | |
# - A `sequence` is a series of concatenated symbols | |
# - A `letter` is any character | |
# - A `letter` is valid if and only if it occurs in MorseTable | |
# - A `word` is a series of concatenated letters | |
# - A `sentence` is a series of `words` joined by whitespace characters | |
$TimeUnit = 200 # in milliseconds | |
$ShortBlinkDuration = 1 * $TimeUnit | |
$LongBlinkDuration = 3 * $TimeUnit | |
$BetweenSymbolsDuration = 1 * $TimeUnit | |
$BetweenLettersDuration = 3 * $TimeUnit | |
$BetweenWordsDuration = 7 * $TimeUnit | |
$LongBlinkSymbol = '1' | |
$ShortBlinkSymbol = '0' | |
$DefaultCsvPath = ".\morse.csv" | |
# strings which match this regex are valid symbol strings | |
$ValidSymbolRegex = "^($( | |
[Regex]::Escape($LongBlinkSymbol) | |
)|$( | |
[Regex]::Escape($ShortBlinkSymbol) | |
))*$" | |
# error types | |
$EmptyTableError = 1 | |
$MalformedHeaderError = 2 | |
$InvalidSequenceError = 3 | |
$InvalidCharacterError = 4 | |
$NoArgumentsPassedError = 5 | |
# WScript interface for sending keys | |
$wshell = New-Object -ComObject wscript.shell | |
function SendKeys([string] $keys) { | |
$wshell.SendKeys($keys) | |
} | |
function CapsLock() { | |
SendKeys("{CAPSLOCK}") | |
} | |
function IsValidSequence([string] $code) { | |
$code -match $ValidSymbolRegex | |
} | |
# NOTE: MorseTable is indexed by characters, **not** singleton strings | |
$MorseTable = @{} | |
function LoadMorseTable([string] $pathToCsv) { | |
$csv = Import-Csv "$pathToCsv" | |
# ensure non-empty csv | |
if($csv.length -eq 0) { | |
Write-Error "Table read was empty" | |
exit $EmptyTableError | |
} | |
# ensure proper column naming | |
$head = $csv[0] # sample csv; we know the first element must exist | |
if($head.Symbol -eq $null -or $head.Sequence -eq $null) { | |
Write-Error "Malformed table header" | |
exit $MalformedHeaderError | |
} | |
# update $MorseTable | |
$csv | foreach { | |
# ensure proper formatting of Sequence | |
if(-not (IsValidSequence($_.Sequence))) { | |
Write-Error "Entry '$($_.Symbol)' has an invalid sequence '$($_.Sequence)'" | |
exit $InvalidSequenceError | |
} | |
$MorseTable[[char] $_.Symbol] = $_.Sequence | |
} | |
} | |
# given sequence of $LongBlinkSymbol and $ShortBlinkSymbol, blinks the light | |
# for the appropriate duration | |
function BlinkSequence([string] $code) { | |
for($i = 0; $i -lt $code.length; $i++) { | |
$char = $code[$i] | |
CapsLock | |
if($char -eq $LongBlinkSymbol) { | |
Sleep -m $LongBlinkDuration | |
} | |
else { | |
Sleep -m $ShortBlinkDuration | |
} | |
CapsLock | |
# do not wait after the last symbol | |
if($i + 1 -ne $code.length) { | |
Sleep -m $BetweenSymbolsDuration | |
} | |
} | |
} | |
function GetSequence([char] $char) { | |
return $MorseTable[$char] | |
} | |
function BlinkWord([string] $word) { | |
for($i = 0; $i -lt $word.length; $i++) { | |
$char = $word[$i] | |
$code = GetSequence($char) | |
BlinkSequence($code) | |
# do not wait after the last letter | |
if($i + 1 -ne $word.length) { | |
Sleep -m $BetweenLettersDuration | |
} | |
} | |
} | |
function BlinkSentence([string] $sentence) { | |
$words = $sentence.ToUpper().split() | |
# verify that no invalid symbols occur | |
$letterset = $words | % { $_.ToCharArray() } | Sort-Object | Get-Unique | |
$letterset | foreach { | |
if($MorseTable[$_] -eq $null) { | |
Write-Error "Input contains the invalid character '$_'" | |
exit $InvalidCharacterError | |
} | |
} | |
# all symbols must be valid | |
for($i = 0; $i -lt $words.length; $i++) { | |
$word = $words[$i] | |
BlinkWord($word) | |
# do not wait after the last word | |
if($i + 1 -ne $words.length) { | |
Sleep -m $BetweenWordsDuration | |
} | |
} | |
} | |
if($args.length -eq 0) { | |
ShowHelp | |
exit $NoArgumentsPassedError | |
} | |
$input = $args[0] | |
$pathToCsv = $DefaultCsvPath | |
if($args.length -ge 2) { | |
$pathToCsv = $args[1] | |
} | |
LoadMorseTable $pathToCsv | |
BlinkSentence $input |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment