Datos importantes para los exámenes de cursada y finales
A tener en cuenta antes de comenzar a escribir el examen
Escriba con birome, no importa si tiene que tachar.
Escriba de un solo lado en cada hoja.
No empiece un nuevo módulo en una página que está escrita si ve que no lo va a terminar en la misma página, comience en una nueva.
Preguntas a hacerse antes de entregar el examen
¿He asumido alguna condición especial que no está claramente expresada en el enunciado? Si es así ¿incorporé un comentario aclarándolo?
¿Hice el diagrama de estructura (DE)?
¿Le puse todas las cuplas?
En las funciones ¿le puse la cupla de retorno?
¿Las funciones tienen nombre “de función” ?
¿Los “procedimientos” tienen nombre de acción?
¿Respeté los nombres del DE y los del código? ¿Son los mismos? ¿Sobran? ¿Faltan?
Analizo cada módulo (procedimiento o función). ¿Hay alguno que realiza más de una tarea conceptualmente? ¿Es conveniente dividirlo?
¿Las cuplas del DE se corresponden con todos los parámetros? ¿Sobran? ¿Faltan?
¿Todas las cuplas de salida del DE están pasadas por referencia (utilizando &) en los módulos? ¿Y viceversa?
¿Todas las variables/arreglos tienen nombres representativos?
¿Todos los módulos tienen nombres representativos?
¿Incorporé comentarios en el código?
¿Tengo definida alguna variable o parámetro en alguna función que no uso? ¿Y alguna que uso y no definí?
Dentro de cada código, programa o módulo, ¿definí e inicialicé todas las variables que uso al principio?
Parcial
Enunciado
Una alternativa de Resolución
<?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";
}
?>