Don't forget to also checkout my second blog containing articles to all other related ICT topics!!

Friday, June 15, 2012

Using early member definitions with Traits


scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Environment {
    val mode: String

    override val toString = "Running in mode '" + mode + "'"
}

// Exiting paste mode, now interpreting.

defined trait Environment


scala> val x = new Environment { override val mode = "production" }
x: java.lang.Object with Environment = Running in mode 'null'

//As you can see the mode is still null so instantiating Traits this way is a bad idea.


//You can however use the construct below looking like an anonymous class definition
scala> class Acceptance extends {val mode = "Acceptance"} with Environment
defined class Acceptance

scala> val y = new Acceptance
y: Acceptance = Running in mode 'Acceptance'

//or you can even skip constructing a class and just create a new Object directly
scala> val dev = new {val mode = "Development"} with Environment
dev: java.lang.Object with Environment = Running in mode 'Development'

Monday, June 4, 2012

Micro Scala benchmark

I wanted to check how well Scala performs doing the same test as in Python on my laptop by zipping 2 identical vectors and calculating the sum. It didn't really surprise me that Scala outperformed Python but the outcome really gives me another WTF moment. I probably made a stupid mistake somewhere but just in case here is the test executed on scala. I did a few tests with smaller vectors and those gave the same results with Python and Scala. The strange outcome is due to the result not fitting into an integer !! Changing generic type [Int] to [Long] will result in ouf-of-memory exception unfortunately. For completeness a link to the simple Profiler used.
import Profiler._

object MicroBenchMark extends App {

  val v1 = 1 to 9999999 //scala includes .to(x) while Python excludes .to(x)
  val v2 = 1 to 9999999
  
  def vector_op(vector1: Iterable[Int], vector2: Iterable[Int], op: (Int, Int) => Int): Iterable[Int] = {
       vector1.zip(vector2).map(op.tupled)
  }
  
   profile(println("sum is " +  vector_op(v1, v2, (x,y) => x + y).sum))
   //python prints 99999990000000 instead of 266447232
  
}

sum is 266447232
Execution took 8 seconds

Friday, June 1, 2012

Python: Creating dictionary of adjacent elements of circular iterable

In many problems you will need to deal with circular datastructures which are most of the time presented in a simple iterable. If you need to quickly find for a specific element what the left and right adjacent elements are, you can use this generic function presented below.
#we got a list of persons sitting next to each other in a circle. 
#This means Robby is sitting next to Alice (left) and Valerie (right) for below example.
#We want to create a quick lookup dict for who sits next to each other

def getCircularLookupDictionary(iter):
   #generic function which returns a dict of items with format (key, (leftadjacent, rightadjacent))
   l = len(iter)
   """ 
   return dict(
               (iter[i], (iter[l - 1], iter[i+1])  ) if i == 0 else 
               (iter[i], (iter[i - 1], iter[0])    ) if i == l -1 else 
               (iter[i], (iter[i - 1], iter[i+1])  ) for i in range(l)
          )
   """
   #nice oneliner provided by my colleague Ivan Lagunov !!
   return dict((iter[i], (iter[i - 1], iter[i + 1 - l])) for i in range(l)) 

circle = ['Robby', 'Valerie', 'Lindsey', 'Audrey', 'Alice']
neighbours = getCircularLookupDictionary(circle)

print neighbours['Robby']
print neighbours['Lindsey']
print neighbours['Alice']

assert neighbours['Robby'] == ('Alice', 'Valerie')
assert neighbours['Lindsey'] == ('Valerie', 'Audrey')
assert neighbours['Alice'] == ('Audrey', 'Robby')

('Alice', 'Valerie')
('Valerie', 'Audrey')
('Audrey', 'Robby')

We can even make it more generic if we want to specify what keys and values to use from the iterables.
#we got a list of persons sitting next to each other in a circle. 
#This means Robby is sitting next to Alice (left) and Valerie (right) for below example.
#We want to create a quick lookup dict for who sits next to each other

def getCircularLookupDictionary(iter, keyf, valuef):
   #generic function which returns a dict of items with format (key, (leftadjacent, rightadjacent))
   l = len(iter)
   """
   return dict(
               (keyf(iter[i]), (valuef(iter[l - 1]), valuef(iter[i+1]))  ) if i == 0 else 
               (keyf(iter[i]), (valuef(iter[i - 1]), valuef(iter[0]))    ) if i == l -1 else 
               (keyf(iter[i]), (valuef(iter[i - 1]), valuef(iter[i+1]))  ) for i in range(l)
          )
   """
   #nice oneliner provided by my colleague Ivan Lagunov
   return dict((keyf(iter[i]), (valuef(iter[i - 1]), valuef(iter[i + 1 -l]))  ) for i in range(l))

#circle contains tuples of persons (name, age)
circle = [('Robby', 35), ('Valerie', 5), ('Lindsey', 9), ('Audrey', 40), ('Alice', 59)]
neighbours = getCircularLookupDictionary(circle, lambda (name,age): name, lambda (name,age): age)

print neighbours['Robby']
print neighbours['Lindsey']
print neighbours['Alice']

assert neighbours['Robby'] == (59, 5)   #ages of Alice, Valerie
assert neighbours['Lindsey'] == (5, 40) #ages of Valerie, Audrey
assert neighbours['Alice'] == (40, 35)  #ages of Audrey, Robby

(59, 5)
(5, 40)
(40, 35)

Python: Using attributes with functions

Python offers the possibility to store attributes on a function. This can be very useful in a number of situations. Below an example that shows usage.
import inspect

def viewCount(page):
   #returns a function which keeps track of how many times the page got viewed
   def f():
       f.numberOfViews += 1
       return f.numberOfViews
   f.__name__ = "ViewCount for page " + page
   f.numberOfViews = 0 
   return f 
        
 
viewCountOne = viewCount('index.html')
viewCountTwo = viewCount('faq.html')
 
 
print viewCountOne()
print viewCountOne()
print viewCountTwo()
print viewCountOne()
print viewCountTwo()
print viewCountOne.__name__
print viewCountTwo.__name__

print hasattr(viewCountOne, 'numberOfViews')
print inspect.isfunction(viewCountOne)
print viewCountOne.__name__.find('index') != -1

1
2
1
3
2
ViewCount for page index.html
ViewCount for page faq.html
True
True
True