[go: up one dir, main page]

0% found this document useful (0 votes)
236 views22 pages

ICT159 - Assignment 2

Uploaded by

f23ari18
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
236 views22 pages

ICT159 - Assignment 2

Uploaded by

f23ari18
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 22

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 Description


Main This module handles the main program logic, including
user input and invoking the file validation process.
File_exists This module checks if the specified file exists. Input:
filename (char array). Output: exists (int).
Validate_file This module validates the entire file content. Input:
filename (char array). Output: validation_result (int).
validate_unit_code This module validates the unit code. Input: unit_code (char
array). Output: is_valid (int).
validate_unit_name This module validates the unit name. Input: unit_name
(char array). Output: is_valid (int).
validate_assessable_components This module validates the assessable components. Input:
components (array of char arrays), num_components (int).
Output: is_valid (int).
validate_student_records 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
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

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;

6
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 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
} Unit;

d. Provide the structure chart of a program that 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 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 Description


get_filename Prompts the user to enter a filename or Q/q to quit. Returns
the entered filename as a char*.
file_exists Checks if a file with the given filename exists. Takes char* as
input and returns int (1 if exists).
validate_file Validates the content of the file according to specified criteria.
Returns 1 if valid, error code if not.
print_error Prints the error code and line number where the error
occurred. Takes int error code and line number as input.
read_unit_info Reads the unit information from the file and stores it in a Unit
struct. Takes char* filename and Unit* as input.
read_student_records 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

9
- 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

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;

10
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;
}

student->total_mark = total_mark / total_weight;

if (student->total_mark >= 80) {


strcpy(student->grade, "HD");
} else if (student->total_mark >= 70) {
strcpy(student->grade, "D");
} else if (student->total_mark >= 60) {
strcpy(student->grade, "C");
} else if (student->total_mark >= 50) {
strcpy(student->grade, "P");
} else if (student->total_mark >= 45) {
strcpy(student->grade, "SX");
} else {
strcpy(student->grade, "N");
}
}

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.

15
Algorithm of the Main program:
int main() {
char filename[100];

while (1) {
printf("Enter the filename (or Q/q to quit): ");
scanf("%s", filename);

if (strcmp(filename, "Q") == 0 || strcmp(filename, "q") == 0) {


printf("Exiting program.\n");
break;
}

if (file_exists(filename)) {
int validation_result = validate_file(filename);
if (validation_result == 1) {
printf("The file is valid.\n");
Unit unit;
StudentRecords records;
read_unit_info(filename, &unit);
read_student_records(filename, &records);
compute_all_students_final_marks_and_grades(&records, unit);

char results_filename[100];
sprintf(results_filename, "%s_results.txt", unit.unit_code);
save_results_to_file(results_filename, unit, records);

printf("Results saved to %s\n", results_filename);

} else {
int error_code = validation_result / 1000;
int line_number = validation_result % 1000;
print_error(error_code, line_number);
}
} else {
printf("File does not exist. Please try again.\n");

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

17
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.

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
21
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);

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

You might also like