|
Home > Archive > Unix Programming > February 2006 > Datafile Manipulation
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Datafile Manipulation
|
|
|
| Hi,
I'm trying to write a shell which will assess a list of student's
grades. The data file consists of the following...
2068344
8
6
3
8
2
8
2068943
9
7
3
7
3
7
The large numbers being the student ID, the small numbers being the
mark on a certain question.
My overall target is to output the student ID and the overall
percentage.
i.e.
2068344 78%
2068943 47%
I have run into a problem in that when performing the mathematics on
the file (at this stage the addition of the marks, leading to working
out the percentage), I can not dfferentiate between each individual
student, leaving me with one very large and useless number.
Any help on the matter would be brilliant.
Thank you.
| |
| Roger Leigh 2006-02-17, 10:40 pm |
| -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
"Adam" <adamsalisbury@gmail.com> writes:
> 2068344
> 8
> 6
> 3
> 8
> 2
> 8
> 2068943
> 9
> 7
> 3
> 7
> 3
> 7
>
> The large numbers being the student ID, the small numbers being the
> mark on a certain question.
> I have run into a problem in that when performing the mathematics on
> the file (at this stage the addition of the marks, leading to working
> out the percentage), I can not dfferentiate between each individual
> student, leaving me with one very large and useless number.
We don't do homework questions here. However, one fairly obvious
observation is that there are two kinds of numbers, the 7-digit
student ID and the marks. Perhaps your shell script should
differentiate between them, and do something when it sees a new
student ID or the end of the file (like, say, a calculation).
Regards,
Roger
- --
Roger Leigh
Printing on GNU/Linux? http://gutenprint.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8+ <http://mailcrypt.sourceforge.net/>
iD8DBQFD86wCVcFcaSW/uEgRAvs2AKDH1DwtDy/hfU/ER8wC1AdBEtNkCgCghsVM
j3H8RRWLPflwduTzPOQyCfw=
=fGTL
-----END PGP SIGNATURE-----
| |
| Pascal Bourguignon 2006-02-17, 10:40 pm |
| "Adam" <adamsalisbury@gmail.com> writes:
> Hi,
> I'm trying to write a shell which will assess a list of student's
> grades. The data file consists of the following...
>
> 2068344
> 8
> 6
> 3
> 8
> 2
> 8
> 2068943
> 9
> 7
> 3
> 7
> 3
> 7
>
> The large numbers being the student ID, the small numbers being the
> mark on a certain question.
>
> My overall target is to output the student ID and the overall
> percentage.
> i.e.
> 2068344 78%
> 2068943 47%
>
> I have run into a problem in that when performing the mathematics on
> the file (at this stage the addition of the marks, leading to working
> out the percentage), I can not dfferentiate between each individual
> student, leaving me with one very large and useless number.
It would be smarter to use awk rather than the shell.
$ awk '
BEGIN{student=0;maxmark=10;}
function report_student(){
if(student!=0){printf "%s %4.1f%%\n",student,total/nummark;}}
/[0-9][0-9][0-9]/{report_student(); student=$0; total=0;nummark=0; next;}
{total+=100.0*$0/maxmark; nummark++;}
END{report_student();}' <<EOF
2068344
8
6
3
8
2
8
2068943
9
7
3
7
3
7
EOF
2068344 58.3%
2068943 60.0%
--
__Pascal Bourguignon__ http://www.informatimago.com/
Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
| |
|
| Pascal Bourguignon wrote:
> "Adam" <adamsalisbury@gmail.com> writes:
>
>
> It would be smarter to use awk rather than the shell.
>
> $ awk '
> BEGIN{student=0;maxmark=10;}
> function report_student(){
> if(student!=0){printf "%s %4.1f%%\n",student,total/nummark;}}
> /[0-9][0-9][0-9]/{report_student(); student=$0; total=0;nummark=0; next;}
> {total+=100.0*$0/maxmark; nummark++;}
> END{report_student();}' <<EOF
> 2068344
> 8
> 6
> 3
> 8
> 2
> 8
> 2068943
> 9
> 7
> 3
> 7
> 3
> 7
> EOF
Pascal, I'm not sure you'd have passed the assignment :-)
Here's a bash version; but since it is clearly homework, I have left
three deliberate errors in it: Two fairly easy, and one (thanks to
bash's quirks) fiendishly obscure. Printing one decimal place left as a
further exercise 
#!/bin/bash
MAXMARK=10
printtot() {
local AVG
let AVG=(TOT*100)/(GRADES*MAXMARK)
echo "$NUM: $GRADES grades totalled $TOT = $AVG%"
}
while read VALUE ; do
if (( VALUE > MAXMARK )) ; then
if (( NUM )) ; then printtot ; fi
NUM= $VALUE
# reset for next student
TOT=0
GRADES=0
else
let TOT+=VALUE
let +GRADES
fi
done
printtot
Here's the result of the corrected script:
$ ./grades.sh <input
2068344: 6 grades totalled 35 = 58%
2068943: 6 grades totalled 36 = 60%
$
>
> 2068344 58.3%
> 2068943 60.0%
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
>
> Nobody can fix the economy. Nobody can be trusted with their finger
> on the button. Nobody's perfect. VOTE FOR NOBODY.
| |
| William James 2006-02-20, 2:48 am |
| Adam wrote:
> Hi,
> I'm trying to write a shell which will assess a list of student's
> grades. The data file consists of the following...
>
> 2068344
> 8
> 6
> 3
> 8
> 2
> 8
> 2068943
> 9
> 7
> 3
> 7
> 3
> 7
>
> The large numbers being the student ID, the small numbers being the
> mark on a certain question.
>
> My overall target is to output the student ID and the overall
> percentage.
> i.e.
> 2068344 78%
> 2068943 47%
>
> I have run into a problem in that when performing the mathematics on
> the file (at this stage the addition of the marks, leading to working
> out the percentage), I can not dfferentiate between each individual
> student, leaving me with one very large and useless number.
>
> Any help on the matter would be brilliant.
>
> Thank you.
Ruby:
Max_score = 10
a = []
while s=gets
if s =~ /\d{7}/
a << [ s.strip ]
else
a.last << s.to_f
end
end
a.each{ |x|
printf "%s %0.1f%%\n", x.shift,
x.inject{|sum,i|sum + i}/(Max_score*x.size)*100
}
|
|
|
|
|