Thursday, January 12, 2017

Some more Ruby

Trying out Ruby code again today for no specific reason other than to try out some different languages. Expanding on the previous example I decided to allow edge detection for multi-row matrix. This time we look for changes to the matrix with the left character and the row above.

Some comments on the syntax

- I found the for loop syntax a little weird “…” does not seem very intuitive.
- Reading from standard Input was really simple and felt good.
- Some of the syntax like ‘gsub’, ‘def’ (instead of 'function') would take a little getting used too, but Stack Overflow was a big help with that.
- RegEx was never my favourite technology, but Rubular website was very good; however did not work on Safari only Chrome.
- Closing ‘if' statements with ‘end’ felt like I was coding basic again.
Full code example is below.
#!/usr/bin/env ruby
# Usage:     cat <filename> | ./<edge.rb>
def CalculateEdge(arr)
  result = ""     # loop over each line of the array of text items
  for lineIndex in 0 ... arr.size
     topChar = "0" # start empty
     prevChar = "0" # start empty
     for charIndex in 0 ... arr[lineIndex].chomp.size
       # consider <whitespace> as '0'
       currentChar = arr[lineIndex][charIndex].gsub(/\s/,'0')
       # validation checks
       if lineIndex == 0 then
          topChar = currentChar  # assume current char if first row
        elsif lineIndex > 0 && charIndex > arr[lineIndex-1].chomp.size
          topChar = "0"  # assume "0" if missing on row above
        else
          topChar = arr[lineIndex-1][charIndex].nil? ? "0" : arr[lineIndex-1][charIndex].gsub(/\s/,'0')
        end
        # XOR char against the previous char to the left of current
        edgeLeft = prevChar.to_i(2) ^ currentChar.to_i(2)
        # XOR char against the char above the current
        edgeTop = currentChar.to_i(2) ^ topChar.to_i(2)
        # if the left char has not changed use the top row
        edge = edgeLeft == 1 ? edgeLeft : edgeTop
        prevChar = currentChar
        result = result+"#{edge}"
     end   result = "#{result}\n\t"
   end
   return result
end
# Place each line into an array
input = $stdin.read
if not (input =~ /[^0-1\W]/).nil? then
    puts "Error: Only 0-1 values allowed. e.g. 0100001111"
    puts "       Whitespace will be considered '0'"
    exit
end
arr = input.split(/\n/)
result = CalculateEdge(arr)
puts "Input :\t#{input}"
puts "Output:\t#{result}"

Next steps for the language

Must see if you can Unit Test this language ….. debugging on the command line was not great.

Tuesday, January 10, 2017

Going with Ruby

Today I decided to try some different languages just to see what would happen. I decided to try Ruby, just because it was on my laptop. Created by Yukihiro "Matz” Matsumoto around 1995, Ruby is one of those dynamic languages, primevally used on the Web. I have found out however that it’s also quite general so can be used as an alternative for Bash.
I took a simple edge case computation to try out. This is where a string of binary numbers is suppled and the program notes when the pattern changes. It’s a fairly simple problem, but nice as it hits all the main pain points, input for users, validation, loops, output of results, etc.
I’m happy to say it was a really simple language to understand. The “IRB” (Interactive RuBy) command within Terminal, lets you try out code on the fly. Getting the script to run on the Mac required a change to permissions to give it execute rights (“chmod 777”), but that’s was acceptable.
#!/usr/bin/env ruby
# Edge detection script
input = gets.chomp
if not (input =~ /[^0-1]/).nil? then
    puts "Error: Only 0-1 values allowed. e.g. 0100001111"
    exit
end
prevChar = "0"
result = ""
begin
   input.split("").each do |currentChar|
    # XOR each char against the previous
    edge = (prevChar.to_i(2) ^ currentChar.to_i(2)).to_s(2)
    result = result+"#{edge}"
    prevChar = currentChar
  end
puts "Input : #{input}"
puts "Output: #{result}"
rescue Exception => e
puts 'There was an unexpected error processing. ' + e.messageend 
end
All in all, it’s a nice language