[ Foro de Pascal ]

Function para hallar el mínimo en Pascal

26-May-2011 11:56
Manuel Molina
3 Respuestas

Hola de nuevo,

ah, muchas gracias por la respuesta anteriro.

estoy repasando el código para entregar el programa, pero para mi sorpresa esta funcion no me funciona y no se por qué, pues esta bien codificada. La podeis mirar a ver si se me escapa algo?

(* FUNCION QUE DEVUELVE VALOR MÍNIMO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Minimo(biblioteca: Tbiblioteca; longitud: integer): integer;
(*variables del bucle de biblioteca y min para almacenar el mínimo*)
var
i: integer;
min: integer;

begin

min:= 0;

for i:= 1 to longitud do

if biblioteca[i].alta = true then
begin
if min > biblioteca[i].precio then   (*Calculo del mínimo precio de la biblioteca*)
min:= biblioteca[i].precio;
Minimo:= min;
end;

end;


26-May-2011 14:39
Antonio P.G.

Hola Miguel.

El error es común y sencillo. Si te das cuenta, al principio del programa le asignas el valor 0 a la variable "min", y luego andas preguntando en el buble "¿Es el precio de este libro menor que 'min'?", y así varias veces. Pero... ¿hay acasao un precio menor que 'min', cuyo valor inicial es 0? Claro que no (vamos, supongo que no hay precios negativos ;-).

Entonces, lo que puedes hacer en tu código es asignarle a 'min' un número descomunalmente grande (opción muy chapucera en este caso) y ya está, o bien la opción elegante: asignarle a 'min' el valor del precio del primer libro, y en vez de comenzar el bucle por el primer libro, empezar directamente por el segundo. Creo que la idea es bastante clara.

Por cierto, lo que también queda bien es no solamente dar el ínfimo precio de entre todos los libros de la biblioteca, sino además decir qué libro es el que tiene ese precio (claro, que entonces habría que modificar la cabecera de la función o incluso plantearse si cambiar la función por un procedimiento).

¡Un saludo!


27-May-2011 12:08
Manuel Molina

Hola Antonio,

Muchas gracias por tu pronta respuesta y por tu ayuda.

He codificado como me has dicho y no sale sigue dando el valor de min:= 1;

Es lo último que me queda para que el programa funciones más o menos como quiero, te envío todo el programa para ver si es que me falla el compilador o no se que le falla a la función Minimo, por que no lo entiendo, espero tu respuesta. gracias.

PROGRAM Bibliotecas;

(*CONSTANTES DEL PROGRAMA, EL TAMAÑO MÁXIMO DE LA LÍNEA Y DE LA BIBLIOTECA*)
CONST
(*Tamaño de la biblioteca*)
  TAMBIBLIOTECA = 5;  
(*Tamaño máximo de la línea*)  
  TAMMAXI     = 25;
TYPE
(* REGISTRO ANIDADO QUE DEFINE LAS CARACTERÍSTICAS DE CADA LIBRO *)
  (* Datos del Préstamo *)
Tprestado = record
nom_apellidos : string [TAMMAXI];
email         : string [TAMMAXI];
fecha  : integer;
codigo_libro  : integer;
end;

(* Datos del libro *)
Tlibro = record
datos  : Tprestado;
codigo : integer;
titulo : string [TAMMAXI];
autor  : string [TAMMAXI];
tema   : string [TAMMAXI];
precio : integer;
alta   : Boolean;
activo : Boolean;
end;

(* -- TABLA SOBRE LA QUE VAMOS A TRABAJAR EN EL PROYECTO BIBLIOTECA --*)
Tbiblioteca = array[1..TAMBIBLIOTECA] of Tlibro;
(* -- FICHERO SOBRE LA QUE VAMOS A ALMACENAR LOS DATOS DE LA BIBLIOTECA--*)
  Tfichero = file of Tlibro;

(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!! FUNCIONES Y PROCEDIMIENTOS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)

(* -- LEE DEL TECLADO TODA LA INFORMACIÓN DE UN LIBRO QUE SE LE PASA--*)
PROCEDURE lee_libro(var libro: Tlibro);

begin

writeln;
libro.alta:= true;  (*Siempre el alta de un libro es true*)
libro.activo:=false; (*Siempre el es false hasta que se modifique el libro *)
writeln('Codigo: ');
readln(libro.codigo);
writeln('Titulo: ');
readln(libro.titulo);
writeln('Autor: ');
readln(libro.autor);
writeln('Tema: ');
readln(libro.tema);
writeln('Precio: ');
readln(libro.precio);
writeln;

end;
(*--PARA BUSCAR POSICION LIBRE Y DAR ALTA UN LIBRO --*)
PROCEDURE alta_libro(VAR biblioteca: Tbiblioteca; longitud: integer);
(*variables para almacenar las búsquedas*)
var

encontrado : Boolean;
posicionlibre : integer;
fin : Boolean;
i: integer;

begin

encontrado:= false; (* Cuando sea TRUE es que he encontrado la posición *)
posicionlibre:= 1; (* Empiezo a buscar por la uno *)
i:= 1;  (* Para ir recorriendo la tabla *)
fin:= false; (* He llegado al final de la tabla *)

(*for i:= 1 to longitud do*)

  begin

While(encontrado = false) AND (fin = false) do (*aplicamos bucle mientras las condicienes de encontrado y fin sea false *)
 
begin

if biblioteca[i].alta = false then begin (*Si alta es false y encontrado es verdadero obtenemos una posición libre*)
encontrado := true;
posicionlibre := i;
end

else

if i <= TAMBIBLIOTECA then begin  (*sumamos 1 posición a la posición libre*)
i:=i+1;
writeln('avanzo una posición hasta' ,i);
end

else
 
fin:= true;
end;

end;

if fin = true then   (* Se nos indica cuando no tenemos más posiciones libres en la biblioteca *)
writeln('No hay sitio en la tabla para los libros');
if encontrado = true then
begin
lee_libro(biblioteca[posicionlibre]);
writeln('Se ha guardado el libro en la posicion',posicionlibre);
end;
end;

(* PRESENTAR LISTADOS DE LA BIBLIOTECA *)
PROCEDURE imprime_libro(libro: Tlibro);  

begin
                                       
writeln('--------------------------------------');
writeln('----------LISTADO POR LIBRO-----------');
writeln('--------------------------------------');
writeln('alta : ', libro.alta);
writeln('Prestado: ', libro.activo);
writeln('Codigo : ', libro.codigo);
writeln('Titulo : ', libro.titulo);
writeln('Autor : ' , libro.autor);
writeln('Tema : ', libro.tema);
writeln('Precio : ', libro.precio);
       writeln;
writeln('--------------------------------------');

end;
(* PROCEDIMIENTO QUE NOS IMPRIME POR PANTALLA LOS DATOS DEL LIBRO *)
PROCEDURE imprime_biblioteca(biblioteca: Tbiblioteca; longitud: integer);

var

i: integer;

begin

for i:= 1 to longitud do

begin
if biblioteca[i].alta = true then  
imprime_libro(biblioteca[i]);
end;

end;

(* PROCEDIMIENTO PARA INTRODUCIR DATOS DE LOS PRESTAMOS*)
Procedure hacer_prestamo(Var biblioteca: Tbiblioteca; longitud: integer; buscado: integer);
Var
 i: integer;
Begin
 For i:= 1 To longitud Do
     Begin
     If biblioteca[i].codigo = buscado Then
 biblioteca[i].activo := true;
 end;
 Begin
         writeln(' Introducir Nombre y Apellido: ');
         readln(biblioteca[i].datos.nom_apellidos);
         writeln(' Introducir Email:  ');
         readln(biblioteca[i].datos.email);
         writeln(' Introducir Fecha: ');
         readln(biblioteca[i].datos.fecha);
 writeln('Introducir Codigo libro: ');
 readln(biblioteca[i].datos.codigo_libro);
     End;
   
End;

(* PROCEDIMIENTO PARA IMPRESION DE PRESTAMOS*)
PROCEDURE imprime_prestamo(biblioteca: Tbiblioteca; longitud: integer);

var
i:integer;
begin

for i:= 1 to longitud do;
writeln('----------------------------------------');
writeln('-----LISTADO DE LIBROS PRESTADOS--------');
writeln('----------------------------------------');
Writeln('Nombre y Apellido: ', biblioteca[i].datos.nom_apellidos);
writeln('Email: ' , biblioteca[i].datos.email);
writeln('Fecha de prestamo: ' , biblioteca[i].datos.fecha);
writeln('Codigo Libro: ', biblioteca[i].datos.codigo_libro);
end;

(* PROCEDIMIENTO QUE NOS IMPREME POR PANTALLA EL PROCEDIMIENTO ANTERIOR *)
PROCEDURE imprime_prestados(biblioteca: Tbiblioteca; longitud: integer);

var

i:  integer;

begin

for i:= 1 to longitud do;

begin
imprime_prestamo(biblioteca, TAMBIBLIOTECA);
end;

end;

(* -- CON ESTE PROCEDIMIENTO PRETENDO BUSCAR Y MODIFICAR SU ESTADO DE ALTA a BAJA --*)
PROCEDURE baja(var biblioteca: Tbiblioteca; longitud: integer; buscado: integer);

var

      i  : integer;
encontrado: Boolean;

begin
(* Variable encontrado siempre a false *)
encontrado:= false;

for i:= 1 to longitud do

begin
if biblioteca[i].codigo = buscado then  (*Si el codigo de la biblioteca es igual al introducido se llama al procedimiento imprime_libro*)
biblioteca[i].alta:= false;
imprime_libro(biblioteca[i]);
end;

if not encontrado = false then begin (* Si  la busqueda anterior no se produce no lee la siguiente línea*)
writeln('Libro no encontrado');
end;

end;
(* PROCEDIMIENTO PARA LA BUSQUEDA Y MODIFICACION DE DATOS*)
PROCEDURE modificacion(var biblioteca: Tbiblioteca; longitud: integer; buscado: integer);
(*variables del buble de la tabla y encontrado*)
var
i  : integer;
encontrado: Boolean;

begin

encontrado:= false; (* Ponemos encontrado a false para procedes a la busqueda*)

for i:= 1 to longitud do

begin
(* if que nos permite buscar en la biblioteca un codigo introducido *)
if biblioteca[i].codigo = buscado then begin  
imprime_libro(biblioteca[i]);
encontrado:= true;
biblioteca[i].alta:=true;
end;
(* if que nos permite introducir datos nuevos sobre un mismo libro *)
if biblioteca[i].codigo = buscado then begin
writeln('Modificar Libro');
lee_libro(biblioteca[i]);
end;

end;

begin
(* if que nos indica cuando un codigo de libro no ha sido encontrado *)
if encontrado = false then begin
writeln('Libro no encontrado');
end;

end;


end;
(* PROCEDIMIENTO PARA LA IMPRESION POR PANTALLA DE LOS LIBROS *)
PROCEDURE imprime_libros(biblioteca: Tbiblioteca; longitud: integer);
(* variable del bucle de la biblioteca *)
var
i: integer;
begin

for i:= 1 to longitud do

begin
imprime_libro(biblioteca[i]); (* llamada al procedimiento *)
end;
end;
(* FUNCION QUE DEVUELVE EL VALOR TOTAL DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION suma_coleccion(biblioteca: Tbiblioteca; longitud: integer): integer;
(*variable del bucle de la biblioteca *)
var

i: integer;
suma: integer;

begin

suma:= 0;

for i:= 1 to longitud do


if biblioteca[i].alta = true then
begin
suma:= suma + biblioteca[i].precio; (*calculo donde sumamos todos libros de la biblioteca *)
suma_coleccion:= suma;
end;

end;

(* FUNCIÓN QUE DEVUELVE VALOR MÁXIMO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Maximo(biblioteca: Tbiblioteca; longitud: integer): integer;
(*variables del buble y para almacenar el maximo del precio*)
var

i: integer;
max: integer;

begin

max:= 0;

for i:= 1 to longitud do

if biblioteca[i].alta = true then
begin
if max < biblioteca[i].precio then   (*Calculo del maximo precio de la biblioteca *)
  max:= biblioteca[i].precio;
  Maximo:= max;
end;
end;

(* FUNCION QUE DEVUELVE VALOR MÍNIMO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Minimo(biblioteca: Tbiblioteca; longitud: integer): integer;
(*variables del bucle de biblioteca y min para almacenar el mínimo*)
var
i: integer;
 min: integer;
begin

min:= 1;

for i:= 2 to longitud do

if biblioteca[i].alta = true then
begin
if min > biblioteca[i].precio then   (*Calculo del mínimo precio de la biblioteca*)
min:= biblioteca[i].precio;
Minimo:= min;
end;
end;

(* FUNCION QUE DEVUELVE EL VALOR MEDIO DE LA COLECCION DE LA BIBLIOTECA *)
FUNCTION Media(biblioteca: Tbiblioteca; longitud: integer): real;
(*Variables del bucle y suma_coleción*)
var

i: integer;
suma: integer;

begin

suma:= 0;

for i:= 1 to longitud do


if biblioteca[i].alta = true then
begin
suma:= suma + biblioteca[i].precio; (*calculo para averiguar la media del valor del precio de la biblioteca*)
Media:= suma / (TAMBIBLIOTECA);
end;

end;
(* PROCEDIMIENTO DONDE ENGLOBA LAS 4 FUNCIONES DONDE SE PIDEN EL CÁLCULO DE VALORES DE LA BIBLIOTECA*)
Procedure Resultados( biblioteca: Tbiblioteca; longitud: integer);

Begin
writeln;
writeln(' Suma: ', suma_coleccion(biblioteca, TAMBIBLIOTECA));
writeln(' Maximo:  ', Maximo(biblioteca, TAMBIBLIOTECA));
writeln(' Minimo: ', Minimo(biblioteca, TAMBIBLIOTECA));
writeln(' Media: ', Media(biblioteca, TAMBIBLIOTECA):0:1);
writeln;
End;

(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!   FUNCIONES DE FICHERO  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)

(*-- ALMACENA DATOS LEIDOS DE UN FICHERO --*)
PROCEDURE graba_fichero(nombre: string; var biblioteca: Tbiblioteca; longitud: integer);
Var
 i : integer;
 fichero : Tfichero;
Begin
 assign(fichero, nombre);
rewrite(fichero);

for i:= 1 to longitud do
if(biblioteca[i].alta = true) then         (* DEBE DE GUARDAR SOLO LOS LIBROS QUE COMO ALTA SEA TRUE*)
write(fichero, biblioteca[i]);

close(fichero);
End;

(*-- LEE DATOS DEL FICHERO --*)
PROCEDURE lee_fichero(nombre: string; var biblioteca: Tbiblioteca; longitud: integer);

Var
 i : integer;
fichero : Tfichero;

Begin
 i := 0;

assign(fichero, nombre);
reset(fichero);

   while ( not(eof(fichero)) AND (i<TAMBIBLIOTECA) ) do begin
   i := i+1;
   read(fichero, biblioteca[i]);

end;

close(fichero);

End;

(*-- FUNCIÓN QUE PRESENTA MENÚ Y DEVUELVE OPCIÓN ELEGIDA --*)
FUNCTION Menu: INTEGER;
(*VARIABLE DE LAS DIFERENTES OPCIONES DEL MENÚ*)
VAR

opc: integer;

BEGIN
(*BUCLE*)
repeat
(* PRESENTACIÓN EN PANTALLA DEL MENÚ Y LAS OPCIONES A ELEGIR *)
writeln('-----------------------------');
writeln('MENU DE GESTION DE BIBLIOTECA');
writeln('-----------------------------');
writeln;
writeln('1. ALTA DE LIBRO');
writeln('2. BAJA DE LIBRO');
writeln('3. DATOS DE PRESTAMO');
writeln('4. MODIFICACION DE DATOS');
writeln('5. GUARDAR DATOS EN FICHEROS');
writeln('6. LECTURA DE DATOS DE FICHERO');
writeln;
writeln('***PRESENTACION DE LISTADO DE BIBLIOTECA***');
writeln;
writeln('7. LISTADO DE TODOS LOS LIBROS DE LA BIBLIOTECA');
writeln('8. LISTADO DE LIBROS PRESTADOS');
writeln('9. LISTADO DE PRECIOS MAXIMOS, MINIMOS, LA MEDIA Y EL VALOR TOTAL DE LA COLECCION');  

writeln('10. SALIR');
writeln('OPCION:  ');
readln(opc);
until ( (opc>=1) and (opc <=9)or(opc=10));

Menu := opc;
End;
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!       VARIABLES GLOBALES         !!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
VAR

biblioteca: Tbiblioteca; (*variable de registro*)
opc  : integer; (*variable de menú*)
nombre    : string; (*variable de utilización, guardar y leer de fichero*)
buscado   : integer;     (*variable de procedimiento de busqueda*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!    PROGRAMA PRINCIPAL          !!!!!!!!!!!!!!!!!!!!!!!!!!!*)
(*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*)  
BEGIN
(*Bucle*)
repeat

opc:= Menu;

case opc of

1: alta_libro(biblioteca, TAMBIBLIOTECA); (*llamada procedimiento para altas de libro*)
 
2: begin (*codigo para dar de baja un libro*)
writeln('Introducir codigo del libro, para dar de baja: ');
readln(buscado);
baja(biblioteca, TAMBIBLIOTECA, buscado); (*LLamada procedimiento*)
  end;
3:  begin  (*codigo para introducir datos de prestamos de libros*)
writeln('Codigo de libro a prestar');
readln(buscado);
hacer_prestamo(biblioteca, TAMBIBLIOTECA, buscado);
end;
4: begin (*codigo para modificar datos de libro*)
writeln('Introducir codigo de libro a modificar: ');
readln(buscado);
modificacion(biblioteca, TAMBIBLIOTECA, buscado);(*LLamada procedimiento*)
end;
5: begin (*Codigo para grabar fichero*)
writeln('Introduzca el nombre del fichero de datos: ');
readln(nombre);
graba_fichero(nombre, biblioteca, TAMBIBLIOTECA);  (*LLamada procedimiento*)
  end;
6: begin (*Codigo para lectura de fichero*)
writeln('Introduzca el nombre del fichero: ');
readln(nombre);
lee_fichero(nombre, biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
imprime_biblioteca(biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
  end;
7: imprime_biblioteca(biblioteca, TAMBIBLIOTECA);(*LLamada procedimiento*)
 
8: imprime_prestados(biblioteca, TAMBIBLIOTECA); (*LLamada procedimiento*)

9: begin (*codigo para sacar estadisticas del precio de los libros*)
writeln('--------------------------------------------------------------');
writeln('LISTADO DE PRECIOS MAXIMOS, MINIMOS, LA MEDIA Y EL VALOR TOTAL');
writeln('--------------------------------------------------------------');
Resultados(biblioteca, TAMBIBLIOTECA);
end;

 
end;
until(opc=10);


END.


27-May-2011 18:37
Nacho Cabanes (+32)

Es que no has hecho lo que te dijo Antonio: no se trata de que des al mínimo el valor prefijado "1", sino el primer valor de tu lista.

Es decir, la línea

min:= 1;

debería ser

min:= biblioteca[1].precio;






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)