Bug Vanquisher

29 October 2009

The World Of Bizarre and Eccentric Failures

Filed under: Tips — Tanveer Badar @ 12:21 PM

public IEnumerable<int> GetIntegers( )
{
    if( <some condition> )
        yield return null;
    yield return <some other value;
}

and the other beauty

public IList<int> Integers { get; set; }

Now befuddled when foreach fails with a NRE. Or when someone extra smart says Integers = null; But don’t blame the other guy who is using your code.

When returning a collection, it is expected that collection itself will never be null (short of OutOfMemoryException)) even when it is empty. Properties which return a collection interface should never have public setters.

23 October 2009

Story of a Parser

Filed under: Dev inside!, Tips — Tanveer Badar @ 8:31 AM

A quick and dirty, precedence parser I wrote in about 2 hours. Minimal error handling, (may be) able to parse expressions of the form

expr := expr combiner expr | expr op ( expr | list ) | term
combiner := AND | OR
op := ‘=’ | in
list := ( term ) | ( term , list )
term := ‘identifer or literal’

op will include usual comparison operators soon. List can only be specified if op is ‘in’. Code follows, you should be able to add the missing pieces yourself as not much more can be revealed.:

public static partial class Parser
{
    static Expression BuildTree( string expr )
    {
        int startIndex = 0;
        Stack<Expression> stack = new Stack<Expression>( );
        BuildTreeRecursive( expr , ref startIndex , stack );
        return stack.Pop( );
    }

    private static void BuildTreeRecursive( string expr , ref int startIndex , Stack<Expression> stack )
    {
        string combiner = null;
        while( startIndex < expr.Length )
        {
            Expression expr1 = null;
            if( string.IsNullOrEmpty( combiner ) )
            {
                expr1 = RecognizeExpression( expr , ref startIndex );
                EatWhiteSpace( expr , ref startIndex );
                combiner = RecognizeOperator( expr , ref startIndex );
            }
            Expression expr2 = null;
            switch( combiner.ToUpper( ) )
            {
                case "AND":
                    expr2 = RecognizeExpression( expr , ref startIndex );
                    stack.Push( new BinaryExpression
                    {
                        LeftSide = expr1 ,
                        RightSide = expr2 ,
                        Type = Expression.Operator.And
                    } );
                    EatWhiteSpace( expr , ref startIndex );
                    combiner = RecognizeOperator( expr , ref startIndex );
                    EatWhiteSpace( expr , ref startIndex );
                    break;
                case "OR":
                    BuildTreeRecursive( expr , ref startIndex , stack );
                    if( stack.Count > 0 )
                        expr2 = stack.Pop( );
                    if( stack.Count > 0 )
                        expr1 = stack.Pop( );
                    stack.Push( new BinaryExpression
                    {
                        LeftSide = expr2 ,
                        RightSide = expr1 ,
                        Type = Expression.Operator.Or
                    } );
                    EatWhiteSpace( expr , ref startIndex );
                    combiner = RecognizeOperator( expr , ref startIndex );
                    EatWhiteSpace( expr , ref startIndex );
                    break;
            }
        }
    }

    private static Expression RecognizeExpression( string expr , ref int startIndex )
    {
        EatWhiteSpace( expr , ref startIndex );
        string attrib = RecognizeAttribute( expr , ref startIndex );
        EatWhiteSpace( expr , ref startIndex );
        string op = RecognizeOperator( expr , ref startIndex );
        EatWhiteSpace( expr , ref startIndex );
        switch( op.ToUpper( ) )
        {
            case "=":
                string value = RecognizeWord( expr , ref startIndex );
                return new BinaryExpression
                {
                    LeftSide = new ConstantExpression( attrib ) ,
                    RightSide = new ConstantExpression( value ) ,
                    Type = Expression.Operator.Equal
                };
            case "IN":
                List<string> values = RecognizeList( expr , ref startIndex );
                return new BinaryExpression
                {
                    LeftSide = new ConstantExpression( attrib ) ,
                    Type = Expression.Operator.In
                };
        }
        return new Expression( );
    }

    private static List<string> RecognizeList( string expr , ref int startIndex )
    {
        List<string> values = new List<string>( );
        if( expr.Length <= startIndex || expr [ startIndex ] != ‘(‘ )
            return values;

        ++startIndex;

        do
        {
            EatWhiteSpace( expr , ref startIndex );
            values.Add( RecognizeWord( expr , ref startIndex ) );
            if( expr.Length <= startIndex || expr [ startIndex ] != ‘,’ )
                break;
        } while( startIndex < expr.Length );

        EatWhiteSpace( expr , ref startIndex );

        if( expr.Length <= startIndex || expr [ startIndex ] != ‘)’ )
            return values;

        ++startIndex;

        return values;
    }

    private static string RecognizeAttribute( string expr , ref int startIndex )
    {
        return RecognizeWord( expr , ref startIndex );
    }

    private static string RecognizeOperator( string expr , ref int startIndex )
    {
        int start = startIndex;
        while( startIndex < expr.Length && !char.IsWhiteSpace( expr [ startIndex ] ) )
            ++startIndex;
        if( start != startIndex )
            return expr.Substring( start , startIndex – start );
        return string.Empty;
    }

    private static void EatWhiteSpace( string expr , ref int startIndex )
    {
        while( startIndex < expr.Length && char.IsWhiteSpace( expr [ startIndex ] ) )
            ++startIndex;
    }

    private static string RecognizeWord( string expr , ref int startIndex )
    {
        int first = expr.IndexOf( "’" , startIndex ) , second = first != -1 ? expr.IndexOf( "’" , first + 1 ) : -1;
        if( first != -1 )
            if( second != -1 )
            {
                startIndex = second + 1;
                return expr.Substring( first , second – first );
            }
            else
            {
                startIndex = expr.Length;
                return expr.Substring( first );
            }
        return string.Empty;
    }
}

This is what you should pass.

string expr = "’attribute1′ = ‘value1’ and ‘attribute2’ = ‘value2’ or ‘attribute3’ in (‘value3’) or ‘attribute4’ = ‘value4’";

Expression expression = Parser.BuildTree( expr );

21 October 2009

The Story of System.IO.FileNotFoundException

Filed under: Tips — Tanveer Badar @ 1:37 PM

‘Impaled by my own sword’, ‘shot myself in the foot’ would be some fine explanations for this exception. Ages ago, I checked ‘break on first chance exception’ for Debug > Exceptions > System.IO.FileNotFoundException. Then, I spent 30 minutes wondering and arguing with others why there was this exception when my code was doing exactly what it should have been doing and nothing changed.

It was long before I remembered to check this setting. So, next time you are bitten by some unexplained exception better see if it is a first chance catch and whether you are catching it as such. Setting is global in VS and persists across projects.

10 October 2009

The Composition Which Isn’t

Filed under: Dev inside!, Tips — Tanveer Badar @ 5:11 PM

Imagine someone trying to write a class which composes two streams together. You better make it a stream itself, meaning something like this:

class CompositeStream : IStream
{
public:
    CompositeStream( IStream* first , IStream* second );
    // blah blah blah
};

Or people will find it amusing that your class isn’t a stream itself.

Similarly, for a mathematical library if you provide a composing function it better be a math-op itself or someone is going to end up in a sticky situation.

class SuperDuperComposingFunction : MathOp
{
public:
    SuperDuperComposingFunction( const std::vector< MathOp* >& operations );
    // blah blah blah
};

Or a cache manager for that matter. It is easy to provide default implementations for simple cache algorithms like LFU, LRU, FIFO etc. But things get interesting if you provide an extensibility point for others to compose them together. Who knows whether I want to archive emails which are older than 3 weeks and I haven’t read them more than once. Things are even more interesting if people need to sub-class your cache manage in order to use composite cache policies.

In the end, it helps to read these things instead of arguing when someone says “yeah sure, great idea. Just one thing, make it a ICachePolicy itself.”.

This post was brought to you by “Working with goons”.

30 September 2009

Infinite Circular Looping

Filed under: Tips — Tanveer Badar @ 10:19 PM

Want to turn a linear sequence into a circular one so you have go round and round over it as long as needed? Here is how (with the added bonus of resetting and stopping the iteration)

   IEnumerable<T> GetNextInterval<T>( IEnumerable<T> input )
        {
            bool flag = true;
            while( flag )
            {
                input.Reset( );
                foreach( T t in input )
                {
                    if( end )
                    {
                        flag = false;
                        end = false;
                        break;
                    }
                    if( reset )
                    {
                        reset = false;
                        break;
                    }
                    yield return t;
                }
            }
        }

Setting reset to true short circuits the loop and starts from beginning again. Setting end to true terminates it entirely.

28 September 2009

Solution to XmlTextReader’s Fiasco

Filed under: Fun, Tips — Tanveer Badar @ 10:22 PM

He’s not that knowledgeable. Mr. pretentious. And he didn’t try this either:

”, hexadecimal value 0x1B, is an invalid character. Line 46, position 128.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Xml.XmlException: ”, hexadecimal value 0x1B, is an invalid character. Line 46, position 128.

The simple solution is to set CheckCharacters = false; And since you would like to know what the heck am I talking about? XmlTextReader is in the bad habit of failing over Unicode characters.

16 September 2009

The Off-by-1 Game

Filed under: Bugz, S&G, Tips — Tanveer Badar @ 7:54 PM

Consider this:

for( int i = list.Count – 1 ; i >= list.Count – 50 ; –i , )
.     array [ i ] = list [ i ];

Intention was the get the last 50 terms from list. Ignoring the facts that it will throw a null reference exception if the list is null and an index-out-of-range exception if it contains no elements it also fails to copy all 50 elements. The condition is to be blamed.

Correct way is not to invent your own logic and use what the framework offers.

if( list != null && list.Count > 50 )
    list.RemoveRange( 50 , list.Count – 50 );

For added bonus, consider this paging code.

for( int i = 0 , index = 0 ; i < some_huge_number ; ++i )
{
    page.Results.Add( results [ i ] );
    if( index == 10 )
    {
        pages.Add( page );
        page = new Page( );
        index = 0;
    }
    ++index;
}

This code strives to divide results into pages each with 10 results. Can you imagine what this will do if there were only 9 results?

It will proceed to add those results to page, then, do nothing. Because of the incorrect if condition. Again, the correct way is divide-and-remainder approach as demonstrated here.

When Oracle Met A Computer Architect

Filed under: Bugz, Dev inside!, Tips — Tanveer Badar @ 7:49 PM

Oracle can’t handle more than 1000 expressions in a single in clause. (Really stupid restriction, I know and here’s the tip: you can do (, ,,,,,) or abc in (,,,,,,) ad infinitum).

When compilers software pipeline a loop, they calculate two things at first. The remainder and the dividend.

(This post got too keyword heavy. Matrix fans will curse me that its the other Oracle. That Oracle’s users will not find all ORA-xyz error descriptions here. Architects may not have any interest in writing computer code. Computer architects will not see any processors discussed. One post to rule them all. ]:) )

The problem at hand was hand generating a query with in clause in its where section. Number of expressions was unbounded. And the genius who came up with the loop did this:

for( int i = 0 , n = 0 ; i < count ; ++i )
{
    n++;
    if( n == 1000 )
    {
        quwry += " ) or in ( ";
        n = 0;
    }
    query += list [ i ] + ‘,’;
}
query = query.Remove( query.Length – 1 , 1 );

Remember this is the work of someone who has never heard about software pipeline and may never know what gcc or cl are. Thinking one level above will help us arrive at the correct solution (notice, there is nothing wrong functionally with the above code either. It does what it says it does.):

int n = numbers.Count / stride , k = numbers.Count % stride;
StringBuilder builder = new StringBuilder( );
if( n > 0 )
{
    builder.AppendFormat( "'{0}’" , numbers [ 0 ] );
    for( int j = 1 ; j < stride ; j++ )
        builder.AppendFormat( " , ‘{0}’ " , numbers [ j ] );
    for( int i = 1 ; i < n ; ++i )
    {
        builder.Append( separator );
        builder.AppendFormat( "'{0}’" , numbers [ i * stride ] );
        for( int j = i * stride + 1 ; j < ( i + 1 ) * stride ; j++ )
            builder.AppendFormat( " , ‘{0}’ " , numbers [ j ] );
    }
}
if( k > 0 )
{
    if( n > 0 )
        builder.Append( separator );
    builder.AppendFormat( "'{0}’" , numbers [ n * stride ] );
    for( int j = n * stride + 1 ; j < numbers.Count ; ++j )
        builder.AppendFormat( " , ‘{0}’ " , numbers [ j ] );
}

No repetitive checking of one variable which also displays off-by-1 error. And which is also mission the other correction in first line of this post in bold.

24 April 2009

Tales From Interviewer’s Desk

Filed under: Dev inside!, Fun, Tips — Tanveer Badar @ 8:24 PM

Part 1:

How to reverse a string in-place?

Take 1: (Fresh)

string reverse( string str )
{
    char ch = str [ 0 ];
    foreach( int i = 0 ; i < str.length ; ++i )
        Response.RedirectWrite( str [ str.length – i ] ) + ch.tostring( );
}

Take 2: (Big words, no knowledge)

string reverse( object obj )
{
    string str = TypeCaste.tostring( obj );
    stack< ch > s;
    for( int i = 0 ; i < length ; ++i )
        s.push( str.charat( i ) );
    for( i = 0 ; i < length ; ++i )
        str.insertat( 0 , s.pop( ) );
}

Take 3: (2.5  year experience in C#)

string reverse( object obj )
{
    if( typeof( obj ) == "string" )
    {
        for( int i = 0 ; i < obj.length ; ++I )
        {
            char ch = str [ i ];
            str [ i ] = str [ length – i ];
            str [ length – i ] = ch;
        }
    }
    return obj.tostring( );
}

Take 4: (Fresh)

string reverse( object obj )
{
    if( obj == "string" )
    {
        char ch = str [ 0 ];
        for( int i = 0 ; i < obj.length ; ++I )
            str [ i ] = str [ length – i ];
        str [ str.length ] = ch;
    }
}

12 October 2008

Tidbit 2

Filed under: Dev inside!, Tips — Tanveer Badar @ 7:29 PM

This one pertains to CLR.

Please, please, please make sure your static constructors do not throw exceptions. Having static state in a class is already asking for trouble in the case of multiple threads, if that reason wasn’t enough proceed below.

For example,

class A
{
      static DataType1 member1 = new DataType1( );
      static DataType2 member2 = DataType2.GetDefaultInstance( );
}

If there is even the remotest chance that either DataType1’s constructor or DataType2.GetDefaultInstance will throw an exception you are better off with this version:

class A
{

    static DataType1 member1;
    static DataType2 member2

    static A( )
    {
        try
        {
            member1 = new DataType1( );
        }
        catch( Exception ex )
        {
            // do some logging
        }
        try
        {
            member2 = DataType2.GetDefaultInstance( );
        }
        catch( Exception ex )
        {
            // do some logging
        }
    }
}

The only reason for all this hassle is the avoid throwing uncaught exceptions from .cctor of a type.

Because, for a type whose static constructor throws an exception, EE ensures that no instance of that type will ever be instantiated in that appdomain.

[Update 11/03/09: Many moons after the original post, I come across this. The exact same problem happens in native world.]

Older Posts »

Create a free website or blog at WordPress.com.