Uploaded by arif2318

ICT159 - Assignment 2 (1)[1]

advertisement
ICT159 Foundations of Programming
ICT159 – Assignment 2
This is an individual assignment, and is worth 20% of the total assessment for the unit. This
assignment has 4 exercises. Each exercise builds on the exercises that precede it. Thus, it is
important that you do them in the order from Exercise 1 to Exercise 4.
Student ID
Name
Final Mark
Objectives






Construct algorithms to solve problems using a combination of sequence, selection and iteration
constructs.
Implement such algorithms in a common programming language, C.
Read/write data to/from files.
Use arrays of records (structs).
Search arrays of records.
Apply the methodology of top-down design to the construction of solutions and implement these
solutions in a modular way.
This is an individual assignment and must be completed by you alone.
Any unauthorised collaboration/collusion may be subject to investigation
and result in penalties if found to be in breach of University policy.
Submission Guidelines
Your assignment must be submitted via LMS following the guidelines listed below. Failure to adhere
to these guidelines will result in marks being lost or a fail grade being awarded.





Create a folder named ICT159_StudentID_Surname_Assignment2. Make sure you replace
StudentID with your student ID and Surname with your surname
For each exercise, create a folder named Exercise 1, Exercise 2, etc. Put the source code
(i.e., C program) files of each exercise into its folder. This includes both the .c and .h files
Answer the questions directly on this Word document (the C programs need to be included
separately; see the previous points). Once done, convert it into PDF and save it inside the
folder ICT159_StudentID_Surname_Assignment2.
Compress the folder into ICT159_StudentID_Surname_Assignment2.zip and upload it to
LMS.
You should always keep a copy of all your work. Keep the backup of your work in cloud
storage like OneDrive. Losing your work/files (for any reason) a few days before the deadline
is not a valid ground for extension.
Note that: You may be required to demonstrate and explain your solution in person after the
submission. If such demonstration is needed, you will be contacted. If you do not defend/demonstrate
in-person, no marks will be given, resulting in a mark of 0.
You must use modular design and modular programming. Failure to use modular programming
will result in a straight 0 for the entire assignment.
Problem
We would like to write a computer program that will help the school of IT manage and monitor the
performance of first year students in the four units they take in Semester 1, namely: ICT159, ICT171,
ICT100 and MAS162.
A student can enrol in at least one unit and at most 4 units. In other words, there will be students who
are enrolled in 4 units, 3 units, 2 units, or just 1 unit.
To keep track of enrolments, the school manager has created has created four (4) files ICT159.txt,
ICT171.txt, ICT100.txt and MAS162.txt. The content of each file is as follows:
ICT159
Foundations of Programming
4
Exercises 20
Assignment1 10
Assignment2 20
Examination 50
AB123456 Laga 5 9 18 33
CDB77777 Rai 8 10 20 47
…
This file is about ICT159. The first row of the file has the unit code, which is always a string of 6
characters.
The second row is the unit name, which is a string of arbitrary length (it can be of any length).
The third row is the number of assessable components of the unit. For example, in ICT159, we have 4
assessable components listed in the following 4 rows. Each of the four following rows contain the
name of the assessable components and its weight. For example, Exercises are worth 20%,
Assignment1 is worth 10%, etc.
After that, starting from row 8 of the example above, we have the list of students. Each row (referred
to as Student Record) is one student and has the following information:
-
Student ID, which is a string of fixed length (always 8 characters)
The student’s last name
The student’s mark in each of the assessable components. For example, student Laga has
scored 5 out of 100 in the weekly Exercises, 9 out of 100 in Assignment1, 18 out of 100 in
Assignment2 and 33 out of 100 in the Examination. Note that if a student did not submit an
assignment, it will show as a 0 for that assignment.
2
Exercise 1 [25 marks]
A file, e.g., ICT159.txt is valid if:
-
-
Its first row has the unit code of length that is exactly 6 characters (Error Code: -1).
The second row is a string that starts with an alphabetical character in upper case. For
example: “Foundations of Programming” is valid but “foundations of Programming” is not
because the first character (“f” in this case) is in lower case (Error Code: -2).
The third row is a number that is larger or equal to 1 and less or equal to 4
(Error Code: -3).
The weight of each of the assessed components is an integer number between 1 and 100
(Error Code: -4).
The sum of the weights of all the assessed components should be equal to 100 (Error Code: 5).
The mark of a student in each assessed component should be a number between 0 and 100
(Error Code: -6).
We would like to write a module that checks whether the content of a file is valid according to the
criteria listed above (note that there are other error cases, but in this assignment, we limit ourselves to
those listed above).
The module should take as input the filename and should return:
-
Value 1 if the file is valid.
If the file is not valid, it should return the Error Code and the row number in the file where the
error has been detected. Note that row numbers start from 1.
The main program, should ask the user to enter the filename. It then checks whether the file exists. If
it does not exist, then it will keep asking the user to reenter the file name or Q or q to abort and exit
the program.
Once the use has entered the name of a file that exists, it then checks whether the file is valid or not.
If it is valid, it should print “The file is valid.”. If not, it should print the error code, the line number
where it occurred, and a description of the error.
a. Provide the structure chart for solving the problem above. The structure chart should include the
high level algorithm and the different modules. It should also show the parameters, their types and
how they are passed across different modules.
Provide your answer in the box below.
3
4
b. Provide in the table below a description of what each module does. In the description, indicate what
is the input (and their type) and what is the output (and their type). Add as many rows as needed.
Module Name
Main
File_exists
Validate_file
validate_unit_code
validate_unit_name
validate_assessable_components
validate_student_records
Description
This module handles the main program logic, including user
input and invoking the file validation process.
This module checks if the specified file exists. Input: filename
(char array). Output: exists (int).
This module validates the entire file content. Input: filename
(char array). Output: validation_result (int).
This module validates the unit code. Input: unit_code (char
array). Output: is_valid (int).
This module validates the unit name. Input: unit_name (char
array). Output: is_valid (int).
This module validates the assessable components. Input:
components (array of char arrays), num_components (int).
Output: is_valid (int).
This module validates the student records. Input:
student_records (array of char arrays), num_students (int).
Output: is_valid (int).
c. Provide the algorithms of each of the modules that compose your structure chart and the table
above. You must follow the format we use in the lecture notes and in the weekly labs.
Algorithms:
Main:
1. Start
2. Prompt user to enter the filename
3. Check if file exists using file_exists(filename)
4. If file does not exist, prompt again or allow exit (Q/q)
5. If file exists, call validate_file(filename)
6. If validate_file returns 1, print "The file is valid."
7. Otherwise, print the error code, line number, and description of the error
8. End
File_Exists:
1. Start
2. Try to open the file in read mode
3. If file opens successfully, return 1
4. If file does not open, return 0
5. End
Validate_file:
1. Start
2. Open the file and read line by line
3. Validate each line according to the criteria
4. Return 1 if all lines are valid
5. If any line is invalid, return the error code and line number
6. End
Validate_unit_code:
1. Start
2. Check if length of unit_code is exactly 6
3. If valid, return 1
4. If invalid, return -1
5. End
5
validate_assessable_components:
1. Start
2. For each component, check if weight is between 1 and 100
3. Calculate the sum of weights
4. If sum is not 100, return -5
5. If all weights are valid and sum is 100, return 1
6. If any weight is invalid, return -4
7. End
validate_student_records:
1. Start
2. For each student record, check if marks are between 0 and 100
3. If all marks are valid, return 1
4. If any mark is invalid, return -6
5. End
d. Implement your solution using C programming language. Put all your code inside a folder named
Exercise 1 as well as the .txt files you used to test it.
Exercise 2 [25 marks]
In this exercise, if the file is valid, we would like to read it into a data structure inside our program so
that we can do some processing and analysis on the data.
a. Which data structure would you use to store the record of one student? Provide the C code of the
data structure in the box below (you are only required to provide the code for the data structure, you
do not need to provide the code for the main function and other modules).
Data Structure to Store the Record of One Student
typedef struct {
char student_id[9];
char last_name[50];
int marks[4]; // Marks for the 4 assessable components
} Student;
b. Which data structure would you use to store the records of ALL students? Provide the C code of
the data structure in the box below (you are only required to provide the code for the data structure,
you do not need to provide the code for the main function and other modules).
Data Structure to Store the Records of ALL Students:
typedef struct {
Student students[100]; // Assuming a maximum of 100 students
int student_count;
} StudentRecords;
c. Which data structure would you use to store the information about a unit (as provided in the .txt
file)? Provide the C code of the data structure in the box below (you are only required to provide the
6
code for the data structure, you do not need to provide the code for the main function and other
modules).
Data Structure to Store the Information about a Unit:
typedef struct {
char unit_code[7];
char unit_name[100];
int num_components;
struct {
char name[50];
int weight;
} components[4]; // Assuming a maximum of 4 assessable components
d. Provide the structure chart of a program that asks the user to enter the filename, it then checks
} Unit; the file is valid or not. If it is not valid, it should print the error code, the line number where it
whether
occurred, and a description of the error. If the file is valid, it should:
-
read the information about the unit into the data structure you defined in Question c above
read the information about all students into the data structure you defined in Questions a and
b above.
This structure chart should be an extension of the one you developed in Question c of Exercise 1. It
should show all modules, including the high level module, as well as the parameters and parameter
passing between modules.
7
Main Program
|
|-- get_filename()
| |-- Parameters: none
| |-- Returns: char* (filename)
|
|-- file_exists(filename)
| |-- Parameters: char* (filename)
| |-- Returns: int (1 if exists, 0 if not)
|
|-- validate_file(filename)
| |-- Parameters: char* (filename)
| |-- Returns: int (1 if valid, error code if not)
|
|-- print_error(error_code, line_number)
| |-- Parameters: int (error_code), int (line_number)
| |-- Returns: void
|
|-- read_unit_info(filename, Unit* unit)
| |-- Parameters: char* (filename), Unit* (pointer to Unit struct)
| |-- Returns: void
|
|-- read_student_records(filename, StudentRecords* records)
| |-- Parameters: char* (filename), StudentRecords* (pointer to StudentRecords struct)
| |-- Returns: void
8
e. Provide in the table below a description of what each module does. In the description, indicate
what is the input (and their type) and what is the output (and their type). Add as many rows as
needed.
Module Name
get_filename
file_exists
validate_file
print_error
read_unit_info
read_student_records
Description
Prompts the user to enter a filename or Q/q to quit. Returns the
entered filename as a char*.
Checks if a file with the given filename exists. Takes char* as
input and returns int (1 if exists).
Validates the content of the file according to specified criteria.
Returns 1 if valid, error code if not.
Prints the error code and line number where the error occurred.
Takes int error code and line number as input.
Reads the unit information from the file and stores it in a Unit
struct. Takes char* filename and Unit* as input.
Reads the student records from the file and stores them in a
StudentRecords struct. Takes char* filename and
StudentRecords* as input.
f. Implement your solution using C programming language. Your code should reuse the functions you
created for Exercise 1. Put all your code inside a folder named Exercise 2.
Exercise 3 [30 Marks]
We would like now to determine the total mark and final grade of each student and save the final
marks and grades of all students into a single file named UnitCode_results.txt. If the unit code is
ICT159, then the file name will be ICT159_results.txt. If it is ICT171, then the file name is
ICT171_results.txt. The result file should be structured as follows:
ICT159
Foundations of Programming
4
Exercises 20
Assignment1 10
Assignment2 20
Examination 50
AB123456 Laga 5 9 18 33 23 N
CDB77777 Rai 8 10 20 47 44 N
…
It follows the same format as the original input file, except that for each student we also add the total
mark (the one highlighted in red) and the final grade (the one highlighted in green). The colors are
here just for illustration.
If:
-
a unit has four assessed components of weights a, b, c and d, respectively, and
a students received mark1, mark2, mark3 and mark4 in the four assessed components
Then the final mark is M = (a * mark1 + b * mark2 + c * mark3 + d * mark4) / (a + b + c + d).
The final grade is either HD, D, C, P, SX, N. It is determined according to the table below
Mark
Grade
80 to 100
HD
9
70 to 79
D
60 to 69
C
50 to 59
P
45 to 49
SX
0 to 44
N
a. What changes would you make to the data structures you defined in Exercise 2, Questions a and b
so that it can also hold/store the final mark of each student and their final grade? Provide the code of
the new data structures in the box below.
Updated Data Structure:
typedef struct {
char student_id[9];
char last_name[50];
int marks[4]; // Marks for the 4 assessable components
float total_mark; // Total mark
char grade[3]; // Final grade
} Student;
typedef struct {
Student students[100]; // Assuming a maximum of 100 students
int student_count;
} StudentRecords;
b. Provide the algorithm of a module that takes as input a student record and outputs the student’s
final mark and her/his grade. You must use the data structures you defined in Question a above. (You
are not required to provide the algorithm of the main function).
Algorithm to Compute Final Mark and Grade:
void compute_final_mark_and_grade(Student *student, Unit unit) {
int total_weight = 0;
float total_mark = 0.0;
for (int i = 0; i < unit.num_components; i++) {
total_mark += (unit.components[i].weight * student->marks[i]);
total_weight += unit.components[i].weight;
}
10
11
c. Provide the algorithm of the module(s) that goes through all students and for each student, it
computes their final mark and final grade. You must reuse the modules you defined in Question a and
b above.
Algorithm to Compute Final Mark and Grade for All Students:
void compute_all_students_final_marks_and_grades(StudentRecords *records, Unit unit) {
for (int i = 0; i < records->student_count; i++) {
compute_final_mark_and_grade(&records->students[i], unit);
}
}
12
d. Provide the algorithm of the module that saves the results of Question c into a file named
UnitCode_results.txt where UnitCode should be replaced by the actual unit code (e.g., for ICT159, it
should be ICT159_results.txt).
Algorithm to Save Results to a File:
void save_results_to_file(const char *filename, Unit unit, StudentRecords records) {
FILE *file = fopen(filename, "w");
if (!file) {
printf("Failed to open the file for writing.\n");
return;
}
fprintf(file, "%s\n", unit.unit_code);
fprintf(file, "%s\n", unit.unit_name);
fprintf(file, "%d\n", unit.num_components);
for (int i = 0; i < unit.num_components; i++) {
fprintf(file, "%s %d\n", unit.components[i].name, unit.components[i].weight);
}
for (int i = 0; i < records.student_count; i++) {
fprintf(file, "%s %s %d %d %d %d %.2f %s\n",
records.students[i].student_id,
records.students[i].last_name,
records.students[i].marks[0],
records.students[i].marks[1],
records.students[i].marks[2],
records.students[i].marks[3],
records.students[i].total_mark,
records.students[i].grade);
}
fclose(file);
}
13
e. We would like now to put together all the modules of this exercise into a complete program. In other
words, the program asks the user to enter the filename, it then checks whether the file is valid or not.
If it is not valid, it should print the error code, the line number where it occurred, and a description of
the error. If the file is valid, it should:
-
read the information about the unit into the data structure you previously defined
read the information about all students into the data structure you previously defined
determine the total mark and final grade of each student and
save the final marks and grades of all students into a single file named UnitCode_results.txt.
Provide the entire structure chart (the structure chart should build on/extend the one you defined in
Exercise 2).
Structure Chart:
Main Program
|
|-- get_filename()
| |-- Parameters: none
| |-- Returns: char* (filename)
|
|-- file_exists(filename)
| |-- Parameters: char* (filename)
| |-- Returns: int (1 if exists, 0 if not)
|
|-- validate_file(filename)
| |-- Parameters: char* (filename)
| |-- Returns: int (1 if valid, error code if not)
|
|-- print_error(error_code, line_number)
| |-- Parameters: int (error_code), int (line_number)
| |-- Returns: void
|
|-- read_unit_info(filename, Unit* unit)
| |-- Parameters: char* (filename), Unit* (pointer to Unit struct)
| |-- Returns: void
|
|-- read_student_records(filename, StudentRecords* records)
| |-- Parameters: char* (filename), StudentRecords* (pointer to StudentRecords struct)
| |-- Returns: void
14
|
|-- compute_final_mark_and_grade(Student* student, Unit unit)
| |-- Parameters: Student* (pointer to Student struct), Unit (unit struct)
| |-- Returns: void
|
|-- compute_all_students_final_marks_and_grades(StudentRecords* records, Unit unit)
| |-- Parameters: StudentRecords* (pointer to StudentRecords struct), Unit (unit struct)
| |-- Returns: void
|
|-- save_results_to_file(filename, Unit unit, StudentRecords records)
| |-- Parameters: char* (filename), Unit (unit struct), StudentRecords (student records struct)
| |-- Returns: void
f. Provide the algorithm of the MAIN (high level) program, which should call the modules you defined
so far in this exercise and also in previous exercises.
Algorithm of the Main program:
int main() {
char filename[100];
while (1) {
15
printf("Enter the filename (or Q/q to quit): ");
g. Provide the entire C program. Put all your codes inside a folder called Exercise 3.
16
Exercise 4 [20 Marks]
We would like to extend the program you developed in Exercise 3 so that we can output on the
screen the number of students who received HD, the number of students who received D, etc….. In
other words, the program should output something like this:
The number of students who received HD is 4
The number of students who received D is 7
The number of students who received C is 11
The number of students who received P is 12
The number of students who received SX is 21
The number of students who received N is 3
a. Provide the algorithm of the module that counts how many students achieved HD, how many
students achieved D, etc. If this module has to call other modules, then you need to provide the
algorithms of these modules as well.
Important note: think carefully about the principles of modular programming, which are: abstraction,
single responsibility, reusability, low coupling.
17
Algorithm:
Algorithm count_students_by_grade(student_records):
Initialize counters for each grade: HD_count = 0, D_count = 0, C_count = 0, P_count = 0,
SX_count = 0, N_count = 0
For each student in student_records:
If student.grade is "HD":
Increment HD_count
Else if student.grade is "D":
Increment D_count
Else if student.grade is "C":
Increment C_count
Else if student.grade is "P":
Increment P_count
Else if student.grade is "SX":
Increment SX_count
Else if student.grade is "N":
Increment N_count
Output "The number of students who received HD is " + HD_count
Output "The number of students who received D is " + D_count
Output "The number of students who received C is " + C_count
Output "The number of students who received P is " + P_count
Output "The number of students who received SX is " + SX_count
Output "The number of students who received N is " + N_count
18
b. Provide the entire structure chart of the program that asks the user to enter the filename, it then
checks whether the file is valid or not. If it is not valid, should print the error code, the line number
where it occurred, and a description of the error. If the file is valid, it should:
- read the information about the unit into the data structure you defined above
- read the information about all students into the data structure you defined above
- determine the total mark and final grade of each student and
- save the final marks and grades of all students it into a single file named UnitCode_results.txt.
- Outputs on screen the number of students who received each grade (Question a above)
The structure chart should extend the one you developed in Exercise 3.
19
+------------------+
|
Main Module |
+------------------+
|
+---------------------------------------------+
|
|
|
+-------------------------+ +------------------+
|
| Validate File Module | | Read Unit Info |
+-------------------------+ +------------------+
|
|
|
|
|
+-------------------------+ +------------------+
| Validate Unit Code
|
| | Read Student
|
+-------------------------+ | Records Module |
|
+------------------+
+-------------------------+
| Validate Unit Name
|
|
|
|
|
| +------------------+
|
+-------------------------+ | Compute Final |
|
|
| Mark and Grade |
|
+-------------------------+ +------------------+
|
| Validate Assessable
|
| Components
|
|
| +------------------+
|
+-------------------------+ | Save Results to |
|
|
| File Module
|
|
+-------------------------+ +------------------+
|
|
|
+-------------------------+ +------------------+
|
| Validate Student Records| | Count Students |
|
+-------------------------+ | by Grade Module |
|
+------------------+
+-------------------------+
|
|
|
|
+------------------+
|
+-------------------------+ | Print Results
|
|
| Module
|
|
|
+------------------+
|
|
|
+-------------------------------------------+
20
|
|
c. Provide the entire program that implements the structure chart of Question b. You must build on
and reuse the modules you defined in the previous exercises.
// Function to count the number of students who achieved each grade
void count_students_by_grade(StudentRecords records);
21
int main() {
// Main program logic as in Exercise 3, with additional function call to count_students_by_grade
}
void count_students_by_grade(StudentRecords records) {
int HD_count = 0, D_count = 0, C_count = 0, P_count = 0, SX_count = 0, N_count = 0;
for (int i = 0; i < records.student_count; i++) {
if (strcmp(records.students[i].grade, "HD") == 0) {
HD_count++;
} else if (strcmp(records.students[i].grade, "D") == 0) {
D_count++;
} else if (strcmp(records.students[i].grade, "C") == 0) {
C_count++;
} else if (strcmp(records.students[i].grade, "P") == 0) {
P_count++;
} else if (strcmp(records.students[i].grade, "SX") == 0) {
SX_count++;
} else if (strcmp(records.students[i].grade, "N") == 0) {
N_count++;
}
}
printf("The number of students who received HD is %d\n", HD_count);
printf("The number of students who received D is %d\n", D_count);
printf("The number of students who received C is %d\n", C_count);
printf("The number of students who received P is %d\n", P_count);
printf("The number of students who received SX is %d\n", SX_count);
printf("The number of students who received N is %d\n", N_count);
}
22
Download