0% encontró este documento útil (0 votos)
14 vistas14 páginas

Entrega Práctica Programación 20232

Este documento describe una práctica de programación que consiste en crear una aplicación y una biblioteca. La aplicación utilizará los métodos de la biblioteca, la cual encapsulará todas las funcionalidades del proyecto. El documento explica los objetivos de la práctica, el formato de entrega, los criterios de corrección y el enunciado del primer ejercicio sobre la preparación del entorno de desarrollo.
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)
14 vistas14 páginas

Entrega Práctica Programación 20232

Este documento describe una práctica de programación que consiste en crear una aplicación y una biblioteca. La aplicación utilizará los métodos de la biblioteca, la cual encapsulará todas las funcionalidades del proyecto. El documento explica los objetivos de la práctica, el formato de entrega, los criterios de corrección y el enunciado del primer ejercicio sobre la preparación del entorno de desarrollo.
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

Prácticas de Programación

PR1 - 20232
Fecha límite de entrega: 15 / 04 / 2024

Formato y fecha de entrega

La práctica debe entregarse antes del día 15 de abril de 2024 a las 23:59.
Es necesario entregar un fichero en formato ZIP, que contenga una carpeta
UOC20232 con el directorio principal de vuestro proyecto, siguiendo la estructura de
carpetas y nombres de ficheros especificados en el enunciado de la práctica. No
debe contener ningún fichero ZIP en su interior. Esta carpeta debe contener:
● Un fichero [Link] con el siguiente formato (ver ejemplo):
Formato:
Correo electrónico UOC
Apellidos, Nombre
Sistema operativo utilizado

Ejemplo:
estudiante1@[Link]
Apellido1 Apellido2, Nombre
Windows 10

● Los ficheros de prueba sin modificaciones.


● Los ficheros *.c y *.h resultantes de los ejercicios realizados.
● Todos los ficheros deben estar dentro de las carpetas correctas (src,
test, …).
● Si se ha utilizado el entorno CodeLite: los ficheros .workspace
y .project que definen el espacio de trabajo y los proyectos de
Codelite.

La entrega debe realizarse en el apartado de entregas de EC del aula de teoría


antes de la fecha límite de la entrega. Únicamente el último envío dentro del
período establecido será evaluado.

El incumplimiento del formato de entrega especificado anteriormente puede suponer


un suspenso de la práctica.

Práctica 1 – Prácticas de programación 20232 pág. 1


Objetivos

● Saber interpretar y seguir el código de terceras personas.


● Saber compilar proyectos de código organizados en carpetas y librerías.
● Saber implementar un proyecto de código a partir de su especificación.

Criterios de corrección:

Cada ejercicio tiene asociada su puntuación sobre el total de la actividad. Se


valorará tanto que las respuestas sean correctas como que también sean
completas.
● No seguir el formato de entrega, tanto por lo que se refiere al tipo y nombre
de los ficheros como al contenido solicitado, comportará una penalización
importante o la cualificación con una D de la actividad.
● El código entregado debe compilar para ser evaluado. Si compila, se
valorará:
○ Que funcionen tal como se describe en el enunciado.
○ Que obtenga el resultado esperado dadas unas condiciones y datos
de entrada diseñadas (pruebas proporcionadas). No es nece s a r i o
pasar todos los tests pero por lo menos debe mostrarse el resultado de
estos por pantalla.
○ Que se respeten los criterios de estilo y que el código esté
debidamente comentado. Se valorará especialmente el uso de
comentarios en inglés.
○ Que las estructuras utilizadas sean las correctas.
○ Que se separe correctamente la declaración e implementación de
las acciones y funciones, utilizando los ficheros correctos.
○ El grado de optimización en tiempo y recursos utilizados en la
solución entregada.
○ Que se realice una gestión de memoria adecuada, liberando la
memoria cuando sea necesario.

Práctica 1 – Prácticas de programación 20232 pág. 2


Aviso

Aprovechamos para recordar que está totalmente prohibido copiar en las PECs y
prácticas de la asignatura. Se entiende que puede haber un trabajo o comunicación
entre los estudiantes durante la realización de la actividad, pero la entrega de esta
debe que ser individual y diferenciada del resto. Las entregas serán analizadas con
herramientas de detección de plagio.
Así pues, las entregas que contengan alguna parte idéntica respecto a entregas de
otros estudiantes serán consideradas copias y todos los implicados (sin que sea
relevante el vínculo existente entre ellos) suspenderán la actividad entregada.

Guía citación: [Link]


Monográfico sobre plagio:
[Link]

Observaciones

En este documento se utilizan los siguientes símbolos para hacer referencia a los
bloques de diseño y programación:

Indica que el código mostrado es en lenguaje algorítmico.

Indica que el código mostrado es en lenguaje C.

Muestra la ejecución de un programa en lenguaje C.

Práctica 1 – Prácticas de programación 20232 pág. 3


Análisis dinámico
En esta actividad se utiliza memoria dinámica, que requiere que el programador
reserve, inicialice y libere la memoria. Para ayudar a detectar memoria que no se ha
liberado correctamente, o errores en las operaciones con punteros relacionadas,
hay herramientas que ejecutan un análisis dinámico del programa. Una herramienta
de código abierto muy empleada es Valgrind ([Link] La utilización de
esta herramienta queda fuera del ámbito del curso.

Para entender el significado de los códigos de error, podéis consultar el siguiente


enlace, donde encontraréis ejemplos de código que os ayudarán a entender cuando
se dan estos errores:

[Link]

DSLab
En esta práctica, como novedad, se introduce el uso de la herramienta DSLab
([Link] Esta herramienta se usa también en otras asignaturas y
tiene como principal objetivo:

● Facilitar un entorno común para la evaluación de los ejercicios de


codificación.
● Facilitar el uso de herramientas de análisis del uso y la gestión de la memoria
(valgrind)

.Os aconsejamos realizar envíos periódicos a la herramienta de los diferentes


ejercicios de código, ya que os permitirá detectar posibles errores antes de la
entrega final. Tened presente que es la herramienta utilizada como base para
corregir vuestros códigos, y que no se corregirá ningún código en otro
entorno o máquina. Así pues, si vuestro código no funciona en la herramienta
DSLab, se considerará que no funciona, aunque lo haga en vuestro ordenador.

En todo caso, hay que tener presente que las entregas finales deben seguir
haciéndose en el apartado correspondiente del aula, tal como indica el
enunciado. Esta herramienta es una ayuda adicional que ponemos a vuestra
disposición, y en ningún caso es obligatorio su utilización.

La información básica que os será de utilidad al utilizar DSLab:

● DSLab considera la entrega correcta únicamente si esta pasa todos los tests.

Práctica 1 – Prácticas de programación 20232 pág. 4


● Se muestra un resumen rápido del número de tests pasados. Por norma
general no será necesario pasarlos todos para aprobar la entrega.
● En los detalles se muestra:
○ El detalle de los tests pasados y de los que han fallado.
○ Es posible descargar un fichero con el texto que el programa muestra
por pantalla (salida estándar). Se ha incluido el uso de valgrind en la
salida estándar de manera que en este apartado podréis ver el informe
sobre la gestión de la memoria. Es recomendable revisar esta parte
para asegurarse de que se hace un uso correcto de los punteros y de
la memoria.
● Existe también un log de ejecución que guarda la evolución de la ejecución
del programa. Si debido a una codificación incorrecta el programa falla y no
es capaz de mostrar el resultado de los tests, se debe revisar este log para
determinar en qué punto se interrumpió la ejecución.

Nota: aunque DSLab es un sistema robusto y utilizado en varias asignaturas de la


UOC, para esta asignatura en concreto está en fase de pruebas. Si encontráis algún
problema indicadlo a los profesores para que podamos corregir cualquier incidencia.

Práctica 1 – Prácticas de programación 20232 pág. 5


Enunciado

En las PECs hemos trabajado de forma aislada partes del problema introducido en
la PEC1. En las prácticas veremos cómo construir una aplicación más compleja que
vaya incorporando de forma incremental lo que se va trabajando en las PECs.

Es habitual que las aplicaciones definan una API (Application Programming


Interface) o interfaz de programación de aplicaciones. Básicamente se trata de una
abstracción de nuestra aplicación, en la cual definimos los métodos y los datos, y
permitimos que otras aplicaciones puedan interactuar con nuestra aplicación sin
necesidad de saber cómo se han implementado estos métodos.

Además, encapsularemos todas las funcionalidades en una librería, que podrá ser
utilizada por cualquier programa. En la siguiente figura se muestra la estructura de
la práctica, en que tendremos una aplicación (ejecutable) que utilizará los métodos
(acciones y funciones) de la API, implementada en una librería.

A nivel de código, lo que tendremos será un espacio de trabajo (Workspace) con


dos proyectos:
● Aplicación: Será un proyecto igual al que utilizamos en las PECs, creado
como un ejecutable simple.
● Librería: Será un proyecto de tipo “Static library”. En este caso, el resultado
de la complicación y entrelazado no produce un ejecutable, sino un fichero .a
o .lib dependiendo del sistema operativo. Este fichero se puede utilizar desde
otra librería o desde una aplicación. A diferencia de las aplicaciones, las
librerías no implementan el método main.

Práctica 1 – Prácticas de programación 20232 pág. 6


Ejercicio 1: Preparación del entorno [0%]

Junto con el enunciado se facilita un fichero de código con un espacio de trabajo


(Workspace) que contiene dos proyectos. A continuación se detallan las principales
características de cada uno de ellos:
● UOCVineyard: Este proyecto corresponde a la librería donde iremos
añadiendo toda la funcionalidad de la práctica.
○ El código se divide en declaraciones (include) e implementaciones
(src).
○ Los ficheros api.h y api.c contienen la declaración de la API, y por lo
tanto, los métodos que se accederán desde la aplicación.
○ Cuando se compila, debe ir a buscar los ficheros de cabecera en la
carpeta include.
○ La librería se debe generar en la carpeta “lib” del Workspace.
○ El nombre de la librería añadirá una “d” cuando se compile en modo
Debug.

● UOC20232: Este proyecto es nuestra aplicación. Se encarga de ejecutar las


diferentes pruebas para verificar el correcto funcionamiento de la librería.
○ El código principal está en la carpeta src, y el código de las pruebas en
la carpeta test, separando las declaraciones (include) y la
implementación (src).
○ Cuando se compila, debe ir a buscar los ficheros de cabecera (*.h)
tanto en la carpeta de las pruebas (test/include) como en la carpeta
correspondiente de la librería (UOCVineyard/include).
○ Cuando se hace el entrelazado (link), se debe indicar que vaya a
buscar las librerías en el directorio lib del Workspace, y que incluya la
librería generada por el proyecto anterior.

El objetivo de este ejercicio es tener el entorno proporcionado funcionando. El


workspace está preparado para funcionar en la máquina virtual de la asignatura. En
caso de no usarla será necesario modificar las opciones de los proyectos para que
funcione.

Si se utiliza un entorno de programación distinto a CodeLite se debe realizar el


mismo ejercicio pero adaptándolo al entorno utilizado. Es muy importante organizar
correctamente el código y este es uno de los objetivos que se debe alcanzar al
finalizar esta práctica.

A continuación se muestra una guía de las opciones (settings) de los proyectos en


donde se definen las características anteriores. Recordad que para acceder a las

Práctica 1 – Prácticas de programación 20232 pág. 7


opciones del proyecto lo podéis hacer a través del menú contextual (botón derecho)
y la opción Settings.

1 1

2 4
3

Localización de las opciones de configuración

1. Permite cambiar entre la configuración de Debug y Release.


2. Define dónde se generan los ficheros resultantes
3. Define qué se ejecuta cuando se utiliza el botón de play de Codelite ( ). Se
debe indicar el directorio de trabajo y el nombre de la aplicación, que será
distinta en Debug y en Release.
4. Define en qué directorios se van a buscar los ficheros de cabecera.
5. Define en qué directorios se va a buscar las librerías y qué librerías se deben
añadir para generar la aplicación.

Cuando se hayan seleccionado las opciones correctas, al ejecutar debéis ver el


resultado de las pruebas. Inicialmente, todas, excepto la del ejercicio 1 aparecen
como fallidas. También os saldrá que el nombre y el correo electrónico no se ha
proporcionado (izquierda). Introducid los datos en el fichero [Link] del
Workspace tal como se indica en el apartado de entrega, y se deberían incorporar.

Práctica 1 – Prácticas de programación 20232 pág. 8


Ejemplo de posible salida del programa

Ejercicio 2: Entrada de datos [60%]

Hasta ahora hemos estado trabajando solamente con los datos de los viticultores
tWinegrowerData. Para facilitar la interacción con la API, queremos agrupar todos
los datos con los que trabajamos en una única estructura de datos (tApiData). Esta
estructura debe guardar los siguientes datos:

● people: Conjunto de personas dadas de alta en el sistema. Cada persona


está identificada de forma única a partir de su documento de identidad. Los
datos de una persona se guardan en un tipo tPerson. El conjunto de
personas se guardan en una tabla (tPeople).

● winegrowers: Lista de viticultores del sistema. Guarda la información de


todos los viticultores con su documento, su identificador de viticultor, la fecha
de alta en el registro y la lista de sus viñedos (tVineyardplotData). Cada
viticultor se identifica de forma única según su id. Los datos de cada
viticultores se guardan en una estructura de tipo tWinegrower. La lista de
viticultores se guarda ordenada por nombre en una lista encadenada
(tWinegrowerList).

A partir de esta práctica se guarda una tabla de viñedos asociada a cada viticultor.
Esto implica que se elimina la restricción de que cada viticultor tenga una única
parcela, pudiendo tener varias. Las parcelas quedan ahora definidas de la siguiente
manera:

● vineyardplots: Esta estructura almacena las parcelas de viñedos. Los datos


de cada parcela se guardan en una estructura de tipo tVineyardplot que
contiene el código de parcela, la DO asociada y la producción estimada. Las
parcelas se guardan en una tabla (tVineyardplotData) y cada viticultor tiene
su propia tabla según las parcelas que disponga.

Nota: Las parcelas se asocian a un viticultor. No existe una lista global de todas las
parcelas del sistema.

Práctica 1 – Prácticas de programación 20232 pág. 9


Como parte del enunciado de la práctica se proporcionan los archivos:

● api.h/api.c con la declaración e implementación de los tipos de datos y


métodos de la API.
● error.h con la declaración de los tipos de error que devolverá la API.
● csv.h/csv.c con la declaración e implementación de los tipos de datos y
métodos relacionados con la gestión de datos en formato CSV.
● date.h/date.c con la declaración e implementación de los tipos de datos y
métodos relacionados con la manipulación de fechas.
● person.h/person.c con la declaración e implementación de los tipos de datos
y métodos relacionados con la gestión de personas.
● winegrower.h/winegrower.c con la declaración e implementación de los
tipos de datos y métodos relacionados con los viticultores.
● vineyardplot.h/vineyardplot.c con la declaración e implementación de los
tipos de datos y métodos relacionados con las parcelas de viñedos.

Estos datos se consultarán y manipularán a través de los métodos de la API


(definidos en el fichero api.h), los cuales retornarán generalmente un valor de tipo
tApiError que indicará si se ha producido algún error o si la acción se ha ejecutado
correctamente. Encontraréis los códigos de error definidos en el fichero error.h de la
librería.

A continuación se detallan algunos de los posibles errores:

E_SUCCESS Operación ejecutada correctamente


E_NOT_IMPLEMENTED La funcionalidad aún no está implementada
E_INVALID_ENTRY_TYPE El tipo de dato es incorrecto
E_INVALID_ENTRY_FORMAT El formato del dato no es correcto
E_INVALID_VINEYARD_CODE El formato del código de la parcela no es válido
E_WINEGROWER_NOT_FOUND No se ha encontrado el id del viticultor
E_DUPLICATED_VINEYARD La parcela ya existe en la lista del viticultor
E_DUPLICATED_PERSON Se está intentando añadir una persona que ya
está registrada

Por norma general las funciones devuelven inicialmente el valor


E_NOT_IMPLEMENTED. Una vez implementadas devuelven el valor E_SUCCESS
si todo ha funcionado correctamente. En caso contrario devuelven un código de
error asociado al tipo de error producido.

Práctica 1 – Prácticas de programación 20232 pág. 10


Se pide:

a) Completa la definición del tipo de datos tApiData del fichero api.h para que
se guarden todos los datos especificados.

b) Implementa la función api_initData del fichero api.c que inicializa una


estructura de tipo tApiData dada. La función devuelve un valor de tipo tError.

c) Implementa la función apiWinegrower_find del fichero api.c para que dada


una estructura de tipo tApiData y un id de un viticultor, si lo encuentra
devuelve un puntero de tipo tWinegrower del viticultor encontrado, o en caso
de no encontrarlo NULL.

d) Implementa la función api_addWinegrower del fichero api.c para que dada


una estructura de tipo tApiData y un viticultor junto a una parcela de viñedos
en formato csv tCSVEntry, añada este viticultor y su parcela en los datos de
la aplicación. Si el viticultor ya existe se añadirá el viñedo a su lista de
parcelas. Si la parcela ya existe, la función no añadirá nada y se considerará
la ejecución como E_SUCCESS. Se debe tener en cuenta:

● El formato correcto de la parcela son 13 carácteres:


DO-YYYY-NNNNN
○ DD: dos carácteres en mayúsculas que corresponden a la
Denominación de Origen
○ YYYY: Cuatro dígitos que corresponden al año de registro de
la parcela.
○ NNNNN: Cinco dígitos que identifican a la parcela

Para cada dato se deberá comprobar que el formato sea correcto (asumimos
que es correcto si el número de campos es el esperado, error asociado
E_INVALID_ENTRY_FORMAT), y que su tipo es “WINEGROWER” (podéis
acceder al tipo mediante el método csv_getType, error asociado
E_INVALID_ENTRY_TYPE).

Nota: En los archivos winegrower.h y winegrower.c encontraréis una nueva


definición de winegrower_parse que devuelve la información del viticultor en
una estructura de tipo tWinegrower y la parcela en una estructura
tVineyardplot . También encontraréis los métodos para gestionar la lista de
viticultores tWinegrowerList. También tenéis los métodos winegrower_free
y vineyardplot_free (este último en vineyardplot.h y vineyardplot.c) para
eliminar la memoria dinámica reservada para guardar los datos de viticultores
y parcelas.

Práctica 1 – Prácticas de programación 20232 pág. 11


e) Implementa la función api_addVineyardplot del fichero api.c para que dada
una estructura de tipo tApiData y una parcela de viñedos en formato csv
tCSVEntry añada esta parcela al viticultor en los datos de la aplicación. Si el
viticultor no existe la función devolverá el error
E_WINEGROWER_NOT_FOUND y si la parcela ya existe se devolverà
E_DUPLICATED_VINEYARD.

De manera análoga a la función anterior para cada dato se deberá comprobar


que el formato sea correcto y que su tipo es “VINEYARD_PLOT”. Además se
comprobará que el código de la parcela tiene un formato correcto (error
esperado E_INVALID_VINEYARD_CODE)

f) Implementa los métodos api_peopleCount, api_winegrowersCount y


api_vineyardplotCount que dada una estructura de datos de tipo tApiData
devuelven el número de personas, viticultores y parcelas respectivamente. En
el caso de las parcelas, se tendrán en cuenta el total de todos los viticultores.

g) Implementa la función api_freeData del archivo api.c que elimina toda la


información guardada en una estructura de tipo tApiData dada.

h) Implementa la función api_addDataEntry del fichero api.c que dada una


estructura de tipo tApiData y un nuevo dato en formato csv tCSVEntry
guarda este nuevo dato dentro de la estructura tApiData. Una entrada de
datos puede ser de tipo “PERSON”, “WINEGROWER” o “VINEYARD_PLOT”.
Para cada dato será necesario comprobar que el formato sea correcto
(asumimos que es correcto si el número de campos es el esperado). Los
valores de retorno de esta función son: E_SUCCESS,
E _ N O T _ I M P L E M E N T E D , E _ I N VA L I D _ E N T RY _ T Y P E ,
E _ I N V A L I D _ E N T R Y _ F O R M A T, E _ D U P L I C A T E D _ P E R S O N ,
E_INVALID_VINEYARD_CODE, E_WINEGROWER_NOT_FOUND o
E_DUPLICATED_VINEYARD.

Importante: para realizar esta práctica es necesario aplicar el diseño descendente.


De esta manera es posible simplificar la solución de los ejercicios y se evita repetir
código, es decir, no será necesario implementar dos o más veces la misma
funcionalidad.

Práctica 1 – Prácticas de programación 20232 pág. 12


Ejercicio 3: Acceso a los datos [40%]

Con la finalidad de no exponer los tipos de datos internos de la API, se ha decidido


que todos los intercambios de datos a través de la API se realizarán utilizando CSV.
Recordad que cada entrada de un fichero CSV corresponde a un dato (fila, objeto,
…), y que por lo tanto el fichero es un conjunto de datos. Utilizaremos el tipo
tCSVData para intercambiar múltiples datos (por ejemplo listados), y el tipo
tCSVEntry para objetos únicos.

Se pide:

a) Implementa la función api_getWinegrower del fichero api.c que dada una


estructura de tipo tApiData y el nombre de un viticultor, guarde los datos del
viticultor en una estructura de tipo tCSVEntry. El formato del viticultor será:

“winegrowerId;document;registrationDate”

El tipo de registro contendrá el valor “WINEGROWER”. Los valores de


retorno de esta función son: E_SUCCESS, E_NOT_IMPLEMENTED y
E_WINEGROWER_NOT_FOUND.

b) Implementa la función api_getVineyardplot del fichero api.c que dada una


estructura de tipo tApiData y los datos de una parcela, guarde la información
de esa parcela en una estructura de tipo tCSVEntry. El formato será:

“vineyardplotId;DOcode;DOname;weight”

El tipo de registro contendrá el valor “VINEYARD_PLOT”. Los valores de


retorno de esta función son: E_SUCCESS, E_NOT_IMPLEMENTED,
E_VINEYARD_NOT_FOUND y E_INVALID_VINEYARD_CODE.

c) Implementa la función api_getWinegrowers del fichero api.c que dada una


estructura de tipo tApiData guarde los datos de todos los viticultores
registrados en una estructura de tipo tCSVData. Cada viticultor estará
guardada en una estructura de tipo tCSVEntry en el formato:

“winegrowerId;document;registrationDate”

El tipo de registro contendrá el valor “WINEGROWER”. Los valores de


retorno de esta función son: E_SUCCESS y E_NOT_IMPLEMENTED.

Práctica 1 – Prácticas de programación 20232 pág. 13


d) Implementa la función api_getVineyardplots del fichero api.c que dada una
estructura de tipo tApiData guarde los datos de todas las parcelas en una
estructura de tipo tCSVData. Cada parcela estará guardada en una
estructura de tipo tCSVEntry en el formato:

“vineyardplotId;DOcode;DOname;weight”

El tipo de registro contendrá el valor “VINEYARD_PLOT”. Los valores de


retorno de esta función son: E_SUCCESS y E_NOT_IMPLEMENTED.

Nota: Podéis asumir que un string en formato csv nunca superará los 2048
caracteres (2Kb) de longitud. Os pueden resultar de ayuda para realizar este
ejercicio los siguientes métodos:

csv_init / csv_free Inicializa / libera una estructura de tipo tCSVData


csv_parseEntry Rellena una estructura de tipo tCSVEntry con la información
contenida en un string en formato csv.
csv_addStrEntry Añade a una estructura de tipo tCSVData una nueva
entrada (tCSVEntry) a partir de un string en formato csv.
sprintf Método similar a printf, pero que en lugar de mostrar una
información formateada por pantalla, la guarda en un string.

Práctica 1 – Prácticas de programación 20232 pág. 14

También podría gustarte