Sunday 14 October 2012

Building a Rig

Hey Fellas

Its been a while that I updated any stuff on my blog. Actually I was having troubles with my laptop that used to die but I could not accept. Every time it will go off, I would get a CPR (repair/refurbish) and it will run again for few months.
To start with my long story, I actually own(ed) a HP DV9734tx laptop. This was in February - 2008. 
Some quick specifications:
  1. 17" (16:10 Aspect Ratio) 1440 x 900 WXGA
  2. Intel Core 2 Duo T8100 (2.1 GHz, 3M Cache)
  3. Intel 965OM Chipset
  4. 3 GB DDR2 RAM 667Mhz
  5. 500 GB HDD (250X2 SATA) 5400 RPM
  6. Nvidia GeForce 8600M GS 512MB
  7. LightScribe DVD R/W
  8. Wireless, Ethernet, Bluetooth
  9. Remote Control, Finger Print
  10. Altec Lansing Audio
To be honest, I was a novice with specs at that time (Just went for a Large Screen, Processor and GPU).
Though the stuff I chose was the best in the market (and costly too). I was very happy with the machine I bought and I would spend hours and hours of my life on it (mostly playing online games with my buddies).
Then came October - 2010 when my laptop crashed for the first time.

Symptoms:
I just switched it on, the windows Vista (Home Prem.) login screen came up and I started seeing colored lines on display. These lines grew in count (the ones that you see if the RAM is faulty). So I rebooted the laptop, and it never came up.
Some lessons learnt:
  • Assume a laptops life is 3 Years.
  • Never use a laptop on Bed/Pillow where the Heat sink cannot exhaust hot air.
  • Read a lot of reviews before buying an electronic product.
To shorten the story, I got it repaired for the first time, the shopkeeper told me that the mobo has to be replaced, so I spent about 1/6 of the actual cost of laptop.
The laptop worked for 2-4 Months (shop covered the repair warranty for 1 Month).
Then when it dies 2nd time the other guy told me it was GPU issue and it cost me about 5K.

Now I started researching and found about faulty product line (HP DV9000 series) and pending law suit.
The problem was in the Mobo design. The GPU and CPU sit next to each other with practically no
heat isolation. And to top that, they share same heat sink. So my heated CPU was frying up the GPU.
Anyways, it was too late to understand this, so I got it repaired a 3rd time before losing faith in it,
This time I used a Belkin Heat Sink dock. But the GPU was destined to failed.

In 2012 when it failed for the last time, I gave up the affection I had. Having spent over 90K on this piece of ever-dying hardware killed me. Thats when I decided to get a desktop. Instead I decided to build myself one so that I can rest assured that all components that I chose aren't faulty.

I also learnt that its better to chose wisely, as I do not want to run into another sad investment.
Here is what my configuration looks like:
  • Intel 3rd Gen Core i5 3550
  • AsRock z77 Extreme4
  • Corsair Vengeance 1600 - 4GBX2
  • Seagate Barracuda ST2000DM001 - 2TB 7200.14 RPM 6Gb/s SATA 3.0
  • Cooler Master Thunder 500W
  • Cooler Master Elite370 Cabinet
  • ASUS E-Green DVD R/W
  • 2 X Cooler Master 1200mm Fans
  • Samsung S20B300 20" LED (16:9)
  • Altec Lansing 2.1
  • APC back UPS 1100V (650W)
  • 250 GB X 2 SATA 5400RPM (from my laptop)
All the stuff cost me around 55K (+ expenses of travelling).
I did not choose the K series processors as I know I am not going to Over Clock (and kill my PC).
I chose an AsRock mobo (over ASUS) just to have latest features in an affordable price.
I got a UPS back up in this era because the country I live in still has power outages.

Overall, it was a great period of about 1 Month over which I got all the components and built (with seagate HDD failing, and replacement taking about 2 Weeks) the machine. Feels great to work on a PC I have built down to each screw and bolt.

Friday 3 August 2012

Python - Last Minute Code

Two weeks back I attended a much awaited training to learn python. The syntax was (funny) new and needed attention to (whitespaces) details. After the training was over (phew...) we had to submit a script code!!!
This was the time to put my learning (graspings) to test.
Posting below the code that I wrote (Incomplete though) just to keep an archive of how python works:


class Stock:
def __init__(self, stockTicker, stockName, purSize, purPrice):
self.Ticker=stockTicker
self.Name=stockName
self.PurchaseSize=purSize
self.PurchasePrice=purPrice

def __str__(self):
return '%s,%s,%d,%f' % (self.Ticker,self.Name,self.PurchaseSize,self.PurchasePrice)


def main():
choice='x'
while choice.upper()!='Q':
createMenu();
choice = raw_input('\n\t:\>')


if choice.upper()=='A':
addStocks();
if choice.upper()=='L':
loadFile();
if choice.upper()=='D':
deleteStock();
#--------------- End of Main Method ---------------------#


def addStocks():
tckr = raw_input('Ticker: ')
name = raw_input('Name: ')
size = input('No. of Shares: ')
price = input('Purchase Price: ')
stk = Stock(tckr,name,size,price)
saveStockInFile(stk);
#--------------- End of addStocks Method ---------------------#


def deleteStock():
stkTicker = raw_input('Ticker: ')
filePtr = open('MyPortfolio.txt', 'r');
del LoadedStocks[:]
while True:
try:
LoadedStocks.append(pickle.load(filePtr));
except EOFError:
break;



for stk in LoadedStocks:
if stk.Ticker == stkTicker:
LoadedStocks.remove(stk);
break;

filePtr.close();
filePtr = open('MyPortfolio.txt', 'w');
filePtr.write('');
filePtr.close();


for stk in LoadedStocks:
saveStockInFile(stk)
#--------------- End of deleteStock Method ---------------------#


def loadFile():
filePtr = open('MyPortfolio.txt', 'r');
del LoadedStocks[:]
while True:
try:
LoadedStocks.append(pickle.load(filePtr));
except EOFError:
break;


filePtr.close();


for stk in LoadedStocks:
print str(stk)
#--------------- End of loadFile Method ---------------------#


def createMenu():
print '\n\t\tWelcome to Portfolio Manager (ver 1.0)'
print '\t\t--------------------------------------'
print '\n - What would you like to do Today?'
print '\n\t(A)dd Stocks\n\t(D)elete Stocks\n\t(L)oad File\n\t(U)pdate Prices\n\t(R)eport\n\t(Q)uit:'


def saveStockInFile(stk):
filePtr = open('MyPortfolio.txt', 'a');
#line = 'Ticker=%s\nName=%s\nShares=%d\nPurchase Price=%f'%(stk.Ticker, stk.Name, stk.PurchaseSize, stk.PurchasePrice)
#filePtr.write(line)
pickle.dump(stk, filePtr)
filePtr.flush();
filePtr.close();


import pickle;
LoadedStocks = []
main();

Monday 11 June 2012

Cracking the Code

Expression Evaluation Problem

I came across this problem (I am unwilling to share the source, however this might be helpful in a wrong way to some fellows). So, the crux is, design/suggest improvements over a given code for a given scenario.

C# Coding/Design Task
A junior member of your team has been asked to create a simple calculation module
(and related tests) that can process arithmetic commands with the input specification:
Grammar:
cmd::= expression* signed_decimal
expresion::= signed_decimal ' '* operator ' '* operator::= '+' | '-' | '*'
signed_decimal::= '-'? decimal_number 
decimal_number::= digits | digits ‘.’ 
digits digits::= '0' | non_zero_digit digits* 
non_zero_digit::= '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'

He has produced the following Code. What changes will you suggest? Please consider the quality of the solution (including the design), and provide an updated version of the code, applying your suggestions.

Given Version of Code:


Calculator.cs
using System;

namespace Calculator
{
///<summary>
///Basic calc engine for handling +, -, * operations.
///</summary>
public class CalcEngine
{
///<summary>
///Process a calculation command string
///</summary>
///<param name="p">cmd</param>
///<returns></returns>
public string Process(string p)

{

String[] stuff = p.Split(' ');

double result = 0;

bool nextOpAdd = false;

bool nextOpSubtract = false;

bool nextOpMultiply = false;

foreach (string x in stuff)

{

try

{

double nextVal = Double.Parse(x);

if (nextOpAdd)

result += nextVal;

else if (nextOpSubtract)

result -= nextVal;

else if (nextOpMultiply)

result *= nextVal;

else

result = nextVal;
}
catch

{

nextOpAdd = false;

nextOpSubtract = false; nextOpMultiply = false;if (x == "+")
nextOpAdd = true;else if (x == "-")
nextOpSubtract = true;else if (x == "*")
nextOpMultiply = true;
}
}
return result.ToString();
}
}
}
//-------------------- This is the NUnit Test Class ------------------//
using Calculator;
using NUnit.Framework;
namespace TestCalculator
{
[TestFixture]
public class CalcEngineTest
{
[Test]
public void Test()
{
CalcEngine engine = new CalcEngine(); System.Console.WriteLine(engine.Process("1 + 2"));
}
}
}

Solution Design:
Given Grammar:
cmd::= expression* signed_decimal
expresion::= signed_decimal ' '* operator ' '* operator::= '+' | '-' | '*'
signed_decimal::= '-'? decimal_number decimal_number::= digits | digits ‘.’ digits digits::= '0' | non_zero_digit digits* non_zero_digit::= '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
Assumption: Signed Decimal and Operator may not be separated by spaces. i.e. 5+2-3 * 6+ 2 is a valid scenario and it should evaluate to 26.
Based on my understanding of the Given Predicate/Grammar & from the given code
I have the following observations:

  • Developer code is based on a strict rule that operands and operators will be separated by space
  • (that’s why use of .Split(‘ ‘) ). This may not be true and should be able to handle variety of inputs.
  • All the code lies within one method (Process()), which may grow unmaintainable.
  • One Boolean variable for each operation has been used, Design is not flexible/adaptable for addition of more operators (like divide, square root etc.)
  • Code has operator detection logic handled in Catch block. Actually, catch block shouldn’t be used for input verification purpose.
  • Program State is not being maintained, as all code is within single method.
  • Generation of test suites/cases for such code is little tricky.
  • No naming conventions were followed.
  • Use logical and contextual names for local variables
  • Use variable/object pooling as and when possible instead of creating local variables.
Suggestions:

  • Modularize code into logical units (classes) [as shown in code below]
  • Return proper/informative error codes/messages as and when needed.
  • Maintain state of the application using classes/objects
  • Though I too have used ForEach loop, but For performs better, so this program can be tuned more for performance
  • Modularized code is better maintainable, readable and extendable
  • Usage of Switch construct instead of if else if makes code flexible for future modifications
  • CCommand class manages the user input and has a property that will store computed Result.
  • CBetterCalcEngine class manages state of the Calculation Engine/Application
  • TryParse has been used instead of Parse.




namespace BetterCalculator
{
       class Program
       {
              static void Main(string[] args)
              {
                     CCommand cmdObj = new CCommand("1 + 2 + 3+4+5");
                     CBetterCalcEngine myEngine = new CBetterCalcEngine(cmdObj);
                     EErrorCodes eCode = myEngine.Compute();
              }
       }
       // Instead of a bool for each operator, using delegate
       public delegate double ExpressionOperators(double op1, double op2);
       public enum EErrorCodes
       {
              NoError,
              InvalidCommandString,
              InvalidOperands,
              InvalidOperation,
              DivideByZero,
       }
       public class CBetterCalcEngine
       {
              //Using Customized logic of Expression Evaluation
              //Traverse the user input expression from Left to Right
              //If you encounter Operand (Multi-Digit), push into Stack
              //If you encounter Operator, Enqueue into a Queue
              private CCommand InputCommand;
              private Stack<double> OperandStack;
              private Queue<char> OperatorQueue;
              public CBetterCalcEngine(CCommand userCommand)
              {
                     InputCommand = userCommand;
                     OperandStack = new Stack<double>();
                     OperatorQueue = new Queue<char>();
              }
              public EErrorCodes Compute()
              {
                     double nextOperand = 0, result = 0, op1, op2; OperandStack.Clear();
                     OperatorQueue.Clear();
                     string operand = string.Empty;
                     foreach (char opChar in InputCommand.Command)
                     {
                           if (opChar == ' ')
                           {
                                  continue;
                           }
                           if (InputCommand.IsValidOperator(opChar) == false)
                           {
                                  operand += opChar;
                           }
                           else
                           {
                                  if (Double.TryParse(operand, out nextOperand) == false)
                                  {
                                         return EErrorCodes.InvalidOperands;
                                  }
                                  OperandStack.Push(nextOperand);
                                  OperatorQueue.Enqueue(opChar); operand = string.Empty;
                                  if (OperandStack.Count == 2)
                                  {
                                         op1 = OperandStack.Pop(); op2 = OperandStack.Pop();
                                         ExpressionOperators operation = InputCommand.GetOperation(OperatorQueue.Dequeue());
                                         if (operation != null)
                                         {
                                                result = operation(op2, op1); OperandStack.Push(result);
                                         }
                                         else
                                         {
                                                return EErrorCodes.InvalidOperation;
                                         }
                                  }
                           }
                     }
                     if (OperandStack.Count == 1 && OperatorQueue.Count > 0)
                     {
                           if (Double.TryParse(operand, out nextOperand) == false)
                           {
                                  return EErrorCodes.InvalidOperands;
                           }
                           OperandStack.Push(nextOperand); operand = string.Empty;
                           if (OperandStack.Count == 2)
                           {
                                  op1 = OperandStack.Pop(); op2 = OperandStack.Pop();
                                  ExpressionOperators operation = InputCommand.GetOperation(OperatorQueue.Dequeue());
                                  if (operation != null)
                                  {
                                         result = operation(op2, op1); OperandStack.Push(result);
                                  }
                                  else
                                  {
                                         return EErrorCodes.InvalidOperation;
                                  }
                           }
                     }
                     else
                     {
                           return EErrorCodes.InvalidOperands;
                     }
                     InputCommand.Result = OperandStack.Pop().ToString(); return EErrorCodes.NoError;
              }
       }
       public class CCommand
       {
              //Stores user Input Command/Expression
              public string Command { get; set; }
              //Computed Result of the Command/Expression
              public string Result { get; set; }
              //For future extension. Add new operator to this Variable
              public string ValidOperators = "+-*";
              public CCommand(string commandString)
              {
                     Command = commandString; Result = string.Empty;
              }
              public bool IsValidOperator(char opChar)
              {
                     return ValidOperators.Contains(opChar);
              }
              public ExpressionOperators GetOperation(char currentOpertor)
              {
                     // For future extension. Add Case for the new operator here
                     switch (currentOpertor.ToString())
                     {
                           case "+":
                                  return AddOperation;
                           case "-":
                                  return SubstractOperation;
                           case "*":
                                  return MultiplyOperation;
                           default:
                                  return null;
                     }
              }
              private double AddOperation(double op1, double op2)
              {
                     return op1 + op2;
              }
              private double SubstractOperation(double op1, double op2)
              {
                     return op1 - op2;
              }
              private double MultiplyOperation(double op1, double op2)
              {
                     return op1 * op2;
              }
              // For future extension. Add Handler Method for the new operator here
       }
}
·This code can still be tuned/refined for performance
·Try Catch block exception handling can be employed.