Cómo concatenar archivos en bash

Concatenar archivos con bash

Muchas veces tengo, por ej., los archivos guia1.txt guia2.txt... guian.txt en el directorio guias y los quiero concantenar a todos en un único archivo:

Utilizaremos como estándar de documentación:
# para referirnos a superusuario (root)
$ para referirnos a un usuario

$ for i in $(ls /guias/guia*.scm); do
> cat $i >> guia_completa.txt;
> done

$less guia_completa.txt


Finalmente el archivo "guia_completa.txt" tiene todos las guias concatenadas en orden.

Programación Funcional con Scheme parte III

;;----------------------------------------------------------------;;
;; Ejercicio 1
;; Contrato: dada una posición en una lista,
;; devuelve el elemento en ESA posición, sin
;; modificar la lista.
;;-----------------------------------------------------------------;;

(define obtener_elemento (lambda (n lista)
(letrec(
(devolver_n (lambda (cont n lista)
(if (null? lista)
"null"
(if (= n cont)
(car lista)
(devolver_n (+ cont 1) n (cdr lista))
);if
);if
);lambda
);devolver_n
)
(devolver_n 1 n lista)
);let
);lambda
);define

(obtener_elemento 1 (list '11 '12 '13 '14 '())) ;=> 11


;;---------------------------------------------------------------------------;;
;; Contrato: dada una posicion en una lista,
;; devuelve el lado izquierdo de la misma.
;;---------------------------------------------------------------------------;;

(define devolver_l_izquierdo (lambda (posicion lista)
(letrec(
(largo (length lista))
(devolver_lista (lambda (cont pos lista)
(if (null? lista)
"null"
(if (= pos cont)
(car lista)
(cons (car lista) (devolver_lista (+ cont 1) pos (cdr lista)))

);if
);if
);lambda
);devolver_n
)

(devolver_lista 1 posicion lista)
);letrec
);lambda
);define

(devolver_l_izquierdo 3 (list '11 '12 '13 '14 '5 '7)) ;=> (11 12 . 13)
(devolver_l_izquierdo 9 (list '11 '12 '13 '14 '5 '7)) ;=> (11 12 13 14 5 7 . "null")


;;---------------------------------------------------------------------------;;
;; Contrato: eliminar de la lista el elemento en
;; la posicion indicada, y devolver el resto de la
;; lista.
;;---------------------------------------------------------------------------;;

(define extraer_elemento (lambda (pos listado)
(letrec (
(funcion (lambda (contador posicion lista)
(if (null? lista)
'()
(if (= contador posicion)
(cdr lista)
(cons (car lista) (funcion (+ contador 1) posicion (cdr lista)))
);if
);if
);lambda
);funcion
)
(funcion 1 pos listado)
);letrec
);lambda
);define

(extraer_elemento 5 (list 10 20 30 40 50));=>(10 20 30 40)


;;---------------------------------------------------------------------------;;
;; Contrato: dada una lista, devolver un nueva
;; lista con los elementos de la primera
;; invertidos.
;; Requiere de: OBTENER_ELEMENTO(N LISTA),
;; EXTRAER_ELEMENTO(N LISTA).
;;---------------------------------------------------------------------------;;

(define invertir_lista (lambda (listado)
(letrec (
(invertir (lambda (contador lista)
(if (null? lista)
'()
(cons (obtener_elemento (length lista) lista) (invertir_lista (extraer_elemento (length lista) lista)))
);if
);lambda
);invertir
)
(invertir 1 listado)
);letrec
);lambda
);define

(invertir_lista (list 5 4 3 2 1 0));=>(0 1 2 3 4 5)


;;---------------------------------------------------------------------------;;
;; Contrato: dadas dos listas, concatenarlas.
;; Donde la segunda lista aparezca en orden
;; inverso.
;;---------------------------------------------------------------------------;;

(define concat-inv (lambda (lista1 lista2)
(letrec(
(concatenar (lambda (l1 l2)
(if (and (null? l1) (null? l2))
'()
(if (null? l1)
(cons (car l2) (concatenar l1 (cdr l2)))
(if (null? l2)
(cons (car l1) (concatenar (cdr l1) '()))
(cons (car l1) (concatenar (cdr l1) l2))
);if
);if
);if
) ;lambda
);concatenar
)
;(concatenar lista1 (reverse lista2)); REVERSE es una función de Scheme.
(concatenar lista1 (invertir_lista lista2))
);let*
);lambda
);define

(concat-inv '(1 2) '(8 7 6 5 4 3)) ;=> (1 2 3 4 5 6 7 8 )


;;--------------------------------------------------------------------------;;
;; Ejercicio 2
;; Contrato: dados una lista y un elemento. Si el
;; elemento se encuentra en la lista devuelve #t,
;; caso contrario #f.
;;---------------------------------------------------------------------------;;

(define elemento_en_lista (lambda (elemento lista)
(if (null? lista)
#f
(if (eqv? elemento (car lista))
#t
(elemento_en_lista elemento (cdr lista))
);if
);if
);lambda
);define

;(elemento_en_lista '5 (list 1 2 3 4 5 6)) ;=> #t


;;---------------------------------------------------------------------------;;
;; Contrato: dadas dos listas y un elemento.
;; Si el elemento se encuentra en AMBAS listas
;; devuelve #t, caso contrario #f.
;;---------------------------------------------------------------------------;;

(define n_en_2_listas (lambda (elemento lista1 lista2)
(if (or (null? lista1) (null? lista2))
#f
(if (and (n_en_lista elemento lista1) (n_en_lista elemento lista2))
#t
#f
);if
);if
);lambda
);define

;(n_en_2_listas '5 (list 3 4 2 1) (list 1 2 3 4 6));=> #f
;(n_en_2_listas '5 (list 3 4 5 2 1) (list 1 2 3 6));=> #f
;(n_en_2_listas '5 (list 3 4 2 1) (list 1 2 3 4 5 6));=> #f
;(n_en_2_listas '5 (list 5 3 4 2 1) (list 5 1 2 3 4 5 6))=> #t


;;--------------------------------------------------------------------------;;
;; Ejercicio 3
;; Dado una lista y un elemento, devolver la cantidad
;; de atomos a la izquierda del elemento.
;;---------------------------------------------------------------------------;;

(define posicion_de_elemento (lambda (elem listado)
(letrec (
(devolver_posicion (lambda (posicion elemento lista)
(if (null? lista)
"null"
(if (eqv? (car lista) elemento)
posicion
(devolver_posicion (+ posicion 1) elemento (cdr lista))
);if
);if
);lambda
);devolver_posicion
)
(devolver_posicion 0 elem listado)
);letrec
);lambda
);define

(posicion_de_elemento 0 (list 'a 'b 'c 4 5 1 'd));=> "null"
(posicion_de_elemento 1 (list 'a 'b 'c 4 5 1 'd));=> 5


;;---------------------------------------------------------------------------;;
;; Ejercicio 4
;; Contrato: dados una lista y un elemento. Si el
;; elemento no se encuentra en la lista es agregado
;; al final de la misma.
;;---------------------------------------------------------------------------;;

(define agregar_en_lista_si_no_esta (lambda (elemento lista)
(if (null? lista)
'()
(if (eqv? (car lista) elemento)
(agregar_en_lista_si_no_esta (cdr lista))
(cons lista elemento)
);if
);if
);lambda
);define

(agregar_en_lista_si_no_esta 42 (list '38 '39 '40 '41 )) ;=> (38 39 40 41 42)


;;---------------------------------------------------------------------------;;
;; Ejercicio 5
;; Contrato: en caso de que el año sea bisiesto
;; devuelve 29, caso contrario devuelve 28.
;;---------------------------------------------------------------------------;;

(define bisiesto (lambda (año)
(if (= (modulo año 400) 0)
29
(if (and (= (modulo año 4) 0) (not(= (modulo año 100) 0)))
29;es bisiesto
28;no bisiesto
);if
);if
);lambda
);define

;(bisiesto 1900);=> 28
;(bisiesto 1700);=>28
;(bisiesto 1600);=>29
;(bisiesto 2004);=>29


;;---------------------------------------------------------------------------;;
;; Contrato: dada una posición en una lista,
;; devuelve el elemento en ESA posición.
;;---------------------------------------------------------------------------;;

(define obtener_elemento (lambda (n lista)
(letrec(
(devolver_n (lambda (cont n lista)
(if (null? lista)
"null"
(if (= n cont)
(car lista)
(devolver_n (+ cont 1) n (cdr lista))
);if
);if
);lambda
);devolver_n
)

(devolver_n 1 n lista)
);let
);lambda
);define

;;---------------------------------------------------------;;
;; Contrato: determinar si una fecha
;; ingresada es valida.
;;---------------------------------------------------------;;

(define fecha_es_valida( lambda (lista)
(let* (
(año (caddr lista))
(mes (cadr lista))
(dia (car lista))
(meses (list 31 (bisiesto año) 31 30 31 30 31 31 30 31 30 31))
)
(if (null? lista)
#f
(if (< año 0)
(display "Ingresaste un año que no es válido")
(if (and (> dia 0) (< dia (+ (obtener_elemento mes meses) 1)))
#t
(display "Cantidad de días no válido para ese mes")
);if
);if
);if
);let*
);lambda
);define

(fecha_es_valida (list 12 12 1986)) ;=> #t
(fecha_es_valida (list 29 02 1900)) ;=> #f (1900 no fue año bisiesto)


;;---------------------------------------------------------------------;;
;; Ejercicio 6
;; Contrato: Insertar un elemento en una lista en
;; la posición indicada.
;;---------------------------------------------------------------------;;

(define insertar_elemento (lambda (pos elem listado)
(letrec (
(largo (length listado))
(insertar (lambda (contador posicion elemento lista)
(if (null? list)
(cons lista elemento)
(if (= contador posicion)
(cons elemento lista)
(cons (car lista)(insertar (+ contador 1) posicion elemento (cdr lista)))
);if
);if
);lambda
);insertar
)
(insertar 1 pos elem listado)
);letrec
);lambda
);define

;(insertar_elemento 6 '6 (list 1 2 3 4 5));


;;---------------------------------------------------------------------------;;
;; Contrato: dados una lista y un elemento.
;; Si el elemento se encuentra en la lista
;; devuelve su posicion, caso contrario "null".
;;---------------------------------------------------------------------------;;

(define posicion_en_lista (lambda (elem listado)
(letrec (
(devolver_posicion (lambda (posicion elemento lista)
(if (null? lista)
"null"
(if (eqv? elemento (car lista))
posicion
(devolver_posicion (+ posicion 1) elemento (cdr lista))
);if
);if
);lambda
);devolver_lista
)
(devolver_posicion 1 elem listado)
);letrec
);lambda
);define

;(posicion_en_lista 's (list 'a 'n 'a 'l 'i 'a 's))


;;---------------------------------------------------------------------------;;
;; Contrato: dados una lista y un elemento.
;; Si el elemento se encuentra en la lista
;; devuelve #t, caso contrario #f.
;;---------------------------------------------------------------------------;;

(define elemento_en_lista (lambda (elemento lista)
(if (null? lista)
#f
(if (eqv? elemento (car lista))
#t
(elemento_en_lista elemento (cdr lista))
);if
);if
);lambda
);define

;(elemento_en_lista '4 (list 1 2 3))


;;---------------------------------------------------------------------------;;
;; Contrato: agrego el elemento junto a los demás
;; elementos iguales de la lista o al final de la
;; misma, en caso de no encontrar semejantes.
;;---------------------------------------------------------------------------;;

(define agrupar_elem_lista (lambda (elemento lista)
(if (null? lista)
(cons lista elemento)
(if (elemento_en_lista elemento lista)
(insertar_elemento (posicion_en_lista elemento lista) elemento lista)
(insertar_elemento (+ (length lista) 1) elemento lista)
);if
);if
);lambda
);define

;(agrupar_elem_lista '4 '(1 2 3 4 5 6 4)) ;=>(1 2 3 4 4 5 6 4)


;;---------------------------------------------------------------------------;;
;; Contrato: la función AGRUPAR recibe dos
;; argumentos: lista y elemento, en cualquier
;; orden. Comprueba cuál de ellos es un elemento
;; y cuál una lista. A continuación agrega el
;; elemento junto a los demás elementos iguales
;; de la lista o al final de la misma, en caso
;; de no encontrar semejantes.
;;---------------------------------------------------------------------------;;

(define agrupar (lambda (parametro1 parametro2)
(if (list? parametro1)
(agrupar_elem_lista parametro2 parametro1)
(agrupar_elem_lista parametro1 parametro2)
);if
);lambda
);define

(agrupar '(a b b c c) 'c);=> (a a b b c c c)
(agrupar 'c '(a b b c c));=> (a a b b c c c)


;;---------------------------------------------------------------------------;;
;; Ejercicio 7
;; Contrato dadas dos listas: l1 y l2, concatena
;; las mismas devolviendo un única lista resultante
;; por los elementos de l1 más los de l2.
;; Aplicable a listas propias e impropias.
;;---------------------------------------------------------------------------;;

(define concatenar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (not (null? lista1))
(cons (car lista1) (concatenar_listas (cdr lista1) lista2))
(if (not (null? lista2))
(cons (car lista2) (concatenar_listas lista1 (cdr lista2)))
'()
);if
);if
);if
);lambda
);define

;(concatenar_listas (list '0 '1 '2 '3) (list '4 '5 '6));=> (0 1 2 3 4 5 6 ) Probado con listas impropias.


;;---------------------------------------------------------------------------;;
;; Contrato: la función APLANAR reciba como
;; argumento una expresión simbólica y elimina
;; todos los paréntesis que aparezcan en esa
;; expresión, devolviendo como resultado una
;; lista con todos los átomos que aparezcan en
;; el argumento.
;; Requiere de: (CONCATENAR l1 l2)
;;---------------------------------------------------------------------------;;

(define aplanar (lambda (lista)
(if (null? lista)
'()
(if (list? (car lista))
(concatenar_listas (aplanar (car lista)) (aplanar (cdr lista)))
(concatenar_listas (list (car lista)) (aplanar (cdr lista)))
);if
);if
);lambda
);define

(aplanar '( (1 2 3) (9 (2 3 4) ) ( ( ( ( 3 4 ( 7 ) ) ) ) ) ));=> (1 2 3 9 2 3 4 3 4 7)
(aplanar '( 1 2 3)) ;= >(1 2 3)


;;---------------------------------------------------------------------------;;
;; Ejercicio 8
;; Contrato: eliminar de la lista el elemento
;; indicado, y devolver el resto de la lista.
;;---------------------------------------------------------------------------;;

(define extraer_elemento (lambda (pos listado)
(letrec (
(funcion (lambda (contador posicion lista)
(if (null? lista)
'()
(if (= contador posicion)
(cdr lista)
(cons (car lista) (funcion (+ contador 1) posicion (cdr lista)))
);if
);if
);lambda
);funcion
)
(funcion 1 pos listado)
);letrec
);lambda
);define

;(extraer_elemento 1 (list 10 20 30 40 50));=>(10 20 30 40)


;;---------------------------------------------------------------------------;;
;; Contrato: dada una posición en una lista,
;; devuelve el elemento en ESA posición.
;;---------------------------------------------------------------------------;;

(define obtener_elemento (lambda (n lista)
(letrec(
(devolver_n (lambda (cont n lista)
(if (null? lista)
"null"
(if (= n cont)
(car lista)
(devolver_n (+ cont 1) n (cdr lista))
);if
);if
);lambda
);devolver_n
)

(devolver_n 1 n lista)
);let
);lambda
);define

;(obtener_elemento 1 (list '11 '12 '13 '14 '())) ;=> 11


;;------------------------------------------------------------------------;;
;; Contrato: dada una lista, rotar el último
;; elemento hacia la izquierda.
;; Requiere de: (OBTENER_ELEMENTO pos lista)
;; (EXTRAER_ELEMENTO pos lista)
;;------------------------------------------------------------------------;;

(define rotar_izquierda (lambda (lista)
(if (null? lista)
'()
(cons (obtener_elemento (length lista) lista) (extraer_elemento (length lista) lista))
);if
);lambda
);define

;(rotar_izquierda (list 1 2 3 4 5 6 0)); → (0 1 2 3 4 5 6)


;;---------------------------------------------------------------------------;;
;; Contrato dadas dos listas: l1 y l2, concatena
;; las mismas devolviendo un única lista resultante
;; por los elementos de l1 más los de l2.
;; Aplicable a listas propias e impropias.
;;---------------------------------------------------------------------------;;

(define concatenar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (not (null? lista1))
(cons (car lista1) (concatenar_listas (cdr lista1) lista2))
(if (not (null? lista2))
(cons (car lista2) (concatenar_listas lista1 (cdr lista2)))
'()
);if
);if
);if
);lambda
);define

;(concatenar_listas (list '0 '1 '2 '3) (list '4 '5 '6));=>(0 1 2 3 4 5 6) Probado con listas impropias.


;;---------------------------------------------------------------------------;;
;; Contrato: la función APLANAR reciba como
;; argumento una expresión simbólica y elimina
;; todos los paréntesis que aparezcan en esa
;; expresión, devolviendo como resultado una
;; lista con todos los átomos que aparezcan
;; en el argumento.
;; Requiere de: CONCATENAR_LISTAS(l1 l2)
;;---------------------------------------------------------------------------;;

(define aplanar (lambda (lista)
(if (null? lista)
'()
(if (list? (car lista))
(concatenar_listas (aplanar (car lista)) (aplanar (cdr lista)))
(concatenar_listas (list (car lista)) (aplanar (cdr lista)))
);if
);if
);lambda
);define

;(aplanar '( (1 2 3) (9 (2 3 4) ) ( ( ( ( 3 4 ( 7 ) ) ) ) ) ));=> (1 2 3 9 2 3 4 3 4 7)


;;----------------------------------------------------------------------;;
;; Contrato: dada una lista, rotar el último
;; elemento hacia la derecha.
;; Requiere de: APLANAR(lista) ;;
;;----------------------------------------------------------------------;;

(define rotar_derecha (lambda (lista)
(if (null? lista)
'()
(aplanar (cons (extraer_elemento 1 lista) (list (obtener_elemento 1 lista))))
);if
);lambda
);define

(rotar_derecha (list 5 0 1 2 3 4)); => (0 1 2 3 4 5)


;;----------------------------------------------------------;;
;; Ejercicio 9
;; Contrato: dado un valor, devuelve el
;; cuadrado del mismo.
;;----------------------------------------------------------;;

(define cuadrado (lambda (x)
(expt x 2)
);lambda
);define


;;---------------------------------------------------------------------------;;
;; Contrato: dada una lista de valores, devuelve
;; una lista con cada uno de los cuadrados de la
;; primer lista.
;;---------------------------------------------------------------------------;;

(define calcula_cuadrados (lambda (lista)
(map
(lambda (y)
(cuadrado y)
);lambda
lista
);map
);lambda
);define

(calcula_cuadrados (list 1 2 3 4)); → (1 4 9 16)


;;---------------------------------------------------------------------------;;
;; Ejercicio 10
;; Contrato: eliminar de la lista el elemento
;; indicado, y devolver el resto de la lista.
;;---------------------------------------------------------------------------;;

(define extraer_elemento_e (lambda (elemento lista)
(if (null? lista)
'()
(if (eqv? elemento (car lista))
(extraer_elemento_e elemento (cdr lista))
(cons (car lista) (extraer_elemento_e elemento (cdr lista)))
);if
);if
);lambda
);define

;(extraer_elemento_e 6 '(1 2 3 4 5 6));=> (1 2 3 4 5)


;;---------------------------------------------------------------------------;;
;; Contrato: dados una lista y un elemento.
;; Si el elemento se encuentra en la lista
;; devuelve #t, caso contrario #f.
;;---------------------------------------------------------------------------;;

(define elemento_en_lista (lambda (elemento lista)
(if (null? lista)
#f
(if (eqv? elemento (car lista))
#t
(elemento_en_lista elemento (cdr lista))
);if
);if
);lambda
);define

;(elemento_en_lista '5 (list 1 2 3 4 5 6));=> #t


;;-------------------------------------- ------------------------------------;;
;; Contrato: restar 2 listas. Devolver una lista
;; con los elementos de la primera lista que no
;; están en la segunda.
;; Requiere de: (EXTRAER_ELEMENTO_E e l)
;;---------------------------------------------------------------------------;;

(define restar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (null? lista2)
lista1
(if (elemento_en_lista (car lista2) lista1)
(restar_listas (extraer_elemento_e (car lista2) lista1) (cdr lista2))
(restar_listas lista1 (cdr lista2))
);if
);if
);if
);lambda
);define

;(restar_listas '(1 2 3 4 5 6 7 8 9) '(2 5 7 9)); => (1 3 4 6 8)
;(restar_listas '(1 2 3 4 5 6 7 8 9) '(1 2 3 4 5)); => (6 7 8 9)


;;---------------------------------------------------------------------------;;
;; Ejercicio 11
;; Contrato dadas dos listas: l1 y l2, concatena
;; las mismas devolviendo un única lista resultado
;; de los elementos de l1 más los de l2.
;;---------------------------------------------------------------------------;;

(define concatenar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (not (null? lista1))
(cons (car lista1) (concatenar_listas (cdr lista1) lista2))
(if (not (null? lista2))
(cons (car lista2) (concatenar_listas lista1 (cdr lista2)))
'()
);if
);if
);if
);lambda
);define

;(concatenar_listas (list '0 '1 '2 '3) (list '4 '5 '6));Probado con listas impropias.


;;---------------------------------------------------------------------------;;
;; Contrato: la función APLANAR reciba como
;; argumento una expresión simbólica y elimina
;; todos los paréntesis que aparezcan en esa
;; expresión, devolviendo como resultado una
;; lista con todos los átomos que aparezcan en
;; el argumento.
;; Requiere de: (CONCATENAR_LISTAS l1 l2)
;;---------------------------------------------------------------------------;;

(define aplanar (lambda (lista)
(if (null? lista)
'()
(if (list? (car lista))
(concatenar_listas (aplanar (car lista)) (aplanar (cdr lista)))
(concatenar_listas (list (car lista)) (aplanar (cdr lista)))
);if
);if
);lambda
);define

;(aplanar '( (1 2 3) (9 (2 3 4) ) ( ( ( ( 3 4 ( 7 ) ) ) ) ) ));=> (1 2 3 4 2 3 4 3 4 7)


;;---------------------------------------------------------------------------;;
;; Contrato: dados una lista y un elemento.
;; Si el elemento se encuentra en la lista
;; devuelve #t, caso contrario #f.
;;---------------------------------------------------------------------------;;

(define elemento_en_lista (lambda (elemento lista)
(if (null? lista)
#f
(if (eqv? elemento (car lista))
#t
(elemento_en_lista elemento (cdr lista))
);if
);if
);lambda
);define

;(elemento_en_lista '5 (list 1 2 3 4 5 6));=> #t


;;------------------------------------------------------------------------ --;;
;; Contrato: devuelve una lista con los elementos
;; de la primer lista y los de la segunda que no
;; aparecen en la primera.
;; Requiere de: (ELEMENTO_EN_LISTA e, lista)
;; (APLANAR lista)
;;---------------------------------------------------------------------------;;

(define sumar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (null? lista2)
lista1
(if (elemento_en_lista (car lista2) lista1)
(sumar_listas lista1 (cdr lista2))
(sumar_listas (aplanar (cons lista1 (cons (car lista2) '()))) (cdr lista2))
);if
);if
);if
);lambda
);define

;(sumar_listas '(1 2 3) '(4 5));=>(1 2 3 4 5)
;(sumar_listas '(1 2 3) '(3 4 5 2 1));=>(1 2 3 4 5)
;(sumar_listas '(1 2 3 4 5) '(3 4 5 2 1 0));=>(1 2 3 4 5 0)


;;---------------------------------------------------------------------------;;
;; Ejercicio 12
;; Contrato: obtiene el número máximo de listas
;; anidadas que aparecen en una lista. ;;---------------------------------------------------------------------------;;

(define obtener_profundidad (lambda (lista)
(if (null? lista)
0
(if (list? (car lista))
(if (>= (+ (obtener_profundidad (car lista)) 1) (obtener_profundidad (cdr lista)))
(+ (obtener_profundidad (car lista)) 1)
(obtener_profundidad (cdr lista))
);if
0
);if
);if
);lambda
);define


(obtener_profundidad '((1 (2)) (((5 7))) (((((4))))))); → 5

Programación Funcional con Scheme parte II

;;----------------------------------------------------------------------;;
;; Ejercicio 1
;; Contrato: define una estructura que represente un
;; punto en el plano. Crear una función que calcule
;; la distancia entre dos puntos dados recibiendo
;; como parámetros la estructura de cada uno.
;;----------------------------------------------------------------------;;

(define-struct punto (x y))

(define distancia_entre_2_ptos (lambda (punto1 punto2)
(let (
(cuadrado (lambda (x)
(* x x)
);lambda
); cuadrado

(punto1 (make-punto 1 1))
(punto2 (make-punto 3 3))
)
(sqrt ( + (cuadrado (- (punto-x punto2) (punto-x punto1)))
(cuadrado (- (punto-y punto2) (punto-y punto1)))))
);let
);lambda
);define

(define p1 (make-punto 1 1))
(define p2 (make-punto 3 3))

(distancia_entre_2_ptos p1 p2)


;;----------------------------------------------------------------------------;;
;; Ejercicio 2
;; Contrato: definie una estructura que represente un
;; punto en el espacio. Crear una función que calcule
;; el centro de gravedad de una lista de puntos en el
;; espacio representados por la estructura definida
;; previamente.
;;----------------------------------------------------------------------------;;

(define-struct punto3d (x y z))

(define centro_de_gravedad (lambda (lista_puntos)
(letrec (
(centro (lambda (n puntos)
(if (null? puntos)
'(0 0 0)
(list
(+ (/ (punto3d-x (car puntos)) n) (car (centro n (cdr puntos))))
(+ (/ (punto3d-y (car puntos)) n) (cadr (centro n (cdr puntos))))
(+ (/ (punto3d-z (car puntos)) n) (caddr (centro n (cdr puntos))))
);list
);if
);lambda
);centro
)
(centro (length lista_puntos) lista_puntos)
);letrec
);lambda
);define

(define p1 (make-punto3d 2 4 2))
(define p2 (make-punto3d 3 9 4))
(define p3 (make-punto3d 2 1 2))
(define p4 (make-punto3d 1 1 2))

(centro_de_gravedad (list p1 p2 p3 p4))


;;---------------------------------------------------------------------------;;
;;Ejercicio 3
;; Contrato: define una estructura que represente un
;; automóvil con las sgtes. características:
;; - consumo promedio en km /Lts
;; - velocidad promedio km /Hora
;; usar la estructura para calcular el consumo de
;; combustible y el tiempo que tardo en recorrer dos
;; puntos representados por estructuras del ejercicio 1
;;---------------------------------------------------------------------------;;

(define-struct automovil(consumo velocidad))
(define-struct punto(x y))

(define distancia_entre_2_ptos (lambda (punto1 punto2)
(sqrt ( +
(expt (- (punto-x punto2) (punto-x punto1)) 2)
(expt (- (punto-y punto2) (punto-y punto1)) 2)
)
)
)
)

(define tiempo_y_consumo (lambda (punto1 punto2)
(list
(/ (distancia_entre_2_ptos punto1 punto2) (automovil-consumo auto))
(/ (distancia_entre_2_ptos punto1 punto2) (automovil-velocidad auto))
)
)
)

(define p1 (make-punto 1 1))
(define p2 (make-punto 3 3))
(define auto (make-automovil 1 123))

(tiempo_y_consumo p1 p2)


;;----------------------------------------------------------------------;;
;; Ejercicio 4
;; Contrato: calcule la distancia máxima entre dos
;; puntos de una lista, usando el predicado MAP y
;; estructuras.
;;----------------------------------------------------------------------;;

(define-struct punto(x y))

(define distancia_2p (lambda (p1 p2)
(round (sqrt (+ (expt (- (punto-x p2) (punto-x p1)) 2) (expt (- (punto-y p2) (punto-y p1)) 2))))
);lambda
);define

(define maximo (lambda (lista)
(if (null? lista)
'()
(if (null? (cdr lista))
(car lista)
(if (> (car lista) (maximo (cdr lista)))
(car lista)
(maximo (cdr lista))
);if
);if
);if
);lambda
);maximo


(define max_distancia_p_lista (lambda (punto lista_distancias)
(maximo
(map
(lambda (pp) (distancia_2p punto pp))
lista_distancias
);map
);maximo
);lambda
);define


(define punto1 (make-punto 2 4))
(define punto2 (make-punto 3 9))
(define punto3 (make-punto 2 1))
(define punto4 (make-punto 1 1))

(max_distancia_p_lista punto1 (list punto2 punto3 punto4))


;;-------------------------------------------------------------------------;;
;; Ejercicio 5
;; Contrato: cuenta la cantidad de palabras
;; y de caracteres de un archivo.
;;-------------------------------------------------------------------------;;

(define (cant_palabras_archivo archivo)
(letrec (
(contar_palabras(lambda (archivillo cant_palabras)
(let (
(palabra (read archivillo))
);let
(if (eof-object? palabra)
cant_palabras
(contar_palabras archivillo (+ cant_palabras 1))
);if
);let
);lambda
);contar_palabras
)
(contar_palabras archivo 0)
);letrec
);define

(define archivo1 (open-input-file "archivo.txt"))
(display "La cantidad de palabras es: ")
(cant_palabras_archivo archivo1)
(close-input-port archivo1)


(define (cant_caracteres_archivo archivo)
(letrec (
(contar_caracteres(lambda (archi cant_caracteres)
(let (
(caracter (read-char archi))
);let
(if (eof-object? caracter)
cant_caracteres
(contar_caracteres archi (+ cant_caracteres 1))
);if
);let
);lambda
);contar_caracteres
)
(contar_caracteres archivo 0)
);letrec
);define

(define archivo2 (open-input-file "archivo.txt"))
(display "La cantidad de caractéres es: ")
(cant_caracteres_archivo archivo2)
(close-input-port archivo2)


;;-----------------------------------------------------;;
;; Ejercicio 6
;; Contrato: muestra por pantalla
;; un archivo de texto.
;;-----------------------------------------------------;;

(define (mostrar_archivo archivo)
(letrec (
(leer_archivo (lambda(archi contenido)
(let* (
(palabra (read archi))
(contenido_aux (cons contenido (cons palabra '())))
(contenido contenido_aux)
)
(if (eof-object? palabra)
contenido
(leer_archivo archi contenido)
);if
);let*
);lambda
);leer_archivo
);letrec
(leer_archivo archivo "")
);letrec
);define


(define archivo (open-input-file "archivo.txt"))
(mostrar_archivo archivo)
(close-input-port archivo)


;;------------------------------------------------------------------------;;
;; Ejercicio 7
;; Contrato: lee una operación aritmética simple
;; (+, -) y la convierta en sintáxis de Scheme.
;;------------------------------------------------------------------------;;

(let (
(convierte_operacion (lambda (ecuacion)
(let (
(parametro1 (car ecuacion))
(operador (car (cdr ecuacion)))
(parametro2 (car (cdr (cdr ecuacion))))
)
(cons operador (cons parametro1 (cons parametro2 '())))
);let
);lambda
);convierte_operacion
)
(convierte_operacion (list 34 + 2))
);let

;; Nota: como el enunciado dice "una operación
;; aritmética simple", solo contemplo el ingreso
;; de un único operador y de dos operandos.

Programación Funcional con Scheme parte I

Si bien en mi caso, la facultad es la parte aburrida e insulsa de la informática, me ha tocado una materia en la cual intentan hacernos ver diferentes paradigmas de programación. Por lo que debo destacar, que por esta vez, me divertí aprendiendo. A continuación, algunas funciones, desarrolladas bajo el paradigma funcional puro con el lenguaje SCHEME ;)


;;----------------------------------------------------------------------------;;
;; Ejercicio 1 ;;
;; Contrato: cuenta la cantidad de apariciones de un
;; elemento en una lista. El primer parámetro es el
;; elemento a buscar y el segundo la lista en la que
;; se deber buscar.
;;----------------------------------------------------------------------------;;

(define count-elem(lambda (num lista)
(if (null? lista)
0
(if (= (car lista) num)
(+ (count-elem num (cdr lista)) 1)
(count-elem num (cdr lista))
);if
);if
);lambda
);define

(count-elem 3 '(1 3 4 3)) ;=> 2


;;-------------------------------------------------------;;
;; Ejercicio 2
;; Contrato: calcula el factorial del valor
;; pasado en n.
;;-------------------------------------------------------;;

(define factorial (lambda (x)
(if (= x 0)
1
(* x (factorial(- x 1)))
);if
)
)

(factorial 0) ;=> 1
(factorial 1) ;=> 1
(factorial 2) ;=> 2


;;--------------------------------------------;;
;; Ejercicio 3
;; Contrato: devuelve el length
;; de una lista.
;;--------------------------------------------;;

(define largo_lista(lambda (lista)
(if (null? lista)
0
(+ (largo_lista (cdr lista)) 1)
);if
);lambda
);define

(largo_lista (list '1 '23 '31 '4 '() '7)); => 6 Probado en lista impropia.
(largo_lista (list '1 '23 '31)) ; => 3 Probado en lista propia.


;;---------------------------------------------------------------------------;;
;; Ejercicio 4 ;
;; Contrato: dados dos parametros en formato hora,
;; a traves de una lista (hh mm ss).
;; Devuelve la suma de las mismas.
;;---------------------------------------------------------------------------;;

(define suma-horas (lambda (hora1 hora2)
(let (
(mtotal (+ (cadr hora1) (cadr hora2)))
(stotal (+ (caddr hora1) (caddr hora2)))
(htotal (+ (car hora1) (car hora2)))
)
(if (> (+ stotal) 59)
(if (> (+ mtotal 1) 59)
(cons (+ htotal 1) (cons (modulo (+ mtotal 1) 60) (cons (modulo (+ stotal) 60) '())))
(cons (+ htotal) (cons (modulo (+ mtotal 1) 60) (cons (modulo (+ stotal) 60) '())))
);if
:
(if (> (+ mtotal 1) 59)
(cons (+ htotal 1) (cons (modulo (+ mtotal) 60) (cons (modulo (+ stotal) 60) '())))
(cons (+ htotal) (cons (modulo (+ mtotal) 60) (cons (modulo (+ stotal) 60) '())))
);if
);if
);let
);lambda
);define


(define devolver_listado (lambda (lista h_salida)
(if (null? lista)
'()
(cons
(list (caar lista) (suma-horas (cdr (car lista)) h_salida))
(devolver_listado (cdr lista) (suma-horas (cdr (car lista)) h_salida))
);cons
);if
);lambda
);define


(define listado (list
(cons "Federico Lacroze" '(00 00 00))
(cons "Jose Artigas" '(00 03 00))
(cons "Pn Parata" '(00 02 00))
(cons "Dr Fco Beiro" '(00 02 00))
(cons "El libertador" '(00 02 00))
(cons "Antonio Devoto" '(00 02 00))
(cons "Cnelfo Lynch" '(00 02 00))
) ;solo por una cuestión de comodidad no incorporé la lista completa.
)
(devolver_listado listado '(05 30 00))


;;--------------------------------------------------------------------------;;
;; Ejercicio 5
;; Contrato: dadas dos listas, concatenarlas en una
;; única lista resultante.
;;--------------------------------------------------------------------------;;

(define concatenar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (not (null? lista1))
(cons (car lista1) (concatenar_listas (cdr lista1) lista2))
(if (not (null? lista2))
(cons (car lista2) (concatenar_listas lista1 (cdr lista2)))
'()
);if
);if
);if
);lambda
);define

(concatenar_listas (list '1 '2 '3 '()) (list '4 '5 '()));=> (1 2 3 () 4 5 ()) Probado con listas impropias.
(concatenar_listas (list '1 '2 '3) (list '4 '5));=> (1 2 3 4 5) Probado con listas propias.
(concatenar_listas (list '()) (list '()));=> (() ()) Probado con listas vacías


;;---------------------------------------------------------------------------;;
;; Ejercicio 6 ;; Contrato: devuelve el primer elemento
;; de una lista que es un número, si lo
;; encuentra. Caso contrario, devuelve null.
;;---------------------------------------------------------------------------;;

(define devolver_numero (lambda (lista)
(if (null? lista)
"null"
(if (number? (car lista))
:
(car lista)
(devolver_numero (cdr lista))
);if
);if
);lambda
);define

(devolver_numero (list 'a 'b #f '() 'a 89)) ;=> 89


;;------------- -------------------------------------------------------------;;
;; Ejercicio 7
;; Contrato: recibe como parametro un valor y una
;; lista y retorna la lista con los mismos valores
;; excepto el que se pasó por parámetro que se
;; agregará al final.
;;---------------------------------------------------------------------------;;

(define attach-at-end (lambda (numero lista)
(if (null? lista)
numero
(if (= (car lista) numero)
(attach-at-end numero (cdr lista))
(cons (car lista) (attach-at-end numero (cdr lista)))
);if
);if
);lambda
);define

(attach-at-end '2 (list '1 '2 '3 '2 '2 '4 '2 '5));=> (1 3 4 5 2)


;;---------------------------------------------------------------------------;;
;; Ejercicio 8
;; Contrato: recibe 3 parámetros (dos valores y una
;; lista) y devuelve la lista con todos los componentes
;; que son iguales al primer parametro reemplazados
;; por el valor del tercer parámetro.
;;---------------------------------------------------------------------------;;

(define subst(lambda (c k lista)
(if (null? lista)
lista
(if (eqv? c (car lista))
(cons k (subst c k (cdr lista)))
(cons (car lista) (subst c k (cdr lista)))
);if
);if
);lambda
);define

(subst 'c 'k '( c o c o n u t '()))
(subst 'c 'k '( c o c o n u t ))


;;---------------------------------------------------------------------------;;
;; Ejercicio 9
;; Contrato: devolver de la suma del rango de valor
;; que va desde menor hasta mayor.
;;---------------------------------------------------------------------------;;

(define range-sum (lambda (menor mayor)
(if (> menor mayor)
(display "Los parámteros no son correctos")
(if (= menor mayor)
menor
(+ menor (range-sum (+ menor 1) mayor))
);if
);if
);lambda
);define

(range-sum 1 13)
(range-sum 2 2)


;;--------------------------------------------------------------------------;;
;; Ejercicio 10
;; Contrato: recibe como parametros los puntos de
;; dos rectas y determine el punto de intersección
;; de las mismas. Ecuación de la recta que pasa
;; por dos puntos:
;; (y – y1) / (y2 – y1) = (x – x1) / (x2 - x1)
;;--------------------------------------------------------------------------;;

(define interseccion (lambda (x11 y11 x12 y12 x21 y21 x22 y22)
(let* (
(pendiente1 (/ (- y12 y11) (- x12 x11)))
(pendiente2 (/ (- y22 y21) (- x22 x21)))
(ordenada1 (- y11 (* pendiente1 x11)))
(ordenada2 (- y21 (* pendiente2 x21)))
(x-interseccion (/ (- ordenada2 ordenada1) (- pendiente1 pendiente2)))
(y-interseccion (+ (* pendiente1 x-interseccion) ordenada1))
)
(cons x-interseccion y-interseccion)
);let*
);lambda
);define

(interseccion 0.5 0.5 1 1 1 1 3 3)
(range-sum 13 1)

Cómo relacionar 'Provincia' > 'Departamento' > 'Localidad' > 'Zona' en Django

Es muy común la necesidad de relacionar éstos modelos en Django para algún desarrollo que debamos sacar andando. Por supuesto, generé el modelo de datos de la aplicación para lo cual Django te lo hace muy sencillo. Todo venía de un modo casi trivial hasta que necesité crear una vista del tipo Generic View para el alta de un inmueble. El mismo requería setear las relaciones: 'Provincia' > 'Departamento' > 'Localidad' > 'Zona'. Pero las vistas en Django, del tipo Generic View no permiten acceder a modelos relacionados entre si en más de un nivel de profunidad, por ej.: sólo podía relacionar: 'Zona' > 'Localidad'. Por otro lado, el filtro debía hacerse al revés, desde: 'Provincia' > 'Departamento' > 'Localidad' > 'Zona' y no así 'Zona' > 'Localidad' > 'Departamento' > 'Provincia'.
Es aquí cuando vino a mi salvación "Dajax".

Seguí al pie la letra la instalación / configuración de:
http://wiki.github.com/jorgebastida/django-dajax/

Y del sgte. sitio obtuve el ejemplo: 'País' > 'Provincia': http://www.dajaxproject.com/forms/

Similar a lo que necesitaba, pero imcompleto. Pués faltaba incorporar relaciones y que los datos sean obtenidos de una base de datos y no desde una variable.

A continuación incorporé los cambios antes mencionados requeridos: las relaciones 'Provincia' > 'Departamento' > 'Localidad' > 'Zona' obtenidos de una base de datos.

############
## ajax.py ##
############
from dajax.core import Dajax
from AppInmo.models import Provincia, Departamento, Localidad, Zona

def cargar_provincias(request)
--dajax = Dajax()
--provincias = Provincia.objects.all()
--out = ""
--for provincia in provincias:
----out = "%s