From 290b0d649e1071ad648eb288a82aed6b64880ce6 Mon Sep 17 00:00:00 2001 From: sengpielto Date: Thu, 5 Nov 2026 15:16:10 +0100 Subject: [PATCH 1/2] implemented header check --- Startcode/imageInput.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/Startcode/imageInput.c b/Startcode/imageInput.c index bb30de1..bc2cfa2 100644 --- a/Startcode/imageInput.c +++ b/Startcode/imageInput.c @@ -8,15 +8,93 @@ // TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei +static GrayScaleImage *readIndividualImage(unsigned int width, unsigned int height, FILE *file){ + + char *buf = calloc(width * height, sizeof(char)); + if(!buf){ + fprintf(stderr, "calloc failed!\n"); + return NULL; + } + if(fread(buf, sizeof(char), width * height,file) != (width* height)){ + fprintf(stderr, "imageline not in the rigth format!\n"); + free(buf); + return NULL; + } + + GrayScaleImage *gimage = calloc(sizeof(GrayScaleImage, 1)); + if(gimage == NULL){ + fprintf(stderr, "calloc failed!\n"); + free(buf); + return NULL; + } + + gimage->buffer = buf; + gimage->width = width; + gimage->height = height; + + return gimage; +} + // TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen GrayScaleImageSeries *readImages(const char *path) { GrayScaleImageSeries *series = NULL; + series = calloc(1, sizeof(GrayScaleImageSeries)); + if(series == NULL){ + fprintf(stderr, "Couldn't allocate enough space!\n"); + return NULL; + } + + FILE *file = fopen(path, "rb"); + if(file == NULL){ + fprintf(stderr, "%s could not be opened!\n", path); + clearSeries(series); + return NULL; + } + + //Schaue ob die erste Zeile der richtige Header ist. + char buffer[32]; + size_t bytes = fread(buffer, sizeof(char), strlen(FILE_HEADER_STRING), file); + if(!strncmp(buffer, FILE_HEADER_STRING, strlen(FILE_HEADER_STRING))){ + fprintf(stderr, "__info2_image_file_format__ not found!\n"); + clearSeries(series); + return NULL; + } + + if(bytes = fread(buffer, sizeof(short), 3, file) != (3*szieof(short))){ + fprintf(stderr, "Couldn't read number of images/sizes of Images!\n"); + clearSeries(series); + return NULL; + } + + series->count = (short)buffer[0]; + unsigned int width = (short)buffer[1]; + unsigned int height = (short)buffer[2]; + + series->labels = calloc(count, sizeof(char)); + if(series->labels == NULL){ + fprintf(stderr, "calloc failed!\n"); + clearSeries(series); + return NULL; + } + + for (int i = 0; i < count; i++){ + if(series->images[i] = readIndividualImage(width, heigth, file) == NULL){ + clearSeries(series); + return NULL; + } + fread(series->labels[i], sizeof(char), 1, file); + } + return series; } // TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt void clearSeries(GrayScaleImageSeries *series) { + for(int i = 0; i < series->count; i++){ + free(series->GrayScaleImage[i]); + } + free(series); } \ No newline at end of file From e982aaf440f725872d570ef1d8067c21e6bf6a95 Mon Sep 17 00:00:00 2001 From: ScheuerleinNico Date: Thu, 5 Nov 2026 15:25:22 +0100 Subject: [PATCH 2/2] Ich habe die neuralNetworkTests.c implementiert. Scheint zu funkionieren, aber Fehler in der matrix.h. --- Startcode/neuralNetworkTests.c | 87 +++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/Startcode/neuralNetworkTests.c b/Startcode/neuralNetworkTests.c index 21ab370..e4da80f 100644 --- a/Startcode/neuralNetworkTests.c +++ b/Startcode/neuralNetworkTests.c @@ -4,13 +4,55 @@ #include #include "unity.h" #include "neuralNetwork.h" - - -static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn) +/* + --------------------------------------------------------------------------------------------------------- +*/ +// TODO Nico +static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn) //Exklusive Funktion ohne Rückgabewert mit Übergabewerten "path" für den Dateinamen und "nn" für das neuronale Netz dessen Daten abgespeichert werden soll { - // TODO -} + /*---Datei zum Schreiben im Binärmodus öffnen---*/ + FILE *file = fopen(path, "wb"); //Öffnet die Datei "path" als write Binary + if(file == NULL) //Wenn Datei nicht geöffnet werden kann, bringe einen Fehler und breche das Programm ab + { + return; + } + /*---Indifikationstag an den Anfang schreiben---*/ + const char *fileTag = "info2_neural_network_file_format"; //Der Text der laut Angabe am Anfang der Datei stehen muss + fwrite(fileTag, sizeof(char), strlen(fileTag), file); //Schreibbefehl mit Parametern (Vorgegebener Text soll geschrieben werden (Adresse), Größe eines Buchstaben, Länge des Textes, Zielort "file") + + /*---Anzahl der Layer speichern---*/ + fwrite(&nn.numberOfLayers, sizeof(int), 1, file); //Schreibbefehl mit Parametern (Die Adresse von "nn.numberOfLayers" soll geschrieben werden, eine ganze Zahl als "int" wird abgespeichert, es wird genau eine solche Zahl geschrieben, Zielort "file") + + /*---Schleife für jeden Layer um Gewichte und Bias zu speichern---*/ + for(int i = 0; i < nn.numberOfLayers; i++) //Schleife von 0 bis Anzahl der Layer + { + Layer layer = nn.layers[i]; //Benutzt aktuellen Layer mit Nummer "i" und benutzt Hilfsvariable "layer" + + /*---Weights speichern---*/ + fwrite(&layer.weights.rows, sizeof(int), 1, file); //Schreibbefehl mit Parametern mit (Anzahl Zeilen Weights (Adresse), eine ganze Zahl als "int" abspeichern, es wird genau eine solche Zahl gespeichert, Zielort "file") --> Speichert ab, wie viele Zeilen Gewichts-Tabelle hat + fwrite(&layer.weights.cols, sizeof(int), 1, file); //Schreibbefehl mit Parametern mit (Anzahl Spalten Weights (Adresse), eine ganze Zahl als "int" abspeichern, es wird genau eine solche Zahl gespeichert, Zielort "file") --> Speichert ab, wie viele Spalten Gewichts-Tabelle hat + + int weightCount = layer.weights.rows * layer.weights.cols; //Berechnet die Gesamtzahl der Zahlen in der Weight Tabelle + + fwrite(layer.weights.buffer, sizeof(MatrixType), weightCount, file); //Schreibbefehl mit Parametern mit (Weight Buffer (Adresse), eine ganze Zahl in "MatrixType" abspeichern, es wird der zuvor berechnete Wert gespeichert, Zielort "file") --> Speichert alle eigentlichen Zahlenwerte der Weights auf einmal in die Datei. Buffer ist bereits intern ein Zeiger, deswegen kein "&" + + + /*---Bias speichern---*/ + fwrite(&layer.biases.rows, sizeof(int), 1, file); //Schreibbefehl mit Parametern mit (Anzahl Zeilen Bias (Adresse), eine ganze Zahl als "int" abspeichern, es wird genau eine solche Zahl gespeichert, Zielort "file") --> Speichert ab, wie viele Zeilen Bias-Tabelle hat + fwrite(&layer.biases.cols, sizeof(int), 1, file); //Schreibbefehl mit Parametern mit (Anzahl Spalten Bias (Adresse), eine ganze Zahl als "int" abspeichern, es wird genau eine solche Zahl gespeichert, Zielort "file") --> Speichert ab, wie viele Spalten Bias-Tabelle hat + + int biasCount = layer.biases.rows * layer.biases.cols; //Berechnet die Gesamtzahl der Zahlen in der Bias Tabelle + + fwrite(layer.biases.buffer, sizeof(MatrixType), biasCount, file); //Schreibbefehl mit Parametern mit (Bias Buffer (Adresse), eine ganze Zahl in "MatrixType" abspeichern, es wird der zuvor berechnete Wert gespeichert, Zielort "file") --> Speichert alle eigentlichen Zahlenwerte der Weights auf einmal in die Datei. Buffer ist bereits intern ein Zeiger, deswegen kein "&" + } + + /*---Datei wieder schließen---*/ + fclose(file); //Schließe die Datei wieder, wenn alle Daten sauber geschrieben wurden +} +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelReturnsCorrectNumberOfLayers(void) { const char *path = "some__nn_test_file.info2"; @@ -35,7 +77,9 @@ void test_loadModelReturnsCorrectNumberOfLayers(void) TEST_ASSERT_EQUAL_INT(expectedNet.numberOfLayers, netUnderTest.numberOfLayers); clearModel(&netUnderTest); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelReturnsCorrectWeightDimensions(void) { const char *path = "some__nn_test_file.info2"; @@ -59,6 +103,9 @@ void test_loadModelReturnsCorrectWeightDimensions(void) clearModel(&netUnderTest); } +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelReturnsCorrectBiasDimensions(void) { const char *path = "some__nn_test_file.info2"; @@ -81,7 +128,9 @@ void test_loadModelReturnsCorrectBiasDimensions(void) TEST_ASSERT_EQUAL_INT(expectedNet.layers[0].biases.cols, netUnderTest.layers[0].biases.cols); clearModel(&netUnderTest); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelReturnsCorrectWeights(void) { const char *path = "some__nn_test_file.info2"; @@ -106,7 +155,9 @@ void test_loadModelReturnsCorrectWeights(void) TEST_ASSERT_EQUAL_INT_ARRAY(expectedNet.layers[0].weights.buffer, netUnderTest.layers[0].weights.buffer, n); clearModel(&netUnderTest); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelReturnsCorrectBiases(void) { const char *path = "some__nn_test_file.info2"; @@ -131,7 +182,9 @@ void test_loadModelReturnsCorrectBiases(void) TEST_ASSERT_EQUAL_INT_ARRAY(expectedNet.layers[0].biases.buffer, netUnderTest.layers[0].biases.buffer, n); clearModel(&netUnderTest); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_loadModelFailsOnWrongFileTag(void) { const char *path = "some_nn_test_file.info2"; @@ -154,7 +207,9 @@ void test_loadModelFailsOnWrongFileTag(void) TEST_ASSERT_NULL(netUnderTest.layers); TEST_ASSERT_EQUAL_INT(0, netUnderTest.numberOfLayers); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_clearModelSetsMembersToNull(void) { const char *path = "some__nn_test_file.info2"; @@ -186,7 +241,9 @@ static void someActivation(Matrix *matrix) matrix->buffer[i] = fabs(matrix->buffer[i]); } } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void test_predictReturnsCorrectLabels(void) { const unsigned char expectedLabels[] = {4, 2}; @@ -215,15 +272,19 @@ void test_predictReturnsCorrectLabels(void) TEST_ASSERT_EQUAL_UINT8_ARRAY(expectedLabels, predictedLabels, n); free(predictedLabels); } - +/* + --------------------------------------------------------------------------------------------------------- +*/ void setUp(void) { // Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden } + void tearDown(void) { // Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden } +/*----------------------------------------------------------------------------------------------------------- */ int main() { UNITY_BEGIN(); @@ -239,4 +300,4 @@ int main() RUN_TEST(test_predictReturnsCorrectLabels); return UNITY_END(); -} \ No newline at end of file +}