;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; FUNCIONES DEL TIPO ABSTRACTO DE DATOS: DONANTE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCI?N DE CREACI?N ;===================== (define (crear-donante nombre num_donaciones grupo rh) (list (list 'nombre nombre) (list 'numero_donaciones num_donaciones) (list 'grupo grupo) (list 'rh rh) ) ) ; FUNCIONES DE CONSULTA O ACCESO ;================================ (define (nombre donante) (cadr (assoc 'nombre donante)) ) (define (numero_donaciones donante) (cadr (assoc 'numero_donaciones donante)) ) (define (grupo donante) (cadr (assoc 'grupo donante)) ) (define (rh donante) (cadr (assoc 'rh donante)) ) ; FUNCIONES DE MODIFICACI?N ;========================== (define (cambiar-nombre! donante nuevo) (set-cdr! (assoc 'nombre donante) (list nuevo)) ) (define (cambiar-donaciones! donante nuevo) (set-cdr! (assoc 'numero_donaciones donante) (list nuevo)) ) (define (cambiar-grupo! donante nuevo) (set-cdr! (assoc 'grupo donante) (list nuevo)) ) (define (cambiar-rh! donante nuevo) (set-cdr! (assoc 'rh donante) (list nuevo)) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PROGRAMA ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (programa) ;; FUNCIONES AUXILIARES ;; FUNCI?N QUE MUESTRA LAS OPCIONES DEL MEN? Y PERMITE ELEGIR UNA DE ELLAS (define (pedir-opcion) (newline) (display "Elige una opcion" ) (newline) (display "1 -> Introducir un donante desde el teclado" ) (newline) (display "2 -> Cargar donantes desde un fichero" ) (newline) (display "3 -> Grabar los donantes en un fichero" ) (newline) (display "4 -> Mostrar los donantes por pantalla" ) (newline) (display "5 -> Mostrar la estructura interna de la lista de donantes" ) (newline) (display "0 -> Salir" ) (newline) (newline) (display " --> ") ;; lee la opci?n elegida (read) ) ;; LEE UN DATO DEL TECLADO Y LO DEVUELVE ;; Par?metro: ;; mensaje: cadena de texto que indica el dato que se solicita ;; (define (leer-teclado mensaje) (display mensaje) (display " --> ") (read) ) ;; LEE UNA CADENA DEL TECLADO Y LA DEVUELVE ;; Par?metro: ;; mensaje: cadena de texto que indica el dato que se solicita ;; (define (leer-teclado-cadena mensaje) (display mensaje) (display " (escribe con comillas) ") (display " --> ") ;; Elimina el car?cter de salto de l?nea #\newline, si existe (if (char=? (peek-char) #\newline) (read-char) ) ;; Lee los caracteres hasta que encuentra el car?cter de salto de línea #\newline (do ( (cadena (make-string 0) (string-append cadena (string caracter))) (caracter (read-char) (read-char)) ) ;; ((char=? #\newline caracter) ;; devuelve la cadena leída cadena ) ;; ) ) ;; LEE DEL TECLADO UNA SERIE DE CARACTERES "SIN COMILLAS" Y LOS DEVUELVE COMO CADENA ;; Par?metro: ;; mensaje: cadena de texto que indica el dato que se solicita ;; (define (leer-teclado-cadena-sin-comillas mensaje) (display mensaje) (display " (escribe sin comillas) " ) (display " --> ") ;; Elimina el car?cter #\newline, si existe (if (char=? (peek-char) #\newline) (read-char) ) ;; (do ( (cadena (make-string 0) (string-append cadena (string caracter))) (caracter (read-char) (read-char)) ) ;; ((char=? #\newline caracter) ;; devuelve la cadena le?da cadena ) ;; ) ) ;; INTRODUCIR LOS DATOS DE UN DONANTE DESDE EL TECLADO (define (leer-donante-teclado) (crear-donante (leer-teclado-cadena "Nombre del donante: ") (leer-teclado "Numero de donaciones: ") (leer-teclado "Grupo Sanguineo: ") (leer-teclado "Factor rh: ") ) ) ;; FUNCI?N QUE PONE LAS COMILLAS INICIALES Y FINALES A UN TEXTO Y LO DEVUELVE COMO CADENA ;; Par?metro: ;; texto: caracteres a los que se les va a poner las comillas ;; (define (poner-comillas texto) (string-append (string #\") texto (string #\")) ) ; CARGAR LOS DONANTES DESDE UN FICHERO (define (leer-donantes-fichero) (define puerto (open-input-file (leer-teclado-cadena-sin-comillas "nombre del fichero"))) (do ( (lista_donantes () (append lista_donantes (list (crear-donante (poner-comillas nombre) (read puerto) (read puerto) (read puerto) ) ) ) ) (nombre (read puerto) (read puerto)) ) ;; Condicion de salida del bucle ((eof-object? nombre) ;; Se cierra el puerto asociado al fichero de entrada (close-input-port puerto) ;; Se devuelve la lista de donantes lista_donantes ) ;; No hay cuerpo del bucle ) ) ;; GRABAR LOS DATOS DE LOS DONANTES EN UN FICHERO ;; Par?metro: ;; lista_donantes: lista que contiene a los donantes que se van a grabar ;; (define (grabar-donantes-fichero lista_donantes) (do ( (puerto (open-output-file (leer-teclado-cadena-sin-comillas "nombre del fichero"))) (lista_auxiliar lista_donantes (cdr lista_auxiliar)) ) ;; Condicion de salida del bucle ((null? lista_auxiliar) ; Se cierra el puerto asociado al fichero de salida (close-output-port puerto) ) ;; Cuerpo del bucle (display (nombre (car lista_auxiliar)) puerto) (display " " puerto) (display (numero_donaciones (car lista_auxiliar)) puerto) (display " " puerto) (display (grupo (car lista_auxiliar)) puerto) (display " " puerto) (display (rh (car lista_auxiliar)) puerto) (newline puerto) ) ) ;; MOSTRAR POR PANTALLA LOS DATOS DE LOS DONANTES ;; Par?metro: ;; lista_donantes: lista que contiene a los donantes que se van a mostrar ;; (define (mostrar-donantes lista_donantes) (do ( (lista_auxiliar lista_donantes (cdr lista_auxiliar)) ) ;; Condicion de salida del bucle ((null? lista_auxiliar) (newline)) ;; Cuerpo del bucle (display "Nombre: ") (display (nombre (car lista_auxiliar))) (newline) (display "Numero de donaciones: ") (display (numero_donaciones (car lista_auxiliar))) (newline) (display "Grupo sanguineo: ") (display (grupo (car lista_auxiliar))) (newline) (display "Factor rh: ") (display (rh (car lista_auxiliar))) (newline) (newline) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CUERPO DEL PROGRAMA DE DONANTES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (do ;; Variables ( ;; LISTA EN LA QUE SE VAN A ALMACENAR LOS DONANTES (donantes ()) ;; (opcion (pedir-opcion) (pedir-opcion)) ) ;; condicion de salida ((= opcion 0) (display "fin del programa")) ;; cuerpo del bucle (cond ;; INTRODUCIR UN DONANTES DESDE EL TECLADO ((= opcion 1) (display "Introduccion de datos de un donante") (newline) ;; Uso obligatorio de set! (set! donantes (append donantes (list (leer-donante-teclado)))) ) ;; CARGAR DONANTES DESDE UN FICHERO ((= opcion 2) (display "Carga de los datos de los donantes contenidos en un fichero") (newline) (set! donantes (append donantes (leer-donantes-fichero))) (display "Datos cargados") (newline) ) ;; GRABAR LOS DONANTES EN UN FICHERO ((= opcion 3) (display "Grabacion de los datos de los donantes en un fichero") (newline) (grabar-donantes-fichero donantes) (display "Datos grabados") (newline) ) ;; MOSTRAR LOS DONANTES POR LA PANTALLA ((= opcion 4) (mostrar-donantes donantes) ) ;; MOSTRAR LA ESTRUCTURA INTERNA DE LA LISTA DE DONANTES ((= opcion 5) (display donantes) (newline) ) ;; CONTROL DE ERRORES (else (display "Opcion incorrecta") (newline) ) ) ) ) ;;LLAMADA AL PROGRAMA (programa)