CodeSOD: Lowest-Bidder Conversion


Circa 2003, or so, Annie’s employer contracted a lowest-bidder to produce a relatively massive .NET Web Forms project. The code was built, signed off, and chucked into production without any of the in-house developers being involved, despite being the team that would support it in the long term. There was no documentation, no knowledge transfer, and no code review.

Over the next few years, there was a rush of feature requests as gaps in functionality were found. A series of in-house developers passed through, doing their best to patch them in, but the original project’s code quality didn’t exactly make it maintainable, and since they were operating in a rush, they weren’t exactly improving the code quality.

Fast forward to 2017, and the code is finally unmaintainable enough that someone put together the budget for a ground-up rewrite in .NET MVC, and once again shopped it around to a different lowest-bidder, who would do the conversion. This time, at least, Annie gets to review the code before they accept it. It isn’t going well.

private string AddOne(int DecimalPlace)
{
    string Outpout = ".";
    for (int i = 1; i < DecimalPlace; i++)
    {
        Outpout = Outpout + "0";
    }
    Outpout = Outpout + "1";
    return Outpout;
}

Yes, that’s a stringly-typed operation to create a number in the form “.00001”.

But don’t worry, we can also get the integer value of any string (or any object), nice and easy:

/// <summary>
/// Get Integer Value.
/// </summary>
/// <param name="obj">Object type obj</param>
/// <returns></returns>
public int GetIntegerValue(object obj)
{
    return GetIntegerValue(obj, 0);
}
public int GetIntegerValue(object obj, int defaultReturnValue)
{
    try
    {
        if (obj != null && obj.ToString().Length > 0)
        {
            string objvalue = ClearSpecialChar(Convert.ToString(obj));
            defaultReturnValue = Convert.ToInt32(objvalue);
        }
        //else
        //{
        //    defaultReturnValue = Convert.ToInt32(obj);
        //}
    }
    catch
    {

    }
    return defaultReturnValue;
}

module also needs to handle rounding, and yes, that’s also stringly-typed.

/// <summary>
/// This Methods for round off item weight for(USPS)
/// EX: .15 Pound =1 Pound
/// </summary>
/// <param name="inPutVal"></param>
/// <returns></returns>
public int MakeRoundOffDecimal(string inPutVal)
{
    int contenerVal = 0;
    int intValAfterPoint = 0;

    string ValBeforePoint = inPutVal.Substring(0, inPutVal.IndexOf('.'));
    string valAfterPoint = inPutVal.Substring(inPutVal.IndexOf('.') + 1);

    try
    {
        contenerVal = Convert.ToInt32(ValBeforePoint);
        intValAfterPoint = Convert.ToInt32(valAfterPoint);
        if (intValAfterPoint > 0)
        {
            contenerVal += 1;
        }
    }
    catch
    {
        contenerVal += 1;
    }
    return contenerVal;
}

/// <summary>
/// This Method  Can make decimal value with desiger
/// length with updating last number (if last number after decimel point >=5 then 6 and lessthan <5 then
/// the same value
/// Ex:- 10.012547 will be 10.01255 if i call this method with GetDecimalPlaceValue("10.012547",5)
/// and 12.012351 will be 12.01235 if i cakll this method with GetDecimalPlaceValue("12.012351",5)
/// </summary>
/// <param name="Value"></param>
/// <param name="DecimalPlace"></param>
/// <returns></returns>
public virtual decimal GetDecimalPlaceValue(string Value, int DecimalPlace)
{
    decimal RetunValue = 0.00M;
    int NextToDecimalPlaceValue = 0;
    int DecimalPlaceValue = 0;
    string InputValue = Value;
    try
    {
        RetunValue = Convert.ToDecimal(InputValue.Substring(0, (InputValue.IndexOf('.') + DecimalPlace + 1)));
        NextToDecimalPlaceValue = GetIntegerValue(InputValue.Substring(RetunValue.ToString().Length, 1));
        if (NextToDecimalPlaceValue > 4)
        {
            RetunValue = RetunValue + Convert.ToDecimal(AddOne(DecimalPlace));
        }
    }
    catch
    {
        RetunValue = GetDecimelValue(Value);
    }
    return RetunValue;
}

If you note, the GetDecimalPlaceValue method claims to round (despite not being named anything like it), but will round numbers off incorrectly- the input 1.9 yields 1.

Calls to these various methods are peppered throughout the code base. It appears to be a common utility library that’s simply dropped into every project by this lowest-bidder contractor, and everyone on their team knows to use this for data type conversions.

Annie raised her issues with management, who raised it with their lowest-bidder. Unfortunately, as the lowest-bidder, they’ve already been paid for the first milestone, and are perfectly happy to drag their feet until the code quality issues are forgotten before they bother delivering the second.

[Advertisement]

Release!

is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies – only $9.95 shipped!


http://ift.tt/2zGuvFJ

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: