Parsing a sms thread in a readable way on Android

First get SMS Backup & Restore app from Play store and backup all the sms and then take the xml and run the following snippet to generate a readable conversation in a text file.

from __future__ import print_function
from xml.dom import minidom

xmldoc = minidom.parse('/Users/narendrayadala/Downloads/sms-20130317085953.xml')
sms_file = open('/Users/narendrayadala/Downloads/Jyothi.txt', 'w')
smslist = xmldoc.getElementsByTagName('sms')

for sms in smslist:
    if sms.attributes['contact_name'].value == 'Jyothi Nerella':
        if sms.attributes['type'].value == '1':
            print(sms.attributes['readable_date'].value + u' - Jyothi: ' + sms.attributes['body'].value, file=sms_file)
        else:
            print(sms.attributes['readable_date'].value + u' - Narendra: ' + sms.attributes['body'].value, file=sms_file)
Advertisements

Indenting blocks of text easily on MacVim

Being a windows user previously, I prefer selecting text using Shift+Arrow keys and increase/decrease indent of the text using Tab/Shift-Tab keys. Doing this on MacVim requires a little fiddling with the .vimrc file. The following needs to be added to the .vimrc file.

vnoremap <Tab> >gv
vnoremap <S-Tab> <gv

if has("gui_macvim")
    let macvim_hig_shift_movement = 1
endif

First section of the code causes vim to use Tab key as a mapping for >gv key sequence and second section of the code causes vim to use Shift+Arrow keys to select the text.

Using bind method of Function object

When new elements are dynamically added to the DOM, appropriate event handlers need to be attached to them. When attaching event handlers proper context needs to be set so that the event handler routines can use this object in a productive way. Since JavaScript 1.8.5 doing this is made simple using bind method of the Function object. Prior to the introduction of bind method, Function.apply method is used to set the this context. The following html/js code illustrates a typical usage of bind method.

<!DOCTYPE html>
<head>
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
</head>
<html>
	<body>
		<div id="container"></div>
	</body>
	<script type="text/javascript">
		function changeBackgroundColor(){
			$(this).css('background-color', this.attr('data-backgroundcolor'));
		}
                //the following data is generally obtained from server as a result of some request
		var newDiv = $("<div id='newDiv' data-backgroundcolor='#abc'><h4>Sample content from server</h4></div>")
		newDiv.bind('click', changeBackgroundColor.bind(newDiv));
		$('#container').append(newDiv);
	</script>
</html>

Here changeBackgroundColor.bind(newDiv) creates a new bound function with newDiv as this context inside changeBackgroundColor method.

A simple shell script to verify checksums

Often I find myself comparing checksums manually which is a bit cumbersome, so I wrote this trivial shell script to automate the verification.

#!/bin/bash
if [ $# -lt 3 ] ; then
        echo 'usage -- compare-checksum.sh hashfunction filename checksum'
        exit 1
elif [ `$1 $2 | awk '{print $1}'` = $3 ] ; then
        echo 'File not corrupted. We are saved.';
else
        echo 'File corrupted. We are doomed.';
fi

Usage:

compare-checksum.sh sha1sum foobar.txt 988881adc9fc3655077dc2d4d757d480b5ea0e11

If there are multiple files and their corresponding checksums, then one can write them in a file in the following format

988881adc9fc3655077dc2d4d757d480b5ea0e11  foobar1.txt
988881adc9fc3655077dc2d4d757d480b5ea0e11  foobar2.txt
988881adc9fc3655077dc2d4d757d480b5ea0e11  foobar3.txt
988881adc9fc3655077dc2d4d757d480b5ea0e11  foobar4.txt

and run the following command to verify all of the checksums at once

sha1sum -c checksum.txt

Generating all possible postfix expressions

The following Java program returns the list of all possible postfix expressions for a given list of operands and operators. The number of all postfix expressions grows exponentially with the number of operands and is around 5 billion for 10 operands and 4 operators (*,+,/,-). The precise number of all possible postfix expressions is C(n-1)*(noOfOperators^(n-1)) where n is the number of operands and C(n-1) is the n-1th Catalan number.

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PostfixExpressionGeneratorSansRecursion {
	private static final String [] OPERATORS = new String[] {"*", "+", "/", "-"};
	
	public static void main(String[] args) {
		List<String> x = new ArrayList<String>();
		x.add("1");
		x.add("2");
		x.add("3");
		x.add("4");
		
		for (String ex : generateAllPostfixExpressions(x)){
			System.out.println(ex);
		}
	}
	
	/**
	 * Assumes input is a list of single digit positive numbers.
	 * @param operands
	 * @return list of all possible postfix expressions for the given list of operands
	 */
	private static List<String> generateAllPostfixExpressions(List<String> operands) {
		List<String> allPossiblePostFixExprs = new ArrayList<String>();
		Stack<String> stack = new Stack<String>();
		stack.push(""); //start with a empty partial expression
		int finalPFExprLength = 2*operands.size() - 1;
		int sizeOfOperands = operands.size();
		
		while (!stack.isEmpty()) {
			String partialExpr = stack.pop();
			int partialExprLength = partialExpr.length();
			
			if (partialExprLength == finalPFExprLength) {
				allPossiblePostFixExprs.add(partialExpr);
				continue;
			}
			
			int noOfOprdsConsumed = 0;
			for (char c : partialExpr.toCharArray())
				noOfOprdsConsumed += Character.isDigit(c) ? 1 : 0;
			
			if (2*noOfOprdsConsumed - partialExprLength > 1)
				for (String op : OPERATORS)
					stack.push(partialExpr + op);
			
			if (noOfOprdsConsumed != sizeOfOperands)
				stack.push(partialExpr + operands.get(noOfOprdsConsumed));
		}
		
	    return allPossiblePostFixExprs;
	}
}

Copying large files — BufferedReader vs FileChannel

When copying large files java.nio.channels.FileChannel takes 20% less time than java.io.BufferedReader. On an average FileChannel takes 25 seconds for each run and BufferedReader takes 30 seconds for each run. Here is the code used for the performance test. Size of test.txt is 1 GB. Used a buffer of size 8 KB as it was giving the best results. [Environment – -Windows 7/3GB RAM/i3 CPU M 370 @ 2.40GHz]

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class CopyFile {
	//Size of the test file is 1GB.
	private static final String INPUT_FILE_PATH = "test.txt";
	private static final String OUTPUT_FILE_PATH_FOR_FILE_CHANNEL = "test1.txt";
	private static final String OUTPUT_FILE_PATH_FOR_BUFFERED_READER = "test2.txt";
	private static final int DEFAULT_BUFFER_SIZE = 1024 * 8;

	public static void main(String[] args) throws Exception {
		Timer t = new Timer();

		t.start();
		copyFileUsingBufferedReader();
		System.out.println("Copying file using buffered reader takes " + t.end() 
                                                         + " milliseconds");

		t.start();
		copyFileUsingFileChannel();
		System.out.println("Reading file using file channel takes " + t.end() 
                                                         + " milliseconds");
	}

	private static void copyFileUsingFileChannel() throws IOException {
		FileChannel source = null;
		FileChannel destination = null;
		
		try {
			source = new FileInputStream(new File(INPUT_FILE_PATH)).getChannel();
			destination = new FileOutputStream(
                        new File(OUTPUT_FILE_PATH_FOR_FILE_CHANNEL)).getChannel();
			
			//This fails with Map Failed exception on large files
			//destination.transferFrom(source, 0, source.size());
			
			ByteBuffer buf = ByteBuffer.allocateDirect(DEFAULT_BUFFER_SIZE);
	        while((source.read(buf)) != -1) {
	                buf.flip();
	                destination.write(buf);
	                buf.clear();
	        }
		} finally {
			if (source != null) {
				source.close();
			}
			if (destination != null) {
				destination.close();
			}
		}
	}

	private static void copyFileUsingBufferedReader() throws IOException {

		BufferedInputStream source = new BufferedInputStream(
                new FileInputStream(new File(INPUT_FILE_PATH)));
		BufferedOutputStream destination = new BufferedOutputStream(
                new FileOutputStream(new File(OUTPUT_FILE_PATH_FOR_BUFFERED_READER)));
		byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

		try {
	        int n = 0;
	        while (-1 != (n = source.read(buffer))) {
	        	destination.write(buffer, 0, n);
	        }
	        destination.flush();
		} finally {
			if (source != null) {
				source.close();	
			}
			if (destination != null) {
				destination.close();				
			}
		}
	}

}

class Timer {
	long s;

	public Timer() {
	}

	public long start() {
		s = System.currentTimeMillis();
		return s;
	}

	public long end() {
		return System.currentTimeMillis() - s;
	}
}

A week of vim that didn’t suck

I have been using vim for quite a while now. But in the last week I realized that I have been using it in a wrong way all the way through. After stumbling onto some of stackoverflow posts I figured that there is much more to Vim than what I had known. Vim provides so many verbs (aka keyboard shortcuts) that it is more of a complex language than a simple editor. The key to understanding the power of vim is to use this vim language extensively to communicate with the editor. My mistake was that most of the time i was using a very restrictive subset of the vim language to do my work which in turn caused my frustration. Vim has multiple modes of editing, most important of which are normal (for text surgery, this is the default mode, which you can get back to with ESC.), command (for entering commands) and insert (for doing the real editing) modes.

Vim search is very powerful. Consider this search and replace expression

:%s/[s|m]ad/happy/gic

Let me dissect this Vim verb part by part

    : enters command mode
    % denotes the range of search, entire file in this case
    s defines substitute command
    search pattern can be any regex, in this case [s|m]ad
    replace string – happy
    g stands for global match
    i for case insensitive search
    c is for confirm and replace

Vim has a simple to use plugin framework with active community support which makes it extensible as a mini IDE. These are some of the plugins I found useful

  • Pathogen – a plugin which makes plugin management much much simpler
  • Solarized – an awesome color scheme
  • Snipmate – simple utility to embed snippets into your code
  • TComment – easy “(un)comment multiple lines of code” utility
  • EasyMotion – makes moving around much much easier if you are not using GUI based Vim
  • Surround – makes editing surrounding blocks of code easier
  • Fuzzy Finder – utility to open the files anywhere in the filesystem real fast

There are a whole lot of flags such as number(shows line numbers), ignorecase (ignores the case while searching) that you can set and unset inside the .vimrc file. This is the main config file for the Vim editor.