Fundamentos de Programación
PR4 - 20241
Fecha límite de entrega: 15/01/2025 a las 23:59
Enunciado
Esta práctica tiene tres partes (algoritmo, programa y proceso). Las tres son obligatorias.
1a. parte. Algoritmo.[70%].
En esta última actualización del algoritmo, usaremos las PR anteriores para diseñar un
algoritmo completo que calcule la calificación final de todos los estudiantes de la
asignatura, aplicando las condiciones establecidas para la evaluación continua. Además,
calcularemos una serie de estadísticas sobre los resultados. El algoritmo final deberá:
● [Ejercicio 1] Ampliar los campos de la estructura que guarda los datos de un
estudiante (tStudent) para almacenar las notas finales de CAA (caaMark) y PR
(prMark), así como el número de actividades que ha entregado de cada tipo (nCaa y
nPr), la nota final del curso (finalMark) y el registro de No Presentado (absent), un
campo que sea cierto si el resultado final es No Presentado y falso en caso
contrario. Si la nota de un estudiante finalmente se califica como “No presentado”
significa que no ha presentado suficientes actividades de evaluación y, por tanto,
no tendrá nota final de la asignatura.
● Leer por teclado el nombre del fichero donde están las notas de las actividades de
cada estudiante, igual que se hizo en la PR3.
● Leer los datos del fichero de notas, usando la acción diseñada en la PR3
studentsLoadDataFromFile, pasándole como parámetro de entrada el nombre del
fichero leído en el punto anterior y obteniendo de salida una tabla con los datos de
los estudiantes y un booleano que indica si se ha producido un error al leer el
fichero o no.
● Para cada estudiante:
○ [Ejercicio 2] Calcular su nota final numérica de CAA y PR por separado con
una precisión de dos decimales (media ponderada de las notas de cada una
de las actividades teniendo en cuenta los pesos de cada actividad). Además,
contabilizar cuántas actividades ha entregado de cada tipo. Para hacerlo hay
que diseñar una acción que fusione las acciones usadas en la PR3 para
hacer estos cálculos (finalMarkByActivityType y activityTypeNumber). Esta
1
nueva acción tendrá un parámetro de entrada/salida de tipo estudiante
(tStudent).
○ [Ejercicio 3] Calcular la nota final numérica de EC del estudiante, diseñando
una nueva acción que se le pasará por parámetro un estudiante, al que le
actualizará su nota final y el registro de No Presentado.
Para hacer el cálculo de la nota final, se han de tener en cuenta las
siguientes reglas, que deben aplicarse por orden:
■ Si la nota final de CAA no llega a 4: la nota final de EC será la de
CAA.
■ Si la nota final de PR no llega a 5: la nota final de EC será la de PR.
■ En cualquier otro caso, la nota final de EC será la media ponderada
de la nota final de CAA (30%) y la nota final de PR (70%).
■ Si la nota final de EC está aprobada, pero no se han entregado todas
las PR: la nota final de EC será un 4. Para comprobarlo hay que
utilizar la función proporcionada allSubmitedPr.
Para hacer el cálculo del registro de No Presentado, se ha de comprobar si
el estudiante ha entregado menos de tres CAA y menos de dos PR. En caso
de cumplirse estas condiciones, se considerará “No presentado”.
● [Ejercicio 4] Guardar los datos de los estudiantes en un fichero de salida ([Link])
a partir de la tabla de estudiantes. Hay que guardar la siguiente información: el
identificador del estudiante, su nombre, su nota final de CAA y PR, el número de
actividades de cada tipo, su nota final de EC y si tiene registro de “No Presentado”
(se indicará con un 0 si es No Presentado o con un 1 si tiene nota final). También
hay que mostrar la misma información por pantalla, utilizando la acción
writeStudentsData que se proporciona.
● [Ejercicio 5] Ordenar los estudiantes por nota final, en orden descendente. Para
ello, diseñar una nueva acción que ordene la tabla de estudiantes que se le pase
por parámetro. En caso de empate en la nota, irá primero el estudiante con menor
identificador. Mostrar por pantalla el listado de estudiantes ordenados, mostrando
sus datos usando la acción writeStudentsData que se proporciona.
● [Ejercicio 6] Mostrar por pantalla estadísticas del porcentaje de estudiantes que han
aprobado. Para calcularlo, diseñar una nueva función que obtenga el porcentaje de
estudiantes que han aprobado la asignatura, a partir de la tabla de estudiantes. El
resultado se tendrá que mostrar por pantalla con una precisión de dos decimales.
● [Ejercicio 7] Listado de estudiantes candidatos a Matrícula de Honor. Se tiene que
diseñar una acción que obtenga, a partir de la tabla de estudiantes, una nueva
tabla con aquellos estudiantes que tengan una nota superior a 9.0. Mostrar el
resultado por pantalla, usando la acción writeStudentsData que se proporciona.
● [Ejercicio 8] Comprobar si un determinado estudiante es candidato a obtener
matrícula de honor. Se pedirá por la entrada standard un identificador de estudiante
2
y se indicará por pantalla si es candidato o no. Para ello, diseñar una función que, a
partir de la tabla de estudiantes candidatos a matrícula de honor y el identificador
introducido, devuelva si se encuentra en dicha tabla o no.
● [Ejercicio 9] Indicar en el algoritmo, mediante comentarios, cuando se ha utilizado
un esquema de recorrido, un esquema de búsqueda o un algoritmo de ordenación.
La estructura del algoritmo, así como algunas de las funciones y acciones, ya están
declaradas y deben ser el punto de partida para la resolución.
Pseudocódigo de partida
const
MAX_STUDENTS: integer = 20; {Max. number of students}
NUM_ACTIVITIES: integer = 7; {Max. number of activities of the subject}
NUM_CAA_ACTIVITIES: integer = 4; {Number of CAA activities}
NUM_PR_ACTIVITIES: integer = 3; {Number of PR activities}
MIN_C_MINUS: real = 3.0; {Minimum mark for grade C-}
MIN_C_PLUS: real = 5.0; {Minimum mark for grade C+}
MIN_B: real = 7.0; {Minimum mark for grade B}
MIN_A: real = 9.0; {Minimum mark for grade A}
CAA1_WEIGHT: integer = 10; {Percent weight of CAA1 in CAA grade}
CAA2_WEIGHT: integer = 20; {Percent weight of CAA2 in CAA grade}
CAA3_WEIGHT: integer = 30; {Percent weight of CAA3 in CAA grade}
CAA4_WEIGHT: integer = 40; {Percent weight of CAA4 in CAA grade}
PR1_WEIGHT: integer = 20; {Percent weight of PR1 in PR grade}
PR2_WEIGHT: integer = 30; {Percent weight of PR2 in PR grade}
PR3_WEIGHT: integer = 50; {Percent weight of PR3 in PR grade}
{...}
end const
type
{User defined types}
tGrade = {A, B, C_PLUS, C_MINUS, D}
tActivityType = {CAA, PR}
tActivityName = {CAA1, CAA2, CAA3, CAA4, PR1, PR2, PR3}
tActivityState = {SUBMITTED, NOT_SUBMITTED, EXCLUDED}
tActivity = record
name: tActivityName; {Activity Name}
state: tActivityState; {Activity State}
mark: real; {Activity Mark}
end record
tStudent = record
studentId: integer; {Student ID}
name: string; {Student Name}
activities: vector[NUM_ACTIVITIES] of tActivity; {Student Activities}
{Exercise 1}
{...}
end record
tStudentsTable = record
students: vector [MAX_STUDENTS] of tStudent; {Students info and grades}
3
nStudents: integer; {Number of students}
end record
end type
action studentsLoadDataFromFile(in filename: string, out studentsTable: tStudentsTable, out isRead: boolean)
var
fileToRead : file;
newStudent: tStudent;
i: integer;
end var
fileToRead := openFile(filename);
if fileToRead ≠ NULL then
[Link] := 0;
while not isEndOfFile(fileToRead) and [Link] < MAX_STUDENTS do
[Link] := readIntegerFromFile(fileToRead);
[Link] := readStringFromFile(fileToRead);
for i := 1 to NUM_ACTIVITIES do
{Read mark and activity state}
[Link][i].mark := readRealFromFile(fileToRead);
[Link][i].state := readEnumFromFile(fileToRead);
{Assign activity name}
if i = 1 then
[Link][i].name := CAA1;
else
if i = 2 then
[Link][i].name := CAA2;
else
if i = 3 then
[Link][i].name := CAA3;
else
if i = 4 then
[Link][i].name := CAA4;
else
if i = 5 then
[Link][i].name := PR1;
else
if i = 6 then
[Link][i].name := PR2;
else
[Link][i].name := PR3;
end if
end if
end if
end if
end if
end if
end for
{Add newStudent to studentsTable }
[Link] := [Link] + 1;
[Link][[Link]] := newStudent;
end while
closeFile(fileToRead);
isRead := true;
else
isRead := false;
end if
end action
action activityTypeWeight(in activity: tActivityName, out activityType: tActivityType, out activityWeight: real)
activityType := CAA;
4
if activity = CAA1 then
activityWeight := CAA1_WEIGHT;
else
if activity = CAA2 then
activityWeight := CAA2_WEIGHT;
else
if activity = CAA3 then
activityWeight := CAA3_WEIGHT;
else
if activity = CAA4 then
activityWeight := CAA4_WEIGHT;
else
activityType := PR;
if activity = PR1 then
activityWeight := PR1_WEIGHT;
else
if activity = PR2 then
activityWeight := PR2_WEIGHT;
else
activityWeight := PR3_WEIGHT;
end if
end if
end if
end if
end if
end if
end action
function allSubmitedPr(nSubmitedPr: integer): boolean
return nSubmitedPr = NUM_PR_ACTIVITIES;
end function
{Exercise 2}
{...}
{Exercise 3}
{...}
{Exercise 4}
{...}
{Exercise 5}
{...}
{Exercise 6}
{...}
{Exercise 7}
{...}
{Exercise 8}
{...}
action writeStudentsData(in studentsTable: tStudentsTable)
var
i: integer;
end var
if [Link] = 0 then
writeString(“STUDENT LIST EMPTY”);
else
writeString(ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)”);
writeString(“--------------------------------------------------------------------------------------------------------------------”);
5
for i := 1 to [Link] do
writeInteger([Link][i].studentId);
writeString([Link][i].name);
writeReal([Link][i].caaMark);
writeReal([Link][i].prMark);
writeInteger([Link][i]nCaa);
writeInteger([Link][i]nPr);
writeReal([Link][i].finalMark);
writeBoolean([Link][i].absent);
end for
end if
end action
algorithm UOCSubjectGrade
var
studentsTable: tStudentsTable;
i, studentId: integer;
filename: string;
isRead, found: boolean;
approvedPercent: real;;
{...}
end var
{Load data from file}
writeString("LOAD DATA FROM FILE. ENTER FILE NAME >>");
filename := readString();
studentsLoadDataFromFile(filename, studentsTable, isRead);
if isRead then
writeString("RESULTS:");
for i := 1 to [Link] do
{Exercise 2}
{...}
{Exercise 3}
{...}
end for
{Exercise 4}
{...}
writeString(“STUDENTS MARKS”);
writeString(“==================”);
{...}
{Exercise 5}
{...}
writeString(“STUDENTS SORTED BY FINAL MARK”);
writeString(“===================================”);
{...}
{Exercise 6}
{...}
writeString(“Percent students approved: “);
writeReal(approvedPercent);
{Exercise 7}
{...}
writeString(“STUDENTS IN HONOR LIST”);
writeString(“=========================”);
{...}
{Exercise 8}
writeString("SELECT STUDENT BY ID >>");
studentId := readInteger();
{...}
if found then
writeString("STUDENT IN HONOR LIST");
6
else
writeString("STUDENT NOT IN HONOR LIST");
end if
else
writeString("NO STUDENTS RECOVERED");
end if
end algorithm
Ejemplos de ejecución
Ejemplo 1
LOAD DATA FROM FILE. ENTER FILE NAME >>
[Link]
RESULTS:
STUDENTS MARKS
==============
ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)
-------------------------------------------------------------
14 ALAN_TURING 10.00 10.00 4 3 10.00 0
9 ANDREW_TANENBAUM 9.03 3.13 4 2 3.13 0
17 BRIAN_KERNIGHAN 5.29 8.69 3 3 7.67 0
13 DENNIS_RITCHIE 5.49 6.55 4 3 6.23 0
1 DONALD_KNUTH 5.78 6.88 4 3 6.55 0
4 GRACE_HOPPER 8.39 7.57 4 3 7.82 0
3 JEAN_LAURENT 5.09 8.43 4 3 7.43 0
6 JOHN_VON_NEUMANN 6.87 6.37 4 3 6.52 0
8 KATHERINE_JOHNSON 2.09 4.19 4 3 2.09 0
15 LARRY_PAGE 7.84 3.64 4 3 3.64 0
19 LINUS_TORVALDS 2.59 5.15 4 3 2.59 0
18 MARISSA_MAYER 4.32 6.29 4 3 5.70 0
10 RADIA_PERLMAN 5.24 3.81 4 3 3.81 0
2 RICHARD_STALLMAN 2.67 5.35 4 3 2.67 0
11 SERGEY_BRIN 6.73 6.28 4 2 4.00 0
5 SHERYL_SANDERG 4.51 2.73 4 3 2.73 0
20 SUNDAR_PICHAI 4.06 4.75 2 1 4.75 1
16 TIM_BERNERS_LEE 7.23 9.60 4 3 8.89 0
12 VINT_CERF 5.00 5.00 4 3 5.00 0
7 ADA_LOVELACE 10.00 10.00 4 3 10.00 0
STUDENTS SORTED BY FINAL MARK
=============================
ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)
-------------------------------------------------------------
7 ADA_LOVELACE 10.00 10.00 4 3 10.00 0
14 ALAN_TURING 10.00 10.00 4 3 10.00 0
16 TIM_BERNERS_LEE 7.23 9.60 4 3 8.89 0
4 GRACE_HOPPER 8.39 7.57 4 3 7.82 0
17 BRIAN_KERNIGHAN 5.29 8.69 3 3 7.67 0
3 JEAN_LAURENT 5.09 8.43 4 3 7.43 0
1 DONALD_KNUTH 5.78 6.88 4 3 6.55 0
6 JOHN_VON_NEUMANN 6.87 6.37 4 3 6.52 0
13 DENNIS_RITCHIE 5.49 6.55 4 3 6.23 0
18 MARISSA_MAYER 4.32 6.29 4 3 5.70 0
7
12 VINT_CERF 5.00 5.00 4 3 5.00 0
20 SUNDAR_PICHAI 4.06 4.75 2 1 4.75 1
11 SERGEY_BRIN 6.73 6.28 4 2 4.00 0
10 RADIA_PERLMAN 5.24 3.81 4 3 3.81 0
15 LARRY_PAGE 7.84 3.64 4 3 3.64 0
9 ANDREW_TANENBAUM 9.03 3.13 4 2 3.13 0
5 SHERYL_SANDERG 4.51 2.73 4 3 2.73 0
2 RICHARD_STALLMAN 2.67 5.35 4 3 2.67 0
19 LINUS_TORVALDS 2.59 5.15 4 3 2.59 0
8 KATHERINE_JOHNSON 2.09 4.19 4 3 2.09 0
Percent students approved: 55.00
STUDENTS IN HONOR LIST
======================
ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)
-------------------------------------------------------------
7 ADA_LOVELACE 10.00 10.00 4 3 10.00 0
14 ALAN_TURING 10.00 10.00 4 3 10.00 0
SELECT STUDENT BY ID >>
7
STUDENT IN HONOR LIST
Ejemplo 2
LOAD DATA FROM FILE. ENTER FILE NAME >>
[Link]
RESULTS:
STUDENTS MARKS
==============
ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)
-------------------------------------------------------------
1 DONALD_KNUTH 5.38 6.31 3 2 4.00 0
2 RICHARD_STALLMAN 2.11 3.10 2 2 2.11 0
3 JEAN_LAURENT 1.73 6.78 2 2 1.73 0
4 GRACE_HOPPER 3.39 6.34 2 2 3.39 0
5 SHERYL_SANDERG 2.47 0.78 2 2 2.47 0
6 JOHN_VON_NEUMANN 3.57 6.25 2 2 3.57 0
7 ADA_LOVELACE 3.58 6.27 2 2 3.58 0
8 KATHERINE_JOHNSON 1.67 1.99 2 2 1.67 0
9 ANDREW_TANENBAUM 2.31 6.33 2 2 2.31 0
10 RADIA_PERLMAN 1.66 0.94 2 1 1.66 1
11 SERGEY_BRIN 3.55 6.28 2 2 3.55 0
12 VINT_CERF 3.00 1.00 3 1 3.00 0
13 DENNIS_RITCHIE 3.57 6.28 2 2 3.57 0
14 ALAN_TURING 3.00 10.00 1 3 3.00 0
15 LARRY_PAGE 2.84 3.98 2 2 2.84 0
16 TIM_BERNERS_LEE 3.57 6.78 2 2 3.57 0
17 BRIAN_KERNIGHAN 5.53 9.74 3 3 8.48 0
18 MARISSA_MAYER 2.32 0.98 2 1 2.32 1
19 LINUS_TORVALDS 1.17 3.85 2 2 1.17 0
20 SUNDAR_PICHAI 1.83 3.24 2 2 1.83 0
8
STUDENTS SORTED BY FINAL MARK
=============================
ID NAME CAA_MARK PR_MARK N_CAA N_PR FINAL_MARK ABSENT?(1=YES)
-------------------------------------------------------------
17 BRIAN_KERNIGHAN 5.53 9.74 3 3 8.48 0
1 DONALD_KNUTH 5.38 6.31 3 2 4.00 0
7 ADA_LOVELACE 3.58 6.27 2 2 3.58 0
6 JOHN_VON_NEUMANN 3.57 6.25 2 2 3.57 0
13 DENNIS_RITCHIE 3.57 6.28 2 2 3.57 0
16 TIM_BERNERS_LEE 3.57 6.78 2 2 3.57 0
11 SERGEY_BRIN 3.55 6.28 2 2 3.55 0
4 GRACE_HOPPER 3.39 6.34 2 2 3.39 0
12 VINT_CERF 3.00 1.00 3 1 3.00 0
14 ALAN_TURING 3.00 10.00 1 3 3.00 0
15 LARRY_PAGE 2.84 3.98 2 2 2.84 0
5 SHERYL_SANDERG 2.47 0.78 2 2 2.47 0
18 MARISSA_MAYER 2.32 0.98 2 1 2.32 1
9 ANDREW_TANENBAUM 2.31 6.33 2 2 2.31 0
2 RICHARD_STALLMAN 2.11 3.10 2 2 2.11 0
20 SUNDAR_PICHAI 1.83 3.24 2 2 1.83 0
3 JEAN_LAURENT 1.73 6.78 2 2 1.73 0
8 KATHERINE_JOHNSON 1.67 1.99 2 2 1.67 0
10 RADIA_PERLMAN 1.66 0.94 2 1 1.66 1
19 LINUS_TORVALDS 1.17 3.85 2 2 1.17 0
Percent students approved: 5.00
STUDENTS IN HONOR LIST
======================
STUDENT LIST EMPTY
SELECT STUDENT BY ID >>
3
STUDENT NOT IN HONOR LIST
2a. parte. Código y pruebas. [30%].
Codificar en lenguaje C el algoritmo diseñado anteriormente, ejecutarlo y probarlo hasta
asegurar que funciona correctamente diseñando los casos de prueba necesarios.
Nota: Al finalizar el ejercicio 1, hay que descomentar la línea siguiente en el código del
fichero grades.h:
//#define TYPEDEF_COMPLETED
Ejecutar y superar los juegos de prueba automáticos disponibles en la herramienta DSLab.
9
3a. parte. Proceso de resolución.
Explicar el proceso seguido para solucionar la PR2, mediante la grabación de un vídeo
corto (máximo 2 minutos, pero menos de un minuto sería ideal) en el que documentéis cómo
habéis resuelto esta práctica.
Este vídeo es una prueba de la autoría de vuestro ejercicio, y lo revisaremos solo en
caso de que haya dudas al respecto. Por lo tanto, el vídeo debe mostraros a vosotros
explicando cómo habéis seguido el proceso que os sugerimos: primero diseñar el
algoritmo en pseudocódigo, después codificar el programa y probarlo e iterar estos pasos
hasta que el resultado sea correcto y responda al problema que plantea el enunciado.
Queremos que nos expliquéis cómo habéis pensado en el esquema de la solución. ¿Ha
habido algo que os ha costado entender o que no teníais claro cómo resolver? ¿Qué
pasos habéis hecho para convertir el algoritmo en un código C, con qué dificultades os
habéis encontrado, y cómo las habéis resuelto? Y también qué herramientas habéis
usado para codificar el algoritmo y probar el programa, qué pruebas habéis hecho, cómo
las habéis pensado, qué tipo de errores habéis encontrado al compilar y cómo los habéis
resuelto. Y finalmente, qué es lo que os ha costado más, qué unidades de los recursos
habéis consultado en cada paso, si habéis consultado al profesorado, en los foros, etc. No
se trata de que leáis y expliquéis el código, esto ya lo podemos ver en el algoritmo y el
programa. Queremos que nos dejéis claro que el ejercicio lo habéis hecho vosotros.
Es imprescindible entregar las tres partes de la práctica para que se corrija.
10