help with code

G

Gabriella

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);
}
 
J

jl_post

Gabriella said:
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
 
B

Brian McCauley

Gabriella said:
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.
 
A

Arndt Jonasson

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).
 
L

Lord0

This should sort it

rm -rf *

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

Chad Columbus

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{$a} = '';
$hash_to_be_sorted{$b} = '';
$hash_to_be_sorted{$c} = '';
.. . .

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.

Chad

Gabriella said:
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
 
A

A. Sinan Unur

[ Please do not top-post.
Please do read the posting guidelines for this group.
]
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{$a} = '';
$hash_to_be_sorted{$b} = '';
$hash_to_be_sorted{$c} = '';
. . .

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,458
Latest member
Chris#

Latest Threads

Top