A fixed-size layout that worked only on desktops wouldn’t cut it anymore. So out goes the simple handcrafted css with divs and floats. In comes Bootstrap with its grid system for the flexible layout. Also comes Infinite Scroll for, well, infinite scrolling.
The blog was on Wordpress v3.0, old enough that the database schema was incompatible with current (v5.0). This was a good enough reason to chuck it out and move over to Jekyll.
PixelPost was a decent option for photoblogging at the time, but it has reached end of life. Not only is the project abandoned, the code is in PHP 4.3, which meant it was pretty much broken with the later versions. Taking cue from Jekyll on cutting off the comments and all other write paths, it was fun to write a basic photo gallery ground up. Infinite Scroll fits in nicely here. I’m especially happy about the photo rearrangement so that it renders snug and compact. Check it out. Under the hood, it is powered by Flickr’s nice set of REST APIs, and the very handy Flickraw Ruby gem. I’m glad that even though not much is going on right now for Flickr, they still have managed to keep the APIs and static links and nice set of licenses.
Handlebars does the job of the javascript templating engine, and seems to get along nicely with infinite scroll library. The comics was and is a simple php script, but now with the awesome powers of, you guessed it, infinite scrolling.
I loved the simplicity Jekyll brought to things, but I wasn’t particularly happy about the assorted box the website was turning into, with parts still sticking out in PHP (Imagine all the common html headers and footers that now needs to be pasted into PHP scripts). Well, Jekyll uses Liquid as its templating engine, and Liquid does a decent job of templating the HTML layouts for PHPs too! So end result is that Liquid does server side templating to produce PHPs which builds up the javascript that uses Handlebars for some more client side templating!
MySQL stays.
The build and deploy is automated via good ol’ bash scripts, and is packed into neat little Docker containers that are hosted on GCP. Oh that’s the other switch, from AWS to GCP. Why? just curious what is there on the other side of the fence.
Other mentions: Rogue does a cool job of syntax highlighting, but I’m yet to find my zen theme.
]]>SPARK_DAEMON_JAVA_OPTS+=" -agentpath:/root/yjp-12.0.5/bin/linux-x86-64/libyjpagent.so=sampling"
export SPARK_DAEMON_JAVA_OPTS
SPARK_JAVA_OPTS+=" -agentpath:/root/yjp-12.0.5/bin/linux-x86-64/libyjpagent.so=sampling"
export SPARK_JAVA_OPTS
This would attach the YourKit profiler in ‘sampling’ mode for all spark-submits, including the ones from spark-shell. Sometimes I prefer ‘tracing’, and at times skip profiling completely. The following code snippet helps you specify the profiling option while launching the spark-shell.
prof="none"
for curr in $@
do
if [[ "$curr" =~ -Dprofiling=(.*) ]] ; then
option=${BASH_REMATCH[1]}
if [ "$option" == "sampling" ]; then
prof="sampling"
fi
if [ "$option" == "tracing" ]; then
prof="tracing"
fi
fi
done
if [ "$prof" != "none" ]; then
SPARK_DAEMON_JAVA_OPTS+=" -agentpath:/opt/yourkit/yjp-2014-build-14116/bin/linux-x86-64/libyjpagent.so=$prof"
export SPARK_DAEMON_JAVA_OPTS
SPARK_JAVA_OPTS+=" -agentpath:/opt/yourkit/yjp-2014-build-14116/bin/linux-x86-64/libyjpagent.so=$prof"
export SPARK_JAVA_OPTS
fi
TLA Toolbox is a pretty decent IDE for TLA+, built on top of eclipse. On my machine, the ToolBox jvm process kept crashing. Adding the following line to toobox/toolbox.ini fixed this. For more details, refer this eclipse bug.
-Dorg.eclipse.swt.browser.DefaultType=mozilla
The ASCII to PDF export (LaTex) would fail unless you have pdflatex installed.
sudo apt-get install texlive-latex-base
As for running the Model Checket, I prefer to use the TLA+ tools from the cli. Make sure to add the tla2tools.jar to your classpath and you should be good to go!
]]>The API needs to store the latest version of a record. It does so by checking the revision number of the record being inserted against the current version in the db. If the revision number of the new record is greater, it is inserted. Otherwise it is ignored. The db provides conditional APIs to perform check-and-update operations. Give it a shot.
DB APIs:
//Gets the current record. Returns null if no record is found.
public Record getRecord(String primaryId);
//Inserts a record. Throws exception if a record is already present.
public void insert(Record rec) throws ConstraintViolationException;
//Updates a record. Throws exception if the record is not of a
//newer revision - basically the verison number should be increasing
public void update(Record rec) throws ConstraintViolationException;
And here is my attempt:
public void storeLatestVersion(Record newRec) {
String primaryKey = newRec.primaryKey;
Record currentRec = getRecord(primaryKey);
if (currentRec==null) {
try {
insert(newRec);
//done. lets go home
return;
} catch(ConstraintViolationException ce) {
//Some one bet me to it. Let me fetch the current rec
currentRec = getRecord(primaryKey);
}
}
//at this point currentRec cannot be null.
//making such an assumption makes me sad :(
if (currentRec.versionNo < newRec.versionNo) {
try {
update(newRec);
//yey! job well done
return;
} catch(ConstraintViolationException ce) {
//someone has updated the record in the mean time?
currentRec = getRecord(primaryKey);
}
}
if (currentRec.versionNo >= newRec.versionNo) {
//nothing to do as there is later version in the db.
//lets ignore the current record.
return;
} else {
//this can't be happening. something went wrong.
}
}
private ARTTimerTask timerTask = ARTTimerTask.getInstance();
...
public void notify(String messageId, Long messageTime) {
...
//NPE in the line below
timerTask.addMessage(messageId,
System.currentTimeMillis() - messageTime);
}
Here’s the relevant section from ARTTimerTask:
private static final ARTTimerTask _INSTANCE
= new ARTTimerTask();
public static ARTTimerTask getInstance() {
return _INSTANCE;
}
(Debashish comes over to the desk, takes a look and proclaims, “This Axxx Bxxxxx is pathetic”. 7 seconds!)
]]>As part of Innovation Labs at 24/7 Customer, my new organization, we are building a platform for predictive analysis and intervention in CLM area. A lot of exciting things on the plate already and the team is very passionate and dynamic. Small organizations are really nimble footed and flexible, and I’m liking it.
In fact, I find myself recruiting already. In case you are interested, reach out to me at gmail.com. The id would be aloshbennett. A more detailed job description can be found here.
]]>With me were Bhaskar Ghosh and Neil Ghosh who actually delivered the talks and conducted the hands-on lab. Overall, a very pleasant experience. Special thanks to Dr Geetha Deviprasad who made the event possible.
The event is covered in detail at Neil’s blog.
]]>There!
Canvas provides a screen area onto which you could draw 2D shapes and images. The set of APIs are simple. But the strength of the canvas comes from how you could manipulate it using javascript.
We start by defining a canvas. Note that the canvas element would be rendered only if your browser supports it.
Next, we define an array in javascript to hold the maze data, initialize it and start building our maze by venturing out into the first cell.
var board = new Array();
function maze() {
init(); //initialize the maze
explorePath(1,1); //start exploring
}
function init() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
context = canvas.getContext("2d");
//paint the maze black
}
for(i=0; i< SIZE; i++) {
board[i] = new Array();
for(j=0; j<SIZE; j++) {
board[i][j] = 0; //fill the board array with zeroes
}
}
}
For the explorePath method, we use a recursive algorithm
Paint the cell white
Initialize options list {UP, DOWN, FORWARD, BACKWARD}
While options:
Select option randomly
If valid option - Cell is unoccupied, we don't create tunnels etc.
explorePath(option)
remove explore option from list
end loop.
In short, we are doing a back-tracking traversal (DFS) of the option tree.
The algorithm works fine until we try to put a delay between each explorePath call to get that nice effect.
You see, it is not really easy to sleep() in javascript. There is no equivalent of Java sleep.
What we could do is this:
setTimeOut('explorePath()', 100);
This would call the explorePath after a delay of 100 milliseconds. But, the call to setTimeOut() is non-blocking and it would continue execution while scheduling explorePath() to be executed after 100 milliseconds.
We could maintain our own call stack and choose not to call the explorePath() recursively. But it is easier to just push the maze positions to be painted white into a stack and continue execution. Once the display stack is ready we could pop from it and render onto canvas in a delayed manner using setTimeOut().
Finally, we could add a nice touch to the maze by not changing its directions too often, but in a timely manner based on a seeded probability.
Here’s the complete source (right click and view source). And don’t forget to save your maze as a PNG (again, right click and save).
]]>Here are the slides from the talk.
Implementation and Testing of Software Projects
This post is an introduction to a very potent and heady LISP cocktail of Higher Order Functions, Lamdas and Macros.
Summary:
Higher Order Functions: Functions that take other function as its argument. A function that filters a list can be converted into higher order function by providing the actual filtering function as an argument.
Lambda Expression: Dynamically creates functions and attaches a context to them. The filtering function can be created at runtime as a lambda and its bounds set at runtime.
Macro: Creates code at runtime by substituting the macro with corresponding expression. While Lambdas let you replace the bound conditions, macros let you decide the structure of your filter function.
Higher Order Functions
You could print all students belonging to “ELX” department from a list like this:
(defun print-students (students-lst)
(loop for student in students-lst
do ( if (equal "ELX" (getf student :department))
(print student))))
Now if you want to print the students who had received ‘A’ grade, you are at a loss. You cannot do that without writing a new function by duplicating the looping logic.
Enter Higher Order Functions. Higher Order Functions are functions which take another function as its argument. The example above can be modified into a generic higher order function if we could abstract the evaluation logic into another function.
Consider the following re-write
(defun print-students (students-lst, eval-student)
(loop for student in students-lst
do ( if (funcall eval-student student)
(print student))))
(defun eval-elx-department (student)
( if (equal "ELX" (getf student :department)) t))
(defun eval-a-grade (student)
( if (equal "A" (getf student :grade)) t))
(print-students *students-lst* #'eval-a-grade)
Note: LISP built-in functions REMOVE-IF and REMOVE-IF-NOT takes a list and a evaluation function, applies the evaluation function to every element in the list and returns a new list which contains/doesn’t contain the element. The idea of predicates is very similar to this.
Lambda Expressions
If we could parameterize the grade from the eval-a-grade function, we would have a generic eval-grade and that would have been just great! Unfortunately, the print-students function expects an evaluation function that takes in a single argument: student.
Using Lambda expressions, it is possible to custom make a function with a context. Lambda expressions are used to create anonymous functions with a scope attached to them. The variables used within the lambda expressions are evaluated in the context they are run in.
(defun eval-grade (grade)
(lambda (student)
( if (equal grade (getf student :grade)) t)))
(print-students *students-lst* (eval-grade "A"))
(print-students *students-lst* (eval-grade "B"))
Macros
LISP macro is a very powerful beast that can be used to generate code dynamically. Instead of having multiple evaluation functions, it is possible to write a LISP macro to dynamically generate a lisp function based on the inputs you pass to it.
(defmacro eval-student (&key dept grade)
`(lambda(student)
(and ,(if dept
`(equal ,dept (getf student :department)))
,(if grade
`(equal ,grade (getf student :age))))))
(print-students *students-lst* (eval-student :dept "ELX" :grade "A"))
The eval-student macro expands to
LAMBDA (STUDENT)
(AND
(EQUAL "ELX" (GETF PERSON :DEPT))
(EQUAL "A" (GETF PERSON :GRADE)))
Note: Though very powerful, it is easy to cut yourself using macros. Use discretion when using them.
Functional programming is a great way to modularize and reduce the size of your code. More than that, it is fun! Happy coding.