From 451ecbaf1e8eb3dce9794e609a7e44ebed7db51f Mon Sep 17 00:00:00 2001
From: 20041679 <->
Date: Fri, 23 Jun 2023 20:44:20 +0200
Subject: [PATCH] added exam simulation

---
 Simulazione esame/Makefile  | 12 +++++++++
 Simulazione esame/input.txt |  8 ++++++
 Simulazione esame/list.c    | 54 +++++++++++++++++++++++++++++++++++++
 Simulazione esame/list.h    | 21 +++++++++++++++
 Simulazione esame/main.c    | 52 +++++++++++++++++++++++++++++++++++
 Simulazione esame/product.c | 45 +++++++++++++++++++++++++++++++
 Simulazione esame/product.h | 22 +++++++++++++++
 Simulazione esame/util.c    | 10 +++++++
 Simulazione esame/util.h    | 10 +++++++
 9 files changed, 234 insertions(+)
 create mode 100644 Simulazione esame/Makefile
 create mode 100644 Simulazione esame/input.txt
 create mode 100644 Simulazione esame/list.c
 create mode 100644 Simulazione esame/list.h
 create mode 100644 Simulazione esame/main.c
 create mode 100644 Simulazione esame/product.c
 create mode 100644 Simulazione esame/product.h
 create mode 100644 Simulazione esame/util.c
 create mode 100644 Simulazione esame/util.h

diff --git a/Simulazione esame/Makefile b/Simulazione esame/Makefile
new file mode 100644
index 0000000..dd38632
--- /dev/null
+++ b/Simulazione esame/Makefile	
@@ -0,0 +1,12 @@
+CC = cc
+CFLAGS = -Wall -Wextra -g
+OBJS = product.o util.o list.o main.o
+
+all: product.o util.o list.o main.o
+	$(CC) product.o util.o list.o main.o -o main
+run: all
+	./main
+%.o: %.c
+	$(CC) -c $(CFLAGS) $< -o $@
+clean:
+	rm *.o main
diff --git a/Simulazione esame/input.txt b/Simulazione esame/input.txt
new file mode 100644
index 0000000..b682329
--- /dev/null
+++ b/Simulazione esame/input.txt	
@@ -0,0 +1,8 @@
+120435	NONNA_PAPERA	BISCOTTI_CIOCCOLATO	1.60	100
+320001	NONNA_PAPERA	TORTA_DI_MELE		5.00	40
+401200	GIANDUJA	SCATOLA_CIOCCOLATINI	8.00	85
+301293	PULCINELLA	PASTA_VERACE		0.90	300
+034911	WILLY_WONKA	PRALINE_DELIZIA 	6.80	52
+230099	PULCINELLA	PUMMAROLA		2.05	231
+991220	GIANDUJA	GIANDUIOTTI		10.00    93
+  -1	FINE_LISTA
diff --git a/Simulazione esame/list.c b/Simulazione esame/list.c
new file mode 100644
index 0000000..f483d08
--- /dev/null
+++ b/Simulazione esame/list.c	
@@ -0,0 +1,54 @@
+#include "list.h"
+#include <stdlib.h>
+
+Link list_new_raw() {
+	return malloc(sizeof(Element));
+}
+
+Link list_new(Data data[], size_t n) {
+	if (n == 0) {
+			return NULL;
+	}
+	Link new = list_new_raw();
+	new->data = data[0];
+	new->next = list_new(&data[1], n - 1);
+	return new;
+}
+
+Link list_read(FILE *f, int (*read) (FILE *, Data *)) {
+	Data data;
+	Link head = NULL;
+	Link *last  = &head;
+	while (read(f, &data)) {
+		*last = list_new(&data, 1);
+		last = &(*last)->next;
+	}
+	return head;
+}
+
+void list_print(Link head, FILE *f, void (*print) (FILE *f, Data *)) {
+	if (head) {
+		print(f, &head->data);
+		list_print(head->next, f, print);
+	}
+}
+
+float list_float_fold(Link head, float init, float (*op) (float, Data *)) {
+	if (head) {
+		return list_float_fold(head->next, op(init, &head->data), op);
+	}
+	return init;
+}
+
+Link list_filter(Link head, int (*predicate) (Data *, void *), void *param) {
+	if (head) {
+		if (predicate(&head->data, param)) {
+			Link new = list_new(&head->data, 1);
+			new->next = list_filter(head->next, predicate, param);
+			
+			return new;
+		}
+		return list_filter(head->next, predicate, param);
+	}
+	return NULL;
+}
diff --git a/Simulazione esame/list.h b/Simulazione esame/list.h
new file mode 100644
index 0000000..bca46c1
--- /dev/null
+++ b/Simulazione esame/list.h	
@@ -0,0 +1,21 @@
+#ifndef LIST_H
+#define LIST_H
+
+#include "product.h"
+
+typedef Product Data;
+
+typedef struct Element {
+	Data data;
+	struct Element *next;
+} Element;
+
+typedef Element *Link;
+
+Link list_new(Data data[], size_t n);
+Link list_read(FILE *f, int (*read) (FILE *, Data *));
+void list_print(Link head, FILE *f, void (*print) (FILE *f, Data *));
+float list_float_fold(Link head, float init, float (*op) (float, Data *));
+Link list_filter(Link head, int (*predicate) (Data *, void *), void *param);
+
+#endif
diff --git a/Simulazione esame/main.c b/Simulazione esame/main.c
new file mode 100644
index 0000000..cd8e322
--- /dev/null
+++ b/Simulazione esame/main.c	
@@ -0,0 +1,52 @@
+#include "list.h"
+#include "product.h"
+#include "util.h"
+#include <stdlib.h>
+
+Link crealista(FILE *f) {
+	return list_read(f, product_read);
+}
+
+void stampalista(Link head) {
+	FILE *f;
+	if ((f = fopen("output.txt", "a"))) {
+		list_print(head, f, product_print);
+		fclose(f);
+	}
+}
+
+float sum(float acc, Product *p) {
+	return acc + product_price_total(p);
+}
+
+float calcolaval(Link L1) {
+	return list_float_fold(L1, 0, sum);
+}
+
+int compare_producer(Product *p, void *string) {
+	return product_compare_producer(p, (char *)string);
+}
+
+Link listaforni(Link L1, char *fornitore) {
+	return list_filter(L1, compare_producer, fornitore);
+}
+
+int main(void) {
+	FILE *f;
+	if (!(f = fopen("input.txt", "r"))) {
+		return EXIT_FAILURE;
+	}
+	
+	Link list = crealista(f);
+	fclose(f);
+
+	stampalista(list);
+
+	printf("prezzo complessivo dei prodotti: %.2f\n", calcolaval(list));
+
+	puts("inserire fornitore da filtrare:");
+	char buf[64];
+	fgets_strip(buf, ARR_LEN(buf), stdin);
+
+	stampalista(listaforni(list, buf));
+}
diff --git a/Simulazione esame/product.c b/Simulazione esame/product.c
new file mode 100644
index 0000000..5202d1c
--- /dev/null
+++ b/Simulazione esame/product.c	
@@ -0,0 +1,45 @@
+#include "product.h"
+#include "util.h"
+#include <string.h>
+
+int product_parse(char *s, Product *product) {
+	char format[2 + 4 + 4 + 2 + 2 + 1];
+	snprintf(format, ARR_LEN(format), "%%d%%%zus%%%zus%%f%%u",
+	    ARR_LEN(product->producer),
+		ARR_LEN(product->name));
+	sscanf(s, format,
+		&product->code,
+		product->producer,
+		product->name,
+		&product->price,
+		&product->quantity);
+	if (product->code < 0 && strcmp(product->producer, END) == 0) {
+		return 0;
+	}
+	return 1;
+}
+
+int product_read(FILE *f, Product *product) {
+	char buf[256];
+	fgets_strip(buf, ARR_LEN(buf), f);
+	return product_parse(buf, product);
+}
+
+void product_print(FILE *f, Product *product) {
+	fprintf(
+		f,
+		"Codice prodotto: %d\nNome prodotto: %s\nProdotto da: %s\nQuantità: %u\nPrezzo: %.2f\n",
+		product->code,
+		product->name,
+		product->producer,
+		product->quantity,
+		product->price);
+}
+
+float product_price_total(Product *product) {
+	return product->price * product->quantity;
+}
+
+int product_compare_producer(Product *product, char *s) {
+	return strcmp(product->producer, s) == 0;
+}
diff --git a/Simulazione esame/product.h b/Simulazione esame/product.h
new file mode 100644
index 0000000..6da0642
--- /dev/null
+++ b/Simulazione esame/product.h	
@@ -0,0 +1,22 @@
+#ifndef PRODUCT_H
+#define PRODUCT_H
+
+#define END "FINE_LISTA"
+
+#include <stdio.h>
+
+typedef struct {
+	int code;
+	char producer[64];
+	char name[64];
+	float price;
+	unsigned quantity;
+} Product;
+
+int product_parse(char *s, Product *product);
+int product_read(FILE *f, Product *product);
+void product_print(FILE *f, Product *product);
+float product_price_total(Product *product);
+int product_compare_producer(Product *product, char *s);
+
+#endif
diff --git a/Simulazione esame/util.c b/Simulazione esame/util.c
new file mode 100644
index 0000000..ac54b5d
--- /dev/null
+++ b/Simulazione esame/util.c	
@@ -0,0 +1,10 @@
+#include "util.h"
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+char *fgets_strip(char *s, size_t size, FILE *stream) {
+	char *ret = fgets(s, size, stream);
+	s[strcspn(s, "\n")] = '\0';
+	return ret;
+}
diff --git a/Simulazione esame/util.h b/Simulazione esame/util.h
new file mode 100644
index 0000000..a473e60
--- /dev/null
+++ b/Simulazione esame/util.h	
@@ -0,0 +1,10 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <stdio.h>
+
+#define ARR_LEN(x) (sizeof(x) / sizeof(*x))
+
+char *fgets_strip(char *s, size_t size, FILE *stream);
+
+#endif
-- 
GitLab