====== Examen Parcial - 75.08. Sistemas Operativos ====== **Cátedra:** Osvaldo Clua\\ **Fecha:** Primera Oportunidad - Segundo Cuatrimestre 2006\\ **Día:** 31/10/2006\\ **Tema:** PERL Esta página está incompleta; podés ayudar completando el material. ===== Enunciado ===== Desarrollar un comando PERL denominado "parcial.pl" cuyo proposito es acumular la poblacin por pais-provincia, grabar los registros en un archivo de salida y generar un reporte. El comando puede ser invocado **sin** parámetros o con la opción -p seguida del nombre de los paises que se quieren procesar(puede ser uno o más de uno) separados por blanco. En el caso que el usuario invoque **con** parámetros se debe validar que existan los archivos de paises y que cada uno de ellos no tenga problemas en su apertura Si se presenta cualquiera de estos inconvenientes, mostrar por pantalla un mensaje descriptivo del error y terminar el proceso con algun codigo de error. Los archivos de paises estan en el directorio corriente. El nombre del archivo coincide con el nombre del pais pasado como parametro. En el caso que el usuario invoque sin parametros se deberan procesar todos los paises. Para cada archivo se deben procesar todos sus registros, el separador de registros es el new line, el separador de campos es el ";". Los archivos procesados deberan quedar en su estado original. La cantidad de campos dentro de un registro es desconocida pero los primeros 4 campos siempre son:\\ Fecha del Censo; Código de Porvincia; Código de Localidad; Población __**Se pide**__: - Usando una estructura de hash acumular la polacion por pais-provincia. Es obligatorio el uso de la estructura de hash para resolver esto. - Solicitar al usuario, leyendo del Standard Input, el nombre del archivo de salida. Si el archivo de salida existe, no perder los regrisrtos existentes y agregarle los nuevos. **No usar archivos auxiliares bajo ninguna hipotesis**. - Grabar en este archivo de salida todos los registros leidos con : Nombre de pais; Codigo de Provincia; Codigo de Localidad; poblacion. El resto de los campos ignorarlos. El separador de campos debe ser el ";" y el separadaor de registros el new line. - Generar un reporte por Standard output con al menos la siguiente informacion. Para cada pais procesado: - Linea 1: Pais, Poblacion total del pais - Linea 2 y siguientes (1 linea por provincia): Provincia, poblacion por provincia - Ultima linea: poblacion total del pais, Promedio por provincia (poblacion total del pais dividida la cantidad de provincias) **Bajo ningún concepto se podrán utilizar comandos Unix dentro del script de PERL** ===== Ejemplos ===== parcial.pl -p Argentina Uruguay Brasil Se deberan procesar 3 paises parcial.pl Se deben procesar todos los paises parcial.pl -p Argentina Se debe procesar solo Argentina ===== Resolución ===== #!/usr/bin/perl %hashProvincias=(); print "$0\n"; if (@ARGV > 0 ) { if ( $ARGV[0] ne "-p" ){ print "parametro desconocido\n"; exit 1; } else { shift(@ARGV); @paises=@ARGV; } } else { @paises=(); } if (@paises == 0 ){ @paises=<*>; print "@paises \n"; } print "Ingrese el nombre del archivo reporte: "; $reporte=; chomp($reporte); open($fdreport,">>$reporte") || die "$reporte: $!"; foreach $pais (@paises){ open($fdpais,"<$pais") || die "$pais: $!"; $poblacion=0; while (<$fdpais>){ chomp($_); if($_ ne ""){ @campos=split(";",$_); print $fdreport "$pais;$campos[1];$campos[2];$campos[3]\n"; $hashProvincias{"$campos[1]"}+=$campos[3]; $poblacion+=$campos[3]; } } print "Pais, $pais,poblacion total del pais:\n"; foreach $provincia (keys %hashProvincias){ print "$provincia,$hashProvincias{$provincia}\n"; } $promedio = $poblacion/(scalar(keys(%hashProvincias))); print "$poblacion, promedio por provincia $promedio\n"; close($fdpais); } close($fdreport); ===== Discusión ===== Si ves algo que te parece incorrecto en la resolución y no te animás a cambiarlo, dejá tu comentario acá. Maximiliano Milicich (maximiliano.milicich@gmail.com) : Comentarios * En la lista de archivos a procesar (cuando procesamos todos los paises) deberiamos filtrar el propio archivo script 'parcial.pl'. * Para obtener la lista de archivos existentes, otra opcion alternativa a <*> es usar opendir() + readdir(). opendir(DIRPAISES, "./paises") || die "No se encontro el directorio paises."; @paises = grep {! /^parcial\.pl$/} grep {! /^\.+$/} readdir(DIRPAISES); closedir(DIRPAISES); * De todas maneras creo q el enunciado podria declarar que los archivos de paises estan en un subdirectorio aparte, pues estando en el mismo directorio que el script de programa, luego de una corrida, el archivo de salida se suma al directorio y en las subsiguientes corridas el programa falla ya que intentara procesar el mismo archivo de salida...Y filtrarlo es casi imposible...