<?php define('SEPARADOR_CAMPOS', ';'); define('POS_CAMPO_PRODUCTO', 0); define('POS_CAMPO_FECHA', 1); // en este problema en particular pareciera que no se usa... define('POS_CAMPO_PRECIO', 2); /** * Carga el contenido del archivo de nombre $nombre_entrada y lo devuelve como un arreglo asociativo. * * @param string $nombre_entrada nombre del archivo que contiene los precios * @return mixed un arreglo con los precios, si el archivo se cargó correctamente; * false si hubo algún error */ function precios_desde_archivo($nombre_entrada) { $precios = false; $archivo_precios = fopen($nombre_entrada, 'r'); if ($archivo_precios) { $precios = array(); while (!feof($archivo_precios)) { $linea = fgets($archivo_precios); // Si el archivo tiene un \n en la última línea, en la última vuelta // feof devuelve false (entra al while), pero fgets no tiene una línea // para leer y devuelve false también if (!feof($archivo_precios)) { $campos = explode(SEPARADOR_CAMPOS, trim($linea)); if (!array_key_exists($campos[POS_CAMPO_PRODUCTO], $precios)) { $precios[$campos[POS_CAMPO_PRODUCTO]] = array( 'inicial' => $campos[POS_CAMPO_PRECIO], 'final' => $campos[POS_CAMPO_PRECIO] ); } else { $precios[$campos[POS_CAMPO_PRODUCTO]]['final'] = $campos[POS_CAMPO_PRECIO]; } } } fclose($archivo_precios); } return $precios; } /** * Calcula la diferencia porcentual entre dos valores. * * @param float $valor_inicial * @param float $valor_final * @return float */ function diferencia_porcentual($valor_inicial, $valor_final) { return (($valor_final / $valor_inicial) - 1) * 100; } /** * Agrega a cada producto en $precios la diferencia porcentual entre el precio inicial y el final. * * @param array $precios datos sobre los precios de los productos */ function calcular_variaciones_precios(&$precios) { foreach ($precios as $producto => $datos_producto) { $precios[$producto]['diferencia'] = diferencia_porcentual($precios[$producto]['inicial'], $precios[$producto]['final']); } } /** * Devuelve estadísticas sobre los precios dados. * * @param array $precios arreglo con los precios de los productos * @return array un arreglo con las claves: * - 'maximo': máxima diferencia de precio * - 'producto_maximo': producto con la máxima diferencia de precio * - 'minimo': mínima diferencia de precio * - 'producto_minimo': producto con la mínima diferencia de precio * - 'promedio': diferencia de precio promedio entre todos los productos */ function estadisticas_variacion_precios($precios) { $estadisticas = array(); $productos = array_keys($precios); $max = $min = $dif_total = $precios[$productos[0]]['diferencia']; $prod_max = $prod_min = $productos[0]; for ($i = 1; $i < count($precios); $i++) { $diferencia = $precios[$productos[$i]]['diferencia']; if ($diferencia > $max) { $max = $diferencia; $prod_max = $productos[$i]; } if ($diferencia < $min) { $min = $diferencia; $prod_min = $productos[$i]; } $dif_total += $diferencia; } $estadisticas['maximo'] = $max; $estadisticas['producto_maximo'] = $prod_max; $estadisticas['minimo'] = $min; $estadisticas['producto_minimo'] = $prod_min; $estadisticas['promedio'] = $dif_total / count($precios); return $estadisticas; } /** * Guarda en el archivo de nombre $nombre_salida los datos dados en $variaciones. * * @param string $nombre_salida nombre del archivo de salida * @param array $variaciones datos a guardar, con el formato devuelto por estadisticas_variacion_precios * @return boolean true si se la operación se completó correctamente; false si hubo algún problema */ function guardar_variaciones_precios($nombre_salida, $variaciones) { $archivo_variaciones = fopen($nombre_salida, 'a'); if ($archivo_variaciones) { $salida = "Máximo" . SEPARADOR_CAMPOS . $variaciones['producto_maximo'] . SEPARADOR_CAMPOS . $variaciones['maximo'] . "\n"; $salida .= "Mínimo" . SEPARADOR_CAMPOS . $variaciones['producto_minimo'] . SEPARADOR_CAMPOS . $variaciones['minimo'] . "\n"; $salida .= "Promedio" . SEPARADOR_CAMPOS . "Todos" . SEPARADOR_CAMPOS . $variaciones['promedio'] . "\n"; $ok = fwrite($archivo_variaciones, $salida); $resultado = $ok !== false; fclose($archivo_variaciones); } else $resultado = false; return $resultado; } define('ARCHIVO_PRECIOS', 'precios.txt'); define('ARCHIVO_VARIACIONES', 'variaciones.txt'); $precios = precios_desde_archivo(ARCHIVO_PRECIOS); if ($precios !== false) { // debe usarse !==, porque también puede retornar un array vacío, que es válido if (count($precios) > 0) { // si el archivo está vacío, no hay más para hacer calcular_variaciones_precios($precios); $estadisticas = estadisticas_variacion_precios($precios); $ok = guardar_variaciones_precios(ARCHIVO_VARIACIONES, $estadisticas); if ($ok) echo "Se guardaron correctamente las variaciones de precios."; else echo "Hubo un error al guardar el archivo de variaciones (" . ARCHIVO_VARIACIONES . ").\n"; } else echo "El archivo " . ARCHIVO_VARIACIONES . " no contiene precios guardados.\n"; } else { echo "Hubo un error al leer el archivo de precios (" . ARCHIVO_PRECIOS . ").\n"; } ?>