# help with code

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

I figure that this code try to compare 2 ligns and sort them in
increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
person who codes this introduce the \$imgA, \$imgB What is he trying to
achieve ?

sub sortRule {
my (\$wordA, \$wordB, @numA, @numB, \$lgA, \$lgB, \$min, \$imgA, \$imgB);
\$wordA = \$a;
\$wordB = \$b;
#print "\nwordA=\$wordA\n";
#print "wordB=\$wordB\n";
\$wordA =~ s/^([0-9.]+).*\$/\$1/;
\$wordB =~ s/^([0-9.]+).*\$/\$1/;
#printc "a=\$wordA b=\$wordB", 'blue';
@numA = split(/\./, \$wordA);
@numB = split(/\./, \$wordB);
\$lgA = \$#numA;
\$lgB = \$#numB;
#printc "lgA=\$lgA, lgB=\$lgB";
if (\$lgA > \$lgB) { \$min = \$lgB }
else { \$min = \$lgA }

my \$fin = 0;
for (my \$i=0; (\$i<=\$min && !\$fin); \$i++) {
if (\$numA[\$i] > \$numB[\$i]) {
\$imgA = 2;
\$imgB = 1;
\$fi
n = 1;
}
elsif (\$numA[\$i] < \$numB[\$i]) {
\$imgA = 1;
\$imgB = 2;
\$fin = 1;
}
}

if (!\$fin) {
if (\$lgA > \$lgB) {
\$imgA = 2;
\$imgB = 1;
}
else {
\$imgA = 1;
\$imgB = 2;
}
}

#printc "imgA=\$imgA, imgB=\$imgB", 'green';
return (\$imgA <=> \$imgB);
}

## Re: help with code

Gabriella wrote:
> I figure that this code try to compare 2 ligns and sort them in
> increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
> person who codes this introduce the \$imgA, \$imgB What is he trying to
> achieve ?
>
> sub sortRule {
>   my (\$wordA, \$wordB, @numA, @numB, \$lgA, \$lgB, \$min, \$imgA, \$imgB);
>   \$wordA = \$a;
>   \$wordB = \$b;
>   #print "\nwordA=\$wordA\n";
>   #print "wordB=\$wordB\n";
>   \$wordA =~ s/^([0-9.]+).*\$/\$1/;
>   \$wordB =~ s/^([0-9.]+).*\$/\$1/;
>   #printc "a=\$wordA b=\$wordB", 'blue';
>   @numA = split(/\./, \$wordA);
>   @numB = split(/\./, \$wordB);
>   \$lgA = \$#numA;
>   \$lgB = \$#numB;
>   #printc "lgA=\$lgA, lgB=\$lgB";
>   if (\$lgA > \$lgB) { \$min = \$lgB }
>   else { \$min = \$lgA }
>
>   my \$fin = 0;
>   for (my \$i=0; (\$i<=\$min && !\$fin); \$i++) {
>     if (\$numA[\$i] > \$numB[\$i]) {
>       \$imgA = 2;
>       \$imgB = 1;
>       \$fin = 1;
>     }
>     elsif (\$numA[\$i] < \$numB[\$i]) {
>       \$imgA = 1;
>       \$imgB = 2;
>       \$fin = 1;
>     }
>   }
>
>   if (!\$fin) {
>     if (\$lgA > \$lgB) {
>       \$imgA = 2;
>       \$imgB = 1;
>     }
>     else {
>       \$imgA = 1;
>       \$imgB = 2;
>     }
>   }
>
>   #printc "imgA=\$imgA, imgB=\$imgB", 'green';
>   return (\$imgA <=> \$imgB);
> }

Dear Gabriella,

Hmm... the code is difficult to read.  It bothers me when people
figure out a process to achieve what they want, and then don't even
bother to explain it, as if their way is the only way that could ever
be thought of or they think their method is so clear that it needs no
explanation.  In other words, if you think up a solution, it's a good
idea to explain along the way what you are doing, in case somebody
after you ever tries to figure out what you are doing.  (I definitely
think that you should write the simplest, clearest code, but even then
it's not always clear what the code is trying to do, which is why I
think good code should have in-code documentation (in the form of
comments) explaining what is being done.)

I looked at the code, and it appears that \$imgA and \$imgB (I don't
know what "img" is supposed to stand for) are temporary placeholders
that keep track of which value (\$a or \$b) is greater.  When they are
set, one of them receives a value of 1 and the other a value of 2.  The
one that got the value of 2 represents the greater value.  For example,
if \$imgA gets the value of 2, it means that \$a was determined to be the
greater value.

No comments were included to specify this.  It would have been nice
if the original writer of the code mentioned this.  As for me, I think
it would have been clearer if, instead of setting \$imgA, \$imgB, and
\$fin, that the function would end immediately returning 1 (if \$a was
greater) or -1 (if \$b was greater).  At the end of the function, if no
value was found to be greater, then 0 would be returned.

To illustrate my point, I have included my own small program, which
is hopefully clearer to you (and should do the same thing):

============= START OF CODE ================
#!/usr/bin/perl
use strict;
use warnings;

sub specialSort
{
# Note:  1.2.3 is greater than 1.2.2

# Split out all numbers into arrays @a and @b:
my @a = split(/\./, \$a);
my @b = split(/\./, \$b);

# Compare the numbers in each array.
# As soon as the number differ, return
# the proper value (-1 if \$a is greater;
# 1 if \$b is greater):
while (@a and @b)
{
my \$aNum = shift @a;
my \$bNum = shift @b;

return -1  if \$aNum < \$bNum;  # b is greater
return 1  if \$aNum > \$bNum;  # a is greater
}

# All the values so far were identical.
# If one array still contains values, then
# it's value is greater:
return -1  if @b;  # b is greater
return 1  if @a;  # a is greater
return 0;  # both numbers the same
}

### Main code: ###

# Get the numbers:
my @listOfNums = <DATA>;
chomp(@listOfNums);  # remove the newlines

# Do the sort:
my @sortedNums = sort specialSort @listOfNums;

# Print out the sorted values:
print "\$_\n" foreach @sortedNums;

__DATA__
7
5.2
5.7
5.9
8.56.4.3
5.0
5.5.5
1.788.34.3
5.5.4
5.2.6
5.2.6.7
============= END OF CODE ================

There is only one problem that I see with my code, and that is that
it treats the value 5.0 to be greater than 5 .  This might be what you
want (or it might not), so you will have to modify it (to check for
something like m/(\.0)*\$/ ) if you need 5 to equal 5.0 .

I hope this helps, Gabriella.

-- Jean-Luc

## Re: help with code

Just wondering, couldn't this be done by assigning each of these to a hash key
then sorting with like this:
\$hash_to_be_sorted = '';
\$hash_to_be_sorted = '';
\$hash_to_be_sorted = '';
.. . .

foreach \$x (sort {\$a <=> \$b} (keys(%hash_to_be_sorted))) {
push(@return, \$x);
}

It will give you back the values in an array where \$return[0] is the smallest
and \$return[\$#return] is the biggest.

> Gabriella wrote:
>> I figure that this code try to compare 2 ligns and sort them in
>> increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
>> person who codes this introduce the \$imgA, \$imgB What is he trying to
>> achieve ?
>>
>> sub sortRule {
>>   my (\$wordA, \$wordB, @numA, @numB, \$lgA, \$lgB, \$min, \$imgA, \$imgB);
>>   \$wordA = \$a;
>>   \$wordB = \$b;
>>   #print "\nwordA=\$wordA\n";
>>   #print "wordB=\$wordB\n";
>>   \$wordA =~ s/^([0-9.]+).*\$/\$1/;
>>   \$wordB =~ s/^([0-9.]+).*\$/\$1/;
>>   #printc "a=\$wordA b=\$wordB", 'blue';
>>   @numA = split(/\./, \$wordA);
>>   @numB = split(/\./, \$wordB);
>>   \$lgA = \$#numA;
>>   \$lgB = \$#numB;
>>   #printc "lgA=\$lgA, lgB=\$lgB";
>>   if (\$lgA > \$lgB) { \$min = \$lgB }
>>   else { \$min = \$lgA }
>>
>>   my \$fin = 0;
>>   for (my \$i=0; (\$i<=\$min && !\$fin); \$i++) {
>>     if (\$numA[\$i] > \$numB[\$i]) {
>>       \$imgA = 2;
>>       \$imgB = 1;
>>       \$fin = 1;
>>     }
>>     elsif (\$numA[\$i] < \$numB[\$i]) {
>>       \$imgA = 1;
>>       \$imgB = 2;
>>       \$fin = 1;
>>     }
>>   }
>>
>>   if (!\$fin) {
>>     if (\$lgA > \$lgB) {
>>       \$imgA = 2;
>>       \$imgB = 1;
>>     }
>>     else {
>>       \$imgA = 1;
>>       \$imgB = 2;
>>     }
>>   }
>>
>>   #printc "imgA=\$imgA, imgB=\$imgB", 'green';
>>   return (\$imgA <=> \$imgB);
>> }
>
>
> Dear Gabriella,
>
>   Hmm... the code is difficult to read.  It bothers me when people
> figure out a process to achieve what they want, and then don't even
> bother to explain it, as if their way is the only way that could ever
> be thought of or they think their method is so clear that it needs no
> explanation.  In other words, if you think up a solution, it's a good
> idea to explain along the way what you are doing, in case somebody
> after you ever tries to figure out what you are doing.  (I definitely
> think that you should write the simplest, clearest code, but even then
> it's not always clear what the code is trying to do, which is why I
> think good code should have in-code documentation (in the form of
> comments) explaining what is being done.)
>
>   I looked at the code, and it appears that \$imgA and \$imgB (I don't
> know what "img" is supposed to stand for) are temporary placeholders
> that keep track of which value (\$a or \$b) is greater.  When they are
> set, one of them receives a value of 1 and the other a value of 2.  The
> one that got the value of 2 represents the greater value.  For example,
> if \$imgA gets the value of 2, it means that \$a was determined to be the
> greater value.
>
>   No comments were included to specify this.  It would have been nice
> if the original writer of the code mentioned this.  As for me, I think
> it would have been clearer if, instead of setting \$imgA, \$imgB, and
> \$fin, that the function would end immediately returning 1 (if \$a was
> greater) or -1 (if \$b was greater).  At the end of the function, if no
> value was found to be greater, then 0 would be returned.
>
>   To illustrate my point, I have included my own small program, which
> is hopefully clearer to you (and should do the same thing):
>
>
> ============= START OF CODE ================
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> sub specialSort
> {
>   # Note:  1.2.3 is greater than 1.2.2
>
>   # Split out all numbers into arrays @a and @b:
>   my @a = split(/\./, \$a);
>   my @b = split(/\./, \$b);
>
>   # Compare the numbers in each array.
>   # As soon as the number differ, return
>   # the proper value (-1 if \$a is greater;
>   # 1 if \$b is greater):
>   while (@a and @b)
>   {
>      my \$aNum = shift @a;
>      my \$bNum = shift @b;
>
>      return -1  if \$aNum < \$bNum;  # b is greater
>      return 1  if \$aNum > \$bNum;  # a is greater
>   }
>
>   # All the values so far were identical.
>   # If one array still contains values, then
>   # it's value is greater:
>   return -1  if @b;  # b is greater
>   return 1  if @a;  # a is greater
>   return 0;  # both numbers the same
> }
>
> ### Main code: ###
>
> # Get the numbers:
> my @listOfNums = <DATA>;
> chomp(@listOfNums);  # remove the newlines
>
> # Do the sort:
> my @sortedNums = sort specialSort @listOfNums;
>
> # Print out the sorted values:
> print "\$_\n" foreach @sortedNums;
>
> __DATA__
> 7
> 5.2
> 5.7
> 5.9
> 8.56.4.3
> 5.0
> 5.5.5
> 1.788.34.3
> 5.5.4
> 5.2.6
> 5.2.6.7
> ============= END OF CODE ================
>
>
>   There is only one problem that I see with my code, and that is that
> it treats the value 5.0 to be greater than 5 .  This might be what you
> want (or it might not), so you will have to modify it (to check for
> something like m/(\.0)*\$/ ) if you need 5 to equal 5.0 .
>
>   I hope this helps, Gabriella.
>
>   -- Jean-Luc
>

## Re: help with code

]

> Just wondering, couldn't this be done by assigning each of these to a
> hash key then sorting with like this:
> \$hash_to_be_sorted = '';
> \$hash_to_be_sorted = '';
> \$hash_to_be_sorted = '';
> . . .
>
> foreach \$x (sort {\$a <=> \$b} (keys(%hash_to_be_sorted))) {
>     push(@return, \$x);
> }
>
> It will give you back the values in an array where \$return[0] is the
> smallest and \$return[\$#return] is the biggest.

Incidentally, I do not have the faintest idea what you are talking about.
Trying to run the program above gives me an error.

Sinan.

## Re: help with code

Gabriella wrote:

> I figure that this code try to compare 2 ligns and sort them in
> increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
> person who codes this introduce the \$imgA, \$imgB What is he trying to
> achieve ?

The code is quite inefficient - trying to reason what was going on in
the mind of the programmer is probably not useful.

## Re: help with code

gabriella@istop.com (Gabriella) writes:
> I figure that this code try to compare 2 ligns and sort them in
> increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
> person who codes this introduce the \$imgA, \$imgB What is he trying to
> achieve ?
>
> sub sortRule {
>   my (\$wordA, \$wordB, @numA, @numB, \$lgA, \$lgB, \$min, \$imgA, \$imgB);
>   \$wordA = \$a;
>   \$wordB = \$b;
>   #print "\nwordA=\$wordA\n";
>   #print "wordB=\$wordB\n";
>   \$wordA =~ s/^([0-9.]+).*\$/\$1/;
>   \$wordB =~ s/^([0-9.]+).*\$/\$1/;
>   #printc "a=\$wordA b=\$wordB", 'blue';
>   @numA = split(/\./, \$wordA);
>   @numB = split(/\./, \$wordB);
>   \$lgA = \$#numA;
>   \$lgB = \$#numB;
>   #printc "lgA=\$lgA, lgB=\$lgB";
>   if (\$lgA > \$lgB) { \$min = \$lgB }
>   else { \$min = \$lgA }
>
>   my \$fin = 0;
>   for (my \$i=0; (\$i<=\$min && !\$fin); \$i++) {
>     if (\$numA[\$i] > \$numB[\$i]) {
>       \$imgA = 2;
>       \$imgB = 1;
>       \$fi
> n = 1;
>     }
>     elsif (\$numA[\$i] < \$numB[\$i]) {
>       \$imgA = 1;
>       \$imgB = 2;
>       \$fin = 1;
>     }
>   }
>
>   if (!\$fin) {
>     if (\$lgA > \$lgB) {
>       \$imgA = 2;
>       \$imgB = 1;
>     }
>     else {
>       \$imgA = 1;
>       \$imgB = 2;
>     }
>   }
>
>   #printc "imgA=\$imgA, imgB=\$imgB", 'green';
>   return (\$imgA <=> \$imgB);
> }

Apart from being bulky, I see two problems with the code:

1) It returns -1 when \$a and \$b are equal.
2) It removes trailing non-numeric text, thereby becoming unstable (once
problem 1 is fixed).

Problem 1 and 2 combined result in "1.2.a" < "1.2.b" and at the same
time "1.2.b" < "1.2.a". Such behaviour in a comparison operator make
some sorting algorithms very upset (some C implementations of 'qsort'
even dump core).

## Re: help with code

This should sort it

rm -rf *

Unmeaningful variable names, no comments - jeez - it's just like work

## Re: help with code

Lord0 wrote:
> This should sort it
> rm -rf *

And if not, at least it will remove the source of the confusion.

--
Wes Groleau
-----------
Daily Hoax: http://www.snopes2.com/cgi-bin/random/random.asp