in reply to Summing the odd/even digits of a larger number (for upc check digits)...a better way?

EvanK:

Mine still splits & loops. I made only small changes:

#!/usr/bin/perl -w use strict; use warnings; # returns error message on failure, undefined value on success sub checkUPCrobot { # grab and immediately split upc into array, 1 char per element my @chars = split(//, shift); # return error message if incorrect length if( $#chars != 11 ) { return "should be 12 digits in length"; } # loop through to seperately sum even and odd chars my $odd=shift @chars; my $even=0; foreach (0..4) { $even += shift @chars; $odd += shift @chars; } # calculate correct check digit my $mult = ($odd * 3) + $even; my $check = 10 - ($mult%10); # return error message if wrong check digit was initially given if($check != shift @chars) { return "invalid checkdigit...should be $check"; } # otherwise, if validated, return undefined return; } #...snipped out the original checkUPC here to save space... print &checkUPC("142687305632"), "\n"; print &checkUPCrobot("142687305632"), "\n";
I first got rid of the if even/odd in the first while loop by shifting the values off the array in pairs. I got rid of the second while loop by direct calculation.

UPDATE: I fiddled with it a little longer and came up with a slightly improved model:

# returns error message on failure, undefined value on success sub checkUPCrobot2 { # grab and immediately split upc into array, 1 char per element my @chars = split //, shift; # return error message if incorrect length return "should be 12 digits in length" if $#chars != 11; my ($even, $odd, $check); foreach (0..5) { $odd += shift @chars; $check = shift @chars; $even += $check; } my $mult = 3*$odd+$even-$check; my $chk2 = 10 - ($mult%10); return "invalid checkdigit...should be $chk2" if $check!=$chk2; }
--roboticus
  • Comment on Re: Summing the odd/even digits of a larger number (for upc check digits)...a better way?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Summing the odd/even digits of a larger number (for upc check digits)...a better way?
by GrandFather (Saint) on Jun 23, 2006 at 00:02 UTC

    Note that the second version doesn't return undef.


    DWIM is Perl's answer to Gödel
      GrandFather:

      OK ... I thought that since the return didn't get to return the string that the function would return undef. So I shouldn't've removed the "return undef;" at the end.

      So what is returned, then? I'm suspecting that it's the value of the condition at the end (i.e. false), but I await edification! ;^)

      --roboticus

        That's what I expect too. The following seems to validate that view.

        use warnings; use strict; use Data::Dump::Streamer; my $condRes = 1 == 1; print '1 == 1 '; Dump ($condRes); $condRes = 1 == 0; print '1 == 0 '; Dump ($condRes); $condRes = doCond (1); print 'doCond (1) '; Dump ($condRes); $condRes = doCond (0); print 'doCond (0) '; Dump ($condRes); sub doCond { 1 == shift; }

        Prints:

        1 == 1 $VAR1 = 1; 1 == 0 $VAR1 = ''; doCond (1) $VAR1 = 1; doCond (0) $VAR1 = '';

        DWIM is Perl's answer to Gödel