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'
Friday, June 15, 2012
Using early member definitions with Traits
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 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): #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
Subscribe to:
Posts (Atom)