summaryrefslogtreecommitdiffstats
path: root/2023-2/L02/mitsuo/fun.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2023-2/L02/mitsuo/fun.cpp')
-rw-r--r--2023-2/L02/mitsuo/fun.cpp313
1 files changed, 313 insertions, 0 deletions
diff --git a/2023-2/L02/mitsuo/fun.cpp b/2023-2/L02/mitsuo/fun.cpp
new file mode 100644
index 0000000..8065ca5
--- /dev/null
+++ b/2023-2/L02/mitsuo/fun.cpp
@@ -0,0 +1,313 @@
+#include <iomanip>
+#include <cstring>
+#include <algorithm> // find
+#include "fun.hpp"
+
+using namespace std;
+
+void lecturaDeProductos(const char *archivo, char ***&productos, int *&stock, double *&precios) {
+ ifstream in(archivo);
+ if (!in) {
+ cerr << "Error: no se pudo abrir el archivo.\n";
+ exit(1);
+ }
+
+ // read (stack memory)
+ char code[MAXLEN];
+ char description[MAXLEN];
+ double price;
+ int qty;
+
+ char **productos_tmp[MAX];
+ int stock_tmp[MAX];
+ double precio_tmp[MAX];
+
+ int i;
+ for (i = 0; i < MAX; i++) {
+ in.getline(code, MAXLEN, ',');
+ in.getline(description, MAXLEN, ',');
+ in >> price; in.get();
+ in >> qty; in.get();
+ if (!in) {
+ break;
+ }
+
+ productos_tmp[i] = crea_producto(code, description); // this is the "Primary Key" of the parallel arrays
+ stock_tmp[i] = qty;
+ precio_tmp[i] = price;
+ }
+
+ // write (heap memory)
+ int n = i + 1; // "null terminated list"
+ productos = new char ** [n];
+ stock = new int [n];
+ precios = new double [n];
+
+ for (i = 0; i < n; i++) {
+ productos[i] = productos_tmp[i];
+ stock[i] = stock_tmp[i];
+ precios[i] = precio_tmp[i];
+ }
+ productos[i] = NULL;
+}
+
+char **crea_producto(char * code, char * description) {
+ char * field1 = new char [strlen(code) + 1];
+ char * field2 = new char [strlen(description) + 1];
+
+ strcpy(field1, code);
+ strcpy(field2, description);
+
+ return new char * [2] {field1, field2};
+}
+
+void pruebaDeLecturaDeProductos(const char *archivo, char ***productos, int *stock, double *precios) {
+ ofstream out(archivo);
+ if (!out) {
+ cerr << "Error: no se pudo abrir archivo.\n";
+ exit(1);
+ }
+
+ char ** producto;
+ int i;
+ for (i = 0; i < MAX && (producto = productos[i]); i++) {
+ out << left;
+ out << setw(12) << producto[0];
+ out << setw(72) << producto[1];
+ out << right << setprecision(2) << fixed;
+ out << setw(8) << stock[i];
+ out << setw(12) << precios[i];
+ out << '\n';
+ }
+}
+
+void lecturaDePedidos(const char *archivo, int *&fechaPedidos, char ***&codigoPedidos, int ***&dniCantPedidos) {
+ ifstream in(archivo);
+ if (!in) {
+ cerr << "Error: no se pudo abrir el archivo.\n";
+ exit(1);
+ }
+
+ int date, dd, mm, yy;
+ char code[MAXLEN];
+ int dni;
+ int qty;
+
+ // read (stack memory)
+ int fechas[MAX];
+ char * productos[MAX]; // code array
+ int * dniqtys[MAX]; // dni + qty array
+
+ int n, i;
+ for (i = 0; i < MAX; i++) {
+ in.getline(code, MAXLEN, ',');
+ in >> dni; in.get();
+ in >> qty; in.get();
+ in >> dd; in.get(); in >> mm; in.get(); in >> yy; in.get();
+ date = yy*10000 + mm*100 + dd;
+ if (!in) {
+ break;
+ }
+
+ // First load data in arrays. Then group by date.
+ fechas[i] = date; // "PK"
+ productos[i] = new char [strlen(code) + 1]; strcpy(productos[i], code);
+ dniqtys[i] = new int [2] {dni, qty};
+ }
+ n = i;
+
+ // aggregate by date
+ int grouped_fecha_tmp[MAX];
+ char ** grouped_producto_tmp[MAX];
+ int ** grouped_dniqty_tmp[MAX];
+
+ /* Loop over the dates, then look for all occurrences of a date in
+ `agrega_pedidos_fecha`. Store already processed dates.
+ (this is required because you need to know how many orders are in a
+ specific date, in order to allocate memory)
+
+ Another strategy could be to first sort the 3 parallel arrays. And then
+ Add the products to a date, until the date changes.
+
+ On second thought, the report only makes sence if the dates are sorted
+ (doesn't make much serve the orders in seaminly random order, but
+ it also doesn't make sence that the Pedidos.csv is randomly shuffled,
+ should come in-order). Lab 3 is exactly the same but now with
+ "metodo por incrementos", and the professors commented that they
+ made a similar exercise in class and they grouped by dates "in-order"
+ (insertion sort).
+ */
+ int fechas_procesadas[MAX]; // ignore already processed dates
+ int n_procesadas = 0;
+ int i_grouped = 0;
+ for (i = 0; i < n; i++) {
+ int fecha = fechas[i];
+ if (find(fechas_procesadas, fechas_procesadas + n_procesadas, fecha) != fechas_procesadas + n_procesadas) {
+ // already processed date
+ continue;
+ }
+
+ grouped_fecha_tmp[i_grouped] = fecha;
+ agrega_pedidos_fecha(fecha,
+ grouped_producto_tmp[i_grouped], grouped_dniqty_tmp[i_grouped],
+ fechas, productos, dniqtys, n);
+ i_grouped += 1;
+
+ fechas_procesadas[n_procesadas++] = fecha;
+ }
+
+ // write (heap memory)
+ n = i_grouped;
+ fechaPedidos = new int [n + 1];
+ codigoPedidos = new char ** [n + 1];
+ dniCantPedidos = new int ** [n + 1];
+
+ for (i = 0; i < n; i++) {
+ fechaPedidos[i] = grouped_fecha_tmp[i];
+ codigoPedidos[i] = grouped_producto_tmp[i];
+ dniCantPedidos[i] = grouped_dniqty_tmp[i];
+ }
+ fechaPedidos[i] = 0;
+}
+
+/* agrega todos los pedidos de una determinada fecha en los arreglos paralelos */
+void agrega_pedidos_fecha(
+ int fecha, char **& pedido_producto, int **& pedido_dniqty,
+ int * fechas, char ** productos, int ** dniqtys,
+ int n)
+{
+ int i;
+ char * productos_tmp[MAX];
+ int * dniqtys_tmp[MAX];
+ int j = 0; // numero de pedidos para una fecha
+ for (i = 0; i < n; i++) {
+ if (fecha == fechas[i]) {
+ productos_tmp[j] = productos[i];
+ dniqtys_tmp[j] = dniqtys[i];
+ j += 1;
+ }
+ }
+ int n_pedidos = j;
+ pedido_producto = new char * [n_pedidos + 1];
+ pedido_dniqty = new int * [n_pedidos + 1];
+
+ for (i = 0; i < n_pedidos; i++) {
+ pedido_producto[i] = productos_tmp[i];
+ pedido_dniqty[i] = dniqtys_tmp[i];
+ }
+ pedido_producto[i] = NULL;
+ pedido_dniqty[i] = NULL;
+}
+
+void pruebaDeLecturaDePedidos(const char *archivo, int *fechaPedidos, char ***codigoPedidos, int ***dniCantPedidos) {
+ ofstream out(archivo);
+ if (!out) {
+ cerr << "Error: no se pudo abrir archivo.\n";
+ exit(1);
+ }
+
+ int fecha;
+ int i, j;
+ for (i = 0; i < MAX && (fecha = fechaPedidos[i]); i++) {
+ char ** productos = codigoPedidos[i];
+ int ** dniqtys = dniCantPedidos[i];
+ for (j = 0; j < MAX && productos[j]; j++) {
+ int dni = dniqtys[j][0];
+ int qty = dniqtys[j][1];
+ char * code = productos[j];
+
+ out << right << setprecision(2) << fixed;
+ out << setw(2) << j + 1 << ") ";
+ out << left;
+ out << setw(12) << dni;
+ out << setw(12) << code;
+ out << setw(12) << qty;
+ out << '\n';
+ }
+ }
+}
+
+void reporteDeEnvioDePedidos(const char *archivo,
+ char ***productos, int *stocks, double *precios, // productos parallel arrays
+ int *fechaPedidos, char ***codigoPedidos, int ***dniCantPedidos // pedidos parallel arrays
+) {
+ ofstream out(archivo);
+ if (!out) {
+ cerr << "Error: no se pudo abrir archivo.\n";
+ exit(1);
+ }
+
+ int fecha;
+ int i, j;
+ for (i = 0; i < MAX && (fecha = fechaPedidos[i]); i++) {
+ int dd = fecha % 100;
+ int mm = fecha / 100 % 100;
+ int yy = fecha / 10000;
+ out << " REPORTE DE ENTREGA DE PEDIDOS\n"
+ "=====================================================================================================================================\n"
+ ;
+ out << "FECHA: " << dd << "/" << mm << "/" << yy << '\n';
+ out << "=====================================================================================================================================\n"
+ "No. DNI Producto Cantidad Precio Total de ingresos\n"
+ "-------------------------------------------------------------------------------------------------------------------------------------\n"
+ ;
+
+ char ** pedido_productos = codigoPedidos[i];
+ int ** dniqtys = dniCantPedidos[i];
+
+ double served_income = 0;
+ double not_served_income = 0;
+ for (j = 0; j < MAX && pedido_productos[j]; j++) {
+ int dni = dniqtys[j][0];
+ int qty = dniqtys[j][1];
+ char * code = pedido_productos[j];
+
+ int i_product = busca_producto(productos, code);
+ char * name = productos[i_product][1];
+ int * stock = &stocks[i_product];
+ double price = precios[i_product];
+
+ int qty_served;
+ if (*stock >= qty) {
+ qty_served = qty;
+ *stock -= qty;
+ } else {
+ qty_served = max(*stock - qty, 0);
+ *stock = 0;
+ }
+ served_income += qty_served * price;
+ not_served_income += (qty - qty_served) * price;
+
+ out << right << setprecision(2) << fixed;
+ out << setw(2) << j + 1 << ") ";
+ out << left;
+ out << setw(12) << dni;
+ out << setw(12) << code;
+ out << setw(64) << name;
+ out << right << setprecision(2) << fixed;
+ out << setw(12) << qty;
+ out << setw(12) << price;
+ if (*stock == 0) {
+ out << left;
+ out << setw(12) << " SIN STOCK";
+ } else {
+ out << setw(12) << price * qty_served;
+ }
+ out << '\n';
+ }
+ out << right << setprecision(2) << fixed;
+ out << "-------------------------------------------------------------------------------------------------------------------------------------\n";
+ out << "Total ingresado: " << served_income << '\n';
+ out << "Total perdido por falta de stock: " << not_served_income << '\n';
+ }
+}
+
+int busca_producto(char *** productos, char * producto) {
+ for (int i = 0; productos[i]; i++) {
+ if (strcmp(productos[i][0], producto) == 0) {
+ return i;
+ }
+ }
+ return -1;
+
+} \ No newline at end of file