Objetivo
Supongamos un sistema utilizado para registrar las consultas médicas. Una consulta médica tiene un archivo pacientes.csv con los datos personales de sus pacientes. Cada línea del archivo tiene el rut, el nombre y la edad de un paciente, separados por un símbolo ;. Así se ve el archivo:12067539-7;Lorena López;32
15007265-4;Saúl Morales;26
8509454-8;Diego Muñoz;45
7752666-8;Gabriel Navarro;49
8015253-1;Darío Pacheco;51
9217890-0;Aldo Pimienta;39
9487280-4;Juan Rosas;42
12393241-2;Felipe Rubio;33
11426761-9;Samanta Pérez;35
15690109-1;José Ruiz;26
6092377-9;Alfonso Iúdica;65
9023365-3;Nancy Toledo;38
10985778-5;Tomás Valdés;38
13314970-8;Adán Vázquez;30
7295601-k;Wilson Muñoz;60
5106360-0;Alejandra Vega;71
8654231-5;Andrés Dib;55
10105321-0;Antonio Cabalgante;31
13087677-3;Walter Álvarez;28
9184011-1;Soledad Andrade;47
12028339-1;Jorge Bogado;29
10523653-0;Francisca Avaria;40
12187197-1;Felipe Mañas;36
5935556-2;Pablo Barriga;80
14350739-4;Eduardo Velo;29
6951420-0;Oscar Benítez;68
11370775-5;Hugo Leguizamón;31
11111756-k;Cristóbal Colón;34
Además, cada vez que alguien se atiende en la consulta, la visita es registrada en el archivo atenciones.csv, agregando una línea que tiene el rut del paciente, la fecha de la visita (en formato dia-mes-año) y el precio de la atención, también separados por ;. El archivo se ve así:
8015253-1;4-5-2016;69580
12393241-2;6-5-2016;57274
10985778-5;8-5-2016;73206
8015253-1;10-5-2016;30796
8015253-1;12-5-2016;47048
12028339-1;12-5-2016;47927
11426761-9;13-5-2016;39117
10985778-5;15-5-2016;86209
7752666-8;18-5-2016;41916
8015253-1;18-5-2016;74101
12187197-1;20-5-2016;38909
8654231-5;20-5-2016;75018
8654231-5;22-5-2016;64944
5106360-0;24-5-2016;53341
8015253-1;27-5-2016;76047
9217890-0;30-5-2016;57726
7752666-8;1-6-2016;54987
8509454-8;2-6-2016;76483
6092377-9;2-6-2016;62106
11370775-5;3-6-2016;67035
11370775-5;7-6-2016;47299
8509454-8;7-6-2016;73254
8509454-8;10-6-2016;82955
11111756-k;10-6-2016;56520
7752666-8;10-6-2016;40820
12028339-1;12-6-2016;79237
11111756-k;13-6-2016;69094
5935556-2;14-6-2016;73174
11111756-k;21-6-2016;70417
11426761-9;22-6-2016;80217
12067539-7;25-6-2016;31555
11370775-5;26-6-2016;75796
10523653-0;26-6-2016;34585
6951420-0;28-6-2016;45433
5106360-0;1-7-2016;48445
8654231-5;4-7-2016;76458
Note que las fechas están ordenadas de menos reciente a más reciente, ya que las nuevas líneas siempre se van agregando al final.
- Escriba una función costo_total_paciente(rut) que entregue el costo total de las atenciones del paciente con el rut dado:
>>>Calcular el costo total del paciente
Por favor, ingrese rut del paciente: 8015253-1
Costo total del paciente: 297572
>>>Calcular el costo total del paciente
Por favor, ingrese rut del paciente: 14350739-4
Costo total del paciente: 0
- Escriba una función pacientes_dia(dia, mes, ano) que entregue una lista con los nombres de los pacientes que se atendieron el día señalado:
>>> Pacientes que se atendieron en una fecha dada
Por favor, ingrese el dia: 2
Por favor, ingrese el mes: 6
Por favor, ingrese el año: 2016
['Diego Muñoz', 'Alfonso Iúdica']
>>> Pacientes que se atendieron en una fecha dada
Por favor, ingrese el dia: 23
Por favor, ingrese el mes: 6
Por favor, ingrese el año: 2016
[]
- Escriba una función pacientes_menores(edad) que construya un archivo CSV con los pacientes con edad <= a la edad dada.
>>>Pacientes menores a una edad dada
Por favor, ingrese la edad: 30
>>>jovenes.csv
15007265-4;"Saúl Morales";26
15690109-1;"José Ruiz";26
13314970-8;"Adán Vázquez";30
13087677-3;"Walter Álvarez";28
12028339-1;"Jorge Bogado";29
14350739-4;"Eduardo Velo";29
Solución en Perl
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Data::Dumper;
# el costo total de las atenciones del paciente con el rut dado
sub costo_total_paciente{
my $rut= shift;
# conectamos
my $dbh= DBI->connect('DBI:CSV:');
my $tabla= 'atenciones.csv';
# seteamos el atributo sep_char para que use el separador ; en vez de ,
$dbh->{csv_sep_char}= ";";
# describimos los nombres de las columnas del archivo atenciones.csv
$dbh->{csv_tables}{$tabla} = {
col_names => [qw( rut fecha costo )]
};
# ejecutamos la consulta como un comando SQL
my $query= "SELECT sum(costo) as costo_total FROM $tabla WHERE rut='$rut'";
my $sth = $dbh->prepare($query);
$sth->execute();
my $row = $sth->fetchrow_hashref;
my $costo_total= 0;
if ($row->{costo_total}){ $costo_total= $row->{costo_total}; }
$sth->finish();
return $costo_total;
}
print "Calcular el costo total del paciente \n";
print "Por favor, ingrese rut del paciente: ";
my $rut = <stdin>;
chomp($rut);
my $costo_total= costo_total_paciente($rut);
print "Costo total del paciente: $costo_total \n";
# listar los nombres de los pacientes que se atendieron el día dado
sub pacientes_dia{
my ($dia, $mes, $anio)= @_;
# conectamos
my $dbh= DBI->connect('DBI:CSV:');
# seteamos el atributo sep_char para que use el separador ; en vez de ,
$dbh->{csv_sep_char}= ";";
# describimos los nombres de las columnas del archivo atenciones.csv
my $atenciones= 'atenciones.csv';
$dbh->{csv_tables}{$atenciones} = {
col_names => [qw( rut fecha costo )]
};
# describimos los nombres de las columnas del archivo pacientes.csv
my $pacientes= 'pacientes.csv';
$dbh->{csv_tables}{$pacientes} = {
col_names => [qw( rut nombre edad )]
};
# ejecutamos la consulta como un comando SQL
my $fecha= join('-',$dia,$mes,$anio);
my $query= "SELECT distinct rut FROM $atenciones WHERE fecha like '$fecha%'";
my $sth = $dbh->prepare($query);
$sth->execute();
while ( my $row = $sth->fetchrow_hashref ) {
$query= "SELECT nombre FROM $pacientes WHERE rut='$row->{rut}'";
my $sth2= $dbh->prepare($query);
$sth2->execute();
my $row2= $sth2->fetchrow_hashref;
print $row2->{nombre} . "\n";
$sth2->finish();
}
$sth->finish();
return;
}
print "Pacientes que se atendieron en una fecha dada\n";
print "Por favor, ingrese el dia: ";
my $dia = <stdin>;
chomp($dia);
print "Por favor, ingrese el mes: ";
my $mes = <stdin>;
chomp($mes);
print "Por favor, ingrese el año: ";
my $anio = <stdin>;
chomp($anio);
pacientes_dia($dia, $mes, $anio);
# generar un archivo jovenes.csv con los datos de los pacientes menores a cierta edad dada
sub pacientes_menores{
my $edad= shift;
# conectamos
my $dbh= DBI->connect('DBI:CSV:');
# seteamos el atributo sep_char para que use el separador ; en vez de ,
$dbh->{csv_sep_char}= ";";
# describimos los nombres de las columnas del archivo atenciones.csv
my $pacientes= 'pacientes.csv';
$dbh->{csv_tables}{$pacientes} = {
col_names => [qw( rut nombre edad )]
};
# creamos la nueva tabla de menores
my $jovenes= 'jovenes.csv';
$dbh->do("CREATE TABLE $jovenes (rut CHAR(12), nombre CHAR(50), edad CHAR(3))")
|| die "No se pudo crear la tabla " . $dbh->errstr();
# ejecutamos la consulta como un comando SQL
my $query= "SELECT * FROM $pacientes WHERE edad < '$edad'";
my $sth = $dbh->prepare($query);
$sth->execute();
while ( my $row = $sth->fetchrow_hashref ) {
$dbh->do("INSERT INTO $jovenes VALUES (".
$dbh->quote($row->{rut}) . "," .
$dbh->quote($row->{nombre}) . "," .
$dbh->quote($row->{edad}) . ")")
|| die "No puedo insertar un registro, " . $dbh->errstr();
}
$sth->finish();
return;
}
print "Pacientes menores a una edad dada\n";
print "Por favor, ingrese la edad: ";
my $edad = <stdin>;
chomp($edad);
pacientes_menores($edad);