Friday, December 19, 2014

vi and terminal

For most parts vim is an amazing tool. It has a huge initial learning curve but the functionality it provides are simply amazing.
The only other software which I have heard a lot of good stories about is Emacs.
Vim has this amazing functionality where you can set vi on terminal
 set -o vi  

This feature helps you to use vi when trying to type out long commands on the terminal. Or better you could edit the long command on vi and come back to terminal to execute the command all in a bunch of simple commands which I plan to explain here.

  Warning

vim on terminal is similar to vim editor you can only type commands on your terminal using the INSERT MODE. Now that's awesome because you also get the command functionalities which you get in vim. "/" this means search on your existing command. So if you have a huge command which you want to search through use the "/" command modes.

  Use case

For the meat of vim usage. Say you are running a curl command and inserting a huge json file and you are doing it in command line.
If you have been in this situation before you feel my pain. With Vim mode things become a bit easier. First get inside the vi editor.
  • Open a terminal
  • Type vi in shell without going into insert mode (just type vi in shell)
  • This takes you inside a temp vi file. Now you can use normal vi commands.
  • Copy paste your long curl command in here. Make the necessary changes.
  • Now save the file ":w" and quite ":q"
  • Wala Vi runs the command in your terminal.
This is a powerful feature.

  Caveat and Fix

For some reason vi environment resets auto complete with tabspace which is quite annoying. After some searching I came across this q&a. This solution worked for me so I ended up using this as an alias in my ~/.profile. Makes my life super easy now. Just use the alias when I want to get inside vim mode.
 alias ii="set -o vi; bind '"\C-i": menu-complete'"  

Wednesday, April 16, 2014

How to use pycurl to provide status bar and percentage using python

Today I was tasked to write a python script that uses pycurl to upload a 30GB binary file to a cloud storage portal. The problem is using curl doesn't provide useful information such as progress and percentage completed. This is very useful if you want to redo parts of the artifact. Since our cloud storage supports partitioned uploads it becomes all the more important to upload in parts and provide the percentage uploaded. I used pycurl documentation to figure out most of the args that I needed to set for the upload. However the part which I felt most cute about was the progress bar. The way I hooked it up to the pycurl was using call back mechanism which pycurl provides Disclaimer: This code has been tested out in Redhat Linux v6 machine.
import pycurl
import os, sys

# pretty print progress and percentage completed
def progress(total_to_download, total_downloaded, total_to_upload, total_uploaded):
  if total_to_upload:
    percent_completed = float(total_uploaded)/total_to_upload       # You are calculating amount uploaded
    rate = round(percent_completed * 100, ndigits=2)                # Convert the completed fraction to percentage
    completed = "#" * int(rate)                                     # Calculate completed percentage
    spaces = " " * ( 100 - completed)                               # Calculate remaining completed rate      
    sys.stdout.write('[%s%s] %s%%' %(completed, spaces, rate))      # the pretty progress [####     ] 34%  
    sys.stdout.flush()


def upload_to_cloud(url, filename, is_proxy=False):
  if not os.path.exists(filename):
    raise Exception('did not find file')

  # initialize py curl
  c = pycurl.Curl()
  c.setopt(pycurl.UPLOAD, 1)
  if is_proxy:
    c.setopt(pycurl.PROXY, 'XXX')
    c.setopt(pycurl.PROXYPORT, 80)
  
  #For authenticated cloud store
  c.setopt(pycurl.USERPWD, 'XXXX' + ':' + 'XXXX')
  c.setopt(pycurl.READFUNCTION, open(filename, 'rb').read)
  c.setopt(pycurl.VERBOSE, 0)
  c.setopt(pycurl.URL, url)
  c.setopt(pycurl.NOPROGRESS, 0)
  c.setopt(pycurl.PROGRESSFUNCTION, progress)

  #Set size of the file to be uploaded
  filesize = os.path.getsize(filename)      # you can simply open the file and do a byte counter for this. Initially that's what I did then moved to os API
  c.setopt(pycurl.INFILESIZE, filezie)
  
  # Start transfer
  print 'Uploading file %s to url %s' %(filename, url)
  c.perform()         # this kicks off the pycurl module with all options set.
  c.close()


if __name__=='__main__':
  if len(sys.argv) < 2:
    print 'Usage python upload_to_cloud URL FILE_PATH'

  upload_to_cloud(sys.argv[1], sys.argv[2])
  
  

Saturday, August 25, 2012

Re-blogging my experience on this really cool blog.

The other day, I was going through some JDK code to understand what was happening under the hood. I saw this code in a couple of places. (such as binary search and merge sort) I really couldn't figure out why someone would want to use the unsigned right shift operator to do simple division.
mid = low + high >>> 1;
mid = low + high / 2
instead of this,

Until I recently came across this post from Peter Norvig in this blog Google Research Blog This bug must have been fixed by Josh Bloch I guess. Since he seems to be the author of the classes which I was checking.
A small side note here, I too fell into the trap of thinking this was done for performance issues. However the blog clearly states the root cause was something more sinister. Love to be in a place where your code get's pushed to the limit. I guess scale is an awesome beast to deal with.
When will my day arrive :-(. When millions use my code.

Sunday, August 12, 2012

Simple stuff in java that I learnt today

Coming from a C background I never really got to write code in java to do some string processing. The other day I was doing some simple stuff in java and I hit these problems.
  1. Converting a string to an integer array: It came as a shocker when I couldn't get this to work right away. However a quick google search gave me a whole bunch of answers. I have written the method below:
      public int[] getIntArrayFromString(String s) {
      int[] result = new int[s.length()];
      for(int i =0; i < s.length(); i++) 
        result[i] = Character.digit(s.charAt(i));
      return result;
    }
    
    The Character wrapper class comes to rescue here. However the logic for digit is pretty similar to C logic. Where the char ASCII vale is taken and subtracted from ASCII value of One '1'.
  2. Reversing a string:
    Again using String Buffer to do this is the best method possible.One from the front and the other from the rear.
     
      public static String revertString(String msg) {
          StringBuffer sb = new StringBuffer();
          for(int i=msg.length() - 1, i >= 0; i++ )
              sb.append(msg.charAt(i));
          return sb.toString();
      }
    
Super simple stuff wanted to see if my coding tags work.

Wednesday, April 18, 2012

How to Fix ConcurrentModificationException?

I was recently writing a java program to find dependency jars for a given Jar. The approach was pretty simple. I had two HashMaps.
One to store the final list of jar dependencies and the other to store the visited Jar names. This way I could keep track of my recursive loop and wouldn't loose my way if there were any circular dependencies. A little background, the jar in question had about 500 dependency jars and many had cyclic dependencies. Here is my initial code which threw the ConcurrentModificationException.
import java.util.HashMap;
....

public class FindJarDependencies {
   String pathToInitialJar;

  // Mapping from "name of jar" -> "path of jar"
  Map dependencies = new HashMap();
  // Mapping from "name of jar" -> "True|false" ( True, if jar has been visited otherwise  false)
  Map visitedJars = new HashMap();
   
  public List getDependenciesForJar(String pathToInitialJar) {
    List result = ArrayList();
    Iterator iter = dependencies.valueSet().iterator();
    while (iter.hasNext()) {
      result.add(iter.next());
    }
    return result;
  }

  /**
   * In view of having a short blog, 
   * lets assume this method adds the manifest-classpath 
   * for a given jar into the dependency Map. 
   */
  private void addJarDependencies(String pathOfJar) {
    // Open the jar file and add manifest-classpath to dependencies Map.
  }

  public void walkDependencyJar(String pathOfJarDependency) {
     // Strip name from path of jar
     String jarName = getNameFromPath(pathOfJarDependency);

     // add jar if not present in dependency Map.
     if (!dependency.get(jarName)) 
       addJarDependencies(pathOfJarDependency);


    // Add dependency Map values to visitedJars. 
    // By default the value would be false.    
    for (String s : dependencies.keySet()) {
      if (!visitedJar.containsKey(s)) {
        visitedJar.put(s,false);
      }
    }
    
    // Iterate through the visitedJars and add them to the dependency as and when 
    // you find new jars.
    Iterator iter = visitedJars.keySet().iterator();
    while(iter.hasNext()) {
      String jarClasspath = iter.next();
      if (!visitedJar.get(jarClasspath)) {
        visitedJar.put(jarClasspath, true);         // Oops ConcurrentModificationException
        walkDependencyJar();
      }          
    }   
  }
}

When I ran this program all hell broke loose on line number 54. On further debugging I figured out the problem.
In my code I was iterating over "visitedJar" at line 51 but inside the same loop at line number 54 I am trying to change the Map. This was the root cause. Java Iterator doesn't allow for changes to iterating data structure. For better understanding I wrote a stripped down version which throws the same error.

package com.example.ConcurrentModificationExample;

import java.util.*;

public class ConcurrentModificationExample {
  static Map map = new HashMap();

  public static void main(String[] args) {
    map.put(1, false);
    map.put(2, false);
    map.put(3, false);
    map.put(4, false);

    Iterator iter = map.keySet().iterator();
    while(iter.hasNext()) {
      int value = iter.next();
      System.out.println("Value is: '" + value +"'");
      if (value == 3)
        map.put(5, false); // place where ConcurrentModificationException occurs
    }
  }
}
When I ran this code. I was able to reproduce the problem. Wala I knew exactly what was going on. After some googling I found couple of good resources and the way out. There are different solutions to this problem. They are:
  • Use the iterator to perform data structure manipulation
  • The Iterator provides manipulation by the remove() method. However in this case you would like to insert and not remove.
  • The other solution is to use ConcurrentHashMap .
  • blog
  • Use a synchronized block within your code.
However in my code I went ahead with ConcurrentHashMap and it worked fine. If time permits I would like to make this a multi threaded program. May become a topic for my later posts.

Friday, March 9, 2012

Journey with python

Most parts of my programming experience have been in C and Java. I have written a fair amount of code mostly in Java for my daily bread winning purposes. I haven't really worked on a scripting language before. I did get my hands dirty with Perl for parsing through huge sized test logs. However the experience was primarily Regular Expression 101.

I recently bought the book python programming and have gotten my hands dirty. I am especially thrilled to work on the examples and see how python will help launch my web development skills.

I will keep posting as and when I have something cool to show.

Wednesday, February 15, 2012

Trying out new things

A long time dream just materialized, yesterday. I have my very own home-office with a three monitor setup with three gorgeous machines at my disposal.
To get started I first installed synergy and setup a single keyboard and mouse for multiple laptops. Will be updating this blog as and when something cool materializes.

Sign off...