Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: unxpected sort warnings while using sort

by perlynewby (Scribe)
on Jul 22, 2015 at 23:40 UTC ( [id://1135923]=note: print w/replies, xml ) Need Help??


in reply to Re: unxpected sort warnings while using sort
in thread unxpected sort warnings while using sort

made changes but no change in output

commented out slurp

made reable code by using @_ as used per subs

no sort and no change in message

open my $in, '<', 'numbers.txt' or die $!; # local $/; # slurp mode my @data = <$in>; chomp @data; close $in; sort_num(@data); my @new_sort=sort_num(); print "this is new sorted data ;",@new_sort; sub sort_num{ my @sorted=sort {$a <=> $b}@_; return @sorted; }
Argument "2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1" isn' +t numeric in sort at C:\Users\Alberto\Documents\NetBeansProjects\Perl +Project\Perl Essentials\subroutines\ave_mode_median_range sub.pl line + 24. this is new sorted data ;

Replies are listed 'Best First'.
Re^3: unxpected sort warnings while using sort
by AnomalousMonk (Archbishop) on Jul 22, 2015 at 23:53 UTC

    What is your data? The warning message
        Argument "2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1" isn't numeric in sort at ...
    shows that Perl still thinks it's a single string with a bunch of digits and spaces in it. sort will never sort this numerically — or any other way, since it's just a single-element list and so is already "sorted"!


    Give a man a fish:  <%-(-(-(-<

Re^3: unxpected sort warnings while using sort
by NetWallah (Canon) on Jul 23, 2015 at 04:09 UTC
    As AnomalousMonk has pointed out, the way your data is formatted is important.

    The way most programmers would expect to see your data is like this:

    2 3 3 3 5 7 8 12 ...
    If, instead, it looks like this:
    2 3 3 3 5 7 8 12 ...
    then you have a problem .. or rather, it needs to be handled differently in your code.

    For the second case, you need:

    my @data = split /\s+/,<$in>;

    In addition, the way the "sort_num" is called has some issues in your code.

    This is how it should be called:

    my @new_sort = sort_num (@data);
    And call it only ONCE.

            "Despite my privileged upbringing, I'm actually quite well-balanced. I have a chip on both shoulders."         - John Nash

      correct formatting of data is something new to me...I never thought about it once in this case of numbers vs strings but ,now, I will.

      One more question

      can anyone explain why I can't do slurp while populating the data var? I am aware of the memory issue that may arise if file is big but for these little programs is not an issue to me...but then again I am learning and you may have some experiences to share ;-)

       local $/;    # slurp mode

      thank you all!

      learning to do subs and modules now so many more new things to think about

        ... why I can't do slurp while populating the data var?

        A lot depends on the organization of data in your input file. (These little details really do matter.) The following discussion assumes you have not changed the default value of  $/ which is  "\n" (newline); see perlvar.

        If you have a file in which each individual number is on a separate line that is terminated by a newline, the statement
            # list context file read -- effective slurp: entire file is read
            my @each_element_has_a_line = <$input_filehandle>;
        reads each and every line of the file as a string into a separate element of the array. This is the effect of reading the file in list context. See readline. If this operation is followed by a
            chomp @each_element_has_a_line;
        statement, each element of the array/line read from the file/string has a newline removed from the end, if one was present. See chomp. If you're lucky, you now have an array of strings which each look like a number to Perl, and so can be handled by numeric operators like <=>.

        If you have a file organized as above, the statement
            # scalar context slurp
            my $all_lines_in_a_single_string = do { local $/;  <$input_filehandle>; };
        reads the entire content of the file, all the lines, newlines and all, into a single string. This is the effect of reading the file in scalar context with $/ undefined; this is referred to as file slurp mode. If this operation is followed by a
            chomp $all_lines_in_a_single_string;
        a single newline, if present, will be removed from the end of this single string. What remains requires further processing to extract the digit groups (numbers) from the string to an array so they can be sorted.

        If, OTOH, you have your data in a file organized as a single line of digit groups separated by whitespace(s) (which seems to have been the case with your OPed data), reading the file in slurp mode or not really doesn't matter because there's only one thing there to read to begin with. (This is your answer to the quoted question.) If you read to an array, you get (somewhat confusingly) an array with a single element: a string that is the single string that was in the file. If you read to a scalar... again, a single string. chomp-ing this single element/scalar/string may or may not help you; you still must do further processing to extract the numbers.

        I urge you to do some experimentation with these various permutations of file organization, slurping and file-read context (list vs. scalar). I also urge you read about the general topic of context in Perl (the Context tutorial is one of the Tutorials available in the Monastery; see also Context in perldata) and, in general, RTFM! (Discussion of context should be a significant topic in any decent commercial Perl text or reference book.)


        Give a man a fish:  <%-(-(-(-<

        The "slurp" setting reads all "records" of the file in one shot.

        In your case, your entire file is just one record (a string of space-separated numbers).

        So, for this program, there is no difference whether or not you slurp the file.

        Now - if you DID have multiple records, as in the first example I showed, without slurp, you get one record at a time. With slurp, it reads the entire file into memory, as a string, and it is up to you to separate the pieces.

        In the majority of the cases, you normally process data files one record at a time, so the default of "NO SLURP" makes sense.

        Sometimes, you need the entire content in memory before you can make sense of the file - for example, when reading config information, or an XML file. Typically, these would be small files, where memory consumption would not be an issue. A third case would be if you were comparing the contents of a smaller file with a larger one - you would read the smaller one into memory if possible.

                "After Perl everything else is just assembly language."

Re^3: unxpected sort warnings while using sort
by marinersk (Priest) on Jul 23, 2015 at 02:04 UTC

    Strongly suggest using Data::Dumper to see what your data is and looks like.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1135923]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-04-25 05:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found