0% encontró este documento útil (0 votos)
16 vistas19 páginas

Pec3 20242 Ib

La PEC 3 se centra en el desarrollo de habilidades en programación orientada a objetos, específicamente en la codificación de asociaciones en Java. Incluye cuatro ejercicios que evalúan la comprensión de conceptos como asociación binaria, agregación y composición, así como el uso de enumeraciones y librerías de terceros. La entrega de la actividad está programada para el 28 de abril de 2025 y representa el 30% de la nota total de PECs.

Cargado por

brayansaiago
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
16 vistas19 páginas

Pec3 20242 Ib

La PEC 3 se centra en el desarrollo de habilidades en programación orientada a objetos, específicamente en la codificación de asociaciones en Java. Incluye cuatro ejercicios que evalúan la comprensión de conceptos como asociación binaria, agregación y composición, así como el uso de enumeraciones y librerías de terceros. La entrega de la actividad está programada para el 28 de abril de 2025 y representa el 30% de la nota total de PECs.

Cargado por

brayansaiago
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

PEC 3

Asociaciones

Información relevante:
• Fecha límite de entrega: 28/04/2025.
• Peso en la nota de PECs: 30%.
Contenido
Información docente​ 3
Prerrequisitos​ 3
Objetivos​ 3
Resultados de aprendizaje​ 3
Enunciado​ 4
Ejercicio 1 (2 puntos)​ 4
Ejercicio 2 (5 puntos)​ 9
Ejercicio 3 (1.5 puntos)​ 13
Ejercicio 4 (1.5 puntos)​ 16
Formato y fecha de entrega​ 19

En esta actividad no está permitido el uso de herramientas de inteligencia artificial.

En el plan docente y en la web sobre integridad académica y plagio de la UOC encontraréis


información sobre qué se considera conducta irregular en la evaluación y las consecuencias
que puede tener.

Diseño y Programación Orientados a Objetos pág. 2


Información docente
Esta PEC está vinculada con el módulo teórico “Asociaciones (relaciones entre
objetos)” de los apuntes de la asignatura. Léelo antes de empezar la PEC.

Prerrequisitos
Para realizar esta PEC necesitas:
●​ Tener adquiridos los conocimientos de las PEC 1 y PEC 2. Por eso te
recomendamos que mires las soluciones que se publicaron en el aula y las
compares con las tuyas.

Objetivos
Con esta PEC el equipo docente de la asignatura busca que:

●​ Entiendas las diferencias entre asociación binaria, de agregación y de


composición.

●​ Codifiques asociaciones en Java.

●​ Entiendas qué es una enumeración y el potencial que tienen en Java.

●​ Utilices una librería proporcionada por terceros.

​ ​ Resultados de aprendizaje
Con esta PEC debes demostrar que eres capaz de:

●​ Codificar una clase a partir de unos requisitos y su representación como un


diagrama de clases.

●​ Entender la diferencia entre los distintos modificadores de acceso.

●​ Saber cómo codificar una asociación de composición con Java (y en cualquier


lenguaje).

●​ Saber cómo codificar una asociación de agregación con Java.

●​ Codificar un enum en Java añadiéndole funcionalidades.

●​ Saber cómo tratar las excepciones de un programa Java.

●​ Usar con cierta soltura un entorno de desarrollo integrado (IDE) como IntelliJ.

●​ Utilizar test unitarios para determinar que un programa es correcto.

●​ Saber utilizar Gradle para importar librerías de terceros.

Diseño y Programación Orientados a Objetos pág. 3


Enunciado
Esta PEC contiene 4 ejercicios evaluables. Tienes que entregar tu solución a los 4
ejercicios (ver el último apartado).

Debido a que las actividades están encadenadas (i.e. para hacer una se debe
haber comprendido la anterior), es altamente recomendable hacer los
ejercicios en el orden en que aparecen en este enunciado.

Ejercicio 1 (2 puntos)
Abre el proyecto PAC3Ex1 con IntelliJ. En el package [Link].pac3 del
directorio/src/test/java está el archivo con los tests unitarios que te
proporcionamos. En el package [Link].pac3 del directorio/src/main/java
debes codificar las clases AIPlatform y ComputeCluster, cuya representación
en diagrama de clases UML la tienes disponible en la imagen [Link] que te
adjuntamos con el archivo .zip de este enunciado.

Como puedes ver en el diagrama UML, modelaremos una plataforma de


entrenamiento de modelos de inteligencia artificial (AIPlatform) y su relación con los
datos de su clúster (ComputeCluster). La clase ComputeCluster abstrae los
datos relacionados con el clúster de la plataforma (nombre, número de nodos…). La
relación entre las clases AIPlatform y ComputeCluster es una asociación
unidireccional de composición, con la clase AIPlatform como clase compuesta y
la clase ComputeCluster como componente, de manera que si desaparece el objeto
AIPlatform, desaparezca el objeto ComputeCluster que estaba vinculado.

Para la codificación de estas clases debes tener en cuenta las siguientes


especificaciones/consideraciones:

Clase ComputeCluster

●​ Los atributos de tipo “constante” deben ser inicializados en la propia


declaración, no en el constructor.

●​ Los atributos declarados en mayúsculas en un diagrama de clases UML, [Link].


INVALID_NAME, son declarados como final. Puedes leer sobre qué
significa y cómo se aplica este modificador a un atributo en el apartado 3.8.3
de la Guía de Java. Hablaremos más detenidamente sobre el modificador
final en la PEC 4.

●​ Siempre que haya conflicto de nombres, sobre todo en los métodos setter
(es decir, setXXX), tienes que utilizar la palabra reservada this.

Diseño y Programación Orientados a Objetos pág. 4


●​ setName: Este método asigna el atributo que contiene el nombre del clúster en
formato String. Si el valor que recibe por parámetro (name) y desea asignar
al atributo con el mismo nombre es null, o no cumple con el formato que
deben seguir los clústers, entonces el método no debe asignar este valor y, en
su lugar, debe lanzarse una excepción de tipo
IllegalArgumentException (es una excepción de tipos unchecked,
consulta el apartado 3.12.5 de la Guía de Java) con el mensaje indicado en
INVALID_NAME. Todo nombre de clúster debe empezar por la palabra
“cluster”, seguido de un guión “-” y un valor numérico como “1”, “5” o “01”.

Pista: en PECs anteriores ya has visto cómo utilizar regex para validar cadenas
de texto en determinados formatos.

●​ setNumNodes: Este método asigna el número de nodos que tiene el clúster. Si


el valor que se recibe por parámetro y se desea asignar al atributo numNodes
es inferior 4 (el mínimo de nodos requeridos para poder cargar los modelos),
entonces el atributo no se debe asignar y se debe lanzar una excepción de tipo
IllegalArgumentException con el mensaje indicado en
INVALID_NUM_NODES.

Pista: utiliza los atributos que tiene la clase para referenciar los valores
constantes.

●​ setNumGPUs: Este método asigna la cantidad de GPUs que tiene el clúster. Si


el valor que se recibe por parámetro (numGPUs) es inferior a 1, es decir, al
mínimo de GPUs que tiene que tener cualquier clúster, entonces el método no
debe asignar el atributo y debe lanzar una excepción de tipo
IllegalArgumentException con el mensaje indicado en
INVALID_NUM_GPUS.

●​ setRamCapacity: Este método asigna la memoria RAM total sumando la de


todos los nodos del clúster. Los modelos necesitan una determinada cantidad
de memoria RAM para poder ser cargados. Por lo tanto, este método debe
validar que el parámetro recibido (ramCapacity), que representa la memoria
RAM en GB, tenga un valor superior o igual al mínimo de RAM requerido (16
GB). En caso de que el parámetro recibido no cumpla con dicha condición, el
método no debe asignar el atributo y debe lanzar una excepción de tipo
IllegalArgumentException con el mensaje indicado en
INVALID_RAM_CAPACITY.

●​ setNextMaintenanceDate: Este método asigna la fecha programada para


que se lleve a cambio el siguiente mantenimiento en el clúster. El método debe

Diseño y Programación Orientados a Objetos pág. 5


validar que el parámetro recibido (nextMaintenanceDate) no sea null o
una fecha en el pasado. Si el parámetro incumple alguna de las dos
condiciones, entonces el método no debe asignar el valor y debe lanzar una
excepción de tipo IllegalArgumentException con el mensaje indicado
en INVALID_MAINTENANCE_DATE.

●​ setGPUEnabled: Este método asigna si un clúster tiene activada la GPU. Se


debe asignar en el atributo isGPUEnabled.

Clase AIPlatform

●​ Los atributos de tipo “constante” deben ser inicializados en la propia


declaración, no en el constructor.

●​ Los atributos declarados en mayúsculas en un diagrama de clases UML, [Link].


MAX_CONCURRENCE_USERS, son final. Puedes leer sobre qué significa y
cómo se aplica este modificador a un atributo en el apartado 3.8.3 de la Guía
de Java. Hablaremos más detenidamente sobre el modificador final en la
PEC 4.

●​ Al crear un objeto de tipo AIPlatform es necesario crear el objeto


ComputeCluster que le corresponda (puede ser null). Dado que una
plataforma puede no tener un clúster asociado, la clase AIPlatform también
ofrece un constructor que permite crear una plataforma sin clúster. Ninguno de
los 2 constructores debe lanzar una excepción si algún dato del clúster es
incorrecto, en este caso el clúster (cluster) debe ser null.

●​ Aquellos constructores que no tengan parámetros para poder crear un clúster


(cluster), no podrán crearlo y el objeto AIPlatform creado tendrá un
ComputeCluster con valor null. Además, en caso de que durante la
creación de un clúster se devuelva alguna excepción, esta debe ser capturada
en el constructor y asignar un null al clúster (cluster). Fijaros que la clase
ComputeCluster puede devolver la excepción
IllegalArgumentException.

●​ setName: Este método asigna el nombre de la plataforma de inteligencia


artificial. Si el valor que se desea asignar al atributo name es null o no está
conformado solo por letras (mayúsculas o minúsculas) y espacios, entonces el
método no debe asignar el atributo y debe lanzar una excepción de tipo
IllegalArgumentException con el mensaje indicado en
INVALID_NAME. Si cumple con las condiciones, el método debe eliminar los
espacios en blanco que pueda contener al principio y al final y, además, debe

Diseño y Programación Orientados a Objetos pág. 6


convertir la primera letra del nombre en mayúsculas y convertir el resto en
minúsculas.
●​ setDescription: Este método asigna la descripción de la plataforma. Si el
valor que se desea asignar al atributo description es null, no contiene
ningún carácter o solo está formado por espacios en blanco, entonces el
método no debe asignar el atributo y debe lanzar una excepción de tipo
IllegalArgumentException con el mensaje indicado en
IVNALID_DESCRIPTION.

●​ setDomain: Este método asigna el dominio web de la plataforma. Si el


parámetro recibido (domain) es null o no sigue el patrón que deben tener los
dominios web según la plataforma, entonces el método no debe asignar el
atributo y debe lanzar una excepción de tipo IllegalArgumentException
con el mensaje indicado en INVALID_DOMAIN. Para que un dominio web se
pueda considerar válido debe tener un nombre de dominio conformado solo
por letras en minúsculas, números y guiones seguido de una extensión
formada por un mínimo de 2 letras en minúsculas. Además, el nombre de
dominio no puede empezar o terminar con guión. Asimismo, pueden existir
subdominios, pero en ningún caso se permite que estos sean una cadena de
caracteres vacía, es decir, no puede haber dos puntos correlativamente.

Ejemplo de dominios válidos:

[Link]
[Link]
[Link]
[Link]

Ejemplo de dominios no válidos:

[Link] (no se permiten mayúsculas)


-[Link] (no puede tener un guión al inicio)
[Link]![Link] (no se permiten caracteres especiales)
x..[Link] (no puede haber dos puntos seguidos)

●​ setReleaseDate: Este método asigna la fecha de lanzamiento de la


plataforma de inteligencia artificial. Si el parámetro recibido (releaseDate) es
null o es una fecha a futuro, entonces el método no debe asignar el valor y
debe lanzar una excepción de tipo IllegalArgumentException con el
mensaje indicado en INVALID_RELEASE_DATE.

●​ setMaxConcurrenceUsers: Este método asigna el número máximo de


usuarios que pueden usar la plataforma simultáneamente. Este valor siempre

Diseño y Programación Orientados a Objetos pág. 7


debe estar dentro del rango [1, 100]. Por lo tanto, si el valor recibido por
parámetro está fuera de este rango, el método debe actualizar el valor para
que se encuentre dentro del dominio. Si el valor es inferior a 1, lo actualizará a
1; si es superior a 100, lo debe actualizar a 100.

●​ setCluster: Este método es el encargado de crear el nuevo objeto


ComputeCluster con los valores recibidos como parámetros. En caso de
que no se pueda crear, este método arrastrará la excepción que devuelva
algunos de los setters de la clase ComputeCluster.

Requisito mínimo para evaluar este ejercicio: el programa debe pasar los
tests de tipo sanity y minimum. En la ventana de Gradle, en Task →
verification, encontrarás cinco tareas: testSanity, testMinimum,
testAdvanced, testSpecial y testAll.

●​ testSanity: tarea que ejecuta los tests de tipo sanity, que


comprueban que el esqueleto (i.e. definición de atributos y métodos)
sea correcto.

●​ testMinimum: tarea que ejecuta los tests de tipo minimum, que hacen
referencia a todos los tests de tipo sanity comentados en el punto
anterior y, además, verifican una parte de la funcionalidad del programa.
Concretamente, verifican el funcionamiento de la clase
ComputeCluster.

●​ testAvanced: tarea que ejecuta los tests de tipo advanced, que


hacen referencia a funcionalidades avanzadas del programa. En este
caso, verifican gran parte de las funcionalidades de la clase
AIPlatform.

●​ testSpecial: tarea que ejecuta el test de tipo special, que verifica


que la asociación de composición entre en las clases AIPlatform i
ComputeCluster se haya codificado de manera correcta.

●​ testAll: tarea que ejecuta todos los tests del programa.

Por lo tanto, el requisito para obtener puntos en este ejercicio es superar todos
los test de la tarea testMinimum.

Nota: el estudiante puede recibir una penalización de hasta 0.5 pts. de la nota
obtenida en este ejercicio en función de la calidad del código proporcionado.

(2 puntos: 1 pt. testMinimum; ​


0.75 pts. testAdvanced; 0.25 pts. testSpecial)

Diseño y Programación Orientados a Objetos pág. 8


Ejercicio 2 (5 puntos)
Abre el proyecto PAC3Ex2 de IntelliJ. En el package [Link].pac3 del directorio
/src/test/java está el archivo con los tests unitarios que te proporcionamos.
Copia el package [Link].pac3 del directorio/src/main/java del Ejercicio 1 de
esta PEC3 una vez la hayas completado.

En este ejercicio ampliamos el programa anterior añadiendo una nueva clase,


concretamente la clase Model, la cual modela/representa un modelo entrenado de
inteligencia artificial que se puede usar dentro del cluster. El nuevo diagrama de clases
UML lo puedes encontrar en la imagen [Link] que te adjuntamos con el
archivo .zip de este enunciado:

Ten presente las siguientes especificaciones para la clase Model:

Importante: para realizar este ejercicio sólo se pueden utilizar arrays. No se


pueden utilizar colecciones de Java ([Link]. ArrayList) ni la clase Stream,
incluido métodos como [Link] y [Link].

Clase Model

●​ Los atributos de tipo “constante” deben ser inicializados en la propia


declaración, no en el constructor.

●​ Al atributo id se le asignará aquel valor que tenga el atributo nextId en el


momento de instanciar el objeto. Una vez hecho, el valor de nextId debe
incrementarse una unidad. Todo este proceso sólo debe realizarse si no hay
ningún problema con el resto de parámetros recibidos en el constructor.

●​ El método incNextId incrementa una unidad nextId.

●​ El método setName lanzará una IllegalArgumentException con el


mensaje de INVALID_NAME si el parámetro name recibido es null, está
compuesto solo por espacios en blanco o contiene menos de un número de
caracteres especificado en MIN_NAME_LENGTH ignorando los espacios que
pueda tener al principio y al final en dicha verificación. En caso de cumplir
todas las condiciones, se deben eliminar los espacios en blanco que pueda
contener el parámetro name recibido al principio o al final de la String antes
de validación y asignación.

●​ El método setDescription lanzará una IllegalArgumentException


con el mensaje de INVALID_DESCRIPTION si el parámetro description
recibido es null. Si no es null, debe asignar el valor recibido por parámetro

Diseño y Programación Orientados a Objetos pág. 9


al atributo description eliminando los espacios en blanco que pueda
contener al principio o al final de la String.

●​ Los métodos setTp, setFp, setTn y setFn deben lanzar una


IllegalArgumentException si el parámetro recibido es inferior a 0 con
los mensajes INVALID_TP, INVALID_FP, INVALID_TN e INVALID_FN
respectivamente. En caso contrario, deben asignar los atributos tp, fp, tn y
fn respectivamente.

●​ El método setFirstTrainingDate debe lanzar una


IllegalArgumentException con el mensaje de
INVALID_FIRST_TRAINING_DATE si el parámetro recibido
firstTrainingDate es null o una fecha posterior a la actual. En caso de
recibir una fecha con el mismo día o anterior a la fecha actual, se considerará
como válida y debe asignar el atributo firstTrainingDate.

●​ El método setLastTrainingDate lanzará una


IllegalArgumentException con el mensaje de
INVALID_LAST_TRAINING_DATE si el parámetro recibido
lastTrainingDate es null, contiene una fecha posterior a la actual o si es
una fecha anterior a la fecha asignada en el atributo firstTrainingDate.
Por lo tanto, se considerará como válida si la fecha contiene el mismo día o
anterior a la fecha actual y, además, que sea posterior o igual a la fecha
asignada en el atributo firstTrainingDate.

●​ El método getPrecision debe devolver la precisión del modelo entrenado.


Para ello, debe seguir la siguiente fórmula:
𝑇𝑃
𝑃𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 = 𝑇𝑃 + 𝐹𝑃

●​ El método getRecall debe devolver la tasa de verdaderos positivos del


modelo entrenado. Para ello, debe seguir la siguiente fórmula:
𝑇𝑃
𝑅𝑒𝑐𝑎𝑙𝑙 = 𝑇𝑃 + 𝐹𝑁

●​ El método getF1Score debe devolver el valor de F1-Score, que permite


balancear los valores de la precisión y la tasa de verdaderos positivos en una
única métrica. Para ello, debe seguir la siguiente fórmula:
𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 · 𝑟𝑒𝑐𝑎𝑙𝑙
𝐹1 − 𝑆𝑐𝑜𝑟𝑒 = 2 · 𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 + 𝑟𝑒𝑐𝑎𝑙𝑙
Clase ComputeCluster

●​ El constructor debe inicializar los atributos MAX_MODELS y numModels. Estos


atributos permiten controlar la cantidad máxima de modelos que puede

Diseño y Programación Orientados a Objetos pág. 10


contener el clúster y el número de modelos almacenados respectivamente. Por
lo tanto, el atributo MAX_MODELS debe inicializarse con el parámetro recibido
maxModels. No obstante, antes debe validar que el parámetro maxModels
sea superior a 0. Si no lo es, el constructor debe lanzar una
IllegalArgumentException con el mensaje INVALID_MAX_MODELS. Por
otro lado, el atributo numModels se debe inicializar a 0.

●​ El método findModel devuelve el índice/posición donde se encuentra el


modelo pasado como parámetro. Si el modelo a buscar no se encuentra en el
clúster, entonces debe devolver -1.

Si este método recibe como parámetro el valor null, entonces debe lanzar
una NullPointerException con el mensaje MODEL_NULL.

Nota: el atributo que permite identificar unívocamente a un modelo es su


identificador.

●​ El método containsModel devuelve true si el modelo pasado como


parámetro existe en el clúster. De lo contrario, devuelve false.

Si este método recibe como parámetro el valor null, entonces debe lanzar
una NullPointerException con el mensaje MODEL_NULL.

●​ El método addModel añade un modelo al clúster. Ten en cuenta:

○​ Si este método recibe como parámetro el valor null, entonces debe


lanzar una NullPointerException con el mensaje MODEL_NULL.

○​ Si el clúster ya está lleno, entonces debe lanzar una


IllegalStateException con el mensaje CANNOT_ADD_MODEL.

○​ Si el modelo ya está en el clúster, entonces debe lanzar una


IllegalArgumentException con el mensaje
MODEL_ALREADY_EXISTS.

○​ El modelo se guardará en la primera posición libre que haya en el array


models. No obstante, no pueden existir posiciones vacías (null) entre
modelos, es decir, todos los modelos deben estar almacenados de
manera correlativa en el array. Por ejemplo, si el clúster tiene
almacenados 4 modelos, deben estar entre los índices 0 y 3, ambos
incluidos, del array models.

Pista: haz coincidir el valor del atributo numModels con la siguiente posición
vacía (null) del array models.

Diseño y Programación Orientados a Objetos pág. 11


○​ Si el modelo es añadido correctamente, el método actualiza el atributo
numModels.

●​ El método removeModel elimina del clúster el modelo como argumento. Si el


modelo es eliminado correctamente, el método actualiza el atributo
numModels.

Si este método recibe como parámetro el valor null, entonces debe lanzar
una NullPointerException con el mensaje MODEL_NULL. Además, si no
se encuentra al modelo, debe lanzar una IllegalArgumentException
con el mensaje MODEL_NOT_FOUND.

Finalmente, debes asegurarte de que el método no deje posiciones vacías


(null) entre modelos. Por lo tanto, si se elimina un modelo que no se
encuentra en la última posición, todos aquellos modelos que estén en un índice
superior se deben mover a una posición inferior del array models.

●​ El método getBestModel devuelve el mejor modelo de todo el clúster. Se


considera el mejor modelo aquel que tiene un valor de F1-Score superior. En
caso de empate, se debe devolver el que aparezca primero en el array de
modelos. Si el clúster no tiene ningún modelo, el método debe devolver null.

Clase AIPlatform

●​ Modifica el constructor que recibe el parámetro clusterMaxModels y el


método setCluster para que se pueda iniciar el atributo cluster con el
nuevo parámetro que solicita el constructor de la clase ComputeCluster,
maxModels.

Diseño y Programación Orientados a Objetos pág. 12


Requisito mínimo para evaluar este ejercicio: el programa debe pasar los
tests de tipo sanity y minimum. En la ventana de Gradle, en Task →
verification, encontrarás cuatro tareas: testSanity, testMinimum,
testAdvanced y testAll.

●​ testSanity: tarea que ejecuta los tests de tipo sanity, que


comprueban que el esqueleto (i.e. definición de atributos y métodos)
sea correcto.

●​ testMinimum: tarea que ejecuta los tests de tipo minimum, que hacen
referencia a todos los tests de tipo sanity comentados en el punto
anterior y, además, verifican una parte de la funcionalidad del programa.
Concretamente, verifican el funcionamiento de la clase Model.

●​ testAvanced: tarea que ejecuta los tests de tipo advanced, que


hacen referencia a funcionalidades avanzadas del programa. En este
caso, los métodos implicados en la inserción y eliminación de modelos
del clúster.

●​ testAll: tarea que ejecuta todos los tests del programa.

Por lo tanto, el requisito para obtener puntos en este ejercicio es superar todos
los test de la tarea testMinimum.

Nota: el estudiante puede recibir una penalización de hasta 1 punto de la nota


obtenida en este ejercicio en función de la calidad del código proporcionado.

(5 puntos: 2 pts. testMinimum; 3 pts. testAdvanced)

Diseño y Programación Orientados a Objetos pág. 13


Ejercicio 3 (1.5 puntos)
Antes de empezar debes:

Leer el apartado 3.13 de la Guía de Java que habla de las enumeraciones.


Te recomendamos ver el vídeo sobre enumeraciones que encontrarás en UOCoders.

A continuación, abre el proyecto PAC3Ex3 de IntelliJ. En el package


[Link].pac3 del directorio /src/test/java está el archivo con los tests
unitarios que te proporcionamos. Copia el package [Link].pac3 del
directorio/src/main/java del Ejercicio 2 de esta PEC3 una vez la hayas
completado.

En este ejercicio debes hacer una pequeñas modificaciones en la clase Model y


codificar el enum AlgorithmType siguiendo las especificaciones del diagrama de
clases UML que encontrarás en la imagen [Link] adjuntada dentro del archivo
.zip de este enunciado. Fíjate cómo se definen los enum en UML. Hay otra notación
que consiste en poner el atributo de tipos enum dentro de la clase que lo utiliza
indicando el tipo, de la misma manera que si fuera un atributo de tipo, por ejemplo,
int. En ese caso no habría flecha hacia el enum.

Enum AlgorithmType
AlgorithmType modela el tipo de algoritmo del modelo. Por eso, debes tener en
cuenta:
●​ AlgorithmType tiene un atributo description que almacena la
descripción del tipo de algoritmo en formato String, los atributos
expectedPrecision, expectedRecall y learningRate, que
corresponden a valores esperados para cada tipo de algoritmo (todos de tipo
double). La relación de todos sus atributos siguiendo el mismo orden que el
mencionado anteriormente es la siguiente:
​ LINEAR_REGRESSION​ | Linear Regression​| 0.75 | 0.65 | 1.0
​ Q_LEARNING​ ​ | Q-Learning​ ​ | 0.70 | 0.60 | 0.1
​ NEURAL_NETWORK​ | Neural Network​ | 0.92 | 0.88 | 0.001

Nota: codifica los valores del enum en el orden en que aparecen en el listado
anterior.

●​ AlgorithmType: es el constructor, el cual debe guardar los valores de los


parámetros description, expectedPrecision, expectedRecall y
learningRate.

Diseño y Programación Orientados a Objetos pág. 14


●​ getDescription, getExpectedPrecision, getExpectedRecall y
getLearningRate: cuando son invocados utilizando un valor del enum,
devuelven su valor de description, expectedPrecision,
expectedRecall y learningRate, respectivamente.

●​ getExpectedF1Score: este método debe devolver el valor F1-Score


esperado para un tipo de algoritmo. Para ello, debe calcular la siguiente
fórmula:
𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 · 𝑟𝑒𝑐𝑎𝑙𝑙
𝐹1 − 𝑆𝑐𝑜𝑟𝑒 = 2 · 𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 + 𝑟𝑒𝑐𝑎𝑙𝑙

●​ getType: este método recibe un String que representa la descripción de un


tipo y devuelve cuál de los valores de la enumeración corresponde con esa
descripción. Es decir, devuelve el AlgorithmType correspondiente, o null
si el valor de la codificación pasado como argumento no corresponde con
ningún valor del enum.​

●​ getNextBetterLearningRate: este método devuelve el valor del enum


AlgorithmType con el siguiente tipo de algoritmo con una mejor tasa de
aprendizaje (learningRate). En este contexto, mejor significa que tiene una
tasa de aprendizaje más pequeña, ya que en algoritmos como las redes
neuronales o el Q-Learning, tener un valor learningRate más bajo suele
indicar mayor precisión y estabilidad en el entrenamiento, aunque este sea
más lento. En caso de que el algoritmo ya sea el mejor posible, se debe
devolver a sí mismo (this). Puedes seguir el siguiente criterio:

LINEAR_REGRESSION → Q_LEARNING
Q_LEARNING → NEURAL_NETWORK
NEURAL_NETWORK → NEURAL_NETWORK

Pista: fíjate en el orden de los literales de la enumeración para poder


implementar de manera eficiente el método getNextBetterLearningRate
e investiga sobre los métodos que tiene toda enum en Java.

(1.25 puntos: 0.5 puntos testDescription, testExpectedPrecision,


testExpectedRecall, testLearningRate, testExpectedF1Score; 0.35 puntos
testGetType; 0.4 puntos testGetNextBetterLearningRate)

Clase Model
Debes adaptar esta clase para que cumpla con las especificaciones que encontrarás
en el UML. Para facilitarte la lectura del UML, te enumeramos los cambios realizados a
la clase Model:

Diseño y Programación Orientados a Objetos pág. 15


●​ Se ha modificado el constructor añadiendo un nuevo parámetro.
●​ Se ha añadido un nuevo atributo llamado INVALID_ALGORITHM_TYPE.
●​ Se han añadido dos métodos nuevos llamados getAlgorithmType y
setAlgorithmType. El método setAlgorithmType debe verificar que el
parámetro algorithmType no sea null, si lo es, lanzará una excepción del
tipo IllegalArgumentException con el mensaje
INVALID_ALGORITHM_TYPE.

●​ Considera hacer cualquier modificación más en función de las necesidades


relacionadas con la enumeración.
(0.25 puntos: testAlgorithmType)

Requisito mínimo para evaluar este ejercicio: se deben superar todos los
tests de tipo Sanity, así como el test testAlgorithmType de la clase Model y
los tests testDescription, testExpectedPrecision,
testExpectedRecall, testLearningRate y testExpectedF1Score de
la clase AlgorithmType.

Nota: el estudiante puede recibir una penalización de hasta 0,5 puntos de la


nota obtenida en este ejercicio en función de la calidad del código
proporcionado.

Diseño y Programación Orientados a Objetos pág. 16


Ejercicio 4 (1.5 puntos)
Abre el proyecto PAC3Ex4 de IntelliJ. En el package [Link].pac3 del
directorio/src/test/java está el archivo con los tests unitarios que te
proporcionamos. En el directorio/src/main/java te proporcionamos la clase
RickAndMortyApiClient, donde deberás implementar dos métodos: uno que se
encargue de llamar a la API de Rick and Morty y otro que se encargue de procesar los
datos recibidos.

Para lograrlo, vamos a utilizar una API REST (Application Programming Interface), que
es un servicio web que permite que diferentes aplicaciones se comuniquen entre sí
usando Internet. En el desarrollo con Java, las APIs son muy útiles para obtener datos
externos en tiempo real, como por ejemplo: el tiempo de una ciudad, el precio de
criptomonedas, información sobre películas o, en este caso, personajes de una serie.

Cuando haces una petición HTTP a una API, esta responde normalmente con datos
en formato JSON, que es un formato ligero, fácil de leer y procesar, tanto por humanos
como por programas. En este ejercicio trabajaremos con la API pública de Rick and
Morty. Esta API permite acceder a información sobre los personajes, episodios y
localizaciones de la serie. Por ejemplo, puedes probar en tu navegador la siguiente
URL para ver el contenido en formato JSON de los 20 primeros personajes:
[Link]

Nota: puedes encontrar toda la información sobre esta API en su


documentación oficial:
[Link]

Para poder trabajar con el formato JSON en Java de forma sencilla, debes añadir esta
dependencia al archivo [Link] de tu proyecto dentro de dependencies:

implementation '[Link]:json:20250107'

Una vez añadida, recarga el proyecto para que IntelliJ descargue automáticamente la
biblioteca.

Nota: encontrarás toda la información sobre la descarga de esta biblioteca


en el siguiente enlace:
[Link]

Para codificar cada uno de los métodos, deberás seguir las siguientes instrucciones:

●​ fetchCharactersJsonByPage: este método debe realizar una petición


HTTP de tipo GET a la URL definida en el atributo BASE_URL añadiendo el

Diseño y Programación Orientados a Objetos pág. 17


parámetro page junto a un valor entero que represente la página. Es decir, la
URL debe tener el siguiente formato:

[Link]
donde X es el número de la página recibido como parámetro

Una vez obtenida la respuesta, debe leer el contenido y devolverlo como una
cadena de texto (String).

Pista: para construir la URL y gestionar la conexión HTTP, puedes utilizar


las clases URI, URL, HttpURLConnection e InputStream, todas del
JDK estándar. Puedes consultar un ejemplo de uso de estas clases en el
siguiente enlace: [Link]

Ten en cuenta que este método no puede lanzar ninguna excepción, por lo que
debes controlar todas las posibles excepciones que lancen alguna de estas
clases dentro del mismo método con un bloque try-catch.

En caso de que el código HTTP recibido no sea 200 (petición satisfactoria), el


método debe devolver null.
(1 punto)

●​ getCharacterNamesByPage: este método debe llamar al anterior para


obtener el contenido JSON como String. Luego, debe convertir esa cadena
en un objeto JSON, acceder al array llamado "results" y extraer el valor del
campo "name" de cada personaje, devolviendo finalmente un array de cadenas
(nombres de personajes).

Pista: para manipular JSON en Java puedes usar las clases JSONObject
y JSONArray, que se incluyen en la biblioteca [Link].

(0.5 puntos)

Requisito mínimo para evaluar este ejercicio: debe superarse el test del
método fetchCharactersJsonByPage.

Nota: el estudiante puede recibir una penalización de hasta 0,5 puntos de


la nota obtenida en este ejercicio en función de la calidad del código
desarrollado.

Diseño y Programación Orientados a Objetos pág. 18


Formato y fecha de entrega
Tienes que entregar un archivo *.zip, cuyo nombre debe seguir este patrón:
loginUOC_PEC3.zip. Por ejemplo: dgarciaso_PEC3.zip. Este archivo
comprimido debe incluir los siguientes elementos:

●​ El proyecto IntelliJ PAC3Ex1 completado siguiendo las peticiones y


especificaciones del Ejercicio 1.

●​ El proyecto IntelliJ PAC3Ex2 completado siguiendo las peticiones y


especificaciones del Ejercicio 2.

●​ El proyecto IntelliJ PAC3Ex3 completado siguiendo las peticiones y


especificaciones del Ejercicio 3.

●​ El proyecto IntelliJ PAC3Ex4 completado siguiendo las peticiones y


especificaciones del Ejercicio 4.

El último día para entregar esta PEC es el día 28/04/2025 antes de las 23:59.
Cualquier PEC entregada más tarde será considerada como no presentada.

Diseño y Programación Orientados a Objetos pág. 19

También podría gustarte