How come nobody knows? Introducing NighIsTheEnd.rb, a helper script for making signs

Categories
Mucking About With Things Personal Firsts The Diary of Lupin Pooter
My homemade signboard for velcro-backed felt letters.

First I acquired (read: bought cheap) some packs of velcro-backed felt letters. Then I got some large-ish scraps of thick black felt. On a completely unrelated project, I tried using a hot-glue glue gun for the first time in my life. It clogged. Boo hoo. I still needed a glue gun, so I ordered some from overseas. They worked very well.

Fast-forward a few weeks. I had glue guns and there were off-cut bits of corrugated plastic sheeting around. I glued some of the felt to one of the pieces of the plastic sheeting and, presto, I had the very basic (OK, crappy) felt signboard you can see in the picture atop this post. Then it was time to monkey around with the letters, which I’d previously sorted alphabetically and by case.

I can’t recall now what message (not the one shown above, which is a line from D.O.A. by Sleigh Bells) popped into my head but, without giving it another thought, I started picking out the letters I needed. I hadn’t gotten very far before the flipping back and forth from one end of the alphabet to another began to bug me. I took a moment to manually, as in with a pencil on a scrap of paper, count how many of each letter were required.

That was fine, but it seemed like the sort of thing I ought to automate and it also struck me as a near-ideal, textbook-style programming exercise for trying out a new or unfamiliar language. While this is probably not the first and only Ruby I’ve ever written, it’s not far off:

require 'colorize'

$str_nlnsp = "\n  "

def rtn_hsh_tally_chars_in_msg(str_msg)
  hsh_tally = {}
  str_msg.each_char { |c|
    if hsh_tally.has_key?(c)
      hsh_tally += 1
    else
      unless c.match(" ") or c.match(/[[:punct:]]/)
        hsh_tally = 1
      end
    end
  }
  return hsh_tally
end

def rtn_str_char_occur_list_printable(arr_hsh_tally_sorted)
  str_printable_list = ''
  for arr_char_tally in arr_hsh_tally_sorted
    str_printable_list += $str_nlnsp + "#{arr_char_tally[0].to_s.cyan}: #{arr_char_tally[1].to_s.magenta}"
  end
  str_printable_list += "\n"
  return str_printable_list
end

puts $str_nlnsp + "Type in the message you'd like to tally and press ENTER."

str_msg = gets.chomp
if !str_msg.instance_of? String
  abort($str_nlnsp + "Somehow, you fed a non-string to this script.")
end

str_msg = str_msg.strip
if str_msg.length === 0
  abort($str_nlnsp + "You didn't write anything.")
end

hsh_tally = rtn_hsh_tally_chars_in_msg(str_msg)
arr_hsh_tally_sorted = hsh_tally.sort_by{ |k,v| v}.reverse
arr_vals_hsh_tally = hsh_tally.values.sort.reverse

fxnm_highest_occurrence = arr_vals_hsh_tally[0]
fxnm_num_chars_highest_occur = arr_vals_hsh_tally.count(fxnm_highest_occurrence)

puts $str_nlnsp + "That message included #{hsh_tally.keys.length.to_s.magenta.underline} different characters."

if fxnm_highest_occurrence == 1
  puts $str_nlnsp + "No character occurs more than once."
elsif fxnm_num_chars_highest_occur == 1
  puts $str_nlnsp + "The character #{arr_hsh_tally_sorted[0][0].cyan} was most common, present #{arr_hsh_tally_sorted[0][1].to_s.magenta.underline} times."
else
  str_highest_occur_chars = arr_hsh_tally_sorted[0, fxnm_num_chars_highest_occur].map { |k| "#{k[0].to_s.cyan}" }.join(" ")
  puts $str_nlnsp + "#{fxnm_num_chars_highest_occur.to_s} characters (#{str_highest_occur_chars}) were each present #{fxnm_highest_occurrence.to_s.magenta.underline} times."
end

str_printable_char_occur_list = rtn_str_char_occur_list_printable(arr_hsh_tally_sorted)
puts $str_nlnsp + "Here's the list of characters that occur in your message and the number of times they appear:#{str_printable_char_occur_list}"

exit

It’s sure not much to look at, but it works. Here’s what a run looks like:

Ruby script for tallying the number of each letter or number in a string and reporting some helpful figures.

The message (Philae Found Wedged in a Crack) is ripped from the headlines. Philae, the ESA Rosetta mission’s lander, has been spotted (PHILAE FOUND!) on the surface of comet 67P/Churyumov–Gerasimenko (67P).

Here’s the text alone:

Windows PowerShell
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS ZZZZZZZZZ\NighIsTheEnd> ruby NighIsTheEnd.rb

  Type in the message you'd like to tally and press ENTER.
Philae Found Wedged in a Crack

  That message included 17 different characters.

  3 characters (d a e) were each present 3 times.

  Here's the list of characters that occur in your message and the number of times they appear:
  d: 3
  a: 3
  e: 3
  n: 2
  i: 2
  u: 1
  g: 1
  C: 1
  W: 1
  o: 1
  F: 1
  r: 1
  c: 1
  l: 1
  k: 1
  h: 1
  P: 1
PS ZZZZZZZZZ\NighIsTheEnd>

The script’s name is a reference to “The End is Nigh” signboards.

Postscript: NighIsTheEnd.rb seems to be at good-enough-for-me level now, so I don’t foresee expending a lot of future development energy on it, but I’ve uploaded the repo to my GitHub account: briandonovan/NighIsTheEnd.