# Thread: Logic for Course Marking Scheme

1. ## Logic for Course Marking Scheme

I'm going for a second attempt at my project. The system would allow Lecturer to Create a course marking scheme. A course marking scheme allows a lecturer to set the weightage of individual assessment in a Particular Course. This is the logic that I have come up with so far. Is it okay?

Step 1: Break down into a series discrete steps

Weightage for final exam mark= 40%.
Midterm weightage = 20-30 %
Lab test or quiz or lab test and quiz or none <= 5%
One or more assignment(depending on lecturer)
Assignment 1 mark = weightage & total
Project = weightage & total
Final (40%) + Midterm(range of between 20% to 30%) + (the rest of assessment weightage) = 100% Weightage

Step 2: Convert into codes

Weightage for final exam mark= 40%.
Code:
```scanf("%lf", final_weightage);
if(final_mark != 40)
print("Error\n");```
Midterm weightage = 20-30 %
Code:
```scanf("%lf", midterm_weightage);
if(midterm_weightage <=19 || midterm_weightage >=31)
print("Error\n");```
Lab test or quiz or lab test and quiz or none <= 5%
Code:
```if (option==1)
printf("Lab test\n");
printf("Enter weightage");
scanf("%lf", &lab_test);

//...

else if (option==3)
printf("Lab test and quiz\n");
printf("Enter weightage for lab test\n");
scanf("%lf", &lab_test);
printf("Enter weightage for quiz\n");
scanf("%lf", &quiz);

else if (option==4)
printf("None\n");```
Same way goes to assignment 1 and project.

Final (40%) + Midterm(range of between 20% to 30%) + (the rest of assessment weightage) = 100% Weightage
Code:
```Weightage = final_weightage + midterm_weightage + lab_test + quiz + assignment 1 + project;
if(Weightage != 100)
goto home;
else
/*save course marking scheme in txt file``` 2. Seems reasonable. Though my gut reaction is to cringe at using straight comparison operators on floating point values. It's generally safer to assume inaccuracy in the precision and use a fudge factor:
Code:
```if (fabs(result - expectedResult) < 0.01)
{
// Meh, close enough
}``` 3. Code:
`goto home;`
I would strongly suggest not using "goto". With a little thought, you should be able to structure your logic in a way that "goto" would not be necessary. 4. Code:
```#include<stdio.h>
#include<math.h>

struct result{
double final;
double midterm;
double labtest;
double quiz;
double assignment1;
double project;
};

struct expectedResult{
double expectedFinal;
double expectedMidterm;
double expectedLabtest;
double expectedQuiz;
double expectedAssignment1;
double expectedProject;
}sub1 ={40.0};

main()
{
printf("Enter the final weightage\n");
scanf("%lf", &final);
if (fabs(final - expectedFinal)<0.01)
{
printf("Done\n");
}
else
{
printf("Error\n");
}
}```
I keep getting these few errors. I'm thinking it must be a simple mistake but I can't figure out what it is.

proj.c(25) :error C2065: 'final' : undeclared identifier
proj.c(26) : error C2065: 'final' : undeclared identifier
proj.c(26) : error C2065: 'expectedFinal' : undeclared identifier 5. There is no variable called "final" declared. Nor should there be - you should declare a variable of type "struct result", and access the member of that struct.

Code:
```struct result student;

printf("Enter the final weightage\n");
scanf("%lf", &student.final);```
There is also no constant or variable with the name "expectedFinal". 6. Is that the same with this code?

Code:
```struct result{
double final;
double midterm;
double labtest;
double quiz;
double assignment1;
double project;
}student;```
So I should do it this way?
Code:
```struct expectedResult total;

printf("Enter the final weightage\n");
scanf("%lf", &total.expectedFinal);```
Is the method of declaring constant 40.0 for expectedFinal correct? 7. If the "expected results" are constants, then you should use a named constants in lieu of variables (note that, by convention, named constants and macros are all upper-case).

For example:

Code:
```#include <stdio.h>

#define FINAL_EXPECTED  40.0

struct result{
double final;
};

int main(void)
{
struct result student;

printf("Enter the final weightage\n");
scanf("%lf", &student.final);
if (fabs(student.final - FINAL_EXPECTED)<0.01)
{
printf("Done\n");
}
else
{
printf("Error\n");
}

return 0;
}```

Code:
```/*
Enter the final weightage
30
Error
*/```
Code:
```/*
Enter the final weightage
40
Done
*/``` 8. You used int main(void) instead of what I used which is main(). When should I use int main() and when to use main()? Except for return 0, I don't see much difference in them. Is it advisable to have main(void) rather than main()? Also, which is better void main() or main()? 9. Originally Posted by nadeera You used int main(void) instead of what I used which is main(). When should I use int main() and when to use main()? Except for return 0, I don't see much difference in them. Is it advisable to have main(void) rather than main()? Also, which is better void main() or main()?
Here's what the latest standard has to say: Originally Posted by c11-draft
5.1.2.2.1 Program startup

1 The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent...
So "main()" should always be declared as returning an int. And if no parameters are needed, use "void".

Code:
`int main(void)`
In the latest versions of the standard, if there is no return statement at the end of the program, "return 0" is implied. However, I always prefer to be explicit.

Code:
```int main(void)
{
// ...

return 0;
}```
"void main" should never be used in a hosted implementation. 10. Also note that any function (including main()) should declare the return value since implicit return types are no longer allowed with the current standard.

Jim 11. Okay, got it. What does this error mean and how to avoid it? 12. Originally Posted by nadeera Okay, got it. What does this error mean and how to avoid it?
This appears to be a Visual Studio warning. I don't use VS, but a web search for "not found or not built by the last incremental link; performing full link" produced a lot of results. I'd suggest you try that. 13. This is the code I have written so far.

Code:
```#include <stdio.h>#include<math.h>
#define FINAL_EXPECTED  40.0
#define TOTAL_EXPECTED  100.0

struct result{
double final;
double midterm;
double assignment1;
double project;
double quiz;
double labtest;
double total;
};

int main(void)
{
struct result student;
int option;

FILE * fp;
fp = fopen ("markingscheme.txt","w");

do
{
printf("\n\tWeightage for Final : ");
scanf("%lf", &student.final);
if (fabs(student.final - FINAL_EXPECTED)<0.01)
{
printf("\n\tDone");
}
else
{
printf("\n\tError");
}

printf("\n\n\tWeightage for Mid-Term Exam : ");
scanf("%lf", &student.midterm);
/*if (fabs(student.midterm - 20)<0.01) || fabs(student.midterm -30)<0.01)
{
printf("\n\tDone");
}
else
{
printf("\n\tError");
}*/

printf("\n\n\t1. Weightage for Lab Test\n");
printf("\n\n\t2. Weightage for Quiz\n");
printf("\n\n\t3. Weightage for Lab Test & Quiz\n");
printf("\n\n\t4. None\n");
scanf("\n\n\t%d", &option);

if (option==1)
{
printf("\n\n\tWeightage for Lab Test: ");
scanf("%lf", &student.labtest);
}
else if (option==2)
{
printf("\n\n\tWeightage for Quiz: ");
scanf("%lf", &student.quiz);
}
else if (option==3)
{
printf("\n\n\tWeightage for Lab Test & Quiz: ");
scanf("%lf%lf", &student.labtest, &student.quiz);
}
else
{
printf("None\n");
}

if (fabs((student.labtest + student.quiz) - 5.0)<5.01)
{
printf("\n\tDone");
}
else
{
printf("\n\tError");
}

printf("\n\n\t1. Weightage for Assignment 1\n");
printf("\n\n\t2. Weightage for Project\n");
printf("\n\n\t3. Weightage for Assignment 1 & Project\n");
printf("\n\n\t4. None\n");
scanf("\n\n\t%d", &option);

if (option==1)
{
printf("\n\n\tWeightage for Assignment 1 : ");
scanf("%lf", &student.assignment1);
}
else if (option==2)
{
printf("\n\n\tWeightage for Project : ");
scanf("%lf", &student.project);
}
else if (option==3)
{
printf("\n\n\tWeightage for Assignment 1 & Project : ");
scanf("%lf%lf", &student.assignment1, &student.project);
}
else
{
printf("None\n");
}

student.total = student.final + student.midterm + student.labtest + student.quiz + student.assignment1 + student.project;
}while(fabs(student.total - TOTAL_EXPECTED)<0.01);

fclose(fp);
return 0;
}```
There appears to be something wrong with this line.
Code:
`(fabs(student.midterm - 20)<0.01) || fabs(student.midterm -30)<0.01)`
I'm thinking of using the switch statement here. Which is better if..else or switch statement?

Code:
```if (option==1)
{
printf("\n\n\tWeightage for Lab Test: ");
scanf("%lf", &student.labtest);
}
else if (option==2)
{
printf("\n\n\tWeightage for Quiz: ");
scanf("%lf", &student.quiz);
}
else if (option==3)
{
printf("\n\n\tWeightage for Lab Test & Quiz: ");
scanf("%lf%lf", &student.labtest, &student.quiz);
}
else
{
printf("None\n");
}```
If error was displayed, how can I make the user key in the final marks again?
Code:
```if (fabs((student.labtest + student.quiz) - 5.0)<5.01)
{
printf("\n\tDone");
}
else
{
printf("\n\tError");
}```
If I use this code, does it mean I should change all printf and scanf statements into fprintf and fscanf statements?
Code:
```FILE * fp;
fp = fopen ("markingscheme.txt","w");``` Is the goal to simply ensure the weightages sum to an even 100%? Or do you have to apply weightages to actual grades entered afterwards?

I understand "final + midterm", but what does "the rest of the assessment weightage" mean? Is this just "lab test" or "quiz" or both? What if it's "none"? How do "Assignment 1" and "project" factor into this?

I'll just try to address the questions you asked as best I can, without fully understanding the context.

If the final exam weightage is fixed at 40%, why bother asking the user to enter a value? Just make that value fixed at 40.

There appears to be something wrong with this line.
You don't explain what the problem is were you seeing. And I don't think you understand what that code is doing. This is why it is not a good idea to just copy code and use it.

For starters, you don't even have the correct number of parenthesis:

if (fabs(student.midterm - 20)<0.01) || fabs(student.midterm -30)<0.01)

Assuming we fix that:

Code:
```if (fabs(student.midterm - 20)<0.01 || fabs(student.midterm -30)<0.01)

/*--------------------------------------------------------------------*/
// Case 1: "student.midterm" is 20
fabs(student.midterm - 20)<0.01   ||   fabs(student.midterm -30)<0.01
fabs(20 - 20)<0.01                ||   fabs(20 - 30)<0.01
fabs(0)<0.01                      ||   fabs(-10)<0.01
0<0.01                            ||   10<0.01
TRUE                              ||   FALSE
// TRUE or FALSE = TRUE, so "Done" is printed

/*--------------------------------------------------------------------*/
// Case 2: "student.midterm" is 30
fabs(student.midterm - 20)<0.01   ||   fabs(student.midterm -30)<0.01
fabs(30 - 20)<0.01                ||   fabs(30 - 30)<0.01
fabs(10)<0.01                     ||   fabs(0)<0.01
10<0.01                           ||   0<0.01
FALSE                             ||   TRUE
// FALSE or TRUE = TRUE, so "Done" is printed

/*--------------------------------------------------------------------*/
// Case 3: "student.midterm" is 25
fabs(student.midterm - 20)<0.01   ||   fabs(student.midterm -30)<0.01
fabs(25 - 20)<0.01                ||   fabs(25 - 30)<0.01
fabs(5)<0.01                      ||   fabs(-5)<0.01
5<0.01                            ||   5<0.01
FALSE                             ||   FALSE
// FALSE or FALSE = FALSE, so "Error" is printed, even though it should be a valid input```
As you should be able to see (you should learn to do this kind of analysis by hand), simply OR'ing those two conditions does not meet your requirements.

If you want to check that a value is in range, all you need is something like:

Code:
```if(student.midterm >= 19.9 && student.midterm <= 30.1)  // applied hasty "fudge factor" to account for imprecision
// success
else
// error```

I'm thinking of using the switch statement here. Which is better if..else or switch statement?
It depends on the context. If you have several discrete values like you do here, a switch might be better. But for only a few options, either way is fine.

If error was displayed, how can I make the user key in the final marks again?
Use a loop. For validating input, a "do-while" is a good choice, since it's guaranteed to run at least once and checks at the end, allowing input to be entered in the loop body before being checked.

If you want to validate a floating point value, a flag might make things easier.

Code:
```/*
do
clear flag
get input
if input is invalid:
set flag
print error message
while flag is set
*/```
If I use this code, does it mean I should change all printf and scanf statements into fprintf and fscanf statements?
Beware the mindset of applying blanket changes throughout your entire code like this. You need to make sure every change you make is correct.

Sometimes you might want to write to the screen (e.g. prompts), sometimes you might want to write to the file (e.g. data) - it depends on what the code is supposed to do.

Also, if you're opening the file for writing, and writing to the file, why would you want to use "fscanf()"? Popular pages Recent additions 