14 Replies - 7245 Views - Last Post: 26 January 2013 - 05:17 AM

#1 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

New to Perl

Posted 24 January 2013 - 07:23 PM

Hi I haven't used Perl before and am trying to understand how to do my first assignment. I need to write a Perl program that reads in an arbitrary number of strings from the command line and displays them sorted alphabetically. I know I need to use the sort function but I'm not sure how the program reads the string entered from the command line in the program. This is what I had so far but I'm not sure if it is on the right track. Any help is greatly appreciated.

# Simple Perl Assignment - sort strings 
# Purpose:
     # This program reads in an arbitrary number of 
     # strings from the command line and displays 
     # them sorted alphabetically.
     # 
     # usage: sort.pl <-r, --reverse> two or more strings
     
     # (1) quit unless we have the correct number of command-line args

$num_args = $#ARGV + 1;
if ($num_args != 3) {
  print "\nUsage: name.pl first_name last_name\n";
  exit;
}
     
	$first_arg=$ARGV[0];
	$second_arg=$ARGV[1];
	$third_arg=$ARGV[2];
	
	sort($first_arg, $second_arg, $third_arg);


Is This A Good Question/Topic? 0
  • +

Replies To: New to Perl

#2 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 24 January 2013 - 07:50 PM

Are the elements to be sorted independent of case? I'm not much of a Perl hacker, so I didn't know this before, but you can actually override what type of comparison sort does. This page explains it pretty well:

http://perl5maven.co...-arrays-in-perl

You probably want to be sorting the whole array--no matter how many elements there are in it, so you should probably remove the code that bails when the number of arguments is anything but 3.

Also, sort operates on an array, so you should be doing something like:
my @sorted = sort @ARGV;


After that, you'll have to loop through @sorted and print each value.

Hope this helps.

This post has been edited by NathanMullenax: 24 January 2013 - 07:51 PM

Was This Post Helpful? 1
  • +
  • -

#3 dsherohman  Icon User is offline

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: New to Perl

Posted 25 January 2013 - 03:02 AM

First off, I assume you already realize that the code you posted goes out of its way to not meet the assigned specification - if it requires a specific number of items to sort, then it's not sorting an arbitrary number of items.

Anyhow...

To read a string from the command line, use:
my $entered_string = <STDIN>;


Note that $entered_string will have a newline on the end of it; you'll probably want to use the chomp function to get rid of that before adding the new string to your list of data to sort. When you're done entering lines, hit ctrl-D (assuming a unix-type shell; I think it's ctrl-Z in Windows, but I'm not positive) to indicate that you've reached the end of the input data.

You can also be a little more flexible by using
my $entered_string = <>;


instead. The empty <> will go through ARGV and give you the contents of any files found there or, if ARGV is empty, it will read from STDIN instead.

If you need more help, just ask. I've deliberately kept this answer fairly vague so that you can figure out the details for yourself.
Was This Post Helpful? 0
  • +
  • -

#4 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

Re: New to Perl

Posted 25 January 2013 - 05:14 PM

Is this even close? I've never used this before so I'm having some trouble understanding how to do this.

my $entered_string = <STDIN>;

do{
	if ($entered_string < 3) 
	{
		print "You need at least three strings, re-enter";
	}
}while($entered_string < 3);
     


$i;

for($i = 0; i < $entered_string; i++)
{ 
	sort($entered_string[i]);
}

Was This Post Helpful? 0
  • +
  • -

#5 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 05:26 PM

Reading from the command line and reading from <STDIN> are two different things. The command line arguments are in the @ARGV array--these are the thing that come after the name of your script when you invoke it:

>yourprogramname.pl arg0 arg1 arg2 arg3

Whereas <STDIN> refers to thing that the user enters after your program has started (or pipes into your program, but that's another subject...)

When you do $v = <STDIN>, you are getting the last line of input (everything before the user last hit enter) as a string, so the above code doesn't really make too much sense. Doing this: '$entered_string < 3' is comparing a string to an integer, which might be 'valid', but doesn't really make sense in the context of this program.
Was This Post Helpful? 0
  • +
  • -

#6 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 05:49 PM

Here's a little script to illustrate some functions that might be useful:
#!/usr/bin/perl

use strict;

my @a = ('zed','epsilon','apple','dunkin','copper','beta');

print "The original array:\n\@a = @a\n\n";

my $f = shift( @a );


print "The shift function removes the first element from an array\n";
print "shift(\@a) = $f\n";

# The @a is shorthand for printing all elements in the array
print "\@a after shift:\n@a\n\n";


# note: sort returns a copy of the array;
# it does not sort in place.
print "The sort function sorts an array:\n";
my @sorted = sort @a;
print "@sorted\n\n";

print "You can customize the comparison used during a sort:\n";
my @rev = sort { lc( $b ) cmp lc($a) } @a;
print "@rev\n\n";

The output:

The original array:
@a = zed epsilon apple dunkin copper beta

The shift function removes the first element from an array
shift(@a) = zed
@a after shift:
epsilon apple dunkin copper beta

The sort function sorts an array:
apple beta copper dunkin epsilon

You can customize the comparison used during a sort:
epsilon dunkin copper beta apple

This post has been edited by NathanMullenax: 25 January 2013 - 05:51 PM

Was This Post Helpful? 0
  • +
  • -

#7 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

Re: New to Perl

Posted 25 January 2013 - 07:57 PM

ok thanks I'm getting it to print the strings from the command line. The only problem now is it is not sorting the strings and I need it to have at least three strings entered.

my @a = @ARGV;



my @sorted = sort @a;
print "@a\n\n";


Was This Post Helpful? 0
  • +
  • -

#8 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 08:04 PM

print "@a\n\n";

Should be
print "@sorted\n\n";

Sort copies the array, so the original array is left unchanged and the sorted one is a return value. Your first post had code to check for the number of arguments:
$num_args = $#ARGV + 1;
if ($num_args < 3) {
    print "\nUsage: name.pl first_name last_name\n";
    exit;
}

This will work, but you should probably update the 'usage' statement to reflect what the program actually does as described in your comments.

This post has been edited by NathanMullenax: 25 January 2013 - 08:16 PM

Was This Post Helpful? 1
  • +
  • -

#9 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

Re: New to Perl

Posted 25 January 2013 - 08:07 PM

I was able to get it to sort just had to make a minor change to this
my @a = @ARGV;



my @sorted = sort @a;
print "@sorted\n\n";


Now how can I get it to display an error if at least 3 strings arent entered?

thanks nathan, can you help with my last question above?
Was This Post Helpful? 0
  • +
  • -

#10 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 08:15 PM

$num_args = $#ARGV + 1;
if ($num_args < 3) {
    print "\nError: this program expects at least 3 arguments.\n";
    exit;
}

It looked like you already had it. You could change it to the above, but it is more typical (at least in the linux world) to print a usage statement instead of an error when you get command line arguments that don't make sense.

This post has been edited by NathanMullenax: 25 January 2013 - 08:15 PM

Was This Post Helpful? 0
  • +
  • -

#11 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

Re: New to Perl

Posted 25 January 2013 - 08:22 PM

Can you show me how to asks the user if they want to display the array sorted a-z or z-a? I can't figure out how to prompt the user to pick how they want it sorted?
Was This Post Helpful? 0
  • +
  • -

#12 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 08:33 PM

By the comments at the top of the file--which I assume are from the project template--you should be looking at the first parameter to determine the sort order. If the first parameter on the command line is '-r' or '--reverse' the sort order should be reversed.

To sort in reverse, you could use something like this:
my @rev = sort { lc( $b ) cmp lc($a) } @a;

The lc function converts a string to its lowercase equivalent, which is probably what you want for sorting strings.

The 'cmp' operator is a little strange--it returns -1, 0, or 1 depending on whether the lefthand side is less than, equal to, or greater than the righthand side. This is the same convention as a Java IComparable, if you are familiar.

This post has been edited by NathanMullenax: 25 January 2013 - 08:39 PM

Was This Post Helpful? 1
  • +
  • -

#13 ferguson32  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 178
  • Joined: 29-May 12

Re: New to Perl

Posted 25 January 2013 - 10:02 PM

ok so if I was to ask how they want it sorted, what function do I use to read their input for Perl. Like I know Java uses the scanf function, but what would I do in this case?
Was This Post Helpful? 0
  • +
  • -

#14 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 176
  • Joined: 23-September 12

Re: New to Perl

Posted 25 January 2013 - 10:07 PM

As dsherohman mentioned, you can use $v = <STDIN>; to get input.

For example:
print "Would you like to sort in reverse (Y|N)?\n";
var $p_reverse = <STDIN>;
if( lc($p_reverse)=="y" )
{
    # do reverse sorting
}
else
{
    # do regular sorting
}

This post has been edited by NathanMullenax: 25 January 2013 - 10:08 PM

Was This Post Helpful? 0
  • +
  • -

#15 dsherohman  Icon User is offline

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: New to Perl

Posted 26 January 2013 - 05:17 AM

View PostNathanMullenax, on 26 January 2013 - 01:26 AM, said:

Reading from the command line and reading from <STDIN> are two different things. The command line arguments are in the @ARGV array--these are the thing that come after the name of your script when you invoke it:

>yourprogramname.pl arg0 arg1 arg2 arg3

Whereas <STDIN> refers to thing that the user enters after your program has started (or pipes into your program, but that's another subject...)


Fair point... I took "read in an arbitrary number of strings from the command line" to mean that the strings are entered via the command-line interface, in which case they would be coming in on STDIN. Looking again at the "usage" in the comments at the top of the program, I see now that the strings are intended to be provided as command-line arguments, which is a very strange interface indeed... I've certainly never seen any real-world program which works that way.

OP: Per the "usage" example in the top comment block, you should not prompt the user for whether to sort in reverse order. That should be indicated by the value of the first argument provided - if it's -r or --reverse, you should sort in reverse order (presumably excluding that first argument; look at the shift command for this). If the first argument is anything else, do a normal, non-reversed sort.

As far as providing the reversed sort, you don't need to write a custom sorting function with cmp. Just do a default sort, then use the reverse command.

View PostNathanMullenax, on 26 January 2013 - 01:26 AM, said:

Reading from the command line and reading from <STDIN> are two different things. The command line arguments are in the @ARGV array--these are the thing that come after the name of your script when you invoke it:

>yourprogramname.pl arg0 arg1 arg2 arg3

Whereas <STDIN> refers to thing that the user enters after your program has started (or pipes into your program, but that's another subject...)


Fair point... I took "read in an arbitrary number of strings from the command line" to mean that the strings are entered via the command-line interface, in which case they would be coming in on STDIN. Looking again at the "usage" in the comments at the top of the program, I see now that the strings are intended to be provided as command-line arguments, which is a very strange interface indeed... I've certainly never seen any real-world program which works that way.

OP: Per the "usage" example in the top comment block, you should not prompt the user for whether to sort in reverse order. That should be indicated by the value of the first argument provided - if it's -r or --reverse, you should sort in reverse order (presumably excluding that first argument; look at the shift command for this). If the first argument is anything else, do a normal, non-reversed sort.

As far as providing the reversed sort, you don't need to write a custom sorting function with cmp. Just do a default sort, then use the reverse command.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1