HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Calculating Czechsum digits for barcodes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
czechsumdigitsbarcodescalculatingfor

Problem

Every coder knows that if you give six developers an assignment to write a bit of code that will perform some specific task, you will end up with at least six different ways of doing it.

I recently realized/discovered a radical example of this. I wrote some code to calculate check digits for barcodes. I then found some legacy code of ours to do the same thing. I have tested both with several barcodes, and so far they produce the same results, but I find it rather fascinating just how different the "how" of the solutions are.

If anybody wants to play around with it, I'll add the entire code below (you will see in the button click event what you will need to name the few labels and buttons and the edit control); but first: the two methods that calculate the check value (actually, my solution uses several functions, which are called by the primary function).

First, the legacy function:

public static char CalculateChkDigit(string CheckValue)
{
    if (CheckValue.Length > 6)
    {
        char ch;
        int a, b, i, j;
        a = 0;
        b = 0;
        j = ((int)CheckValue.Length) - 1;
        i = j;
        while (i >= 0)
        {
            a = a + (int)(CheckValue[i]) - 48;
            i = i - 2;
        }

        j = ((int)CheckValue.Length) - 2;
        i = j;
        while (i >= 0)
        {
            b = b + (int)(CheckValue[i]) - 48;
            i = i - 2;
        }
        a = 3 * a + b;
        b = a % 10;
        if (b != 0) b = 10 - b;

        ch = (char)(48 + b);
        return ch;
    }
    else
        return ' ';
}


Actually, this was cleaned up using Resharper to become this in my test/comparison utility:

```
private static char GetBarcodeChecksumWithLegacyCode(string barcodeWithoutCzechSum)
{
if (barcodeWithoutCzechSum.Length > 6)
{
int a = 0;
int b = 0;
int j = barcodeWithoutCzechSum.Length - 1;
int i = j;
while (i >= 0)
{
a = a + barcodeWithoutCzechSum[i] - 48

Solution

The first thing that caught my eye, was that they are not functionally equivalent. Yours is missing the case when a barcode is below 7 in lenght.
Another thing that strikes me as odd about both solutions is the verbosity and inefficiency involved in both. Both needlessly iterate twice, and im not sure the names of variables and methods in your rewrite, are accurately portraying what they are actually doing.
As you encouraged people to tinker with it, heres is my shot at it:

public static string Check(string barcode)
    {
        if (barcode.Length <= 6) return " ";

        var sums = new int[2];
        for (int i = 0; i < barcode.Length; i++)
        {
            sums[(i+1)%2] += barcode[i] - '0';
        }

        sums[barcode.Length%2] *= 3;

        int mod = sums.Sum()%10;
        return (mod == 0 ? mod : 10 - mod).ToString();
    }

Code Snippets

public static string Check(string barcode)
    {
        if (barcode.Length <= 6) return " ";

        var sums = new int[2];
        for (int i = 0; i < barcode.Length; i++)
        {
            sums[(i+1)%2] += barcode[i] - '0';
        }

        sums[barcode.Length%2] *= 3;

        int mod = sums.Sum()%10;
        return (mod == 0 ? mod : 10 - mod).ToString();
    }

Context

StackExchange Code Review Q#30829, answer score: 2

Revisions (0)

No revisions yet.