 |
 |
Sorting some numbers
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Hello,
I have to make a program which sorts some grades out along with a students id number in decreasing order like this
id# grade
id#2 grade
id#3 grade and so on.
I have to read a file which contains some data like this (at least 20 students):
id# grade grade grade grade grade
id# grade grade grade grade grade
....
or the data file may even be like this
id# grade grade grade grade grade id# grade grade grade grade grade
Does it even matter which way?
What I have to do is to read this file and put it in an array and then average the five grades per student. Next, I have to sort the students according to their grades and id #.
I already have the program which will sort out the numbers. But what i was wondering is how can I first determine which data is the id# apart from the grade and how will I parse the id# into a parallel array with the averaged grades? Thanks!
edit: This is in C.
[This message has been edited by mindwaves (edited 04-07-2001).]
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 1999
Location: Georgetown, Demerara, Guyana
Status:
Offline
|
|
Hi mindwaves,
It usually doesn't matter whether the separators (between successive students' data) are newlines or spaces/tabs. For example, the 'fscanf()' routine is generally quite smart when reading whitespace separators; a numeric format-spec such as "%d" (for integers) should automatically skip past any preceding spaces, tabs or newlines. Also, there probably won't be any ambiguity between the ID#s and the grades, *if* there are strict regularities in the data. For instance, if for each student the ID# always precedes the grades and there are always exactly 5 grades, then every 1st, 7th, 13th, etc., value would be an ID#, regardless of whether the separators are newlines, spaces or tabs.
In terms of reading/parsing the students' data, and designing the overall program, your instructor might be flexible enough to let you choose certain aspects such as how many arrays to use. For example:- - When reading the students' data, you could store the ID#s in successive slots of a 1-dimensional array, and store the grade "groups" in successive rows of a separate 2-dimensional array. Then, the calculated averages could be stored in successive slots of yet another 1-dimensional array. (The three arrays' corresponding major indexes would tie them together conceptually; i.e., the nth ID# in the ID#s-array would correspond to the nth row of grades in the grades-array, and to the nth average in the averages-array.) Later on, as you sort the averages-array (shuffling/swapping the elements around by index), you'd just need to make the same adjustments to the corresponding elements of the ID#s-array, so as to keep the two arrays in synch throughout the sorting operation.
Here's an example of a two-level loop that uses this approach to read the students' data, with a 1-D integer array for holding the ID#s (assuming that the ID#s are numeric), and a 2-D integer array for holding the grade-groups:-
Code:
#include <stdio.h>
/* [...] */
#define MAX_NUM_STUDENTS 100 /* <== Change as appropriate */
#define NUM_GRADES_PER_STUDENT 5
/* [...] */
FILE *pDataFile;
int studentIndex, gradeIndex;
int student_IDNums[ MAX_NUM_STUDENTS ];
int student_Grades[ MAX_NUM_STUDENTS ][ NUM_GRADES_PER_STUDENT ];
pDataFile = fopen( "someFileName", "r" );
studentIndex = 0;
while( ! feof( pDataFile ) ) {
fscanf( pDataFile, "%d", &(student_IDNums[ studentIndex ]) );
for( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++) {
fscanf( pDataFile, "%d", &(student_Grades[ studentIndex ][ gradeIndex ]) );
}
studentIndex++;
}
fclose( pDataFile );
/* [...] */
- If the ID#s are indeed numeric, you could instead choose to store the ID#s along with the grade-groups in a single 2-D array. E.g., you could increase the number of columns by one, and store the ID#s as the first element in each row. Similarly, you could even reserve an additional column to hold the calculated averages as well. This way, all of the data would reside in one 2-D array. Then, you'd just need to modify the sort algorithm to shuffle/swap the ID#s (and the grades if you wish) along with the averages, so as to keep everything in synch.
The code for reading the students' data into a single 2-D array is quite similar to the code shown above for two separate arrays. You'd just need to:- remove the 'student_IDNums' array declaration; increase the 'student_Grades' array's declared number of columns by 1 (or 2, to accommodate averages later) [i.e., 'int student_Grades[ MAX_NUM_STUDENTS ][ (NUM_GRADES_PER_STUDENT + 1) ]']; adjust the first 'fscanf()' statement to read the ID# into the 'student_Grades' array instead [i.e., 'fscanf( pDataFile, "%d", &(student_Grades[ studentIndex ][ 0 ]) );']; and, increase the for-loop control's start/end values by 1 [i.e., 'for( gradeIndex = 1; gradeIndex < (NUM_GRADES_PER_STUDENT + 1); gradeIndex++) ...'].
- Or, you could choose to take another approach somewhere between these two extremes. E.g., you could use one 2-D array to hold the ID#s and averages, and another to hold only the grade-groups; then, you'd just need to modify the read loop and the sort algorithm accordingly.
Anyway, good luck with the assignment, and you can always post back here if there's anything that needs clarification.
Regards,
--Paul
|
|
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Thanks a lot Paul. You have helped me a lot.  I am still woking on it but I do have a general question. I use CodeWarrior 6 and I cannot find out how to indent my code in a hierarchy. I look in the prefs and all I can find is "auto-indent," but that feature is already on. What am I doing wron? Thanks again!
[This message has been edited by mindwaves (edited 04-09-2001).]
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Hello,
I am having some problem with summing the numbers together so that I can take the average of each row. Can you help me? Thanks. I am using a 2D array as listed above.
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 1999
Location: Georgetown, Demerara, Guyana
Status:
Offline
|
|
Hi again mindwaves,
Sorry, I haven't checked this Forum in a couple of days...
1. In terms of line-indentation in CodeWarrior's editor, unfortunately the "auto-indent" behaviour isn't quite as smart/configurable as it should be. ;-) For instance, although it lets each line inherit the indentation of the previous line, it doesn't indent the first line after the start-token of a compound statement ('{').
2. In terms of summing & averaging the students' grades, you could loop through each student's row of the 'student_Grades' array in turn, "accumulating" the 5 grades into a running-total amount (and then calculating the student's grade-average based on that). These calculated grade-averages could be stored into successive slots of a new 1-D 'student_GradeAverages' array. For example, assuming that the grade-averages will be stored as (rounded) integers, you could do something like this:-
Code:
/* Include new header, for 'round()' routine */
/* [ ... ] */
#include <math.h>
/* Introduce new declarations, to support grade-averages */
/* [ ... ] */
int totalNumStudents;
double gradeSum;
int student_GradeAverages[ MAX_NUM_STUDENTS ];
/* Read the students' ID#s & grade-groups into the 1-D & 2-D arrays */
/* [...] */
/* At the end of the read-loop, save the total # of students */
totalNumStudents = studentIndex;
/* Calculate the students' grade-averages, storing them in the new averages-array */
for( studentIndex = 0; studentIndex < totalNumStudents; studentIndex++ ) {
/* Initialise this student's grades-sum */
gradeSum = 0;
/* Accumulate this student's grades-sum */
for( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++ ) {
gradeSum += student_Grades[ studentIndex ][ gradeIndex ];
}
/* Calculate (and store) this student's grade-average */
student_GradeAverages[ studentIndex ] = ( round( gradeSum / NUM_GRADES_PER_STUDENT ) ) ;
}
/* (The sorting code, etc.) */
/* [...] */
Note that this approach is somewhat sub-optimal overall, as it involves *two* loops through the 'student_Grades' array (the first read-loop and the second sum-accumulation-loop), so you could combine the reading & the sum-accumulation in a single loop for improved efficiency. Also, if the assignment requires the grade-averages to be real numbers (rather than integers), then just declare the 'student_GradeAverages' array as type 'double' or 'float' instead of 'int' [ Update 2001/04/16: {and eliminate the 'round()' call & the '#include <math.h>' directive}].
Regards,
--Paul
[This message has been edited by Paul Crawford (edited 04-16-2001).]
|
|
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Thanks a lot again Paul. I now have everything parsed correctly into the correct arrays.  Now, all I have to do is to sort them which should not be too hard.
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
I just spent the last 3 hrs trying to make my program work. It does everything right now but I cannot figure how how to sort parallel arays. I've tried but I cannot seem to do it althought I will try some more. Can you please help me with this Paul? I appreciate your help!
Here is the program that sorts the grades, but I want the id numbers to be sorted with the grades. Here it is:
Code:
void quicksort(double a[], int left, int right)
{
int v,s,j,t;
if (left >= right) return;
v = a[left];
s = left + 1;
j = right;
for (; ; )
{
while ((a[s] < v) && (s < right) && (s < j)) s++;
while ((a[j] >= v) && (j > left + 1) && (s < j)) j--;
if (s == j) break;
t = a[s];
a[s] = a[j];
a[j] = t;
}
if (a[s] < a[left])
{
t = a[s];
a[s] = a[left];
a[left] = t;
quicksort(a,left,s-1);
quicksort(a,s+1,right);
}
else
{
t = a[s-1];
a[s-1] = a[left];
a[left] = t;
quicksort(a,left,s-2);
quicksort(a,s,right);
}
return;
}
The array "a" is for the grades.
Besides sorting the parallel arrays, this sorting program for some reason does not sort "doubles" correctly. It seems to sort "ints" correctly, but it does sort the doubles correctly but it seems to leave out the decimal points on only some of the numbers. I dont know why.
I tried just putting new variables in for the array that holds the ID numbers and then switching them wehever the grade array got switched, but it doesnt seem to work.
[This message has been edited by mindwaves (edited 04-14-2001).]
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
I fixed the problem!!!!  Evidentally, I must have used some wrong variables or something, but now it works. Thanks again! 
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
edit: I fixed every single bug now. Thanks!
[This message has been edited by mindwaves (edited 04-16-2001).]
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 1999
Location: Georgetown, Demerara, Guyana
Status:
Offline
|
|
Hi again mindwaves,
Glad to hear that you resolved all the remaining issues... way to go! :-) [BTW, on looking over my previous post, I also realised that I didn't explicitly mention a few important (albeit perhaps obvious) details in the final paragraph; I've updated it accordingly, just for completeness' sake.]
For the benefit of others who might be reading this thread, there are a couple of modifications that could be made in the version of the 'quicksort' routine shown above, to avoid the "lost precision" issues and to support sorting the ID#s in tandem with the grade-averages. [Update 2001/04/17: Note that mindwaves independently discovered & implemented suitable solutions; these are merely my own observations after-the-fact.] The possible changes to the 'quicksort()' routine are as follows:-[list=1][*] The 'v' and 't' variables could be declared as 'double' instead of 'int', to preserve precision during comparisons and "swapping".
[*] The integer ID#s-array could somehow be made accessible within the 'quicksort()' routine, so that its corresponding elements could be swapped in synch with those of the averages-array. For instance, the ID#s-array could be passed in as a parameter (say, 'int id[]') to the 'quicksort()' routine, both at the top level and in the four recursive calls within the body. Then, after declaring another variable (say, 'int tID') for ID#-swapping, new statements would need to be inserted to swap the corresponding ID#s just before/after each of the three existing places where grade-averages are being swapped. E.g., after the existing '...; a[j] = t;' statement, the following new statements could be inserted:- 'tID = id[s]; id[s] = id[j]; id[j] = tID;', and similarly for the other two places where grade-averages are being swapped.[/list=a][On a side note, the use of records ('struct's) and/or lists can help to make these kinds of tasks much easier, but there are often restrictions on the kinds of data structures allowed in a particular assignment/course.]
Once again, mindwaves, I'm glad that things worked out well! Feel free to post back here from time to time, to let us know how you're getting along in the course.
Regards, and happy developing. :-)
--Paul
[This message has been edited by Paul Crawford (edited 04-17-2001).]
|
|
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Hi again Paul, I hope that you don't mind me asking another question, but this one is really confusing. I changed my program just a little bit to allow for structures and borrowed a few concepts that you talked about and I made my program. Everything works perfectly now. However, I am supposed to make a program that i supposed to eliminate the duplicates in the test.dat file. So, what that means is if the ID # is read twice, then I would have to eliminate it somehow. Since I am a devious person, I made a way so that if the same ID# is read again then I will just reduce the student index thereby bypassing the complicated sorting process if I had just added them in the array in the first place. My program which eliminates the duplicates works fine for most of the time; however, when I compile it multiple times (with no alterations to the file) with the same test.dat file, I get different answers (most of them being the correct one however). When I complie it several times, I get 1 of these posssibilities:
1) It works perfectly.
2) It gives a garbage result on the first line which may/may not spill out to the other lines.
3) It requires a force quit (nothing bad at all)
Can you please help me figure out what is the problem because it is strange that multiple compilings to the sme file and same test file gives a different result every time. I do not know. Thanks!
Here is my program( I am sorry if it is a bit long):
Code:
#include <stdio.h>
#include <math.h> /*for the round function which can be used if needed*/
#include <iostream> /* I may use some C++ functions */
void quicksort(double a[], int new_id[], int left, int right);
/* [...] */
#define MAX_NUM_STUDENTS 100 /* <== Change as appropriate */
#define NUM_GRADES_PER_STUDENT 5
double average(int student_Grades[]);
/* [...] */
int main(void)
{
using namespace std; /* Namespace for C++ */
FILE *fp;
int studentIndex, gradeIndex;
int i, j = 0; /* a simple counter used to resort the id_numbers*/
int totalNumStudents;
double gradeSum;
int new_id[ MAX_NUM_STUDENTS ];
double a[MAX_NUM_STUDENTS ];
/* begin display -- Display some information about the program */
printf("Hello user! This program sorts some averages from highest to lowest.\n\n");
printf("ID # \t\t|\t\t Average:\n");
printf("----------------------------------\n");
/* end display*/
struct student
{
int student_IDNums[ MAX_NUM_STUDENTS ];
double student_Grades[ MAX_NUM_STUDENTS ][ NUM_GRADES_PER_STUDENT ]; /* 2D array */
double student_GradeAverages[ MAX_NUM_STUDENTS ];
}student;
fp = fopen( "test.dat", "r" );
studentIndex = 0;
while( ! feof( fp ) ) {
fscanf( fp, "%d", &(student.student_IDNums[ studentIndex ]) ); /* Puts id# in array */
for(i = 1; i < studentIndex - 1; i++) /* used to eliminate any duplicates in the array before sorting */
{
if(student.student_IDNums[ studentIndex ] == student.student_IDNums[ i ])
{
studentIndex--;
}
}
/* Puts grades into the array */
for( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++)
{
fscanf( fp, "%lf", &(student.student_Grades[ studentIndex ][ gradeIndex ]) );
}
studentIndex++;
}
totalNumStudents = studentIndex;
/* Calculate the students' grade-averages, storing them in the new averages-array */
for( studentIndex = 0; studentIndex < totalNumStudents; studentIndex++ ) {
/* Initialize this student's grades-sum */
gradeSum = 0;
/* Accumulate this student's grades-sum */
for( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++ ) {
gradeSum += student.student_Grades[ studentIndex ][ gradeIndex ];
}
/* Calculate (and store) this student's grade-average */
student.student_GradeAverages[ studentIndex ] = /* round */( gradeSum / NUM_GRADES_PER_STUDENT ) ;
/*printf("%lf\n", student_GradeAverages[ studentIndex ]); for a test*/
}
for(i = 0; i < totalNumStudents; i++)
{
new_id[i] = student.student_IDNums[j];
j++;
/*printf("%d\n", new_id[i]); test only */
}
fclose( fp );
/*/////////////////////The sorting and printing process/////////////////////////*/
for(i = 0; i < totalNumStudents; i++)
{
a[i] = student.student_GradeAverages[i]; /*simplifies the array process */
}
quicksort(a,new_id, 0,totalNumStudents-1);
for (i = totalNumStudents - 1; i > 0; i--)
{
printf("%d \t\t|\t\t%4.2lf\n", new_id[i], a[i]); /* prints out the values */
}
return 0;
}
/* Begin modified quicksort function */
void quicksort(double a[], int new_id[], int left, int right)
{
int s,j;
double v, t;
int h; /* variable used to sort the ID #s */
if (left >= right) return;
v = a[left]; ;
s = left + 1;
j = right;
for (; ; )
{
while ((a[s] < v) && (s < right) && (s < j)) s++;
while ((a[j] >= v) && (j > left + 1) && (s < j)) j--;
if (s == j) break;
t = a[s]; h = new_id[s];
a[s] = a[j]; new_id[s] = new_id[j]; /* modified line */
a[j] = t; new_id[j] = h; /* modified line */
}
if (a[s] < a[left])
{
t = a[s]; h = new_id[s];
a[s] = a[left]; new_id[s] = new_id[left]; /* modified line */
a[left] = t; new_id[left] = h; /* modified line */
quicksort(a,new_id, left,s-1);
quicksort(a, new_id,s+1,right);
}
else
{
t = a[s-1]; h = new_id[s-1]; /* modified line */
a[s-1] = a[left]; new_id[s-1] = new_id[left]; /* modified line */
a[left] = t; new_id[left] = h; /* modified line */
quicksort(a,new_id,left,s-2);
quicksort(a,new_id,s,right);
}
return;
}
/* end modified quicksort function */
and here is the test file that I used (called test.dat)
Code:
432156 32 46 32 98 46
843214 46 37 48 94 32
945321 89 99 97 98 56
329821 27 43 89 72 65
654321 59 63 97 28 64
123456 97 80 72 63 94
789101 46 92 81 43 13
345678 12 11 9 8 94
654321 59 63 97 28 64
123456 97 80 72 63 94
901234 3 10 18 26 72
123457 24 38 42 96 48
479283 93 92 91 90 87
598762 56 54 53 57 59
252565 36 58 47 48 59
965658 52 69 47 58 25
546566 25 14 47 89 69
901234 3 10 18 26 72
901234 3 10 18 26 72
901234 3 10 18 26 72
901234 3 10 18 26 72
789101 46 92 81 43 13
789101 46 92 81 43 13
789101 46 92 81 43 13
654321 59 63 97 28 64
123456 97 80 72 63 94
654321 59 63 97 28 64
123456 97 80 72 63 94
999999 12 15 23 21 1
The problem is in the for loop where I quoted "used to eliminate any duplicates in the array before sorting." Everything else seems to work fine. I will work on this more however and maybe find out the answer myself. Thanks!
[This message has been edited by mindwaves (edited 04-19-2001).]
[This message has been edited by mindwaves (edited 04-19-2001).]
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 1999
Location: Georgetown, Demerara, Guyana
Status:
Offline
|
|
Hi again mindwaves,
Not to worry, these kinds of glitches are just an inevitable part of the coding / testing / debugging cycle... I bet you're beginning to have a lot more sympathy for software developers now. :-) [Well, maybe not for Microsoft... ;-)]
Problematic outcomes:-
====================
Of the two problematic outcomes that you mentioned, I might have an answer about case #2 ("garbage" output on the first line). I suspect that your 'test.dat' input file contains an empty line at the end, which would cause the read-loop to behave unexpectedly... I.e., after reading the 5th grade value for the final student, the EOF condition wouldn't be set (as there's a Return char following the last digit). The program would then fall into the next iteration, trying to "read" the nonexistent ID# & grade values for this phantom student, and it wouldn't react to the EOF condition until after the 'studentIndex' counter had already been incremented. Since the phantom student's entries in the ID#s-array and the grades-array were never actually assigned any values, they could contain random uninitialised data whose computed average might be large enough to float to the top of your inverse-sorted output. To avoid this issue, try removing any trailing empty lines from 'test.dat', or try adjusting the read-loop to test for EOF immediately after calling 'fscanf()'. [On the other hand, if there are no such isolated Return chars, then I guess we're headed back to the drawing board to find the real cause.]
I'm not at all sure about case #3 (app may require a force quit)... At first, I thought that it might be due to the accidental use of an out-of-bounds index in some assignment statement for an array (which could cause the overwriting of a possibly vital portion of memory). However, from my initial inspection of the code, I couldn't find any such occurrences. If you haven't already found the source of the problem, I'll try to take a closer look to see what I can come up with.
Additional issues:-
================
I should also mention that there is another potentially serious issue with the program as it currently stands. From my test run in CW 5, using your 'test.dat' input file, it seems that the grade-averages shown are incorrect for some of the students. E.g., the third output student (ID# 546566) is shown having an avergae of 81.20 instead of 48.80. Similarly, the fourth output student (ID# 345678) is shown having an average of 81.20 instead of 26.80. These inconsistencies are due to the way in which duplicates are being eliminated. Decrementing the 'studentIndex' counter tends to work reliably for consecutive duplicates. However, for non-contiguous duplicates -- such as student ID# 654321 of input line 5 (duplicated on lines 9, 25 & 27), or student ID# 123456 of input line 6 (duplicated on lines 10, 26 & 28) -- this technique might lead to the accidental overwriting of the grade values of a previous student.
In addition, I noticed one other discrepancy in the current version of the program, where the data for the student with the lowest average (ID# 999999) isn't being displayed in the output.
One possible approach for resolving these additional issues is shown below. The modifications (highlighted in bold, with comments in italics) primarily involve the read-loop of the 'main()' routine. [Note that there are also changes in the start-value and/or exit-test of various for-loop control statements.]
Code:
int main( void ) {
/* Declare a boolean flag for "marking" duplicate students */
/* NOTE: Might require 'Enable bool support' option (in 'C/C++ Language' Settings panel) */
bool isDuplicateID;
/* The intial "Hello user" output, etc., etc. */
/* [...] */
studentIndex = 0;
while( ! feof( fp ) ) {
/* Reset the duplicate-student flag */
isDuplicateID = false;
fscanf( fp, "%d", &(student.student_IDNums[ studentIndex ]) ); /* Puts id# in array */
/* Change the start-value & exit-test, to allow scanning all previous students */
for(i = 0; i < studentIndex; i++) /* used to eliminate any duplicates in the array before sorting */
{
if(student.student_IDNums[ studentIndex ] == student.student_IDNums[ i ])
{
/* Use a flag to "mark" this duplicate student */
isDuplicateID = true;
break; /* One match is sufficient */
}
}
/* Puts grades into the array */
/* Add an 'if/else' construct, to handle a duplicate student */
if ( isDuplicateID )
/* Skip past the grades for this duplicate student */
for ( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++ )
{
fscanf( fp, "%*lf" ); /* Use the '*' spec to "read-&-skip" */
}
else {
for ( gradeIndex = 0; gradeIndex < NUM_GRADES_PER_STUDENT; gradeIndex++ )
{
fscanf( fp, "%lf", &(student.student_Grades[ studentIndex ][ gradeIndex ]) );
}
studentIndex++;
} /* End if */
}
totalNumStudents = studentIndex;
/* Calculate the students' grade-averages, etc., etc. */
/* [...] */
/*/////////////////////The sorting and printing process/////////////////////////*/
/* [...] */
/* Changed the exit-test, to allow inclusion of the bottomost student */
for (i = totalNumStudents - 1; i >= 0; i--)
{
printf("%d \t\t|\t\t%4.2lf\n", new_id[i], a[i]); /* prints out the values */
}
return 0;
}
Hope these issues are all resolved painlessly, no matter which particular modifications you end up using. Let us know how things turn out.
[One more thing: I noticed that you decided to use a 'struct' containing the three arrays. I had been thinking more along the lines of the other way around, i.e., using an array of 'struct's. Each array-element would be a 'struct' record that holds data for one student; the record would have three fields (an ID#, an array of 5 grades, and a grade-average). This kind of packaging would have simplified some operations such as passing parameters to 'quicksort()', but it would also have complicated the syntax of the sorting code itself... Anyway, it doesn't really matter much which way it's done, as long as the program is readable and robust.]
Regards,
--Paul
[This message has been edited by Paul Crawford (edited 04-21-2001).]
|
|
|
| |
|
|
|
 |
|
 |
|
Moderator 
Join Date: Sep 2000
Location: Irvine, CA
Status:
Offline
|
|
Thanks again Paul! I had no idea that an empty return statement at the end could cause so much confusion (yes, I did have an empty return char at the end).
I also did not realize that some of my values were wrong because I only tested a few of them and I guess that I tested the ones that came out right. Now I know that I should do a better job of testing my program just to make sure that everything is right.
Also, I knew about boolean expressions before but I have never used them before because I did not realize the power of them. Now I know and I will use them in future programs that I will create. They are so neat.
I will also try to incorporate your idea of using an array of structures instead of what I did so maybe my program will be better. Thanks again!
I was also wondering since you are very good in programming and I have looked over how you named your variables (i.e. uppercase and/or lowercase) and I was wondering,what criteria do you have for deciding what variables get to be uppercase and/or loweracse? Thanks! 
|
|
{{{ mindwaves }}}
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 1999
Location: Georgetown, Demerara, Guyana
Status:
Offline
|
|
Hi again mindwaves,
Been away for a while again... Thanks again for all the kind words! However, as you might have guessed, very often the reason I might be aware of potential problems/solutions is that I've run into them in my own work. ;-) As with any other endeavour, most of the valuable troubleshooting skills (such as intuition) that we acquire in programming/development come the hard way, through personal experience.
As for the general style of naming variables (or functions & methods), I believe that this is a matter of personal taste. There are many devotees of one style or another, but I think the most important thing is to use meaningful/readable names wherever possible, no matter how they're spelled. It also helps to use high-level comments that describe the overall purpose of a statement or statement-group, rather than just the literal actions (e.g., you had a very good comment that made it clear what the relevant for-loop was designed to do:- '/* used to eliminate any duplicates in the array before sorting */'). With the use of meaningful names and comments, the code won't be too incomprehensible if you need to look back at it a few months later; this is especially important in professional environments, where code is often developed by teams, and maintained by many different people. The reason why different styles of naming arose at all is that the vast majority of programming languages do not permit spaces in names. So, developers devised various conventions for readability:- - Some prefer to use upper-case letters to "mark" the boundaries between individual words in a name (e.g., 'myMultiWordVariableName'); others prefer to use the "underscore" character (e.g., 'my_multi_word_variable_name'); and, still others use a combination of both.
- It's also quite common to adopt special conventions for entire categories of names, such as for constants, globals and functions/methods. One could use an "all-upper-case + underlines" combo for the names of defined constants (e.g., '#define MY_VERY_OWN_DEFINITION someValue'). Also, one could prefix the names of all other constants with 'k' or 'k_', and prefix the names of all globals with 'g' or 'g_'. Similarly, one could prefix the names of all functions with 'fn' or 'fn_', and explicitly prefix the names of all methods with the relevant class-names [e.g., 'myClass_myMethod(...)']. Alternatively, one could reserve the use of initial-upper-case for functions/methods only (e.g., 'MyFunctionName' instead of 'fn_myFunctionName').
In general, you should just use whatever readable naming style you like, unless specific external rules apply (e.g., one's instructor or boss enforces a standard namimg convention).
Regards, and happy developing,
--Paul
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|