Removing unused references in dot net solutions

By pratyak at July 27, 2014 17:42
Filed Under: Software

Several tools exist that try resolving references and removing unused ones but none really do the job. Read more about it here.

This prompted me write my own. The idea is simple, read the references by itemgroups in each project of the solution, remove it, build it and if there are errors go back to prebuild solution.

Once the process completes, we would have removed all unused references.

Build time is the bottleneck here; unless you do it too often, running the tool once in a while for large projects isn't going to hurt.

The source repository of project aptly named ResolveUR - resolve unused references, is at github.

String, binary string and Python

By pratyak at January 07, 2014 15:07
Filed Under: Software

Well something like: mybinarystr = b'asdfg' is a binary string and mystr = 'asdfg' is a string in (mighty) python.

Then, how do you inter-convert literals or variables of either type? Here it is:

  • String to byte string
    mystr = bytes(mybinarystring, 'utf-8') Substitute utf-8 with ascii, latin...
  • Binary string to string
    mybinarystring = mystr.decode("utf-8")
  • Phew!

Cloning an existing git repository originally cloned from svn

By pratyak at March 05, 2013 19:11
Filed Under: Software

Would be a one liner - git clone [path] [local path] you would think. Not!


Git clone knows nothing about any existing svn remotes and hence completely ignores that silo. There are manual steps involved and even after those revision map file doesn't get copied over. I got around to writing a script that can setup git clone with svn remotes from a git file share repository ready to use. Here it is: (make sure you modify relevant paths and stuff)


UPDATE: A better script is on top.

# if prompted for password, elect ‘permanent’ save of certificate information.

# Re-run this script if post repo creation doesn’t pass a simple test with ‘git svn rebase’

# init required params

$rootDir = "c:\dev"

$sharePath = "[machinename]/dev"

$gitFolder = ".git"

# create root dir

mkdir $rootDir

cd $rootDir

# new repo

git init

git remote add origin file:////$sharePath/$gitFolder

# Prevent fetch/pull from remote git server in the future,

git config --replace-all remote.origin.fetch '+refs/remotes/*:refs/remotes/*'

git fetch

# we only want to use git svn for future updates

git config --remove-section remote.origin

# Create a local branch from one of the branches just fetched

git checkout -b master FETCH_HEAD

# Initialize 'git svn' locally (be sure to use the same URL and -T/-b/-t options as were used on server)

git svn init

# Pull the latest changes from Subversion

git svn rebase


# done!

Write-Host "Git repo clone complete!"

-------------------------------------Old Script ---------------------

# init required params
$rootDir = "c:\dev"
$sharePath = "[machine-name]/[path]"
$revMapPath = "svn\refs\remotes\git-svn"
$gitFolder = ".git"

# create root dir
mkdir $rootDir
cd $rootDir

# clone repo with master branch from source share
git clone file:////$sharePath/$gitFolder -b master .

# copy svn config
cd $rootDir\$gitFolder\
Add-Content config @"
[svn-remote "svn"]
	url = https://[domain]/svn/svn-repos/[path]/Trunk
	fetch = :refs/remotes/git-svn

# this will fail but will create svn refs folders letting us copy missing rev map hash file
cd $rootDir
git svn rebase

# copy rev_map hash file since refs path's created
copy-item \\$sharePath\$gitFolder\$revMapPath\.rev_map* $rootDir\$gitFolder\$revMapPath\

# re-run git svn rebase, which should succeed.
git svn rebase

# done!
Write-Host "Git repo clone complete!"


Git Powershell Aliases

By pratyak at February 15, 2013 19:54
Filed Under:

Wrote a set of useful functions to work with git and few for git-svn. Shared @

Git Merge vs Rebase

By pratyak at February 15, 2013 04:34
Filed Under: Software

As I was reading several posts this morning about how git merge differs from rebase. It dawned on me that it's really simple to understand this in a picture. Developers don't generally draw as often as they code. I also discovered the other day while talking to my spouse that I forgot lot of things about photoshop I used to love. Yeah, you guessed it. This post show the difference between git merge and rebase graphically. Only thing not represented here is the fact that while rebasing the resut of replaying local committs on top results in NEW git commit ids.



Bad Drivers - Just Bad attitude - Bad courtesy

By pratyak at January 11, 2013 02:39
Filed Under: People

And you knew this was a rant about somebody's bad driving. Smile


Yeah. Was driving to work the other day and got stopped by a garbage truck ahead of me. Knowing garbage pickup might take few minutes, I decided to overtake(!). So I signal and move left and barely turned my head to look behind and discovered I almost dodged a collision.


The guy behind me was rushing past me doing the same thing as I. What more, he was in rage and started yelling. Well, rage is an infective emotion. Before I could calm myself, I blamed him for rushing past me, he had no reason to be rude or rash. He probably wanted to take it further and was going to get out of his car, to get into a fight or whatever sorts. That'll be a new one for me in many years.


I look ahead of me and see the garbage trunk has now moved further. I tell myself, it's not worth my time for arguments so I simply drive ahead calming myself, him behind.


First, it was my mistake for not being patient enough for the garbage trunk to pass. Second, guy behind me trying to overtake to get past the truck while seeing me move was being stupid and uncourteous. Our basic driving sense is to let vehicle before us pass, unless we think we own the road. It remined me of India, traffic in most places is ruled by who can get into empty space first.


Moral of story: Be courteus and be patient. It's worth the time.

Phone or SMS Alerts for FREE with Google Voice in your C# app

By pratyak at October 08, 2012 19:04
Filed Under:

Yeah! I mean free with no cost. Fine print is it works free for calls within US only.

Quite simple to setup. Activate Google voice and get a new number from them. When the wizard prompts, select your US Mobile number.

Use the SharpVoice.cs file in app and place call or SMS:

var voiceConnection = new Voice("[Gmail username]""[gmail password");

voiceConnection.login();"[Google voice number]""[your mobile number]");


// SMS

voiceConnection.sendSMS("[Google voice number]", "SMS Text Message");

Yep, it's that simple! Smile

WHY would you use it? You are away and want to monitor on your laptop/PC/server and need an alert when something is out of whack, like a service or app is down. You DO need to have network(internet) access though.


File Attachments Here:

SharpVoice.cs (12.86 kb)

Returning objects vs null

By pratyak at September 19, 2012 10:11
Filed Under: Software

Read or heard this somewhere a while back that returning null objects at times is a bad thing. Better to return an empty object and so entire codebase follows this premise. Rationale was real and clear at that time.

This issue came up couple of years ago but for the life of me I couldn't remember the rationale but it seems to have come back now so this post :-)


The most convincing reason is specific to programming environments with garbabge collectors. With complex, generational garbage collectors in multithreaded environments, returning null from methods can give unexpected results. The simpler reason is obviating the need for unnecessary null checks.

For e.g, you get some collection returned from another method and you wish to operate on it. You might use lambdas (c#, ruby) or plain old loops (POL). In either case if your method returns null you'll need to test for it before you operate on it. If you returned a collection object(a container) with no items, you'll need no null checks. Iterative/Recursive operations would complete without the need for null checks. 

Another case is when you use method returns for a conditional test. Methods that return null will require you to save the return to a variable, examine if it's null and proceed to use anything interesting in it. If you make it a practice to return objects instead, conditionals can simply examine method returns in a single statement. Compare:

object MethodA(){ .. .. .. return o; }

void MethodB(){

   object o = MethodA();

   if ( o != null and o.Property == false) { // do stuff }


To this:


void MethodB(){

   if ( MethodA().Property == false) { // do stuff }



Destructive human behavior at work

By pratyak at October 09, 2011 09:41
Filed Under:

This happens every day around you. Somebody says something personal on phone or to a co-worker that's overheard. Prying co-worker asks sensitive questions looking for potentially destructive information they can use against you. Complements that have sexual connotations. Invading personal space without permission. Ingrate behavior to simple greeting like you say good morning and there'll be no return. This list goes on, different situations different circumstances. The purpose of all of these is the same. Idle mind, devil workshop. 


Back-biting, tale-bearing and hangel-mongering. And if it's a supervisor or boss type add asinine micro-management to it. Favorite pass times of people who can't mind their own business. Problem with such people particularly at work if you are polite and calm is, you will hesitate to say something curt or rude and this works to evil's advantage. You may ask why these people do such nasty things. It's just the diabolical nature of humans concealed that gets out. People who do it consciously and willfully have just killed their soul and given it to the devil.


A person who cares for their job and treats others as he/she wants to be treated themselves will abhor such behavior. Unfortunately, most work spaces in companies are infested with a majority of these evil-natured people. You see, where you spend eight hours of your quality time gives a lot of scope to explore these menial traits of evil left within.


Over years of work, I've seen many sincere and hardworking people leave their jobs when pestered by people described above. Personally it's disheartening to see how company at large suffers due to this. The diablo is still there causing mayhem while companies go on hiring bouts that are not just expensive on time and money but on opportunity. Not having the right candidate to get the job done can make a difference in having market share or not. Unfortunately most companies believe such incidents are minor and don't impact them as much. But the sad fact is that they do. It's like smoking. Most smokers justify their habit saying it's mild enough not to affect them, people around them or the environment but the sad truth known from copious amount of published medical literature is that it does it's damage over time. Accrual principle hold nicely not just in accounting. 


How can you deal with such people?

The first instance of such a behavior must establish a precedent that such and such a person is a potential behavioral diablo.

The next instance must make it clear to this person that such questions are none of their business and if they want more of such information they can talk to your manager or HR.


Any following instances must be replied with silence with or without a walkaway.

If the person talking has any honor and shame left, they'd stop.

If that still continues, the final call is to make it up in writing and send it to multiple supervisors of the co-worker.

At no point these people should be engaged in conversation, you'd be fueling the fire. 


Efficiency of Array.Sort in .Net

By pratyak at January 08, 2011 10:38
Filed Under: Software

While running sort using Array.Sort() on an array of objects in .Net, I happened to use it with a compareTo since objects had some integers used for sort criterion. While writing this, I placed some diagnostic statements to see how many times compareTo was used. To my suprise, a mere 7 element array took 18 compares. I then replaced sort with a quicksort function which took 12 compares. Wanting to explore this further, I expanded test to double the number of elements and counted compares. Below is the output and code used to test this. At least 30% more comparisons are being made by .Net Array.Sort on average which is inefficient. Are better off writing our own sort? 


------------------Console Output--------------------------------



.Net Array.Sort Hit Count for 10 elements: 48

Hand-written QSort Hit Count for 10  elements: 35

HitCount Diff: 13

Hit Count Fractional Increase: 27.08


.Net Array.Sort Hit Count for 20 elements: 163

Hand-written QSort Hit Count for 20  elements: 83

HitCount Diff: 80

Hit Count Fractional Increase: 49.08


.Net Array.Sort Hit Count for 40 elements: 359

Hand-written QSort Hit Count for 40  elements: 208

HitCount Diff: 151

Hit Count Fractional Increase: 42.06


.Net Array.Sort Hit Count for 80 elements: 848

Hand-written QSort Hit Count for 80  elements: 546

HitCount Diff: 302

Hit Count Fractional Increase: 35.61


.Net Array.Sort Hit Count for 160 elements: 1932

Hand-written QSort Hit Count for 160  elements: 1246

HitCount Diff: 686

Hit Count Fractional Increase: 35.51


.Net Array.Sort Hit Count for 320 elements: 4567

Hand-written QSort Hit Count for 320  elements: 3050

HitCount Diff: 1517

Hit Count Fractional Increase: 33.22


.Net Array.Sort Hit Count for 640 elements: 10778

Hand-written QSort Hit Count for 640  elements: 7120

HitCount Diff: 3658

Hit Count Fractional Increase: 33.94


.Net Array.Sort Hit Count for 1280 elements: 23410

Hand-written QSort Hit Count for 1280  elements: 15363

HitCount Diff: 8047

Hit Count Fractional Increase: 34.37


.Net Array.Sort Hit Count for 2560 elements: 50795

Hand-written QSort Hit Count for 2560  elements: 36584

HitCount Diff: 14211

Hit Count Fractional Increase: 27.98


.Net Array.Sort Hit Count for 5120 elements: 113708

Hand-written QSort Hit Count for 5120  elements: 78454

HitCount Diff: 35254

Hit Count Fractional Increase: 31


.Net Array.Sort Hit Count for 10240 elements: 248855

Hand-written QSort Hit Count for 10240  elements: 170283

HitCount Diff: 78572

Hit Count Fractional Increase: 31.57


.Net Array.Sort Hit Count for 20480 elements: 541349

Hand-written QSort Hit Count for 20480  elements: 389608

HitCount Diff: 151741

Hit Count Fractional Increase: 28.03


.Net Array.Sort Hit Count for 40960 elements: 1147178

Hand-written QSort Hit Count for 40960  elements: 746562

HitCount Diff: 400616

Hit Count Fractional Increase: 34.92


.Net Array.Sort Hit Count for 81920 elements: 2393047

Hand-written QSort Hit Count for 81920  elements: 1682768

HitCount Diff: 710279

Hit Count Fractional Increase: 29.68


.Net Array.Sort Hit Count for 163840 elements: 5129217

Hand-written QSort Hit Count for 163840  elements: 3705967

HitCount Diff: 1423250

Hit Count Fractional Increase: 27.75


.Net Array.Sort Hit Count for 327680 elements: 11312711

Hand-written QSort Hit Count for 327680  elements: 7635725

HitCount Diff: 3676986

Hit Count Fractional Increase: 32.5


.Net Array.Sort Hit Count for 655360 elements: 22918028

Hand-written QSort Hit Count for 655360  elements: 15814584

HitCount Diff: 7103444

Hit Count Fractional Increase: 31



--------------------Code used for this exercise is:-----------------------------------

using System;
using System.Text;

namespace SortTest
    class Program
        static MyInt[] data;
        static void Main(string[] args)

            int diff = 0;
            double frac = 0.0;
            for (int i = 10; i < 1000000; i *= 2)
                Console.WriteLine(".Net Array.Sort Hit Count for " + i.ToString() + " elements: " + hitCount.ToString());
                int prevHitCount = hitCount;
                hitCount = 0;

                qsort(ref data, 0, i - 1);
                Console.WriteLine("Hand-written QSort Hit Count for " + i.ToString() + "  elements: " + hitCount.ToString());
                diff = prevHitCount - hitCount;
                Console.WriteLine("HitCount Diff: " + diff.ToString());
                frac = Math.Round((diff * 1.0/prevHitCount) * 100, 2);
                Console.WriteLine("Hit Count Percent Diff: " + frac.ToString());


        static void qsort(ref MyInt[] d, int l, int u)
            if (l >= u)
            int m = l;
            MyInt tmp = null;
            for (int i = l + 1; i <= u; i++)
                if (d[i].CompareTo(d[l]) > 0)
                    tmp = d[m];
                    d[m] = d[i];
                    d[i] = tmp;

            tmp = d[l];
            d[l] = d[m];
            d[m] = tmp;

            qsort(ref d, l, m);
            qsort(ref d, m + 1, u);


        static void buildData(int sz)
            data = new MyInt[sz + 1];
            Random r = new Random(sz);
            int i = 0;
            while (i < sz + 1)
                data[i] = new MyInt();
                data[i++].intVal = r.Next(sz);

        static int hitCount;
        class MyInt : IComparable
            public int intVal = 0;
            public int CompareTo(Object o)
                MyInt i = (MyInt)o;
                return (i.intVal - this.intVal);