====== Examen Parcial - 75.08. Sistemas Operativos ======
**Cátedra:** Osvaldo Clua\\
**Fecha:** Segunda Oportunidad - Primer Cuatrimestre 2005\\
**Día:** 07/06/2005\\
**Tema:** PERL
Esta página está incompleta; podés ayudar completando el material.
===== Enunciado =====
Desarrollar un comando PERL denominado "RankingCity.pl" que obtiene los totales de llamados (en minutos y en cantidad) que las ciudades hacen a un determinado destino.
Para invocar este comando, el usuario deberá especificar: __Parámetro 1__: Nombre del archivo de ENTRADA __Parámetro 2__: Nombre de la Ciudad Destino.
El archivo de ENTRADAA, esta desordenado, puede tener reistros repetidos, su separador de campos es el punto y coma y posee el siguiente formato:
CodigoCiudadOrigen;CodigoCiudadDestino;cantidad_de_llamadas;cantidad_de_minutos
Para obtener el Código de la ciudad destino contamos con un archivo de ciudades(denominado ciudades.txt) que esta ordenado por Código-de-Ciudad, no tiene registros repetidos, su separador de campos es el punto y coma y posee el siguiente formato: Codigo-de-Ciudad;Nombre de Ciudad
**Es obligatorio el uso de una estructura de hash** para efectuar la suma de la cantidad de minuots y la suma de la cantidad de llamadas por ciudad origen. El campo ciudad origen es el que se debe emplear como clave.
__Salida:__ se debe grabar en el archivo de salida lo siguiente: un primer registro de encabezamiento y luego las ciudades que llaman al destino especificado con su correspondiente cantidad total de minutos y cantidad total de llamadas. El separador de campos debe ser la coma.
__Formato:__
* Para el registro de encabezamiento: "Proceso del día " , "Ciudad Destino solicitada", Nombre de la Ciudad Destino
* Para cada ciudad que llama al destino: Código de Ciudad Origen, Cantidad total de minutos, cantidad total de llamadas.
Solicitar al usuario, **leyendo del standard input** y durante el proceso, el nombre del archivo de salida. Si el archivo existe, NO PERDER LOS REGISTROS EXISTENTES, agregarle los nuevos registros. **No usar archivos auxiliares bajo ninguna hipótesis**.
__Otras Validaciones:__
- Que sean exactamente 2 parámetros
- Que el archivo de ENTRADA exista y tenga permisos de lectura
- Que el archivo de ciudades.txt exista y tenga permisos de lectura
- Que la ciudad destino exista en el archivo de ciudades
En todos los casos si la validación da error mostrar por pantalla un mensaje descriptivo del error y terminar el proceso con algún código de error.
===== Ejemplo de corrida válida =====
__**Archivo de entrada con:**__\\
\begin{array}{|c|c|c|c|}
\hline
ROS001 & BA011 & 1234 & 2239.23 \\
\hline
CBA3457 & BA011 & 345 &823.0 \\
\hline
CBA3457 & ROS001 & 67 & 100.78 \\
\hline
ROS001 & BA011 & 2000 & 3000\\
\hline
BA011 & BA011 & 10 & 120.3345\\
\hline
\end{array}
__**Resultado:(si destino = Buenos Aires = BA011) Achivo de salida con:**__\\
\begin{array}{|c|c|c|}
\hline
\mbox{Proceso del dia 07-06-2005} & \mbox{Ciudad Destino Solicitada} & \mbox{Buenos Aires} \\
\hline
ROS001 & 5239.23 & 3234 \\
\hline
CBA3457 & 823.0 & 345 \\
\hline
BA011 & 120.3345 & 10\\
\hline
\end{array}
===== Resolución =====
#!/usr/bin/perl
@args = @ARGV;
if ($#args != 1) {
die "ERROR: Cantidad de parametros incorrecta.\n";
}
if (!(-e "ciudades.txt")) { // Si no existe...
die "ERROR: El archivo ciudades.txt no existe.\n";
}
if (!(-r "ciudades.txt")) { // Si no tiene permisos de lectura...
die "ERROR: El archivo ciudades.txt no tiene permiso de lectura.\n";
}
if (!(-e "$args[0]")) {
die "ERROR: El archivo $args[0] no existe.\n";
}
if (!(-r "$args[0]")) {
die "ERROR: El archivo $args[0] no tiene permiso de lectura.\n";
}
open CIUDADES, ")) && ($existe eq "no")) {
chomp($linea);
@reg_dest = split /;/, $linea;
if ($reg_dest[1] eq $args[1]) {
$existe = "si";
$cod_dest = $reg_dest[0];
$nom_dest = $args[1];
}
}
close CIUDADES;
if ($existe eq "no") {
die "ERROR: La ciudad de destino no existe en el archivo ciudades.txt\n";
}
open IN, "<$args[0]";
while (defined($linea = )) {
chomp($linea);
@reg_ent = split /;/, $linea;
if ("$reg_ent[1]" eq "$cod_dest") {
if (exists $hash_llam{$reg_ent[0]}) {
$hash_llam{$reg_ent[0]} = $hash_llam{$reg_ent[0]} + $reg_ent[2];
$hash_min{$reg_ent[0]} = $hash_min{$reg_ent[0]} + $reg_ent[3];
}
else {
$hash_llam{$reg_ent[0]} = $reg_ent[2];
$hash_min{$reg_ent[0]} = $reg_ent[3];
}
}
}
close IN;
print "Ingrese el nombre de archivo de salida: ";
$salida = ;
open OUT, ">>$salida";
@fecha = localtime();
$dia = $fecha[3];
$mes = $fecha[4];
$anio = 1900 + $fecha[5];
$fecha = join "-", "$dia", "$mes", "$anio";
$encabezado = join ",", "Proceso del dia $fecha", "Ciudad destino solicitada:", "$nom_dest";
print OUT "$encabezado\n";
while ( ($key, $value) = each %hash_llam) {
$reg_salida = join ",", "$key", "$hash_min{$key}", "$value";
print OUT "$reg_salida\n";
}
close OUT;
===== Otra Resolución =====
#!/usr/bin/perl
# validación 1.
($#ARGV == 1) || die "Error, cantidad de parámetros incorrecta.\n";
$arch_in = $ARGV[0];
$destino = $ARGV[1];
$arch_ciudades = "ciudades.txt";
# validación 2.
open(ENTRADA, "<$arch_in") || die "Error, no se pudo abrir el archivo de entrada: $arch_in.\n";
# validación 3.
open(CIUDADES, "<$arch_ciudades") || die "Error, no se pudo abrir el archivo $arch_ciudades.\n";
# validación 4
$arch = join("", );
@lineas = split("\n", $arch);
$codigo = "";
for $linea (@lineas) {
#chop($linea);
($cod, $nom) = split(";", $linea);
if ($nom eq $destino) {
$codigo = $cod;
}
}
close(CIUDADES);
$codigo == "" || die "Error, no se encontro la ciudad en el archivo $arch_ciudades.\n";
print "Ingrese el nombre del archivo de salida: ";
$archivo_salida = ;
chop($archivo_salida);
open(SALIDA, ">>$archivo_salida") || die "Error, no se pudo abrir en modo escritura el archivo $archivo_salida.\n";
# inicializo el hash.
%cantidad = ();
%minutos = ();
# Levanto el archivo de entrada a memoria.
$arch = join("", );
close(ENTRADA);
# Lo separo en líneas.
@lineas = split(/\n/, $arch);
for $linea (@lineas){
@reg = split(/;/, $linea);
($cod_orig, $cod_dest, $cant, $min) = @reg;
if ($cod_dest eq $codigo) {
if (exists($cantidad{$cod_orig})){
$cantidad{$cod_orig} += $cant;
$minutos{$cod_orig} += $min;
} else {
$cantidad{$cod_orig} = $cant;
$minutos{$cod_orig} = $min;
}
}
}
# Ahora que ya tengo todos los datos que necesito:
$fecha = `date`;
chop($fecha);
print SALIDA "Proceso del día $fecha, Ciudad Destino solicitada: $destino\n";
for $clave (keys(%cantidad)){
print SALIDA "$clave,$minutos{$clave},$cantidad{$clave}\n";
}
close(SALIDA);