martes, 24 de junio de 2014

Agenda últimas fechas


Quedan dos fechas para el cierre de la cursada. Nos organizaremos de la siguiente manera:


29/6: Última fecha para la entrega del informe del trabajo final (ver más abajo detalles del formato y contenido).

30/6: Clase obligatoria. Las actividades serán las siguientes:

  • Devolución del segundo parcial (notas, errores comunes, etc.)
  • Entrega y defensa de trabajo final: entregan lo que tengan hecho. Implica una reunión con cada grupo para que me muestren el trabajo y problemas que tuvieron.
  • Puesta en conocimiento de los trabajos al curso. No es necesario que se preparen para esta actividad.
  • Últimas consultas sobre trabajos prácticos.

6/7: Última fecha para entrega de trabajos prácticos.

7/7: Recuperatorio del segundo parcial y en casos puntuales previamente acordados recuperatorio del primer parcial.

Informe del trabajo final

El informe del trabajo final forma el 25% de la nota del mismo.

Tiene una longitud de entre 1 y 3 páginas y no debe incluir el código, salvo fragmentos puntuales para hacer algún comentario. Entregar preferentemente en un formato libre (por ejemplo PDF). Esos son los únicos requisitos de formato, aunque sugiero incluir las siguientes secciones:

  • Alumno/s
  • Título del trabajo
  • Resultados logrados y ejemplos de uso
  • Problemas encontrados
  • Estructura del código
Para los trabajos de extensión de un TP el informe deberá estar orientado a lectores que no conozcan los enunciados, es decir, explicando el objetivo de cada ejercicio, cada clase y cada método y si se aplica, ejemplos de uso.

Salvo que me soliciten lo contrario publicaré todos o los mejores trabajos en el blog.

miércoles, 18 de junio de 2014

Segundo parcial

El examen será a partir de las 15:30 (puntual) y antes de esa hora estaré respondiendo consultas del contenido del parcial y probablemente mostraré más ejemplos prácticos. No veremos contenidos nuevos. Después del examen (de 17:30 a 18) podrán hacer consultas del TF y TPs.

La clase del 30 de junio es obligatoria (se toma asistencia). Luego les comento los detalles.


No habrán ejercicios de programación. Como siempre, no es necesario saber el seudocódigo de los algoritmos "de memoria", pero sí entender qué hacen y cómo, entender la estrategia. La mitad de las preguntas será de ejercicios prácticos y la otra mitad de teoría y de aplicar conceptos teóricos. La cantidad de preguntas será mucho mayor que en el primer parcial pero cada una abarcará menos conceptos y tendrá menos opciones.

Los temas son heaps, dispersión y las dos clases sobre grafos, es decir los temas correspondientes a las presentaciones 9, 10, 11 y 12. Por si necesitan complementar con los libros: los capítulos son los siguientes:
  • Aho: capítulos 6 y 7.
  • Basee:  secciones 4.8, 6.5, 6.6, 7.1 a 7.6 y capítulo 8
No se evaluarán temas teóricos no vistos en clase.

sábado, 14 de junio de 2014

Recuperatorio: modalidad y horario

El lunes próximo haremos el recuperatorio del primer parcial. El horario será a partir de las 15:30 (puntual) y antes de esa hora estaré respondiendo las consultas que tengan.

No habrá clase (contenidos nuevos). No es necesario que vayan quienes no recuperan. Sin embarbo por consultas sobre otros temas pueden presentarse a las 17:25.

Tanto el temario como la proporción de teoría/práctica serán iguales que en el parcial. No habrán ejercicios de programación pero sí de interpretar código, formular ecuaciones de T(n) (iterativo y recursivo) y resolver ecuaciones de recurrencia. La cantidad de preguntas será mucho mayor pero cada una abarcará menos conceptos.

miércoles, 11 de junio de 2014

Material trabajos prácticos

Lo siguiente es un resumen del material que tienen disponible para completar los trabajos prácticos. Si encuentran algo incorrecto o tienen algo para comentar, por favor avisen por mail o dejen un comentario.

Como verán, hemos desarrollado gran parte de los TP en clase. No hay problema en que compartan dicho material.

Algo que ya comenté anteriormente: si van a editar código publicado por mí, tengan presente que acostumbro a usar tabuladores para la indentación, por lo que quizás necesiten hacer el reemplazo correspondiente.


TP1: Sugiero a quienes ya lo entregaron que no continúen completandolo sino que inviertan sus esfuerzos en los otros TP y el TF. Quienes entregaron el TP1 lo tienen aprobado.


TP2: Sugiero aprovechar que todavía es posible entregarlo no totalmente completo. Resumo el material que tienen disponible para completarlo:

Ejercicio 1: El 3 de mayo publiqué una versión corregida de la resolución que hicimos en clase (http://unajct.blogspot.com.ar/2014/05/clase-284-y-recursos-tp2.html).

Ejercicio 2: Sugiero que lo resuelvan solo si tienen todos los otros ejercicios completos.

Ejercicio 3: Lo declaramos opcional a cambio de la opcionalidad del Ejercicio 4.

Ejercicio 4: Lo resolvimos en clase, si no me equivoco el 2 de junio.

Ejercicio 5: Publiqué una "ayudita" con todo el ejercicio casi resuelto (http://unajct.blogspot.com.ar/2014/06/ayudita-tp2.html).

Ejercicio 6: Es bastante sencillo. Intenten por lo menos responder la primera parte de la pregunta.

Ejercicio 7: Creo que resolvimos por lo menos uno en clase.

Ejercicio 8: Los puntos a y c quedan anulados por estar mal planteados. El punto b lo resolvimos en clase el 9 de junio.

Ejercicio 9: Lo mostré resuelto rápidamente el 9 de junio.

Ejercicio 10: Es muy sencillo.


TP3: Resumo el material que tienen disponible para completarlo:

Ejercicio 1: Si no me equivoco, en clase lo resolvimos casi por completo. Si hace falta también pueden basarse en el ejercicio 1 del TP2.

Ejercicio 2: Los puntos a y b los trabajamos en clase. Los puntos c y d son simplemente ejecutar el código del enunciado y pegar el resultado.

Ejercicio 3: Para los puntos a y b tienen el seudocódigo en la teoría. El punto c es sencillo: un bloque iterativo que va buscando el padre de nodo hasta llegar a la raíz, invocando al método que se menciona.

Ejercicio 4: Es opcional.


TP4: Resumo el material que tienen disponible para completarlo:

Ejercicio 1: publiqué la resolución de los puntos a, b y c (http://unajct.blogspot.com.ar/2014/05/tp4-rev2.html). El punto d consiste en hacer cambios muy puntuales sobre minHeap.

Ejercicio 2: Consiste en hacer una ejecución del método construir del punto 1.

Ejercicio 3: El punto a es simplemente ejecutar y explicar las líneas del enunciado. El punto c lo mostré detenidamente resuelto en clase. Quedaría el punto b, que es similar al c.

Ejercicio 4: Los puntos a y b son simplemente ejecutar y copiar la salida. El punto c pide una breve opinión, que no requiere fundamentación.


TP5: Está preaprobado, es decir que no es obligatorio entregarlo. Solo quienes hayan entregado todos los anteriores, pueden realizarlo para mejorar el promedio. El enunciado no está listo, pero sugiero que quien esté interesado me avise y comience con la implementación de una clase grafo y el algoritmo DFS. Comparto el código de la clase auxiliar desarrollada en clase.

Clase 9/6

El 9/6 vimos la segunda clase teórica sobre grafos, que comienza con una revisión de los algoritmos de recorridos.

También avanzamos un poco con lo que será el Trabajo Práctico 5. Recuerden que dicho TP se da por preaprobado. El post siguiente habla más sobre el tema.

jueves, 5 de junio de 2014

Ayudita TP2

Les dejo una ayuda para el punto 5 del TP2, además de los datos de prueba de biblioteca que les dejé la otra vez. Si encuentran errores pueden dejar comentarios o avisarme por mail.


a) Recuerden que nbiblioteca (definido en biblioteca_borrador.py) es un nodo de árbol. En el punto 1a se define la función dato. Usándola obtenemos el dato relacionado al nodo, que es un objeto de tipo elementoBiblioteca. La clase elementoBiblioteca es muy sencilla, se puede consultar directamente su método texto.

b) Se puede usar la siguiente función. ¿Qué parámetro le pasaría?

def contarLibros(nodo):
        if(nodo.dato().tipo()=='L'):
                c = 1
        else:
                c = 0
        p = nodo.hijoMI()
        while(p):
                c = c + contarLibros(p)
                p = nodo.hermanoDerecho(p)
        return c

c) Dado que no contamos con un método de eliminación simple (que elimine todo el subárbol), limítese a mencionar las dos operaciones que debería realizar una función mover(libro, origen, destino).

d) Podemos contar la cantidad total de capítulos con una función muy parecida a la del punto b y luego dividirla por la cantidad de libros.

e) Se puede usar la siguiente función:

def medirTextoYTitulos(nodo, enLibro=False):
        """
        Mide la longitud del texto de los parrafos y los
        titulos. El parametro enLibro debe ser True solo
        si el nodo esta dentro de un libro
        """
        if(nodo.dato().tipo()=='L'):
                enLibro = True
        if enLibro:
                c = len(nodo.dato().texto())
        else:
                c = 0
        p = nodo.hijoMI()
        while(p):
                c = c + medirTextoYTitulos(p, enLibro)
                p = nodo.hermanoDerecho(p)
        return c


y una variante de la siguiente:

def medirLibros(nodo):
        if(nodo.dato().tipo()=='L'):
                print " ", nodo.dato().texto(), medirTextoYTitulos(nodo)
        p = nodo.hijoMI()
        while(p):
                medirLibros(p)
                p = nodo.hermanoDerecho(p)
        return c


f) Intente con lo siguiente.

def buscarLibro(buscarDesde, libro, camino=''):
        nodo = buscarDesde
        if(nodo.dato().tipo()=='L'):
                if nodo.dato().texto() == libro.texto():
                        return camino
                else:
                        return None
        p = nodo.hijoMI()
        while(p):
                c = camino + '.' + buscarDesde.dato().texto()
                c = buscarLibro(p, libro, c)
                if c:
                        return c
                p = nodo.hermanoDerecho(p)
        return None


g) medirTextoYTitulos puede contar la cantidad de texto de un subárbol. Debería hacer una variante para que cuente solo los párrafos.

h) Es casi igual al punto g.

i) Usamos una estrategia similar a los anteriores, solo que no continuamos la recursión una vez encontrada una sección.

def seccionesPrimerNivel(nodo):
        if(nodo.dato().tipo()=='S'):
                return 1
        p = nodo.hijoMI()
        c = 0
        while(p):
                c = c + seccionesPrimerNivel(p)
                p = nodo.hermanoDerecho(p)
        return c

Clase 2/6

El 2 de junio vimos la primera parte de grafos y entre todos implementamos un grafo con realización de matriz de adyacencia, con un método para hacer el recorrido DFS. Les dejo la presentación.