/***************************************************
MT258 TMA02 q3d.cpp
Question 3 (d) and (e)
Analyzing student records
Programming by Allen Lam 99043953
Dec 2000
****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <mem.h>
#define SIZE 2048
/* A structure for holding student records */
struct TMARecord {
char studentid[8];
int group;
int daysLate;
int articlesRead;
int articlesPosted;
};
struct TMARecord records[SIZE]; /* the actual store */
int recordCount = 0; /* number of records currently in the store */
void printRecords();
/*****************************************************/
/* Question 3(d) */
/* LateAndEarlyGroups */
/*****************************************************/
void LateAndEarlyGroups(struct TMARecord records[], int size){
int i;
int maxCount; /* the maximum lateCount */
struct GROUP{
int daysLate; /* no. of days late */
int lateCount; /* no. of students late */
int studentCount; /* no. of students in the group */
}group[25]; /* group number 1 to 24 (group 0 is unused) */
/* initialize the variables */
for (i=0; i<=24; i++){
group[i].daysLate = 0;
group[i].lateCount = 0;
group[i].studentCount = 0;
}
/* scan through the records */
for (i=0; i<size; i++){
group[records[i].group].studentCount++;
if (records[i].daysLate>0){
group[records[i].group].daysLate += records[i].daysLate;
group[records[i].group].lateCount++;
}
}
/* Find the max lateCount */
maxCount = group[0].lateCount;
for (i=1; i<=24; i++){
if (group[i].lateCount>maxCount) maxCount = group[i].lateCount;
}
/* only display non-empty groups */
clrscr();
printf("TMA late submission analysis in each group\n\n");
printf("Group\tNo. of late students\tAverage days late\t\n");
for (i=0; i<=24; i++){
if (group[i].studentCount>0)
printf("%3d%15d%24.1f\n",
i,
group[i].lateCount,
(float)group[i].daysLate/group[i].lateCount);
}
printf("\nGroup ");
for (i=0; i<24; i++)
if (group[i].lateCount==maxCount) printf("%d, ", i);
printf("have the largest number of late submission students.\n\n");
}
/*****************************************************/
/* Question 3(d) */
/* AnalyseDiscussion */
/*****************************************************/
void AnalyseDiscussion(struct TMARecord records[], int size) {
int maxReadi; /* index of student in records[] with max articlesRead */
int maxPosti; /* index of student in records[] with max articlesPost */
int maxRead = 0; /* store the max Read found */
int maxPost = 0; /* store the max Post found */
int sumRead = 0; /* sum of articles read by all students */
int sumPost = 0; /* sum of articles posted by all students */
int i;
maxRead = records[0].articlesRead;
maxPost = records[0].articlesPosted;
for (i=0; i<size; i++){
/* find maxRead and maxReadi */
if (records[i].articlesRead>maxRead){
maxRead = records[i].articlesRead;
maxReadi = i;
}
/* find maxPost and maxPosti */
if (records[i].articlesPosted>maxPost){
maxPost = records[i].articlesPosted;
maxPosti = i;
}
/* find total read and posted */
sumRead += records[i].articlesRead;
sumPost += records[i].articlesPosted;
}
/* move cursor to the last line */
gotoxy(1,25); cprintf("Press Enter for next page...");
getchar(); clrscr();
printf("Article reading and posting analysis\n\n");
printf("* Student %s has read most articles (%d)\n", records[maxReadi].studentid, maxRead);
printf("* Student %s has posted most articles (%d)\n\n", records[maxPosti].studentid, maxPost);
printf("* All students have read articles %d times\n", sumRead);
printf("* All students have posted articles %d times\n\n", sumPost);
printf("* On average, each student has read %.1f articles\n", (float)sumRead/size);
printf("* On average, each student has posted %.1f articles\n", (float)sumPost/size);
/* move cursor to the last line */
gotoxy(1,25); cprintf("Press Enter for next page...");
getchar(); clrscr();
}
/*****************************************************/
/* Question 3(e) */
/* AnalyseAdvanced */
/*****************************************************/
/* sort record[] based on articlesRead, in accending order */
int sortStruct(struct TMARecord rec[], int sizeofRec, int max){
int i, j;
void* tmp = malloc(sizeofRec);
if (tmp==NULL) return 0;
for (i=1; i<max; i++){
for (j=max-1; j>=i; j--){
if (rec[j].articlesRead<rec[j-1].articlesRead){
/* swap records */
memcpy(tmp, &rec[j], sizeofRec);
memcpy(&rec[j], &rec[j-1], sizeofRec);
memcpy(&rec[j-1], tmp, sizeofRec);
}
}
}
free(tmp);
return 1;
}
/*
** The following two values determine the size and precision of the graph
*/
#define regX 15 /* X-axis divide into how many regions */
#define regY 15 /* Y-axis divide into how many regions */
void plot(int data[]){
int x, y; /* x and y coordinate on screen */
int maxY, minY; /* max & min value in y-data */
float stepY; /* the width of each region in y-axis*/
int offsetX, offsetY; /* offset from left-top screen corner */
int i;
offsetX = 7; offsetY = 2;
/* find max and min from data */
minY = maxY = data[0];
for (i=0; i<regX; i++){
if (data[i]>maxY) maxY = data[i];
if (data[i]<minY) minY = data[i];
}
stepY = (float)(maxY-minY)/regY;
/* draw y axis */
for (i=0; i<=regY+1; i++){
gotoxy(offsetX-1, i+offsetY+1);
cprintf("|");
}
/* draw x axis*/
for (i=0; i<(regX+1)*2; i++) cprintf("-");
/* write labels */
gotoxy(offsetX-5,offsetY+1); cprintf("days");
gotoxy(offsetX-5,offsetY+2); cprintf("late");
gotoxy(offsetX+(regX+1)*2-13,regY+3+offsetY); cprintf("articles read");
/* plot dots */
for (i=0; i<regX; i++){
y = regY+1 - ((int)((float)(data[i]-minY)/stepY)) + offsetY;
x = (i*2)+offsetX+1;
gotoxy(x,y); cprintf("*");
}
}
void AnalyseAdvanced(struct TMARecord records[], int size){
int artRead[regX]; /* seperate articlesRead to different rooms*/
float steps, stepX; /* width of each x-region */
int i, j = 0;
/* sort data according to articlesRead */
sortStruct(records, sizeof(TMARecord), size);
/* initialize */
steps = stepX = (float)(records[size-1].articlesRead-records[0].articlesRead)/regX;
for (i=0; i<regX; i++) artRead[i] = 0;
printf("Relationship between article reading pattern & TMA late submission\n");
/* store sorted data into regions */
for (i=1; i<=size; i++){
if (records[i].articlesRead>steps){j++; steps += stepX;}
artRead[j] += records[i-1].daysLate;
}
/* display figures */
printf("\n\t\tRead articles\t Days late\n");
printf("\t\t %3d-%3d\t\t%3d\n", 0, (int)(stepX), artRead[0]);
for (i=1; i<regX-1; i++)
printf("\t\t %3d-%3d\t\t%3d\n", (int)(stepX*(i))+1, (int)(stepX*(i+1)), artRead[i]);
printf("\t\t %3d or more\t\t%3d\n",(int)(stepX*(i))+1, artRead[i]);
/* move cursor to last line */
gotoxy(1,25); cprintf("Press Enter for next page...");
/* next page, plot graph */
getchar(); clrscr();
printf("Relationship between article reading pattern & TMA late submission\n");
plot(artRead);
gotoxy(1,23); cprintf("Press Enter to finish...");
}
/* Prints all the records currently stored in the array records */
void printRecords() {
for (int i=0; i<recordCount; i++) {
printf("%s %d %d %d %d\n",
records[i].studentid,
records[i].group,
records[i].daysLate,
records[i].articlesRead,
records[i].articlesPosted);
}
}
/* Loads records from a file and stores in the array records */
void loadRecordFile(char* f) {
FILE* infile;
char buffer[256];
/* open the file first and report errors if necessary */
if ((infile = fopen(f, "r")) == NULL) {
fprintf(stderr, "Error in loading '%s'.\n", f);
getchar();
exit(1);
}
/* read the file line by line and add every record to the array */
while (fgets(buffer, 256, infile) != NULL) {
if (sscanf(buffer, "%s %d %d %d %d",
records[recordCount].studentid,
&(records[recordCount].group),
&(records[recordCount].daysLate),
&(records[recordCount].articlesRead),
&(records[recordCount].articlesPosted)) != 5) {
fprintf(stderr, "Error in reading file at record line %d.\n", recordCount);
getchar();
exit(1);
}
recordCount++;
}
fclose(infile);
}
/* main driving program */
int main()
{
loadRecordFile("q3ddata.txt");
/* printRecords(); */
LateAndEarlyGroups(records, recordCount);
AnalyseDiscussion(records, recordCount);
AnalyseAdvanced(records, recordCount);
getchar();
return 0;
}
back