2 Replies - 6490 Views - Last Post: 02 July 2013 - 12:44 AM

#1 blindchicken11  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 63
  • Joined: 19-September 12

reading in a .txt file and displaying it properly

Posted 01 July 2013 - 03:02 PM

Hello all. I'm really new to Pearl, and I've been working on a solution to this problem. My professor gave several problems (non-graded) in different languages to practice for our final at the end of this week. Only thing is, it's a condensed class and we briefly touched on Pearl, but I'd like to get into it more. Here's the problem (I know it's long):

It should read the file from the filehandle STDIN. so, no opening of files necessary--you can just start reading.

Each line consists of a series of fields, separated by tabs ("\t").

The file starts off with a single header line, in which each field is the label for that corresponding column. After splitting the line up into fields at the tabs, scan the list of fields for certain patterns:

A header field called "Name" indicates the "student name" column.
A header field called "Email" indicates the "email address" column.
Any header field that contains the substring "Problem": e.g., "Problem #1" or "Extra Credit Problem", indicates a column containing a grade for that problem. For each of these grade colums, the very next column holds a comment for that grade.

There might be other columns, which you should ignore. Also, the columns are in no particular order (except that each "Problem" column has the corresponding comment column immediately after it).

The rest of the file consists of student grades, one student's record per line. Each record contains that student's name, email address, numerical grade for each problem, and a comment for each problem, in the order specified by the headers. As with the headers, any other fields can be safely ignored.

For each student record, you should do the following:

Break the line up into fields at tabs.
Print out "Name: ", followed by the student's name, then a newline.
Print out "Email: ", followed by the student's email address, then a newline.
For each column position that corresponds to a problem grade:
Print out: "Grade for ", then the label for that problem (saved from the header), then the actual numerical grade.
Then, print out an optional comment according to the following rules:
If the associated comment is non-blank, print that.
Else if the grade is 0, print "Not done."
Otherwise, don't print anything.
Print out "Final Grade: ", then the sum of the numerical grades.
End each student's record with a double newline

So, here's a toy example. The following table represents the contents of the file, rows representing lines, and columns representing tab-separated values in each line.
Name Problem #1 Comments for P1 E.C. Problem Comments Email
Park, John 17 Really bad. 5 park@umbc.edu
Doe, Jane 100 Well done! 0 Why didn't you do this? doe2@umbc.edu
Smith, Bob 0 0 smith9999@gmail.com
Given the input file above, your Perl script should produce the following report:

Name: Park, John
Email: park@umbc.edu
Grade for Problem #1: 17 Really bad.
Grade for E.C. Problem: 5
Final Grade: 22

Name: Doe, Jane
Email: doe2@umbc.edu
Grade for Problem #1: 100 Well done!
Grade for E.C. Problem: 0 Why didn't you do this?
Final Grade: 100

Name: Smith, Bob
Email: smith9999@gmail.com
Grade for Problem #1: 0 Not done.
Grade for E.C. Problem: 0 Not done.
Final Grade: 0

The input file is guaranteed to be properly formatted, i.e. you don't have to do any error checking, like making sure every line has the correct number of fields, that the grade field is numerical, etc. You also don't have to check for quoted strings. The whole program should be about 20-25 lines. Keep it simple, and don't try to abuse Perl's many shortcuts."

This is what I have (not very much I know) just to test some things out. I know I'm not opening the file using STIDN at the moment.
 open (FILE, 'data.txt');
 while (<FILE>) {
 chomp;
 ($name, $#1, $Comments for P1) = split("\t");
 print "Name: $name\n";
 print "#1: $#1\n";
 print "Comments for P1: $Comments for P1\n";
 print "---------\n";
 }
 close (FILE);
 exit;



Is This A Good Question/Topic? 0
  • +

Replies To: reading in a .txt file and displaying it properly

#2 blindchicken11  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 63
  • Joined: 19-September 12

Re: reading in a .txt file and displaying it properly

Posted 01 July 2013 - 03:42 PM

 while (<>) {
 chomp;
 ($name, $problem1, $comments1, $ec, $ecomments, $email) = split("\t");
 print "Name: $name\n";
 print "Problem1 $problem1\n";
 print "Comments1: $comments1\n";
 print "EC: $ec\n";
 print "EComments: $ecomments\n";
 print "Email: $email\n";
 print "---------\n";
 }
 exit;


Have this right now.
Was This Post Helpful? 0
  • +
  • -

#3 dsherohman  Icon User is offline

  • Perl Parson
  • member icon

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

Re: reading in a .txt file and displaying it properly

Posted 02 July 2013 - 12:44 AM

I see you've already discovered while (<>). Good. That was the first thing I was going to suggest. :D

"Also, the columns are in no particular order" is a thoroughly evil requirement for an introductory exercise, because it means that, in order to truly do this properly, you need to parse the first line and use that to identify which is the name field, which is the email filed, and which are problem/comment fields so that they can be printed in the right order while not printing anything else.

If it were not for that requirement, you could easily print the contents of each line with the appropriate headers as simply as
use strict;
use warnings;

# Get the header and break it into fields
my $header_row = <>;
chomp $header_row;
my @header = split "\t", $header_row;

while (<>) {
  chomp;
  my @data = split "\t";
  # Print the value of each field along with its name from the header
  for my $i ([0 .. $#data]) {
    print "$header[$i]: $data[$i]\n";
  }
  print "\n";
}

(Untested code, but simple enough that it should probably work aside from any typos that might have snuck in.)

But, since the assignment says that the fields are in no particular order, you'll have to look at each field in @header and make a note of the interesting ones and their positions. My first thought was to use a hash for this, but, because of the "Problem #x" fields, it might work better to create an @field_order array instead. (If I were to do it with a hash, I would want to use an array reference to track the "Problem #x" fields, but I assume that's well beyond what your class has covered.)

Hopefully this is enough of a pointer to be useful to you without giving the whole thing away. If you need any more help with this, try asking specific questions about the things that are giving you problems. Very broad questions like this one are more difficult to answer, since it's hard to tell what exactly you need help with or how much help you need.

(By the way, the language is spelled "Perl", not "Pearl". When Larry Wall created it, he actually wanted to call it "Pearl", as in "a pearl of great price", but it turned out there was already another, completely unrelated, programming language called "Pearl", so he changed the spelling of his version.)

This post has been edited by dsherohman: 02 July 2013 - 12:44 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1