T.A.P.
Técnicas Actuales de Programación
Curso: 2018/19
|
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
N no lectivo, N fiesta, N estudio, N exámenes, N N clase, N clase anulada |
Clases: {aula: 0.20S} {horario: jueves 10:40-11:30, viernes 9:40-11:30
Laboratorios: {aula: AI.1} {horario: 15:00-17:30}
Tutorias: {con las excepciones que se indiquen en GAUR, generalmente, J 8:00-10:00, V 8:00-9:00, JV 12:00-13:30}
El programa de la asignatura se corresponde casi en su totalidad con un curso de Java, puesto que es posiblemente el lenguaje que mejor soporta las técnicas actuales de programación. A lo largo del desarrollo del curso se irán destacando las técnicas que Java incluye o facilita.
La última versión estable de Java es la 10 -que ha sustituido a la 9 en sólo 6 meses-, pero nos quedaremos con la 8 porque, a la par de la introducción de la versión 9, el mantenimiento del entorno de desarrollo que utilizaremos (Netbeans) pasó de manos de Oracle (la empresa propietaria de Java) a Apache (fundación para desarrollo de software libre), y la versión actual no ha terminado de implantar algunas de las características que se encontraban en la anterior.
También es cierto que la versión 9 de Java introdujo la posibilidad de organizar todo el desarrollo en módulos (entre otras cosas), y esto está soportado por Netbeans 9 pero no por el 8.
Por otro lado, la versión 8 introdujo, entre otras características, la "programación funcional". No se estudirá esto en el curso (sí se comentará en qué consiste y se pondrá en contexto) porque en la práctica supone introducir una visión muy distinta de la programación más extendida (la "imperativa") y no se dipone de tiempo (que además no sería poco... puede ser un curso aparte).
Con todo ello nos quedamos con que:
* usaremos básicamente las capacidades de Java 7
* la programación funcional introducida en Java 8 quedará fuera del temario
* veremos la estructuración en módulos introducida en Java 9 sin practicarla por falta de un IDE
Documentación de utilidad:
* La referencia definitiva del lenguaje Java {suficiente: versión 7}
{actual: versión 10}
* La documentación de la plataforma SE{suficiente: versión 7}
{actual: versión 10}
* Los "tutoriales" de Java
Acceso al estado de evaluación personalizado
Nota: antes de entregar cualquier ejercicio hay que, por lo menos, "adecentar" el código. Lo correcto sería incluso escribir la documentación, pero por lo menos hay que dejarlo "listo para revista": eliminar ficheros abandonados, lineas de código de prueba, etc...
SEPTIEMBRE
TEMA 1 - INTRODUCCIÓN
Continuamos donde lo dejamos...
... y quedamos a punto de ver la Máquina Virtual
Continuamos donde lo dejamos...
... y pasamos a lo siguiente:
TEMA 2 - USO DEL ENTORNO DE DESARROLLO
Qué JDK instalar: definitivamente parece que
Netbeans 8
no puede con JDK 10, así que descargaremos el
JDK 8
(en realidad se puede usar JDK 10 y "trampear" Netbeans 9 para añadir funcionalidades de Netbeans 8, pero a riesgo de que dé algún problema)
Continuamos donde lo dejamos...
... y casi terminamos.
Sólo nos ha faltado hacer un "HolaMundo" con Netbeans así que lo hacemos...
Importancia de los comentarios y la documentación; los "TODO"; identificadores: convenio de nombrado, idoneidad; refactoring;
... y pasamos a lo siguiente:
Adelanto de los puntos 1 y 2 del
TEMA 6 - INTERFACES GRÁFICOS
OCTUBRE
Nos quedó pendiente ver los menús en los GUIs... y sigue pendiente para mañana
Nos sigue quedando pendiente ver los menús en los GUIs...
... y además lo de los espacios de nombres
TEMA 3 - ELEMENTOS BÁSICOS DEL LENGUAJE
Continuamos donde nos quedamos con los elementos básicos del lenguaje...
(* el pdf ha cambiado ligeramente respecto al día anterior, pero los cambios no afectan a lo ya visto.)
... nos quedamos en los "break", "continue",...
Se trata de calcular el número π con precisión de cuatro decimales mediante la serie:
La especificación de cuatro decimales hace referencia al criterio de parada en la suma de términos de
la serie, no a la presentación de la solución, que se hará normalmente mediante System.out.println(.)
y que nos mostrará un número de decimales que no podemos controlar por ahora.
public static double pi() { double pi = 0.0; for (int i = -1; i <= 100_000_000; ) pi += 2.0/(i+=2)/(i+=2); return pi*4; }
Los programas que se utilizan para calcular PI con un número de decimales extremadamente alto utilizan series evolucionadas a partir de la sorprendente fórmula descubierta por Ramanujan en 1910 y demostrada no hace mucho tiempo:
Su convergencia es exponencial y ya el primer término aporta 6 decimales. Puede ser un buen ejercicio utilizar esta fórmula para el cálculo de PI, aunque enseguida se verá que es "demasiado buena" para lo que podemos hacer con variables primitivas (e incluso con otros recursos que nos aporta Java).
Escriba una RUTINA que determine si un número dado es perfecto o no.
static boolean isPerfect(long n) { //TODO hacer lo necesario para que "isPerfect" retorne "true" o "false" si n es perfecto o no. }
Un número perfecto es un entero positivo igual a la suma de sus divisores propios. Los divisores propios de un entero positivo son todos sus divisores a excepción de sí mismo. (Ejemplo de número perfecto: el 6, porque sus divisores propios son 1, 2 y 3 y 6=1+2+3.)
Utilizando dicha rutina debera obtener una lista de números perfectos entre el 1 y el 100.000
Listado de Números Perfectos [pdf]
Dedicaremos la hora a "darles vueltas" a los elercicios planteados. (si podemos, terminamos con las sentencias "break", etc...)
Continuaremos "dando vueltas" a los elercicios planteados, y, terminaremos con las sentencias "break", etc...)
En la clase CalculadorDiversoDeNumerosPerfectos
hemos visto el método perfectosMejor()
donde hay un limite a un ciclo for
que no es preciso calcularlo en cada iteración. No sabemos si el compilador "se da cuenta" y lo evita.
Haga las pruebas necesarias para "descubrirlo".
(Ojo, para descubrir un comportamiento así mediante experimentación, lo razonable es hacer pruebas
con un código lo más simplificado posible. La rutina perfectosMejor()
símplemente ha servido para plantearnos la cuestión)
public static void perfectosMejor(long max){ for (long candidato=1; candidato<max; candidato++) { long suma=1; for (int divisor=2;divisor<=Math.sqrt(candidato);divisor++) if (candidato%divisor==0) suma+=divisor+candidato/divisor; if (candidato==suma) System.out.println(candidato); } }
TEMA 4 - ELEMENTOS RELACIONADOS CON LA ORIENTACIÓN A OBJETOS
El pasado lunes emitieron en "La 2" una película sobre Ramanujan.
En la solución del ejercicio sobre PI he añadido algo al respecto
Comentarios sobre el ejercicio propuesto.
Comentados cambios en el pdf de "elementos básicos" (insertada página 6 -matrices-, y cambios en 5 y 18)
Cambiada la página sobre arrays en el pdf de "elementos básicos" para corregir errores.
Comentario: Hay que tener mucho cuidado con la representación decimal...
Hacemos un inciso para ver el punto 3 del
TEMA 6 - INTERFACES GRÁFICOS
La propuesta es localizar en la Web alguna página en la que se propongan ejercicios en Java y donde encontremos al menos uno con un "nivel razonable" para el punto en que nos encontramos (o poco más, ya que es fácil auto-aprender). Con esto hacer lo siguiente:
Las aportaciones realizadas hasta el momento por varios alumnos (un agradecimiento general a ellos) se encuentran más abajo en la sección "Extras".
Todas tienen su interés, pero mencionaré particularmente las dos primeras de la lista "en inglés" por el hecho de que permiten introducir la solución y
someterla test, y esto de los test es algo de lo que tenemos que hablar un poco próximamente (de las clases de test).
Hasta el jueves a las 7:00 se admiten NUEVAS aportaciones
NOVIEMBRE
Volvemos al
TEMA 4 - ELEMENTOS RELACIONADOS CON LA ORIENTACIÓN A OBJETOS
Calculadora [pdf]
Nada qe añadir :-)
TEMA 5 - MECANISMO DE TRATAMIENTO DE EXCEPCIONES Y ERRORES
Matrices [pdf]
Nada qe añadir :-)
Finalizamos con el punto 3 del
TEMA 6 - INTERFACES GRÁFICOS
TEMA 7 - EL CONTENIDO DE LA BIBLIOTECA DE CLASES
Object
nos queda profundizar en equals(.)-hashCode()-clone()
Dibujando en componentes Swing (JPanel) [pdf]
Fabricar otra subclase de JPanel con un método que pueda recibir un array dobles y representarlos como histograma.
Cuidar un poco la presentación para que no resulte "desagradable".
Como idea "extra": el mismo panel podría incluir un slider (llevarlo ya integrado) de modo que al desplazarlo permitiría variar el ancho y la separación de las baras del histograma.
Más ideas "extras": pueden hacerse paneles similares para "diagramas de tarta", otros tipos de gráficas; también para otros "gadgets"... velocímetros, relojes,...
Como ejemplo: la mejor solución obtenida el curso pasado para este ejercicio.
equals(.)-hashCode()-clone()
(volver al hashCode() generado por NetBeans)clone()
La práctica siguiente nos obliga a adelantar el
TEMA 8 - Entrada y salida de datos
DICIEMBRE
I/O: Babel [pdf]
Sin más ;)>
Volvemos hacia atrás para ver el
TEMA 7 - EL CONTENIDO DE LA BIBLIOTECA DE CLASES
TEMA 9 - Hilos
Ejecución paralela y temporizada. [pdf]
Video ejemplo de resultadoTEMA 10 - Cliente/servidor
No programado pero interesante: Bases de datos
create database actaspv; use actaspv; CREATE TABLE estadisticas ( `id` VARCHAR(8) NOT NULL, `numPalabras` INT NOT NULL, `validas` INT NOT NULL, `media` DOUBLE NOT NULL, `desviacionTipica` DOUBLE NOT NULL, PRIMARY KEY (`id`), UNIQUE INDEX `id_UNIQUE` (`id` ASC));
En ocasiones alguna pregunta nada habitual puede ser de interés general....
He diseñado mi propio tipo de letra. ¿Cómo puedo incluirlo en mi aplicación?
El mundo del diseño de "Fonts" (cosa de las Bellas Artes) y su uso en computadoras no es trivial. Todo lo necesario para el uso con Java se encuentra en el correspondiente tutorial de Oracle. Como respuesta concreta a cómo contar con un tipo de letra propio, se puede entresacar del mismo este sencillo código:
try { GraphicsEnvironment. getLocalGraphicsEnvironment(). registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf")); } catch (IOException|FontFormatException e) { /*Handle exception*/ }
donde se añade al entorno gráfico una nueva "font" que, en concreto, es de tipo "trueType" y se lee de un fichero (puede ser de otro tipo y en general leerse de cualquier "Stream" -véase documentación de Font.createFont-)
Quiero hacer un GUI de calculadora que pueda cambiar entre estándar y científica. ¿Cómo lo hago?
La manera más razonable puede ser agrupar en un par de paneles los botones que deben aparecer y desaparecer en cada caso para proceder a quitar y poner dichos paneles cuando se seleccione un modo u otro.
La siguiente imagen muestra una estructura sencilla de ejemplo: el "frame" lleva un "menuBar" donde se encuentran las dos opciones de paso de un modo a otro. Además hay un panel ("contenedorComun") para los botones que no varian entre ambos modos (componentes no visibles en la imagen) y un contenedor para intercambiar botoneras ("contenedorParaIntercambios"). Inicialmente este contenedor lleva dentro el panel de la calculadora estandar, pero se podrá intercambiar con el contenedor de la botonera cientifica que está "aparcado" en la sección "Other Components".
El modo de hacer el intercambio es extremadamente sencillo: basta con asociar a cada opción de menú su acción correspondiente como se ve en la siguiente imagen. No es otra cosa que sacar todo lo que haya en el panel (la botonera actual) y meter la botonera seleccionada. Una vez hecho esto terminamos con un "pack()" que le dice al "layoutManager" que haga su labor (que "empaquete" convenientemente el contenido)
(nota.- en sentido estricto el panel "contenedorParaIntercambios" es innecesario, pero se ha puesto por clarificar el ejemplo.)
Estoy dibujando histogramas en un JPanel... ¿Cómo puedo centrar el texto de una etiqueta?
Para esto hay que manejar la "métrica" de la fuente de texto que se usa en cada momento. La métrica de una fuente tiene que ver con una serie de conceptos medibles.
En el método paint(Graphics g)
se puede acceder a la fuente a través g.getFont()
/ g.setFont()
, y la métrica se obtiene mediante g.getFontMetrix()
.
Es sencillo conocer la anchura de una String con la metrica activa en un momento dado: simplemente basta con usar g.getFontMetrics.stringWidth("Texto a dibujar")
, que nos da el número de pixels que ocupará.
El siguiente ejemplo muestra una String
centrada en un punto (200,100) -con la coordenada Y en su línea base- y unas líneas cruzadas en dicho punto para comprobar que "funciona" correctamente.