Professional Web Applications Themes

How to dynamically taking the multiple input arguments? - PERL Beginners

Well, I'm kinda new at this stuff myself, but Here's a couple of things I see right away: On Sat, 11 Sep 2004 10:27:44 +0800, Edward WIJAYA <com.sg> wrote:  <<SNIP>>   --You don't really need to use the -w flag here AND the 'use warnings' in your subroutine down below.   -- Nice Job!!   --Try this: unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }   --This is easier and prettier with this: my $file1 = shift;   --You can get all the "\n"'s out at once with a chomp: chomp set1; However, the whole ...

  1. #1

    Default Re: How to dynamically taking the multiple input arguments?

    Well, I'm kinda new at this stuff myself, but Here's a couple of
    things I see right away:


    On Sat, 11 Sep 2004 10:27:44 +0800, Edward WIJAYA
    <com.sg> wrote: 

    <<SNIP>>
     
    --You don't really need to use the -w flag here AND the 'use
    warnings' in your subroutine
    down below.
     
    -- Nice Job!!
     

    --Try this:
    unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }
     
    --This is easier and prettier with this:
    my $file1 = shift;
     
    --You can get all the "\n"'s out at once with a chomp:
    chomp set1;

    However, the whole get_file_data thing and chomping can all be
    done like this:
    open INFILE, $filename or die "Couldn't open $filename: $!\n";
    chomp( my filedata = <INFILE> );

    Then, to clear out the whitespace from each line:
    foreach( filedata ) {
    s/\s+//g;
    }
     

    <<SNIP>>

    Not much, I know, but I'm sure some of the others on the list will
    help out more. I'll work on this some more and post what I figure out
    later.

    --Errin
    Errin Guest

  2. #2

    Default Re: How to dynamically taking the multiple input arguments?

    Here ya go ... this works for me. I tested it with up to 5 input
    files and it was still workin'. It does have a bug, though. It
    doesn't check whether all the input files are the same length. Nor
    did I test what happens when they AREN'T the same length. Let me know
    what ya think:

    #!/usr/bin/perl

    use warnings;
    use strict;

    unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }

    my results;

    foreach( ARGV ) {
    open IN, $_ or die "Couldn't open $_: $!\n";
    chomp( my data = <IN> );
    close IN;
    foreach( data ) { s/\s+//g; }
    foreach( 0..$#data ) { $results[$_] .= $data[$_]; }
    }

    foreach( results ) { print "$_\n"; }

    --Errin
    Errin Guest

  3. #3

    Default Re: How to dynamically taking the multiple input arguments?

    >foreach( ARGV ) { 
    This is a little shorter and saves on iterations:
    for my $file (ARGV) {
    open IN, $file or die "Couldn't open $file: $!\n";
    results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;
    $line } (<IN>);
    close IN;
    }

    -David

    On Fri, 10 Sep 2004 11:35:09 -0500, Errin Ln <com> wrote: 
    David Guest

  4. #4

    Default Re: How to dynamically taking the multiple input arguments?

    On Fri, 10 Sep 2004 12:44:51 -0400, David Greenberg
    <com> wrote: 
    > This is a little shorter and saves on iterations:
    > for my $file (ARGV) {
    > open IN, $file or die "Couldn't open $file: $!\n";
    > results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;
    > $line } (<IN>);
    > close IN;
    > }
    >
    > -David
    >[/ref]

    Can you throw the 'chomp' in the assignment in that 'map' statement?
    Then, can you also throw in the substitution in the mix? like this:
    results = map{ my $line = chomp( s/\s+//g ); } ( <IN> );

    And if so, why not this:

    results = map{ chomp( s/\s+//g ) } ( <IN> );

    As long as we're playing Perl-Golf!!

    I truly don't understand what 'map' is doing. Can you explain it to
    me? I have tried to read perldoc -f map but it's a little weird and
    hard to follow!

    --Errin
    Errin Guest

  5. #5

    Default Re: How to dynamically taking the multiple input arguments?

    I'm no expert, but chomp won't give you what you think it will:
    my arr = ('a', "b\n", "c\n");
    print join (",",chomp (arr));

    This will print:
    2

    while this:
    my arr = ('a', "b\n", "c\n");
    chomp (arr);
    print join (",",arr);

    will print:
    a,b,c

    Map will run whatever is in the code block (between the {}'s) on every
    value in the list passed to it (between the ()'s). The last statement
    in the code block is like a return value. Map builds the results list
    out of all of the return values. With a foreach loop, it would be:
    my results = ();
    foreach (<IN>) {
    my $line = $_;
    chomp $line;
    $line =~ s/\s+//g;
    push (results, $line); #appends $line to the results list
    }

    Hope this helps.

    -David

    On Fri, 10 Sep 2004 11:58:30 -0500, Errin Ln <com> wrote: 
    > > This is a little shorter and saves on iterations:
    > > for my $file (ARGV) {
    > > open IN, $file or die "Couldn't open $file: $!\n";
    > > results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;
    > > $line } (<IN>);
    > > close IN;
    > > }
    > >
    > > -David
    > >[/ref]
    >
    > Can you throw the 'chomp' in the assignment in that 'map' statement?
    > Then, can you also throw in the substitution in the mix? like this:
    > results = map{ my $line = chomp( s/\s+//g ); } ( <IN> );
    >
    > And if so, why not this:
    >
    > results = map{ chomp( s/\s+//g ) } ( <IN> );
    >
    > As long as we're playing Perl-Golf!!
    >
    > I truly don't understand what 'map' is doing. Can you explain it to
    > me? I have tried to read perldoc -f map but it's a little weird and
    > hard to follow!
    >
    > --Errin
    >[/ref]
    David Guest

  6. #6

    Default Re: How to dynamically taking the multiple input arguments?



     
    > This is a little shorter and saves on iterations:
    > for my $file (ARGV) {
    > open IN, $file or die "Couldn't open $file: $!\n";
    > results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;[/ref]

    results seems would be re-assigned when the next file comes...

    Besides, I guess chomp is not nesessary here.. \s+ means [\t\r\n\f]+,
    so \r, \n or \r\n would seem to be cleared by the s expression.

     

    I would suggest to write in this way :
    my res = ();
    foreach( ARGV ) {
    open IN, $_ or die "Couldn't open $_: $!\n";
    my data = <IN>;
    close IN;

    s/\s+//g for data;
    res = ( res, data );
    }

    Code not been tested, but the concept is something like this.
    HTH


    Bee Guest

  7. #7

    Default Re: How to dynamically taking the multiple input arguments?

    On Fri, 10 Sep 2004 13:17:40 -0400, David Greenberg
    <com> wrote: 

    Thanks, David, for the 'map' explanation. However, I've been playing
    with this code, and, after your suggestion (above) it seems to be
    broken. Originally, the question was, taking atleast 2 seperate text
    files on the command line, smoosh them together like this:

    # ./smoosher file1 file2
    OneFirst
    TwoSecond
    ThreeThird

    if our text files are:
    file1:
    One
    Two
    Three

    file2:
    First
    Second
    Third

    The code I have so far is (after your suggestion):

    smoosher:
    #!/usr/bin/perl

    use warnings;
    use strict;

    unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }

    my results = ();

    foreach my $file ( ARGV ) {
    open IN, $file or die "Couldn't open $file: $!\n";
    results = map { my $line = $_; chomp $line; $line =~
    s/\s+//g; $line } (<IN>);
    close IN;
    }

    foreach( results ) { print "$_\n"; }

    The first 'foreach' block in my original code, which was working, was:

    foreach my $file ( ARGV ) {
    open IN, $file or die "Couldn't open $file: $!\n";
    chomp( my data = <IN> );
    close IN;
    foreach( data ) { s/\s+//g; }
    foreach( 0..$#data ) { $results[$_] .= $data[$_]; }
    }

    So my question is, how can we use the map function, as you suggest, to
    reduce the number of iterations, yet still keep our desired output?
    The key was the
    $results[$_] .= $data[$_];
    line in there, which appended the current files line to the results
    array, as opposed to replacing it, which is what our new code seems to
    do.

    --Errin
    Errin Guest

  8. #8

    Default Re: How to dynamically taking the multiple input arguments?

    On Sat, 11 Sep 2004 02:20:32 +0800, Bee <org> wrote: 
    > > This is a little shorter and saves on iterations:
    > > for my $file (ARGV) {
    > > open IN, $file or die "Couldn't open $file: $!\n";
    > > results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;[/ref]
    >
    > results seems would be re-assigned when the next file comes...
    >
    > Besides, I guess chomp is not nesessary here.. \s+ means [\t\r\n\f]+,
    > so \r, \n or \r\n would seem to be cleared by the s expression.

    >
    > I would suggest to write in this way :
    > my res = ();
    > foreach( ARGV ) {
    > open IN, $_ or die "Couldn't open $_: $!\n";
    > my data = <IN>;
    > close IN;
    >
    > s/\s+//g for data;
    > res = ( res, data );
    > }
    >
    > Code not been tested, but the concept is something like this.
    > HTH
    >
    >[/ref]

    Ok ... Thanks for helpin' out, HTH! I tried out your suggestions and
    now the code looks like this:

    #!/usr/bin/perl
    use warnings;
    use strict;

    unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }

    my results = ();
    foreach my $file ( ARGV ) {
    open IN, $file or die "Couldn't open $file: $!\n";
    my data = <IN>;
    close IN;
    s/\s+//g foreach( data );
    results = ( results, data );
    }

    foreach( results ) { print "$_\n"; }

    But now the output is as follows. We want the output to look like this:
    OneFirst
    TwoSecond
    ThreeThird
    But instead, it's coming out like this:
    One
    Two
    Three
    First
    Second
    Third
    Given the two test input files:
    file1: file2:
    One First
    Two Second
    Three Third

    --Errin
    Errin Guest

  9. #9

    Default Re: How to dynamically taking the multiple input arguments?

    Opps, I missed that. Instead of:
    results = map { my $line = $_; chomp $line; $line =~ s/\s+//g; $line } (data);
    try:
    my newresults = map { my $line = $_; chomp $line; $line =~ s/\s+//g;
    shift (results) . $line } (data);
    results = newresults;

    -David

    On Fri, 10 Sep 2004 13:40:04 -0500, Errin Ln <com> wrote: 
    > >
    > > results seems would be re-assigned when the next file comes...
    > >
    > > Besides, I guess chomp is not nesessary here.. \s+ means [\t\r\n\f]+,
    > > so \r, \n or \r\n would seem to be cleared by the s expression.
    > > 
    > >
    > > I would suggest to write in this way :
    > > my res = ();
    > > foreach( ARGV ) {
    > > open IN, $_ or die "Couldn't open $_: $!\n";
    > > my data = <IN>;
    > > close IN;
    > >
    > > s/\s+//g for data;
    > > res = ( res, data );
    > > }
    > >
    > > Code not been tested, but the concept is something like this.
    > > HTH
    > >
    > >[/ref]
    >
    > Ok ... Thanks for helpin' out, HTH! I tried out your suggestions and
    > now the code looks like this:
    >
    > #!/usr/bin/perl
    > use warnings;
    > use strict;
    >
    > unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }
    >
    > my results = ();
    > foreach my $file ( ARGV ) {
    > open IN, $file or die "Couldn't open $file: $!\n";
    > my data = <IN>;
    > close IN;
    > s/\s+//g foreach( data );
    > results = ( results, data );
    > }
    >
    > foreach( results ) { print "$_\n"; }
    >
    > But now the output is as follows. We want the output to look like this:
    > OneFirst
    > TwoSecond
    > ThreeThird
    > But instead, it's coming out like this:
    > One
    > Two
    > Three
    > First
    > Second
    > Third
    > Given the two test input files:
    > file1: file2:
    > One First
    > Two Second
    > Three Third
    >
    > --Errin
    >[/ref]
    David Guest

  10. #10

    Default Re: How to dynamically taking the multiple input arguments?

    > Ok ... Thanks for helpin' out, HTH! I tried out your suggestions and 

    You are welcome, but my name is Bee, HTH stands for 'Hope This Help'
     

    Oops... sorry for I've confused for what you expected, so instead the above
    line with this :
    $results[$_] .= $data[$_] for (0..$#data) ; # would almostly do what you
    want now !






    Bee Guest

  11. #11

    Default Re: How to dynamically taking the multiple input arguments?

    On Fri, 10 Sep 2004 15:01:34 -0400, David Greenberg
    <com> wrote: 

    Ok ... please forgive my n00b-ness, but can you help me understand a
    couple of things here. This part:

    shift (results) . $line

    Is it the same as:

    shift results . $line

    I'm thinking "no". But I don't know what the difference is. I also
    don't understand what exactly that shift is doing, but if I understand
    the difference with the parens maybe It'll start to make more sense to
    me.

    --Errin
    Errin Guest

  12. #12

    Default Re: How to dynamically taking the multiple input arguments?

    I'm not sure if shift (results) . $line; and shift results . $line
    would work differently. It depends on whether the order of operations
    gives precedence to . or to handing an argument to a function. My
    guess is that . gets precedence, in which case shift results . $line;
    will give you something weird that you don't want.

    I suggest you look up the perldocs on shift, but basically if you have
    any array, like:
    my arr = ('a', 'b', 'c');

    the result of:
    print shift (arr);

    will be:
    a

    and arr will now only be:
    ('b', 'c')

    In other words, it takes the first element off of the array. It is
    often used to get arguments to a function:
    sub foo {
    my $arg1 = shift;
    my $arg2 = shift;
    print $arg1 . " " . $arg2;
    }
    foo ("hello", "world");

    would print:
    hello world

    So, shift (results) . $line; is taking the next value from results
    and appending $line to it.
    That value will then be the next value in newresults.

    It takes a bit of getting used to. I suggest reading a little about
    functional programming to fully grasp the list manipulation functions
    like map, grep, split, join, etc.

    -David


    On Fri, 10 Sep 2004 14:37:28 -0500, Errin Ln <com> wrote: 
    >
    > Ok ... please forgive my n00b-ness, but can you help me understand a
    > couple of things here. This part:
    >
    > shift (results) . $line
    >
    > Is it the same as:
    >
    > shift results . $line
    >
    > I'm thinking "no". But I don't know what the difference is. I also
    > don't understand what exactly that shift is doing, but if I understand
    > the difference with the parens maybe It'll start to make more sense to
    > me.
    >
    > --Errin
    >[/ref]
    David Guest

  13. #13

    Default Re: How to dynamically taking the multiple input arguments?

    > > Opps, I missed that. Instead of: [/ref]
    (data); [/ref]

    This works fine, but can be simplier :
    my newresults = map { s/\s+//g; shift (results) . $_ } (data);

     

    This means :
    $x = shift result; # where $x means to $_ or the value carries in memory.
    $x = $x . $line
     

    While this means :

    $x = results . $line ; # results here means scalar results ( how many
    elems inside results )
    shift $x ; # then cause error.
     

    The difference is the scope for the 'shift' , with ( ), the scope for shift
    is results,
    without ( ) , the scope for shift is results . $line .
     

    perldoc -f shift


    Bee Guest

  14. #14

    Default Fwd: How to dynamically taking the multiple input arguments?

    I forgot to CC the list with my last post! sorry, won't happen again.
    --Errin


    ---------- Forwarded message ----------
    From: Errin Ln <com>
    Date: Fri, 10 Sep 2004 15:46:33 -0500
    Subject: Re: How to dynamically taking the multiple input arguments?
    To: Bee <org>

    Alrighty ... So the code I've got now is below. Some of the
    variables' names have changed to make things slightly less confusing
    (probably only less confusing for me!). I also moved those parens
    arount the 'shift' function so it communicates the precendence (again,
    in my opinion) a little more clearly. I have tested this and it seems
    to work! comments?

    #!/usr/bin/perl
    use warnings;
    use strict;

    unless( ARGV >= 2 ) { die "Usage: $0 file1 file2 [file3...]\n"; }

    my final_results = ();
    foreach my $file ( ARGV ) {
    open IN, $file or die "Couldn't open $file: $!\n";
    my tmp_results = map{ s/\s+//g; ( shift final_results ).$_ } ( <IN> );
    final_results = tmp_results;
    close IN;
    }

    print "$_\n" foreach( final_results );

    btw, thanks for all the help and explanations David and Bee (sorry
    about my ignorance of the HTH!). I hope Edward (the original poster!)
    has been paying attention!

    --Errin
    Errin Guest

  15. #15

    Default Re: How to dynamically taking the multiple input arguments?

    Edward WIJAYA wrote: 

    Hello,
     

    You could use the paste program to do that.

    man paste

     

    You are using 'ne' which compares strings when you should be using '!=' which
    is used to compare numbers. Both the comparison operator and the if
    conditional force scalar context so using 'scalar' is redundant.

    if ( ARGV != 1 )

    However that only works if the command line has exactly one filename and you
    want to require two or more.

    if ( ARGV >= 2 )

     
    ^^^^^^^^
    perldoc -q quoting

    Found in /usr/lib/perl5/5.8.2/pod/perlfaq4.pod
    What's wrong with always quoting "$vars"?

     

    use() keeps track of which modules have been loaded so use()ing the same
    module more than once will not incur more overhead and will not do anything
    useful either.

     

    my() creates a lexical variable in an undefined state so assigning an
    undefined value to it is redundant.

     

    You should include the $! (or $^E) variable in the error message so you know
    why open() failed.

     

    If you had used a lexical filehandle you could have skipped the assignment to
    an array.

     

    A valid __END__ token has two underscore characters before and after 'END'.


    You have two basic options for merging files, store all the contents in memory
    which may run out of memory, or read each file line by line which may run out
    of file handles.

    If the aggregate data will fit in memory you can do this:

    #!/usr/bin/perl
    use warnings;
    use strict;

    my ( $line, data );
    while ( <> ) {
    $data[ $line++ ] .= $_ if /\S/;
    $line = 0 if eof;
    }

    # clean up whitespace
    for ( data ) {
    s/^\s+//;
    s/\s+/ /g;
    s/ $/\n/;
    }

    print data;

    __END__


    And if you need to read each file a line at a time you could do something like
    this:

    #!/usr/bin/perl
    use warnings;
    use strict;

    my fhs = map { open my $fh, '<', $_ or die "$_: $!"; $fh } ARGV;

    while ( fhs ) {
    my $line = '';
    for ( fhs ) {
    defined( my $curr = <$_> ) or next;
    redo unless $curr =~ /\S/;
    $line .= $curr;
    }

    for ( $line ) {
    s/^\s+//;
    s/\s+/ /g;
    s/ $/\n/;
    }

    print $line;
    fhs = grep !eof( $_ ), fhs;
    }

    __END__



    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  16. #16

    Default Re: How to dynamically taking the multiple input arguments?

    Errin Ln wrote: 
    >>
    >>This is a little shorter and saves on iterations:
    >>for my $file (ARGV) {
    >> open IN, $file or die "Couldn't open $file: $!\n";
    >> results = map { my $line = $_; chomp $line; $line =~ s/\s+//g;
    >>$line } (<IN>);
    >> close IN;
    >>}[/ref]
    >
    > Can you throw the 'chomp' in the assignment in that 'map' statement?[/ref]

    No.
     

    No.
     

    The substitution operator returns the number of substitutions performed or
    false if there were no substitutions. chomp() returns the number of chomps
    performed. map returns the value of the last statement in the code block.

    So, assuming s/\s+//g returns a number and $/ hasn't been changed, chomp will
    assign 0 to $line which map will return for every line from IN.

     

    Again, map will return 0 for every line from IN.

    Also, the parentheses around the readline operator are redundant as map forces
    list context.

     

    map takes a list, modifies each element, and returns the modified list.



    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  17. #17

    Default Re: How to dynamically taking the multiple input arguments?

    Bee wrote: 

    You are copying the res array. It would be more efficient using push.

    push res, data;


    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  18. #18

    Default Re: How to dynamically taking the multiple input arguments?

    Errin Ln wrote: 

    If you had actually tried to run them you would have seen that the second one
    does not even compile. :-)


    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  19. #19

    Default How to dynamically taking the multiple input arguments?

    Hi,

    I have a simple code that take
    currently fixed to take 3 input files and
    append each line of these files together.

    I wish to know is there anyway I can
    write the code more flexibly so it can
    dynamically take the input argument - from minimum
    2 files to more.

    Is there anywhere I can find information
    about dealing with this matter? Any specific
    module that cater this problem?

    Thanks for your time beforehand.

    Regards,
    Edward WIJAYA
    SINGAPORE


    This is my current (terribly inefficient
    and unflexible) code:

    #!/usr/bin/perl -w
    use strict;
    use Data::Dumper;


    if(scalar ARGV ne 1)
    {
    print "Usage: $0 file1 file2 [file3] etc\n";
    exit(1);
    }
    #the above part doesn't seem to be working well/useful

    my $file1 = $ARGV[0];
    my set1 = get_file_data("$file1");

    #Remove the whitspace and \n from each lines
    set1 = grep { s/^\s+//; s/\s+$//; s/\s+/ /g; length } set1;
    my $s1 = \set1;

    my $file2 = $ARGV[1];
    my set2 = get_file_data("$file2");
    set2 = grep { s/^\s+//; s/\s+$//; s/\s+/ /g; length } set2;
    my $s2 = \set2;

    my $file3 = $ARGV[2];
    my set3 = get_file_data("$file3");
    set3 = grep { s/^\s+//; s/\s+$//; s/\s+/ /g; length } set3;
    my $s3 = \set3;



    #Printout the appended lines from the data
    print map { join("",$set1[$_],$set2[$_],$set3[$_]), "\n" } (0..$#set1);



    #Subroutine
    sub get_file_data {

    my ($filename) = _;

    use strict;
    use warnings;

    # Initialize variables
    my filedata = ();

    unless ( open( GET_FILE_DATA, $filename ) ) {
    print STDERR "Cannot open file \"$filename\"\n\n";
    exit;
    }

    filedata = <GET_FILE_DATA>;
    close GET_FILE_DATA;
    return (filedata);
    }


    ___END____

    Edward Guest

  20. #20

    Default Re: How to dynamically taking the multiple input arguments?

    Edward WIJAYA wrote: 

    Hello,
     [/ref]

    This should do what you want:

    #!/usr/bin/perl
    use warnings;
    use strict;

    my ( $line, data );
    while ( <> ) {
    s/^\s+//;
    s/\s+$//;
    s/\s+/ /g;
    $data[ $line++ ] .= $_ if /\S/;
    $line = 0 if eof;
    }

    print map "$_\n", data;

    __END__



    John
    --
    use Perl;
    program
    fulfillment
    John Guest

Page 1 of 2 12 LastLast

Similar Threads

  1. cfexecute multiple arguments
    By Flanders99 in forum Coldfusion - Advanced Techniques
    Replies: 2
    Last Post: September 27th, 08:58 PM
  2. Dynamically formatting text for input
    By FunkyJunk in forum Macromedia Director Lingo
    Replies: 2
    Last Post: January 23rd, 04:40 PM
  3. map/collect iterating over multiple arrays/arguments
    By Zoran Lazarevic in forum Ruby
    Replies: 5
    Last Post: October 8th, 04:30 PM
  4. Creation of input fields dynamically
    By Bob Barrows in forum ASP
    Replies: 1
    Last Post: August 22nd, 01:12 AM
  5. #24856 [NEW]: Extract taking multiple arguments
    By dave at psntn dot com in forum PHP Development
    Replies: 0
    Last Post: July 29th, 05:52 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139