Showing posts with label 7languages. Show all posts
Showing posts with label 7languages. Show all posts

Friday, April 5, 2013

7 languages in 7 weeks: Scala day 2

Day two is all about collections. Forcing the typical Java developer (me) to think about iteration in a different way.

Exercise 1 is to take a List of strings and add up the number of characters using the fold left function. There is a very similar example in the book so I think the author is just checking you are paying attention:

Exercise 2 introduces you to Traits by asking you to develop a trait that has a method which censors a string by substituting words in a string. The words to substitute and what to substitute them with should be stored in a Map.


Then create a version that loads the substitutions from a file:

I chose to extend the trait and populate the alternatives field. Spending all my days writing Java what I ended up producing looks very alien to me. It works (I think) something like this:

  • Open and read a file using the library method fromFile
  • Get the lines of the file one by one using getLines
  • Map each like to an Array by splitting the like with the = sign (the file is key value pairs like a Java properties file)
  • Map the array to a tuple then turn it into a list
  • Construct a map from the List of tuples
And done! Looks a lot nicer than it sounds! The full source code is available on my github.


Wednesday, April 3, 2013

7 languages in 7 weeks: Scala day 1

I went to a great talk by Sandro Mancuso at Devoxx UK last week. He mentioned the project he is currently working on being written in Java for the main business flow and Scala for the data manipulation (sorry if I have remembered that incorrectly). This got me thinking it was about time I learnt some Scala. I've dipped in and out of the 7 languages in 7 weeks book; fortunately it has a chapter on Scala. So here I go...

 Googling around and reading the first day the following stands out:

  • Type inference with the safety of static typing (we're all sick of typing types aren't we??)
  • Companion objects instead of static methods
  • Higher order functions (why do we need lambas? Can't we just switch to Scala?)
  • Interfaces, no I mean mixins, wait traits: interfaces with implementation? I think these are great when used well.
  • Tuples and ranges.
So on to my home work!

The exercise for day 1 is to write noughts and crosses. I decided to concentrate on setting up a nice environment for writing scala rather than great code. I started with vim, then sublime but decided I fancied using an IDE. I started with Eclipse but moved to IntelliJ as it looks nicer on a retina screen :) In  addition to setting up an IDE I wanted to do TDD from the start, so I got to grips with ScalaTest.

Here are a couple of example tests:


Here is the main Board object. I could pull out the logic to determine a winner into a class like Game but as this was my first Scala code I decided to keep it simple in a single file.


I've omitted the code that calculates the different types thought it's all available on github. I looked at using a case class rather than a class that extends Enumeration but I haven't been taught case classes yet  so I'll leave that until later.

That's it for day one!

Wednesday, February 20, 2013

7 Languages in 7 weeks: Ruby day 3


Ruby Day 3: Serious change 

The final day on Ruby is all about metaprogramming. It takes you through:
  • Adding methods to open classes
  • Using method missing to produce very human readable syntax
  • Adding functionality to classes via Modules
Having used Java reflection, Java IDL Dynamic Invocation Interface (DII) and the Java IDL Dynamic Seketon Interface extensively when I used to develop IBM's Websphere Message Broker I know how cumbersome any form of metaprogramming is in Java. So I enjoyed playing around with a language that does it much better!

Now to the Self study. Only one this time! Modify the Csv application to support an each method to return a CsvRow object. E.g for the following csv file:

one, two
lions, tigers

allow an API that works like this:

csv = RubyCsv.new
csv.each{|row| puts row.one}

This should print "lions".

Well I decided to work with the following input:

one, two, three
1, 2, 3 
uno, dos, tres

And here is my solution using modules and method missing:

module ActsAsCsv
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def acts_as_csv
      include InstanceMethods
    end
  end

  module InstanceMethods
    def read
      @csv_contents = []
      filename = self.class.to_s.downcase + '.txt'
      file = File.new(filename)
      @headers = file.gets.chomp.split(', ')

      file.each  do |row|
        @csv_contents << row.chomp.split(', ')
      end
    end

    def each(&block)
      @csv_contents.each_index do |index|
        hash = Hash[@headers.zip @csv_contents[index]]
        block.call(CsvRow.new(hash))  
      end
    end
  end

  attr_accessor :headers, :csv_contents
  def initialize
    read
  end
end

class RubyCsv
  include ActsAsCsv
  acts_as_csv
end

class CsvRow
  def initialize(arg)
    @arg = arg
  end
  
  def method_missing name, *args
    key = name.to_s
    return @arg[key]
  end
end


m = RubyCsv.new
m.each do |row| 
  puts row.send(ARGV[0])
end


And that is it for Ruby!

Monday, February 18, 2013

7 Languages in 7 weeks: Ruby day 2


Day 2: Floating Down from the sky


On day 2 we're introduced to code blocks, arrays, hashes and mixins. The more I see code blocks in other languages the more I am looking forward to Java 8. Coming from Java I get particulary jealous of languages with syntaxctic sugar for arrays and hashes; initialising them in Java is cumbersome.

Self-Study

1) Print the contents of an array 4 elements at a time:

Sticking to the verbose solution for now:


array = Array(1..16)

array.each do |x|
  if (x % 4 == 0) 
    print "#{x}\n"
  else
    print "#{x},"
  end
end

Now with slice:

irb(main):014:0> array = Array(1..16)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
irb(main):015:0> array.each_slice(4) {  |slice| puts slice.join(",") }
1,2,3,4
5,6,7,8
9,10,11,12
13,14,15,16

2) Tree with a nice constructor:

After finishing this I found a nicer solution with collect, but here is my original:

class Tree
  attr_accessor :children, :node_name

  def initialize( fullTree={})
    @children = []
    @node_name = fullTree.keys.first
    fullTree[@node_name].each do |key,value| 
      children.push(Tree.new( {key=>value} ))
    end
  end
  
  def visit_all(&block)
    visit &block
    children.each{ |c| c.visit_all &block }
  end

  def visit(&block)
    block.call self
  end
end

ruby_tree = Tree.new({ 'grandad' => { 'dad' => { 'child 1' => {}   }, 'uncle'   => {}  } })

ruby_tree.visit_all { |t| puts t.node_name  }

3) Ruby grep!

pattern = Regexp.new(ARGV[0])
file = File.new(ARGV[1], "r")

counter = 0
file.each_line do |line|
  if line.match(pattern)
    puts "#{counter}: #{line}"
  end
  counter = counter + 1
end

Day 3 to come some time this week hopefully!

Saturday, February 16, 2013

7 Languages in 7 weeks: Ruby day 1

Having decided I spend far too much time programming with Java I added the 7 languages in 7 weeks to my Amazon wish list and come Christmas it turned up.

Day 1: Finding a Nanny (Ruby)

Firstly we're introduced to Ruby's interactive console. My first conclusion is that all languages should have an interactive console!

A few differences to Java that stand out:

  • Interpreted: Nuff said.
  • You have the unless conditional so you can write lines that read quite nicely: order.calculate_tax unless order.nil?
  • Everything is an Object, including primitives.
  • Duck typing: You can call any method on an object and if it has it at runtime it will be called. You don't have to have classes inherit from the same class to be used in the same way.

The homework

Print the string Hello, World.

puts 'hello, world'

For the string "Hello, Ruby" find the index of the word "Ruby"

irb(main):007:0> "Hello, Ruby!".index('Ruby')
=> 7

Print your name ten times

irb(main):009:0> for i in 1..10
irb(main):010:1> puts "Christopher"
irb(main):011:1> end

Print the string "This is sentence number 1" where the number 1 changes from 1 to 10

irb(main):009:0> for i in 1..10
irb(main):010:1> puts "This is sentence number #{i}"
irb(main):011:1> end

Run a Ruby program from a file

chbatey ~/dev/7languages/ruby $ cat day1.rb 
#!/usr/bin/env ruby

puts "Hello"

Bonus problem: Guess a number between one and ten:


#!/usr/bin/env ruby
rand = rand(10)
puts "A number between  0 and 9"
user = gets().to_i

if user < rand
  puts "Less"
elsif user > rand
  puts "More"
else
  puts "Equal equal!!"
end

puts "The number was #{rand}"

Well that's day one of Ruby done. I look forward to tomorrow!