Sunteți pe pagina 1din 96

Java TM para Niñ@s

Nadia Ameziane Garcia

Java TM para Niñ@s

Nadia Ameziane Garcia

Copyright

Queda prohibida, salvo excepción prevista en la Ley, cualquier forma de reproducción, distribución, comunicación pública y transformación de esta obra sin contar con la autorización de los titulares de su propiedad intelectual. La infracción de los derechos de difusión de la obra puede ser constitutiva de delito contra la propiedad intelectual (Arts. 270 y ss. del Código Penal).

2017 Nadia Ameziane Garcia.

Diseño de portada: Pixel Dizajn Studio Todas las imágenes del interior obtenidas de Pixabay.com bajo licencia CC0.

Segunda edición, Marzo 2018

Pixabay.com bajo licencia CC0. Segunda edición, Marzo 2018 Java T M es una marca registrada propiedad

Java TM es una marca registrada propiedad de Oracle TM y como tal es mencionada con la primera letra en mayúscula a lo largo de toda la obra.

La autora declina toda responsabilidad respecto a los perjuicios que pudiese causar la aplicación práctica del contenido de este libro.

Intro (para tutores y tutoras)

Ante todo, muchas gracias por tomarte la molestia de hojear este libro, por querer entrar en materia y conocer de primera mano en qué aguas se va a sumergir tu hija, alumno o cualquiera sea la relación que te une al niño que va a aprender de estas páginas.

Quizá seas una persona con conocimientos previos de programación -tal vez incluso una eminencia- que simplemente busca ideas para introducir estos conocimientos de forma creativa o lúdica. En ese caso verás que hay temas por los que este libro pasa de puntillas, y es porque he tratado de hacer pesar más las ideas generales que los detalles, de familiarizar al niño con la forma de expresar instrucciones más que con los mil detalles o posibilidades que cada una podría encerrar.

Si, por contra, no has tenido un contacto previo con esta disciplina, no tengas miedo. Este libro no está pensado para dejar a nadie atrás, y si lo vas siguiendo verás que los conceptos son muy claros y concisos, por lo que seguro que podrás echar una mano si te lo piden. Además después de la introducción encontrarás una guía con todo lo que necesitas preparar en el ordenador para cada capítulo del libro. No te dejaré quedar mal ;)

Tal vez incluso seas un adulto sin complejos que ha comprado este libro para sí mismo, en ese caso ¡enhorabuena también! Estoy convencida de que también puede enseñarte cosas a ti. Aunque lo enfocomo una guía para enseñar a personitas de 8 a 18 años, todo lo que leerás también puede aplicarse a tu caso.

Algunas preguntas que tal vez te estés haciendo

Tal vez te estés preguntando qué puede hacer la programación por los niños. La verdad es que yo sigo preguntándome qué NO puede hacer.

Programar es una excelente forma de construir nuevos puentes en nuestra forma de pensar: nos predispone a abordar de forma LÓGICA las cuestiones que se nos presentan. Nos acostumbra a ORDENAR los datos de que disponemos para abordarlos de forma eficiente. Siempre digo que en toda persona que aprende a programar, a expresarse mediante algoritmos, se produce un click mental que no tiene vuelta atrás. El pensamiento de programador se convierte en una herramienta que nunca se pierde y que resulta útil en muchísimas facetas vitales.

Programando también se ponen a prueba nuestra PACIENCIA y TOLERANCIA A LA FRUSTRACIÓN. A veces un pedazo de código es una partida de ajedrez contra nosotros mismos. De pronto algo no sale y no sabemos por qué, pero simplemente no podemos dejarlo a medias, y programar es algo que sigue ocurriendo en nuestra cabeza de camino al cole, mientras nos duchamos, mientras paseamos… hasta que de pronto la solución al rompecabezas nos ilumina la mente… ¡eureka! La sensación de haber superado un escalón, de haber crecido un

poco más cada vez que esto ocurre es un regalo inmenso para cualquiera, pero más aún para una personita en desarrollo.

Aprender a programar también tiene una dimensión social… destierra de tu mente los prejuicios, las imágenes de niños de 90kg que beben refrescos y no se despegan del ordenador. Tanto en la red como en persona, la programación nos empuja a compartir, contrastar, colaborar… a formar equipos, compartir proyectos y conocimientos, en fijarse en el código que otros han escrito y aprender de sus errores y sus aciertos. A rodearse de otras cabecitas inquietas.

Por último -y no menos importante- programar es DEMOCRÁTICO. No requiere habilidades especiales, no se circunscribe una edad mínima, no se ve limitado por ninguna discapacidad. No necesitas un equipo carísimo, ni licencias de software de pago. Cualquiera puede aprender en cualquier momento.

Tal vez te estés preguntando si programar es una actividad adecuada para tu hijo, que parece ser una persona “de letras”. Aunque desde fuera pueda parecer una magia oscura destinada a cerebritos o gente muy familiarizada con la tecnología, tengo que decirte que programar no es de ni de letras ni de ciencias… sino todo lo contrario. Es una actividad multidisciplinar que trasciende las divisiones más o menos comunes que el sistema educativo se empeña en trazas entre unas y otras materias. Es una herramienta muy potente, que puede servir a la mente artística y creativa del mismo modo que puede satisfacer intereses científicos. Y bueno, humildemente, a veces los mejores programas surgen de la pereza. Del deseo de automatizar tareas tediosas que uno no quiere hacer personalmente -o que quiere reducir a unos pocos segundos- nacen grandes ocasiones de pensar, ingeniar y trabajar el pensamiento abstracto, una herramienta imprescindible para cualquier estudiante.

Por último, pero no menos importante, los objetivos de aprendizaje de este libro. Bien, mi idea al escribirlo no es que el niño o adolescente se convierta en un programador experto, este libro no suple los estudios formales en ese campo. Mi romántico propósito es más bien picar la curiosidad. Trazar un camino lo más fácil posible de seguir, sin una montaña de teoría y de quisquillosas condiciones, para que el lector sea capaz de construir desde el principio pequeños scripts o programas de forma autónoma. Pretendo que el aprendiz de programador se sienta retado, interesado y capaz. Que tenga los conocimientos mínimos para poder llevar a la realidad lo que su imaginación le proponga, y que jamás haga algo de forma mecánica, sin entender el motivo. Confío en que su propia necesidad de ir más allá le llevará a buscar la ampliación de los conocimientos que yo apenas le he esbozado, y nada me haría más feliz que saber que un lector que termina este libro lo acaba con ganas de seguir profundizando, porque si hay una verdad universal en el arte de la programación es que jamás termina uno de aprenderlo.

Intro (para aprendices) ¡Enhorabuena! Ya eres casi programador o programadora. Gracias por confiar en mí

Intro (para aprendices)

¡Enhorabuena! Ya eres casi programador o programadora. Gracias por confiar en mí para semejante misión.

En este libro quería destapar un secreto que todos los libros de texto parecen querer ocultar:

programar es muy divertido. A mí me gusta programar porque es una de las pocas formas en el mundo de hacer sueños realidad (está bien, algunos sueños). Es cierto que no es un sistema infalible, pero personalmente no conozco muchas otras maneras de hacer que una idea se convierta en una orden, y que ésta se cumpla a su vez, haciendo REAL aquello que sólo existía en mi cabeza.

Además, para las personas curiosas programar es una oportunidad de intentar saber cómo funcionan algunos objetos que nos rodean y que hasta ahora no nos llamaban la atención. En cuanto sabes un par de cosas empiezas a mirar el mundo de otra manera, a imaginar qué se cuece dentro de tu videojuego favorito, una máquina expendedora de refrescos, o incluso una báscula de supermercado. Te preguntas si las instrucciones que los hacen funcionar serán las mismas que

tú escribirías. Tal vez incluso seas como yo y te guste ir más allá: ¿habrán tenido en cuenta todas

¿Sabrías dar con la combinación de acciones

las posibles formas de usar ese aparato? imprevista que hace saltar todo por los aires?

En fin, he intentado hacer de este libro algo entretenido e interesante. Quiero que empieces a ser capaz de producir pequeños programas lo antes posible, y que puedas aplicar cada nuevo detalle que aprendas. No he incluido nada que no sea básico y necesario para ti, por lo que te aconsejo que no corras, no te saltes capítulos y sigas el orden del libro.

¡Ah! De vez en cuando verás unas

he ido dejando por si quieres investigar más algunos temas, si tu curiosidad te lo pide o

, son pequeñas pistas que te

anotaciones en recuadros grises

simplemente lo que te enseño te sabe a poco. También puedes dejar esos recuadros para más adelante… o incluso no leerlos nunca: aquí mandas tú.

Sólo dos consejos más:

Si esto te gusta, ten paciencia. No seas demasiado exigente contigo misma/o, nadie nace sabiendo. Date las oportunidades que necesites.

Si esto no te gusta, abandona el libro sin remordimientos. Incluso para las personas más jóvenes la vida es demasiado corta como para perseguir trenes en los que uno no quiere montarse.

¡Buen viaje!

TABLA DE CONTENIDOS

INTRO (PARA TUTORES Y TUTORAS)

INTRO (PARA APRENDICES) ¿QUÉ VAMOS A NECESITAR? PROGRAMAS Y COMPONENTES QUE VAS A NECESITAR

0.

ESA MAGIA OSCURA A LA QUE LLAMAN PROGRAMAR

 
 

ESCRIBIENDO MAGIA: LOS ALGORITMOS

1.

EL LIBRO DE LOS HECHIZOS

 
 

HELLO, WORLD! NUESTRA PRIMERA PRÁCTICA

 

2.

UN TESORO VARIABLE

 
 

¿QUÉ ES UNA VARIABLE? UNA PEQUEÑA PRÁCTICA: IMPRIMIR VARIABLES ¡OPERADORES! LA HUCHA ELECTRÓNICA ANEXO: OTRAS COSAS QUE PUEDES HACER CON STRINGS

2.

MUCHOS CAMINOS DISTINTOS ESTRUCTURAS DE CONTROL DE FLUJO

 

IF - THEN

PERFECCIONAMOS LA HUCHA ELECTRÓNICA

 

IF - THEN -ELSE

 

VOLVEMOS A MODERNIZAR NUESTRA HUCHA LA SENTENCIA SWITCH BLINDANDO NUESTRA HUCHA

 

4.

UN JUEGO DE NIÑOS

PERO ¿QUÉ ES UN BUCLE?

WHILE

DO-WHILE

FOR

JUEGO: PIEDRA, PAPEL, TIJERAS

5. SIGUIENDO EL RASTRO

ALGUNOS CONCEPTOS PREVIOS SOBRE ARCHIVOS LA CLASE FILE

TRY/CATCH

LA CLASE SCANNER (OTRA VEZ) UN PAR DE EXPERIMENTOS

LA CLASE PRINTSTREAM NUESTRA HUCHA ELECTRÓNICA RECUERDA LOS CAMBIOS PRÁCTICA FINAL: EL DOCUMENTO SECRETO

6. ¿POR DÓNDE SEGUIR?

DRY (DONT REPEAT YOURSELF) YAGNI (YOU ARENT GONNA NEED IT) LA REGLA DEL BOY SCOUT NO TE LANCES SOBRE EL TECLADO

TESTEA SIEMPRE

¿Qué vamos a necesitar? Para llevar a cabo los ejercicios prácticos que se proponen en

¿Qué vamos a necesitar?

Para llevar a cabo los ejercicios prácticos que se proponen en este libro necesitaremos un ordenador. Puedes trabajar con un sistema operativo basado en Linux, como Ubuntu (eso sería fantástico), o con Windows o MacOS en cualquiera de sus versiones.

La conexión a internet también te será muy útil.

Programas y componentes que vas a necesitar

JDK, o Kit de Desarrollo de Java TM . Para poder ejecutar nuestras creaciones necesitaremos que nuestro equipo pueda interpretar el lenguaje Java. Podemos descargarlo gratis desde el sitio web de Oracle.com, en su sección de descargas. Recuerda buscar el kit Java SE Development Kit 8, pues es la versión más reciente de Java y en la que he basado este libro.

Recuerda verificar que bajas el kit adecuado a tu SO (Windows, Mac…) y procesador (X86 o X64). Si no sabes qué tipo de procesador tienes, puedes verlo en tu equipo, en la sección de info sobre la máquina (que se llamará Sistema, MiPC, About this Mac o algo similar). Cuando hayas descargado el JDK deberás configurar tu variable de entorno. Este proceso es distinto en cada sistema operativo, pero muy sencillo. Te recomiendo guiarte por los pasos que encontrarás en la propia página de Oracle: https://www.java.com/es/download/help/path.xml

Editor de texto. Para los ejercicios que haremos al principio prefiero que uses un editor de texto lo más sencillo posible. Algunos editores potentes y gratuitos son Notepad++, Atom o Vim. Yo voy a usar el primero para mis ejemplos. Puedes descargar Notepad++ desde https://notepad-plus-plus.org/

Consola de línea de comandos. En el caso de Windows dispondrás de la aplicación conocida como Símbolo del sistema, en caso de Ubuntu y Mac tendrás la Terminal. Sería muy recomendable familiarizarse con la forma de moverse entre directorios, ver los archivos que contienen, etc. Una búsqueda rápida en la Wikipedia nos mostrará los comandos básicos que

podemos necesitar.

No necesitarás un IDE o software de desarrollo especial. Las actividades de este libro se han diseñado para que se puedan completar sólo con el editor de texto.

programar 0. Esa magia oscura a la que llaman Me temo que, antes de ponernos

programar

0. Esa magia oscura a la que llaman

Me temo que, antes de ponernos manos a la obra, hay una serie de cosas que necesitas saber sobre tu ordenador y el modo en que funciona. Programar es como hablarle al ordenador, y si no sabemos cómo piensa nos costará mucho hacer que nos escuche.

Como tal vez ya sepas, un programa es un guion de órdenes en el que se basa tu ordenador para realizar una serie de acciones. El problema aquí es que el ordenador no habla nuestro idioma, sino uno al que llamamos “código máquina”, y que, para hacerlo más complicado, es distinto en cada tipo de procesador. Este lenguaje se basa en números que expresan tipos de operaciones, valores y otros datos y que listan cada acción por insignificante que parezca. Como programar en código máquina sería terriblemente lento y complicado, tenemos otros lenguajes diseñados para ser usados por las personas -como Java, el que aprenderemos en este libro- que, cuando ejecutas el programa, son traducidos a código que tu procesador puede entender. Sí, por confuso que nos parezca un pequeño pedazo de código en lenguaje Java, lo cierto es que ésa no es más que una versión del lenguaje “fácil” para humanos… y esa traducción de la que te hablaba la realiza un programa llamado compilador o intérprete.

Cuando compilamos el código que hemos escrito, el compilador lee nuestras instrucciones, comprueba que las hemos escrito correctamente -aunque puedan ser órdenes equivocadas- y, si es así, las traduce a un lenguaje que nuestra máquina comprende. Si las hemos escrito mal no compilará el programa y nos avisará del error… no te lo tomes a mal, esto les ocurre a diario a las y los programadores más expertos del mundo.

Escribiendo magia: los algoritmos Bueno, ahora ya sabemos que para programar usamos un lenguaje diseñado

Escribiendo magia: los algoritmos

Bueno, ahora ya sabemos que para programar usamos un lenguaje diseñado para que nos resulte cómodo a los humanos, y que luego lo enviamos a traducir para que el procesador lo entienda.

Pero ¿cómo organizamos esta serie de órdenes? El ordenador es terriblemente literal: no hará nada que no le ordenemos, y llevará a cabo todo lo que se le mande siempre que sea posible. Siempre necesitará que le digamos qué, cómo, cuándo y en qué orden, e incluso qué esperamos de él en caso de que algo no pueda hacerse. Para poder expresar todo esto de una manera ordenada y clara necesitamos tener un método de trabajo, una disciplina en nuestra forma de detallar las órdenes. Y aquí entran en juego los algoritmos. Dice la Wikipedia -y no seré yo quien le lleve la contraria- que un algoritmo es un conjunto prescrito de instrucciones o reglas bien definidas, ordenadas y finitas que permite llevar a cabo una actividad mediante pasos sucesivos que no generen dudas a quien deba hacer dicha actividad. Nos lo podemos imaginar como la secuencia de instrucciones que le daríamos a alguien que tiene que hacer algo muy concreto, pero no tiene ni idea de cómo.

Un ejemplo de algoritmo que podríamos escribir para alguien que no sabe cómo regar un geranio:

1. Coger la regadera

2. Situarla bajo el grifo

3. Abrir la maneta del grifo hasta que salga agua

4. Mantenerla abierta hasta que hayan 500ml en la regadera

5. Cerrar la maneta hasta que deje de salir agua

6. Llevar la regadera al jardín

7. Localizar el geranio

8. Inclinar la regadera sobre el geranio, mantenerla así hasta que haya salido toda el agua

9. Guardar la regadera

Como ves, hay varios detalles muy importantes para cada orden que hemos dado a nuestro

aprendiz de jardinero:

El orden en que hacer las acciones orden en que hacer las acciones

Cuándo termina cada acción cada acción

Qué hacer al terminar de regar al terminar de regar

Si no le indicásemos el orden, podría regar primero y llenar la regadera después

moriría de sed. Si no le dijéramos cuándo cerrar el grifo, nuestro amigo sería capaz de inundar la casa. Y si no le avisamos de que al final debe guardar la regadera, capaz es de quedarse con ella colgando sobre el geranio para el resto de la eternidad. Así de literal es nuestro amigo, justo igual que un ordenador, y por eso los algoritmos deben ser exactos, ordenados y tener fin.

y la planta

Y ésta es toda la teoría previa que necesitabas conocer antes de empezar a teclear. ¡Hurra!

necesitabas conocer antes de empezar a teclear. ¡Hurra! EJERCICIOS Ahora te propongo unos ejercicios muy sencillos,

EJERCICIOS Ahora te propongo unos ejercicios muy sencillos, para asegurarnos de que no hayas entendido algo mal. No queremos matar de sed los geranios ;)

(tienes las soluciones a continuación, pero ¡no las mires antes de tiempo!)

UN PEQUEÑO TEST

1.

El procesador puede ejecutar tu código escrito en Java

a)

Por supuesto

b)

Ni hablar

2.

Un algoritmo es…

a)

Un código diseñado para que el procesador lo entienda

b)

Una secuencia de órdenes concretas, exactas y finitas

3.

Para poder comprender el lenguaje en el que escribes, tu ordenador necesita las traducciones de un

a)

Procesador

b)

Intérprete

EVITANDO EL DESASTRE Este algoritmo contiene algunos errores que nos pueden llevar al desastre. ¿Podrías señalarlos y corregirlo?

Instrucciones para cocinar patatas fritas:

y corregirlo? Instrucciones para cocinar patatas fritas: 1. Preparar las patatas necesarias 2. Coger un cuchillo

1. Preparar las patatas necesarias

2. Coger un cuchillo para pelar

3. Empezar a pelar patatas

4. Poner la sartén en el fogón

5. Encender el fuego a media potencia

6. Verter aceite en la sartén

7. Echar las patatas a la sartén

8. Freír las patatas

9. Sacar las patatas de la sartén y ponerlas en un plato

Prácticas extra, para estudiantes aplicados…

ESCRIBE TU PROPIO ALGORITMO

Crea las secuencias de órdenes para facilitar instrucciones a un ordenador imaginario. Te propongo algunas ideas:

Planchar una camisaa un ordenador imaginario. Te propongo algunas ideas: Enviar una carta por correo Lavarse los dientes

Enviar una carta por correoimaginario. Te propongo algunas ideas: Planchar una camisa Lavarse los dientes Hacerse una trenza a un

Lavarse los dientesideas: Planchar una camisa Enviar una carta por correo Hacerse una trenza a un lado de

Hacerse una trenza a un lado de la cabezauna camisa Enviar una carta por correo Lavarse los dientes Atarse los zapatos Hinchar un globo

Atarse los zapatoslos dientes Hacerse una trenza a un lado de la cabeza Hinchar un globo SOLUCIONES Soluciones

Hinchar un globodientes Hacerse una trenza a un lado de la cabeza Atarse los zapatos SOLUCIONES Soluciones del

SOLUCIONES

Soluciones del test:

1 - b

2 - b

Errores del algoritmo:

Instrucciones para cocinar patatas fritas

1.

Preparar las patatas necesarias

2.

Coger un cuchillo para pelar

3.

Empezar a pelar patatas hasta que estén todas peladas

4.

Cortar las patatas en rodajas de 1 cm de grosor (no querrás freírlas enteras)

5.

Poner la sartén en el fogón

6.

Encender el fuego a media potencia

7.

Verter 100ml de aceite en la sartén (no queremos quedarnos para siempre con la botella en la mano…)

8.

Cuando el aceite esté caliente Echar las patatas a la sartén

9.

Freír las patatas hasta que estén doradas/durante x minutos

10.

Sacar las patatas de la sartén y ponerlas en un plato

11.

Apagar el fogón

Obviamente esto es una simulación y no un programa real (aunque podríamos estar programando el software de un robot cocinero), pero como puedes ver es vital concretar siempre en qué orden realizar las acciones y cuándo parar, de lo contrario podemos eternizar algunas (esto lo veremos más adelante).

1. El libro de los hechizos Ahora ya sabemos que para programar usamos un lenguaje

1. El libro de los hechizos

Ahora ya sabemos que para programar usamos un lenguaje especial, diseñado para humanos, y que con él escribimos algoritmos, secuencias con los pasos que deseamos que el procesador dé.

Pero, ¿cómo es en detalle ese proceso cuando se trata de un programa real? En este capítulo por fin lo veremos, y además para cuando llegues al final escribirás tu propio programa. Como sabes, este libro se basa en el lenguaje Java para nuestro aprendizaje. Pues bien, para ejecutar -hacer funcionar- un programa Java en tu ordenador, necesitas tres ingredientes:

Un editor de texto para escribir nuestro código. Nada especial, te sirve uno gratuito como los que tienes recomendados en la sección “¿Qué vamos a necesitar?”

Un compilador de Java, que genera lo que llamamos bytecode El intérprete que hará posible que nuestro procesador particular entienda lo que hemos escrito Para el nivel al que vamos a llegar en este capítulo, un programa Java no es más que una serie de código creado en el editor de texto y guardado con la extensión .java -para que nuestro ordenador sepa que debe procesar su contenido como código Java.

y guardado con la extensión .java -para que nuestro ordenador sepa que debe procesar su contenido
y guardado con la extensión .java -para que nuestro ordenador sepa que debe procesar su contenido
y guardado con la extensión .java -para que nuestro ordenador sepa que debe procesar su contenido
Pero vayamos al meollo de la cuestión. ¿Cómo hacemos para escribir órdenes válidas? ¿Escribo cualquier

Pero vayamos al meollo de la cuestión. ¿Cómo hacemos para escribir órdenes válidas? ¿Escribo cualquier cosa y rezo para que me entiendan, basta con que esté en inglés?

Pues no. Como toda buena magia, la programación se basa en librerías y libros llenos de sortilegios que alguien escribió mucho antes que nosotros, y que aplicados correctamente sobre un objeto generan un encantamiento concreto.

Cuando descargamos el JDK que mencionaba en la sección “Qué vamos a necesitar”, sin saberlo nos trajimos todas las librerías de sortilegios y hechizos que componen Java, y cuando escribimos nuestro programa lo que hacemos es irlos invocando según ciertas reglas. Una de ellas, no la olvides, es que a los hechizos les vamos a llamar métodos y a los libros, clases. Cuando empecemos a programar (sólo tardaremos un par de páginas más, ya verás) lo que haremos será llamar a las clases que queremos usar, para que nos escuchen… y así poder invocar sus métodos y que afecten a todo lo que queremos manejar.

Hello, World!

“Hola, Mundo” son tradicionalmente las primeras palabras que uno escribe cuando se estrena en la programación, y nosotros no vamos a ser menos. A continuación, tenemos un ejemplo de un programa, el primero que vamos a analizar y comprender.

→ FÍJATE: este tipo de letra aparecerá en el libro cada vez que quiera indicarte

→ FÍJATE: este tipo de letra aparecerá en el libro cada vez que quiera indicarte que el texto es código Java.

Lo primero que leemos es “public class”. Esto lo escribimos al principio del documento, para que cuando lo lea el compilador sepa que a partir de ahí todo lo que va a leer es una clase. Y además le damos un nombre a la clase, en este caso “HolaMundo”. Lo siguiente que leemos es “public static void main…” esto lo escribimos siempre como encabezamiento de nuestra clase principal (es como una contraseña que abre el conjuro).

Después tenemos una anotación que empieza con dos barras (//). A esto se le llaman comentarios. ¡Las barras son como un hechizo de invisibilidad! Si las pones delante de una frase el programa se ejecuta sin leerlas, lo cual es muy útil. Puedes usar los comentarios para escribir cosas que necesites recordar luego, que aclaran qué hace el siguiente pedazo de código etc. sin molestar al compilador.

Y aún hay más: para una sola línea puedes escribir las dos barras, pero si

Y aún hay más: para una sola línea puedes escribir las dos barras, pero si quieres hacer un

párrafo entero puedes usar una coraza de invisibilidad, /*así */, y el programa pasará por encima sin leerlas.

//esto sería un comentario de una línea

/*y esto sería todo un bloque de líneas que el programa pasa por alto por estar metidas en su fantástica coraza*/

Y, por último, tenemos la magia en sí. Hemos usado un conjuro que se llama System.println y

que tiene la habilidad de hacer que tu ordenador escriba cosas en la pantalla. En concreto,

las cosas que le pongas entre paréntesis (a eso le llamamos parámetro).

Escribimos el método con esta estructura:

método (“material para el método”) ;

Es decir, siempre:

- el método delante,

- y a continuación en una nube de humo (bueno, un paréntesis y comillas) el texto que queremos embrujar para que se nos aparezca. Y lo sellamos todo con un punto y coma.

Ahora vuelve a mirar el programa, ¿verdad que ya no parece un galimatías? Ahora tiene sentido:

Abro el libro de conjuros (la clase), anuncio que voy a empezar a hacer magia (método main) y ya puedo empezar a lanzar hechizos (método System.println).

public class HolaMundo {

public static void main(String[] args) { // Muestra el texto en una pantalla System.out.println("Hola, Mundo");

}

}

{

Y, para que quede claro que cada pieza de código está contenida en otra, las rodeamos con

estas llaves {}. No las olvides, o el compilador se quejará, ya que no sabrá qué es cada cosa y

dónde parar de leer

}

ya que no sabrá qué es cada cosa y dónde parar de leer } Nuestra primera

Nuestra primera práctica

Ahora escribiremos nuestro primer programa. Sigue los pasos con mucha atención:

1. Abre un editor de texto y copia el programa que hemos analizado. Quizá te apetezca intentar copiarlo de memoria y luego ver qué te has olvidado y añadirlo.

2. Guarda el archivo. No te olvides de nombrarlo igual que el programa, según las CurvasDelCamello, y ponerle extensión .java. Cierra el archivo.

javac y el nombre de tu programa, con su extensión:

4.

javac HolaMundo.java

Automáticamente el compilador crea un nuevo archivo llamado HolaMundo.class, ése es el que ejecutaremos. Si todo ha ido bien no verás ningún mensaje. Ejecutamos el programa, escribiendo java y el nombre del programa -esta vez sin extensión:

java HolaMundo

¡Eureka! nuestro programa se ejecuta y gracias a nuestro hechizo la ventana de la terminal muestra nuestro primer mensaje al mundo.

¿Algo no ha funcionado? Si al tratar de compilar aparece algún mensaje de error revisa los siguientes detalles:

- Que coincidan el nombre de la clase y el del archivo

- Que hayas copiado exactamente el código

- Que hayas escrito la extensión para compilar

No te preocupes si no funciona a la primera… con un poco de mimo y calma, siguiendo de nuevo las instrucciones paso a paso tiene que funcionar.

EJERCICIO

Partiendo del programa que hemos creado hace un momento, intenta crear las siguientes modificaciones:

Un programa que en lugar de “Hola, Mundo” diga “Hasta luego, cocodrilo”un momento, intenta crear las siguientes modificaciones: Un programa que diga “Hola, Mundo” y después “Hace

Un programa que diga “Hola, Mundo” y después “Hace un buen día”lugar de “Hola, Mundo” diga “Hasta luego, cocodrilo” Realiza los siguientes experimentos: Incluir más de un

Realiza los siguientes experimentos:

Incluir más de un mensaje entrecomillado, dentro del mismo paréntesis“Hace un buen día” Realiza los siguientes experimentos: Añadir o quitar llaves ({}) Añadir o quitar

Añadir o quitar llaves ({})de un mensaje entrecomillado, dentro del mismo paréntesis Añadir o quitar el caracter “;” Hacer que

Añadir o quitar el caracter “;”dentro del mismo paréntesis Añadir o quitar llaves ({}) Hacer que no coincida el nombre del

Hacer que no coincida el nombre del archivo con el nombre del programa (que indicas en el método main ) ¿Qué ocurre cuando realizas cada uno de esos cambios? ¿Qué mensajes te da main) ¿Qué ocurre cuando realizas cada uno de esos cambios? ¿Qué mensajes te da el compilador? ¿Es posible ejecutarlo?

SOLUCIONES

Para modificar el texto que se muestra por la pantalla sólo tienes que modificar lo que escribiste entre las comillas. No olvides ponerlas ;)ocurre cuando realizas cada uno de esos cambios? ¿Qué mensajes te da el compilador? ¿Es posible

Para escribir dos mensajes, puedes repetir el método: System.out.println(“Hola, Mundo”); System.out.println(“Hace

Para escribir dos mensajes, puedes repetir el método:

System.out.println(“Hola, Mundo”); System.out.println(“Hace un buen día”);

o poner los dos mensajes seguidos

System.out.println(“Hola, Mundo”, “Hace un buen día); System.out.println(“Hola, Mundo Hace un buen día);

Aunque eso no queda tan bien, ya que nos lo escribe de golpe.

Hay otras formas de hacerlo (más adelante las aprenderás).

Por el momento, con este ejercicio comprobamos que puedes escribir todos los métodos que necesites en la misma clase, dentro de las llaves del método main, o incluso indicar varios parámetros (varios mensajes entre comillas) al método System.out.println.

2. Un tesoro variable Ahora que ya sabemos algunas cosas sobre cómo se organiza un

2. Un tesoro variable

Ahora que ya sabemos algunas cosas sobre cómo se organiza un programa y la manera de usar los hechizos, es hora de conocer un nuevo elemento importantísimo: las variables.

En este capítulo aprenderemos qué son, cuántos tipos existen y cómo empezar a manejarlas mediante nuestros programas.

¿Qué es una variable?

Los manuales de programación nos dicen que una variable es un espacio en la memoria del ordenador, donde guardamos un valor que hemos asignado a la misma. Existen diferentes tipos de variables según el tipo de información que guardemos en ellas.

Pero como esto suena un poco denso, en este capítulo -como magos que somos- vamos a trabajar con un tesoro que hemos creado mágicamente. Nuestro tesoro está guardado en un enorme arcón, que sería como la memoria de un ordenador, y custodia un montón de datos de todos los tipos y formas, y que tienen muuucho valor. En nuestro pequeño inventario tenemos varios tipos de elementos, que usamos según la ocasión. Los que más abundan son:

char - los chars son pequeñas gemas preciosas. Si las miras a contraluz, cada una esconde - los chars son pequeñas gemas preciosas. Si las miras a contraluz, cada una esconde un caracter (un signo, número o letra) en su interior, entre comillas simples.

int - los ints son monedas de oro, cada uno tiene un valor numérico , que - los ints son monedas de oro, cada uno tiene un valor numérico, que puede ir desde

muy por debajo de cero hasta … bueno, un número altísimo y difícil de imaginar

hasta … bueno, un número altísimo y difícil de imaginar double/ float - como las monedas

double/ float - como las monedas siempre son un valor redondo a veces necesitamos extender un cheque para pagar, por ejemplo, 25,75€. Los doubles y floats son eso, cifras que contienen comas.

strings- “string” significa cuerda en inglés. Realmente los strings no son más que collares que - “string” significa cuerda en inglés. Realmente los strings no son más que collares que hemos engarzado entre comillas dobles para mantener juntos y en orden algunos grupos de chars que no queremos tener sueltos, sería una lástima que se nos desperdigasen por el arcón

sería una lástima que se nos desperdigasen por el arcón bool - los booleanos no son

bool - los booleanos no son un tesoro en sí, pero nos ayudan a mantenerlo. Son unos pequeños candados que sólo tienen dos valores: cierto o falso (abierto o cerrado). Quizá ahora te preguntes qué utilidad tienen, en el futuro lo irás descubriendo.

Bien, ahora que sabemos todo esto, volvemos a la carga. ¿Qué es una variable? Es un espacio único en nuestro arcón (de hecho, le pondremos un nombre), de uno de los tipos anteriores, y con un valor concreto. Algunos ejemplos de variables de nuestro tesoro podrían ser:

Un char llamado inicial , con valor ‘i’ inicial, con valor ‘i’

Un int llamado paga , con valor 1500 paga, con valor 1500

Un double, o un float, llamado precio , con valor 1,45 precio, con valor 1,45

Un string llamado saludo , con valor “Hola” saludo, con valor “Hola”

Un booleano llamado abierto con valor “true” abierto con valor “true”

Cuando escribimos el programa podemos crear tantas variables como necesitemos. Las podemos crear (o declarar, como dicen los expertos) al principio del programa, para que se generen en cuanto lo ejecutemos, o en los métodos, para que vayan apareciendo sobre la marcha. Verás que hay un montón de operaciones que podemos hacer con nuestras variables, incluso sabiendo muy poquito.

Podemos realizar operaciones matemáticas con los ints y los doubles, podemos desordenar, recortar y cortar las strings, podemos hacer que el programa tome decisiones usando booleanos… tu imaginación es el límite.

La forma más correcta de crear una variable es con el esquema tipo - nombre - valor. Así declaramos e inicializamos las variables que hemos escrito arriba :

char inicial = ‘i’; int paga = 1500; float precio = 1.45; String saludo = “Hola”; bool abierto = true;

→ Fíjate bien! Escribimos el valor del char entre comillas simples y el del string entre comillas dobles.

Una pequeña práctica: imprimir variables

Vamos a partir otra vez del programa HolaMundo que hicimos en el capítulo anterior. Esta vez en lugar de decirle exactamente qué texto queremos imprimir, le diremos el nombre de la variable y nos mostrará su valor.

Copia este programa, compílalo y ejecuta:

Como puedes ver, al haber inicializado las variables previamente, podemos dar el nombre de las mismas a nuestro método y él sabrá qué mostrar.

Pero, ¿qué ha pasado en la línea 15? Fíjate bien en lo que muestra tu

Pero, ¿qué ha pasado en la línea 15? Fíjate bien en lo que muestra tu programa… ha multiplicado el valor de la variable precio (100) por el número que le hemos indicado, y ha mostrado el resultado. ¿Por qué se ha comportado así?

¡Operadores!

¡Enhorabuena! Has descubierto los operadores: símbolos mágicos que realizan operaciones sobre nuestras variables.

Existen de muchos tipos, por ejemplo los aritméticos, que puedes usar para manipular variables de tipo numérico (int, float, double…): +, -, *, /… y que básicamente hacen operaciones matemáticas. Estos no puedes usarlos con variables no numéricas (salvo el símbolo +, que puede usarse para concatenar strings).

Usar estos símbolos mágicos es muy sencillo, sólo tienes que saber cuál es la función de cada uno. Para eso tienes este manual de instrucciones, que podrás consultar siempre que necesites invocarlos. Recuerda que NO necesitas memorizar esta tabla, no estamos aquí para repetir las cosas como loros… ;) Con el tiempo y la práctica irás recordándolos sin ayuda.

=

Operador simple de asignación

Operadores Aritméticos

+

Suma

-

Resta

*

Multiplica

/

Divide

%

Nos da el resto en una división. Por ejemplo, 7 % 5 = 2

Operadores Unarios

+

Positivo (por ejemplo una temperatura)

-

Negativo

++

Suma 1 a un valor

--

Resta 1 a un valor

!

Invierte el valor de un booleano (de true a false, o viceversa)

Operadores de igualdad y relacionales

==

“igual que”, por ejemplo: 5 == 5

!=

“distinto que”, por ejemplo: 3 != 4

>

mayor que

>=

mayor o igual que

<

menor que

<=

menor o igual que

Operadores condicionales

&&

Y, por ejemplo: “lunes && martes” significa” los dos”

||

O, por ejemplo: “lunes || martes” significa” uno de ambos”

?:

ternaria. La incluimos pero no la usarás en este libro

Operador de comparación de tipo

instanceof

“de cierto tipo”. Por ejemplo, “5.6 instanceof Double” sería = true

Ahora veamos un par de ejemplos de cómo usar estos operadores. ¿Te atreves a adivinar qué mostrarán en pantalla estos programas?

Si compilas y ejecutas verás que, usando los operadores + y -, podemos realizar sumas,
Si compilas y ejecutas verás que, usando los operadores + y -, podemos realizar sumas,

Si compilas y ejecutas verás que, usando los operadores + y -, podemos realizar sumas, restas o

concatenar frases.

Y además, podemos usar los operadores para cambiar el valor de una variable, como hemos

hecho en el ejemplo de arriba al inicializar la variable sumaEdades . En este caso la hemos inicializado como la suma del valor de otras dos, pero podríamos haber hecho cualquier otro cálculo. Por ejemplo, aquí estamos inicializando una nueva variable,

indicando que el valor será el resultado de dividir las otras dos:

int sumaEdades = edadPadre / edadMadre;

o incluso usar una igualdad:

int sumaEdades = edadPadre;

que significa que se creará sumaEdades con el mismo valor que edadPadres tenga en ese

momento… (Por si acaso te lo has preguntado, aunque edadPadre cambie más tarde de valor, sumaPadres no

lo hará, ya que, aunque al crearse haya mirado el valor que tiene para copiarlo, son espacios de

memoria distintos. Del mismo modo que si hoy me hago una foto y mañana cambio de peinado,

la foto no cambia conmigo).

Todo esto de igualar variables, sumarlas, restarlas tipo. Si pruebas a escribir:

String a = edadPadre;

lo podemos hacer porque son del mismo

tendrás un error de compilación, porque no puedes darle a una String el valor que tenías guardado en un int… como ya sabes, no son el mismo tipo de joya, así que no encajan.

a una String el valor que tenías guardado en un int… como ya sabes, no son
Retos con variables y operadores Vamos a atrevernos con algunos retos avanzados. Para eso, usaremos

Retos con variables y operadores

Vamos a atrevernos con algunos retos avanzados. Para eso, usaremos nuevos métodos que hasta ahora no conocíamos. Vamos a conocer la clase Scanner (recuerda, una clase era como un libro de conjuros de la misma temática) que contiene el método Scanner. Este poderoso método nos da la oportunidad de hablarle al programa desde el teclado, mientras se está ejecutando.

Para usar esa clase, primero tenemos que añadirla a nuestro programa, decirle que vamos a usar ese libro. Y eso se hace añadiendo esta indicación al principio del programa:

import java.util.Scanner;

al principio del programa: import java.util.Scanner; Una vez hemos importado la clase, ya podemos invocar sus

Una vez hemos importado la clase, ya podemos invocar sus métodos. Como si nos hubiésemos traído el libro de la estantería para poder ir leyendo en él los conjuros necesarios.

Para usar el Scanner, seguimos estos pasos:

Abrimos un nuevo Scanner, y le ponemos un nombre, el que queramos: , y le ponemos un nombre, el que queramos:

Scanner Jaimito = new Scanner(System.in);

(Fíjate: un nuevo Scanner, llamado Jaimito, que lee de System.in o lo que es lo mismo, el teclado del usuario dentro de paréntesis, a modo de parámetro).

Creamos una variable del tipo que necesitemos. Al inicializarla, le decimos que su valor será igual a lo que escribamos en . Al inicializarla, le decimos que su valor será igual a lo que escribamos en el teclado. Se hace así:

int i = Jaimito.nextInt();

(Como hemos creado un int, el programa esperará que introduzca un número sin decimales. Fíjate que usamos el método como aprendimos lecciones atrás con el método println: nombre del método-punto-parámetro. O lo que es lo mismo, Jaimito-punto-el siguiente Int que entre por el teclado).

Y ya está todo listo para que escribamos. El programa capturará lo que hayamos tecleado y lo

guardará en el arcón de memoria, a modo de valor de una de nuestras joyas, una variable.

a modo de valor de una de nuestras joyas, una variable. La hucha electrónica Vamos a

La hucha electrónica

Vamos a diseñar un programa que simula ser una hucha. El programa tiene estas funciones:

Recibir dineroque simula ser una hucha. El programa tiene estas funciones: Contar el dinero Indicar el saldo

Contar el dinerouna hucha. El programa tiene estas funciones: Recibir dinero Indicar el saldo 1- Escribe el algoritmo

Indicar el saldotiene estas funciones: Recibir dinero Contar el dinero 1- Escribe el algoritmo que describe el proceso

1- Escribe el algoritmo que describe el proceso de uso de la hucha. No hay una única respuesta correcta, existen muchas formas de hacerlo.

2. Asocia las siguientes acciones al método o herramienta que podrías usar para que se realicen:

o herramienta que podrías usar para que se realicen: 3. El ejercicio anterior, una vez solucionado,

3. El ejercicio anterior, una vez solucionado, nos da una pista de cómo podría ser el código de nuestro programa. Intenta escribir el código, no pasa nada si no compila. ¡Es un ejercicio de ingeniería! Después consulta la solución propuesta (recuerda, no hay solo una) y haz los retoques necesarios

hasta que el programa compile.

4. Juega con tu nuevo programa. Intenta hacer que falle. Intenta introducir cantidades en negativo, ¿qué ocurre?

ACTIVIDAD OPCIONAL: SÓLO PARA ALUMNOS MUY AVANZADOS

¿Sabrías modificar tu programa para que pueda aceptar cantidades con decimales? Es decir, que puedas guardar en tu hucha cheques además de monedas. ¿Sabrías modificar tu programa para que acepte variables de tipo String? Así podrás guardar también collares en tu hucha. PISTA: el apartado “otras formas de invocar al Scanner” podría tener la herramienta que necesitas.

SOLUCIONES

1. Algoritmo. No existe una única respuesta correcta, pero aquí tienes una propuesta de solución:

Se inicia el programacorrecta, pero aquí tienes una propuesta de solución: Se muestra el total de dinero ahorrado por

Se muestra el total de dinero ahorrado por pantallatienes una propuesta de solución: Se inicia el programa Se solicita al usuario qué cantidad quiere

Se solicita al usuario qué cantidad quiere echar en la huchaprograma Se muestra el total de dinero ahorrado por pantalla El usuario indica la cantidad Se

El usuario indica la cantidadsolicita al usuario qué cantidad quiere echar en la hucha Se añade el valor al que

Se añade el valor al que ya había en la huchaquiere echar en la hucha El usuario indica la cantidad Se muestra por pantalla el nuevo

Se muestra por pantalla el nuevo ahorro totalla cantidad Se añade el valor al que ya había en la hucha 2. Recibir dinero

2. Recibir dinero - Scanner Mostrar saldo - System.out.println Contar el dinero - Operadores aritméticos Indicar la cantidad - Teclado del usuario

3. Una posible forma de escribir el código y que funcione (el total ahorrado inicial puede ser cero, o cualquier otra cantidad):

ahorrado inicial puede ser cero, o cualquier otra cantidad): Si lo ejecutas verás que el programa

Si lo ejecutas verás que el programa hace lo siguiente:

1. Indica el total inicial

2. Solicita cuánto vas a ingresar

3. Espera hasta que tecleas una cantidad y pulsas Enter

Podíamos haber hecho lo mismo de otras maneras. Si te apetece, piensa en ello e intenta razonar cuál sería la más útil.

4. Para adaptar tu hucha para recibir collares o cheques, sólo tienes que crear otras variables y usar el mismo scanner tantas veces como quieras meter cosas. Prueba con este fragmento de código (añádelo a tu programa dentro del método main):

veces como quieras meter cosas. Prueba con este fragmento de código (añádelo a tu programa dentro

ANEXO: Otras cosas que puedes hacer con strings

Como ya has visto, las Strings son una forma de “hablar” con el usuario. A menudo nos gusta decorar un poco más su aspecto para que nuestro programa parezca más profesional. Por eso aquí te dejo algunos trucos que puedes usar para manipular Strings, crear mensajes más complejos o procesar los mensajes que el usuario teclee. Puedes jugar con ellos ahora o en las prácticas que iremos haciendo a lo largo del libro.

Calcular la longitud de una String con String.lenght:

public static void main(String args[]) {

String collar = "Un collar de 76 perlas";

int longitud = collar.length();

System.out.println( "La longitud de esta String es de : " + longitud );

}

Concatenar Strings Podemos mostrar varias Strings seguidas en un mensaje, como ya hemos hecho, usando el signo “+”.

También podemos usar el método String.concat para concatenar los literales:

"Yo vivo en ".concat("Barcelona");

O concatenando las variables directamente:

String 1 = “Yo vivo en”;

String 2 = “Barcelona”;

1.concat(2);

Esto es así porque concat es un método que acepta como parámetro tanto variables como texto entrecomillado.

Comparar Strings Con el método compareTo puedes comparar dos Strings (usando la variable o directamente el texto entre comillas) para saber si son idénticas. Obtenemos el resultado en una variable de tipo int. Ésta valdrá 0 si son iguales, y una cifra positiva o negativa si son distintas. Un ejemplo de uso:

public static void main(String args[]) {

String 1 = "Buenos días."; String 2 = “Buenos días.”;

int result = 1.compareTo( 2 );

System.out.println("El resultado de la comparación es: "+result);

}
}

(Y usando el método compareToIgnoreCase puedes comparar Strings sin tener en cuenta mayúsculas y minúsculas).

Reemplazar caracteres ¡Puedes reemplazar una letra concreta por otra para “esconder” cosas que has escrito, por ejemplo… como una especie de clave! :)

public static void main(String args[]) {

String mensaje = new String(“Mi mensajito secreto”);

String mensaje = new String(“Mi mensajito secreto”);

System.out.println(mensaje.replace('e', 'r'));

String mensaje = new String(“Mi mensajito secreto”); System.out.println(mensaje.replace('e', 'r'));

Para obtener un mensaje “escondido” así: “Mi mrnsajito srcrrto”).

Puedes cifrar tantos caracteres como quieras, y descifrar después otra vez.

Puedes encontrar más propuestas para manipular Strings en los tutoriales oficiales de Oracle para Java 8:

https://docs.oracle.com/javase/tutorial/java/data/strings.html

2.

2. Muchos caminos distintos En los capítulos anteriores hemos aprendido los básicos de la programación: qué

Muchos caminos distintos

En los capítulos anteriores hemos aprendido los básicos de la programación: qué son los métodos y las clases, qué son las variables -y qué tipos existen- e incluso a usar operadores para jugar con ellas.

Pero cuando empezamos a tener ideas que queremos llevar a la realidad lo anterior se nos queda corto. Los programas que hemos escrito hasta ahora sólo saben hacer la misma secuencia una y otra vez… y en algunas ocasiones necesitamos que piensen un poquito más.

¿Sería posible que nuestro programa Hucha nos preguntase primero qué tipo de valor queremos guardar para que sepa qué tipo de variable crear? ¿Que nos responda con un aviso si nos equivocamos al escribir el dato, y podamos volver a introducirlo?

Por supuesto ¡es posible! (yo todavía no he encontrado nada imposible de programar… sólo cosas que aún no sé hacer).

de programar… sólo cosas que aún no sé hacer). Estructuras de control de flujo Para que

Estructuras de control de flujo

Para que nuestro programa pueda tomar decisiones sobre qué hacer en algunos casos, lo que

hacemos es prevenirlas y utilizar lo que llamamos estructuras de decisión, o de control de flujo.

Existen 3 tipos de estructuras de decisión:

IF IF - ELSE SWITCH CASE

Para entender cómo funcionan estas estructuras podemos imaginar nuestro programa como si fuese un circuito mágico que alimenta un panel luminoso. Nuestro circuito está lleno de caminos por los que corre la electricidad, algunos tienen interruptores abiertos y otros cerrados y por eso la corriente mágica sólo llegará a las bombillas que están detrás de interruptores en posición ON. Cuando encendemos el interruptor principal, se genera el flujo de corriente. Cuando ésta pasa por cada uno de los interruptores comprueba su estado para DECIDIR si debe alcanzar la bombilla correspondiente. Si está en OFF, pasará de largo al siguiente interruptor.

IF - THEN

Entonces, podemos entender fácilmente que la sentencia “if” (“si”, en inglés) nos sirve para realizar una comparación, para que el programa se haga una pregunta. Para componer este tipo de instrucciones además usaremos los operadores condicionales que tienes en la tabla de Operadores que hemos visto unas páginas atrás. Por ejemplo, en nuestro programa Hucha, que ya habíamos visto, podemos añadir una norma que diga que sólo aceptaremos ingresos que aumenten nuestro ahorro, no que lo disminuyan. Para ello, en el punto en que antes hacíamos la suma, escribimos esto:

//crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); totalAhorrado = ingreso + totalAhorrado;

ahora podríamos escribir:

//crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); if (ingreso > 0) { totalAhorrado = ingreso + totalAhorrado;

}

Fíjate: Con el operador “>” (mayor que) estamos diciendo que SI la cantidad ingresada es mayor que 0, entonces puede entrar al bloque de código entre llaves y ejecutar la suma. SI la cantidad ingresada es 0 o negativa, entonces el programa se saltará el bloque entre llaves y pasará a la siguiente instrucción.

La forma de usar la sentencia IF es, por lo tanto:

IF ( elementos a comparar) { bloque a ejecutar si se cumple la condición ;}

Podríamos haber usado cualquiera de los otros operadores que ya conocemos para poner otras normas:

Admitir solo ingresos superiores a 5Admitir ingresos solo si tenemos menos de 100 ahorrados (en este caso la comparación sería

Admitir ingresos solo si tenemos menos de 100 ahorrados (en este caso la comparación sería if totalAhorrado < 100)Admitir solo ingresos superiores a 5 Admitir ingresos si tenemos menos de 100 ahorrados, y con

Admitir ingresos si tenemos menos de 100 ahorrados, y con el ingreso no los superamos:este caso la comparación sería if totalAhorrado < 100) if (totalAhorrado<100 && totalAhorrado+ingreso

if (totalAhorrado<100 && totalAhorrado+ingreso < 100)

&& totalAhorrado+ingreso < 100) Perfeccionamos la hucha electrónica Adapta tu programa

Perfeccionamos la hucha electrónica

Adapta tu programa hucha para que incluya estas nuevas normas:

Aceptar sólo ingresos mayores que 0tu programa hucha para que incluya estas nuevas normas: Aceptar sólo ingresos de cantidades par Puedes

Aceptar sólo ingresos de cantidades parestas nuevas normas: Aceptar sólo ingresos mayores que 0 Puedes usar los fragmentos de código que

Puedes usar los fragmentos de código que tienes más arriba. Lo importante no es que lo escribas todo de memoria, no importa que tengas que copiarlo… sino que entiendas cómo funciona.

Ahora puedes jugar con tu hucha e intentar ingresar cantidades o conceptos no admitidos. ¿Qué ocurre en cada caso?

IF - THEN -ELSE

Hasta ahora hemos visto que con la instrucción “IF” podemos hacer que el programa efectúe una acción “SI” una condición se cumple. Y si no se cumple… ¿Qué hacemos? En algunas ocasiones querremos ir un poco más allá, querremos determinar que si se cumple, se haga A, pero si no se cumple, se haga B. Es decir, un bloque de código concreto al que sólo se entra si NO se cumple la instrucción: a este bloque le llamamos ELSE. Es como nuestro circuito luminoso del ejemplo anterior. Con una instrucción IF podíamos decirle “si el interruptor está abierto enciende la bombilla”, pero con una instrucción IF- ELSE le podríamos decir “Si el interruptor está abierto enciende la bombilla, y si no, que suene una alarma”. Así, en caso de encenderse la bombilla nunca sonará la alarma: el bloque de código contenido en ELSE sólo se ejecuta si la condición del IF no se cumple.

Veamos un ejemplo en código Java:

int temperaturaNevera = 3; if (temperaturaNevera => 4) { System.out.println("¡La temperatura en la nevera es demasiado alta! La” + “ temperatura es de "+temperaturaNevera+” grados.”)

}

else {

System.out.println("Nevera enfriando correctamente");

}

Este podrá ser un fragmento de un programa que controla una nevera. Como ves, el programa guardará el valor de la temperatura en una variable. Después evaluará si es superior a 3 grados, y

si es así nos va a alertar de que algo no está como debería. En cambio, si la temperatura es

inferior (es decir, en cualquier otro caso) nos muestra otro mensaje que confirma que está

enfriando como debería. Si lo pruebas ves que en este caso saldrá el segundo mensaje, y si modificas el valor de temperaturaNevera a 4 o más se mostrará el primero.

La sintaxis es sencilla, solo necesitas introducir el bloque nuevo a continuación del bloque IF:

introducir el bloque nuevo a continuación del bloque IF: Es decir: if ( condición a evaluar)

Es decir:

if ( condición a evaluar) { Acción 1; } else { Acción 2; }

Cada bloque con sus propias llaves {} y cada acción con su punto y coma.

Y aún hay más: ¡puedes añadir tantos bloques como quieras! Simplemente, del segundo al

penúltimo los nombramos “else if” y les añadimos su propia condición a evaluar. Por ejemplo, este código nos diría si hemos aprobado el examen justo, con buena nota o si hemos suspendido:

public class Nota{ public static void main(String []args){

int notaExamen = 8;

if (notaExamen>=8) { System.out.println("Enhorabuena, has aprobado con nota.");

}

else if (notaExamen>= 5) { System.out.println("Has aprobado el examen.");

}

else { System.out.println("Lo siento, has suspendido el examen.");

}

}

}

Fíjate: Aunque el valor de notaExamen cumple las dos primeras condiciones (por pura lógica, si

es superior a 8 también lo es a 5) una vez el programa evalúa como cierto el primer caso, ejecuta

su bloque y abandona todo el bloque IF - ELSE. No continúa leyendo las siguientes condiciones por si cumple alguna más.

Otro punto importante: pon atención a la forma en que se han escrito las condiciones. Si solamente escribieses “mayor que 8”, “mayor que 5” y else, en caso de sacar justamente un 8 o un 5 el programa te diría que has suspendido. ¡Menudo chasco!

5 el programa te diría que has suspendido. ¡Menudo chasco! Volvemos a modernizar nuestra hucha Viendo

Volvemos a modernizar nuestra hucha

Viendo el ejemplo de arriba, podrías modificar la hucha otra vez. Si añadieras un ELSE al IF que ya implementaste, cuando el usuario hace un ingreso no admitido podría mostrarse un mensaje indicándole que se ha equivocado y que el ingreso no se ha realizado.

A nadie le gusta intentar algo, que el ordenador no parezca responder y encima no sea capaz de decirnos qué ocurre, así que es una MUY buena práctica intentar prever los errores y acompañar las acciones del usuario si algo no va bien.

¿Ha funcionado la mejora? Si no ha sido así, a la vuelta de esta página tienes una posible solución.

bien. ¿Ha funcionado la mejora? Si no ha sido así, a la vuelta de esta página

SOLUCIÓN

A continuación, tienes una posible solución al reto anterior. Hay otras cosas que podríamos haber hecho, como por ejemplo mover la sentencia

System.out.println("El total ahorrado es " + totalAhorrado);

justo después de la línea 21 para que sólo muestre el total si éste cambia. Recuerda que en la programación hay tantas maneras de implementar un algoritmo como cabecitas puedan imaginarlo.

implementar un algoritmo como cabecitas puedan imaginarlo. La sentencia SWITCH Además de las sentencias IF y
implementar un algoritmo como cabecitas puedan imaginarlo. La sentencia SWITCH Además de las sentencias IF y

La sentencia SWITCH

Además de las sentencias IF y IF-ELSE, tenemos una tercera herramienta para controlar qué piezas de código se ejecutan: la sentencia SWITCH.

SWITCH significa interruptor en inglés y lo que hace es exactamente eso: interrumpe el paso a todas las instrucciones que no concuerden con la condición inicial. Igual que en una red de tuberías en la que podemos abrir la llave de paso que queremos para llevar el agua por ese camino, la sentencia switch se basa en una lista de posibles caminos, que el programa tomará sólo si coinciden con la condición propuesta.

Veamos un ejemplo para entender mejor cómo usarlo. Ésta es la solución anterior a nuestro programa de la hucha, pero usando una sentencia switch en lugar de if - else:

//crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt();

switch (ingreso) { case 0: System.out.println ("No se ha realizado el ingreso porque el importe debe ser mayor que cero.");

break; case 1: totalAhorrado = totalAhorrado+ingreso; break; case 2: totalAhorrado = totalAhorrado+ingreso; break; case 3: totalAhorrado = totalAhorrado+ingreso; break; default:

break;

}

//muestra al usuario el total actual System.out.println("El total ahorrado es " +totalAhorrado);

}

}

Paso a paso:

Iniciamos la sentencia switch, como parámetro indicamos el nombre de la variable que tiene que comparar con cada caso como parámetro indicamos el nombre de la variable que tiene que comparar con cada caso

Entre llaves, listamos cada uno de los casos a comparar. En el ejemplo hemos listado para el listamos cada uno de los casos a comparar. En el ejemplo hemos listado para el caso que ingreso valga 0, 1, 2, o 3.

Cada uno de los casos contiene la instrucción a ejecutar . instrucción a ejecutar.

Tras cada caso, la sentencia “break” , que ordena al programa salir del bloque switch. Es decir, si coincide sentencia “break”, que ordena al programa salir del bloque switch. Es decir, si coincide con “0” no leerá las instrucciones de los demás.

Opcionalmente, un caso “default” que viene a ser algo así como “ejecuta esto si la variable tiene un “default” que viene a ser algo así como “ejecuta esto si la variable tiene un valor que no coincida con ninguno de estos casos”.

Se puede usar un switch case sin default o con el default vacío. Intenta comentar esas líneas con las barras // y comprueba que compilan ;)

Fíjate: Hemos usado una variable de tipo int para la comparación. La sentencia switch también puede funcionar para comparar chars, ints e incluso (si estás usando Java 7 o posterior) Strings. Siempre comprueba que la variable a comparar sea del mismo tipo que la que indicas en cada case.

Como ves, en este caso no era demasiado buena idea usar una sentencia switch, porque se pide al usuario que introduzca un número cualquiera. Para tenerlo todo previsto deberíamos programar un case para cada uno de los enteros que pueden caber en una variable int (-3, -2, -1, 0, 1, 2, 26…) y no acabaríamos nunca.

Si queremos comparar rangos de datos (cifras menores o mayores que) siempre es mejor utilizar if o if/else. rangos de datos (cifras menores o mayores que) siempre es mejor utilizar if o if/else.

Si queremos comparar unos pocos casos concretos , encontrando coincidencias exactas, una sentencia switch puede ser mejor porque el código casos concretos, encontrando coincidencias exactas, una sentencia switch puede ser mejor porque el código resultante es más limpio y legible, y se ejecuta en menos tiempo.

Blindando nuestra hucha Vamos a utilizar la nueva sentencia aprendida para blindar nuestra hucha frente

Blindando nuestra hucha

Vamos a utilizar la nueva sentencia aprendida para blindar nuestra hucha frente al uso de curiosos no autorizados ;)

Usando un switch y el método Scanner, que ya conoces, al iniciarse la hucha pedirá al usuario la contraseña. Si ésta coincide podrá seguir adelante y ver el saldo. Si se equivoca, lanzaremos un mensaje al usuario diciendo que la contraseña es incorrecta y que no está autorizado para ver el saldo.

1. Escribe el algoritmo de la hucha que incluya iniciarse, pedir la contraseña, validarla, etc. Es importante hacer este paso para tener claro el diseño y lo que tenemos que programar después.

2. Intenta escribir el código para incluir la nueva funcionalidad. Recuerda que este nuevo bloque debería ir antes de la parte en la que se hace el ingreso, y que la contraseña deberá estar previamente guardada para que pueda compararla :)

SOLUCIÓN

No me canso de repetirlo: UNA de las innumerables soluciones posibles al reto.

import java.util.Scanner;

public class MiHucha {

public static void main (String []args){ String contrasena; int totalAhorrado = 0; String pideContrasena = "Introduce tu clave para poder operar y pulsa Enter"; String contrasenaOK = "::::Bienvenido a tu hucha securizada.:::"; String total = " >>> El total ahorrado es "; String gracias = "::: Gracias por usar la hucha electrónica. :::"; String KO = "Contraseña incorrecta. No estás autorizado a usar esta hucha.";

Scanner miScanner = new Scanner(System.in); //abre nuevo Scanner System.out.println(pideContrasena); //pide la contraseña //crea una variable en la que guardar la contraseña que introduzca el usuario contrasena = miScanner.next(); //ahora comprueba si es correcta para dejarle pasar switch (contrasena) { case "abracadabra":

System.out.println(contrasenaOK + "\n" + total + " " + totalAhorrado); //pregunta al usuario System.out.println("Indica la cantidad a ingresar, por favor"); //crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); if (ingreso > 0) {

totalAhorrado = totalAhorrado+ingreso;

} else { System.out.println("El importe debe ser mayor que 0."); System.out.println("No se ha realizado el ingreso.");

}

//muestra al usuario el total actual System.out.println(total + " " + totalAhorrado+ "\n" + gracias); break; default:

System.out.println (KO); break;

}

}

}

Varios detalles importantes a tener en cuenta de esta solución:

Hemos movido la sentencia que muestra el saldo, así como también las que evalúan el ingreso, a dentro del bloque switch, dentro del primer caso. El motivo es que sólo queremos que se ejecute esa parte del programa si el usuario introduce la contraseña correcta.detalles importantes a tener en cuenta de esta solución: Como default hemos creado un mensaje que

Como default hemos creado un mensaje que avisa al usuario de que el texto que ha tecleado no corresponde a la contraseña.El motivo es que sólo queremos que se ejecute esa parte del programa si el usuario

4. Un juego de niños A estas alturas del libro ya tenemos cierto control sobre

4. Un juego de niños

A estas alturas del libro ya tenemos cierto control sobre nuestros programas: sabemos crear

variables, manejarlas con operadores, usar métodos para provocar cambios en ellas e incluso

determinar diferentes tareas a realizar según se den algunas condiciones.

Pero a nuestros programas les sigue faltando “algo”. En nuestro ejemplo de la hucha, es un poco raro que si no introduces la contraseña correcta al primer intento ésta se cierre sin más… a veces nos equivocamos al escribirla y se agradece poder repetir, ¿verdad? Pero, ¿cómo decirle al ordenador que ejecute una tarea varias veces, sin tener que escribir bloques de código idénticos uno tras otro? Tenemos unos poderosos ayudantes para esto: ¡los bucles! Igual que las sentencias condicionales del capítulo anterior, los bucles son también herramientas para controlar el flujo de acciones de nuestro programa. La diferencia es que, mientras las condicionales sirven para decir qué hacer, los bucles indican cuántas veces o durante cuánto tiempo.

Pero ¿qué es un bucle?

Según el diccionario, un bucle es un rizo de cabello. También usamos la palabra bucle para referirnos a las vueltas que dan sobre sí mismas las vías de una montaña rusa, cuando nos

ponemos cabeza abajo. En general, llamamos bucle a algo que gira alrededor de un centro, que

da vueltas sobre sí mismo.

Cuando nos referimos a la programación, al hablar de “bucles” nos referimos a un bloque de instrucciones que se repite una y otra vez, hasta que se alcanza una condición determinada.

Para el caso de nuestra hucha, por lo tanto, podríamos crear un bucle para dar al usuario más oportunidades para teclear la contraseña correcta, diciéndole al programa que repita la secuencia leer del teclado-comparar contraseñas-denegar o dar acceso cada vez que éste se equivoque. Y podríamos decidir si queremos darle un número de intentos concreto, o permitir que lo intente indefinidamente hasta que lo averigüe: la decisión es nuestra.

En el lenguaje Java existen tres tipos de bucles, que aprenderemos a usar en este capítulo:

WHILE – DO WHILE - FOR

a usar en este capítulo: WHILE – DO WHILE - FOR WHILE La sentencia while (que

WHILE

La sentencia while (que significa “mientras” en inglés) evalúa el valor de una condición y, mientras éste sea true, ejecuta el código que ésta contiene.

1.

el

programa comprueba si el valor de la condición es true

2.

siempre que lo sea, a continuación ejecuta el código

3.

vuelve a comprobar el valor de la condición

4.

si

sigue siendo true vuelve a ejecutar el bloque

En el momento en que en una comprobación encuentre que el valor de la condición sea false, dejará de ejecutar el bloque y continuará con el resto del programa (o, dicho de otro modo, saldrá del bucle).

Ten en cuenta:

Si en el paso 1 encuentra que la condición es false, jamás llegará a ejecutar

Si

en el paso 1 encuentra que la condición es false, jamás llegará a ejecutar el bloque de

código, y no lo comprobará más veces; pasará directamente a la siguiente tarea.

Y si el valor de la condición nunca cambia, tendremos un bucle infinito . El

Y

si el valor de la condición nunca cambia, tendremos un bucle infinito. El bloque

nunca dejará de ejecutarse.

nunca dejará de ejecutarse. ¿Has oído hablar de los cañones de pelotas? Los jugadores de tenis

¿Has oído hablar de los cañones de pelotas? Los jugadores de tenis se entrenan con unas máquinas que les van lanzando pelotas, una tras otra, y ellos tienen que golpearlas. Éste sería un buen ejemplo de bucle while, en el que la condición sería “mientras siga lanzando pelotas”. Mientras eso ocurra, ejecutaremos nuestro bloque de código, que es “devolver la pelota con la raqueta”. Cuando deje de lanzar pelotas nosotros dejaremos de golpear y saldremos del bucle.

Así es como programaríamos un bucle while:

while(condición) { bloque a ejecutar;

}

¡Así de simple!

Por ejemplo, este programa simula la cuenta atrás para lanzar un cohete al espacio:

public class CoheteEspacial {

public static void main (String args[]) { int cuentaAtras = 5; String mensaje = "DESPEGUE";

while (cuentaAtras>0){

System.out.println(cuentaAtras);

cuentaAtras--;

}

System.out.println(mensaje);

}

}

Fíjate:

cuentaAtras--; } System.out.println(mensaje); } } Fíjate: La condición es que el contador sea MAYOR que cero.

La condición es que el contador sea MAYOR que cero. Si indicamos >= se mostraría en pantalla una vez de más… pruébalo en tu equipo.

La sentencia cuentaAtras--; significa “resta uno al valor de cuentaAtras”. Como la hemos incluido dentro del bucle, cuentaAtras--; significa “resta uno al valor de cuentaAtras”. Como la hemos incluido dentro del bucle, solo restará cada vez que haya dado una vuelta al mismo, es decir tras cada impresión por pantalla del valor de cuentaAtras.

La impresión del mensaje la dejamos FUERA del bucle. Si la metiésemos dentro se imprimiría cada vez que mostrase un número FUERA del bucle. Si la metiésemos dentro se imprimiría cada vez que mostrase un número por pantalla y no tendría sentido, nuestro cohete saldría 5 veces al espacio ;P

sentido, nuestro cohete saldría 5 veces al espacio ;P UN POCO DE EJERCICIO Para practicar los

UN POCO DE EJERCICIO

Para practicar los loops while, te propongo que codifiques estos programas:

1. Observa el siguiente fragmento de código. ¿Qué crees que se mostrará por pantalla?

int i = 0; while (i < 3) {

System.out.println("eco");

i++;

}

2. Debe haber algún problema en este programa, porque lo he ejecutado y el bucle no

termina jamás, he tenido que cerrarlo por la fuerza. ¿Sabrías decir qué es?

int contador = 0; while (contador <= 3) {

System.out.println("Mensaje para imprimir");

}

contador++;

3. Y uno para adelantados:

Dado un número (que introducirá el usuario) el programa cuenta cuántas veces se puede dividir éste entre 2 sin dejar residuo, y muestra el resultado. Por ejemplo:

El programa pregunta el número2 sin dejar residuo, y muestra el resultado. Por ejemplo: El usuario introduce el 6 El

El usuario introduce el 6el resultado. Por ejemplo: El programa pregunta el número El programa divide el número entre 2

El programa divide el número entre 2 mediante un bucle while, y sus resultados sucesivamente, hasta que uno ya no sea divisible (6÷2, después 3÷2 while, y sus resultados sucesivamente, hasta que uno ya no sea divisible (6÷2, después 3÷2 y el resultado que es 1,5 ya no podría dividirse. La respuesta sería 1 veces).

Se muestra al usuario por pantalla un mensaje con el resultado: “6 puede dividirse 1 veces entre 2”.(6÷2, después 3÷2 y el resultado que es 1,5 ya no podría dividirse. La respuesta sería

SOLUCIONES

1.

Se mostrará la palabra 3 veces:

eco

eco

eco

2. El bucle es infinito porque hemos dejado la sentencia contador++; fuera del bloque while, así

que no va a sumar hasta que abandone el bucle. Entonces, por más vueltas que da, nunca

aumenta el valor.

3. Una posible forma -con la que he desarrollado la solución que te propongo- es iniciar un bucle

que funcione mientras el resultado de la división sea mayor o igual que 1. Y esto, ¿por qué? Pues muy sencillo. Sabemos que ningún número menor que el 2 es divisible entre dos con residuo cero así que, ¿para qué seguir dando vueltas?

int contador = 0; int numeroUsuario = Scanner.nextInt();

while (numeroUsuario >= 1) { numeroUsuario = numeroUsuario / 2; contador++;

}

System.out.println(“Se puede dividir ”+ contador + “ veces.”);

Otra forma podría haber sido iniciar un bucle que funcione mientras numeroUsuario sea divisible entre 2, usando el operador módulo.

DO-WHILE

sea divisible entre 2, usando el operador módulo. DO-WHILE La sentencia Do-While es muy parecida a

La sentencia Do-While es muy parecida a la anterior, pero se diferencia en que primero se inicia la ejecución del bloque de instrucciones y después se comprueba el valor de la condición.

Se podría comparar con el juego de la piñata:

Golpear la piñata con el bastóncondición . Se podría comparar con el juego de la piñata: Comprobar: ¿sigue entera la piñata?

Comprobar: ¿sigue entera la piñata?el juego de la piñata: Golpear la piñata con el bastón Si sigue entera, golpear de

Si sigue entera, golpear de nuevo.la piñata: Golpear la piñata con el bastón Comprobar: ¿sigue entera la piñata? Volver a comprobar

Volver a comprobar si sigue entera…de la piñata: Golpear la piñata con el bastón Comprobar: ¿sigue entera la piñata? Si sigue

Y así sucesivamente. En el momento en que la variable piñataEntera tenga valor falso, saldríamos del bucle, es decir, no daríamos un bastonazo más.

Como ves, la acción a ejecutar (dar un bastonazo) siempre se ejecuta por completo antes de cada comprobación de la condición. Dicho de otro modo, pase lo que pase siempre se va a ejecutar al menos una vez. Por eso le llamamos Do-While, en inglés “Hacer - mientras que…”.

llamamos Do-While, en inglés “Hacer - mientras que…”. UN RETO SENCILLO Retoma el programa de la

UN RETO SENCILLO

Retoma el programa de la hucha e intenta incluir un do-while para que, mientras el usuario no haya indicado la contraseña correcta, siga pidiendo una y otra vez que la ingrese.

Piensa bien antes de lanzarte, te recomiendo primero hacer un borrador con lápiz y papel o al menos escribir el algoritmo que seguirás.

Algunos consejos para la práctica:

Recuerda que primero debes pedir la contraseña una vez, y a continuación comprobar si el usuario acierta.algoritmo que seguirás. Algunos consejos para la práctica: El resultado de la comparación sería la condición

El resultado de la comparación sería la condición para evaluaruna vez, y a continuación comprobar si el usuario acierta. Si el usuario acierta se debe

Si el usuario acierta se debe salir del bucle para dar paso al ingresode la comparación sería la condición para evaluar Si el usuario se equivoca, se imprime el

Si el usuario se equivoca, se imprime el mensaje de error y se vuelve a pedir la contraseñaacierta se debe salir del bucle para dar paso al ingreso SOLUCIÓN import java.util.Scanner; public class

SOLUCIÓN

import java.util.Scanner; public class MiHucha{

public static void main(String []args){ int totalAhorrado = 0; String pass;

//abre nuevo Scanner Scanner miScanner = new Scanner(System.in);

do{ //pide la contraseña System.out.println("Introduce tu clave para poder operar y pulsa Enter"); //crea una variable en la que guardar la contraseña que introduzca el usuario pass = miScanner.nextLine(); } while (!"abracadabra".equals(pass)); //deja de pedirla cuando sea correcta

System.out.println("::::Bienvenido a tu hucha securizada.::: \n >>> El total ahorrado es " + totalAhorrado);

//pregunta al usuario System.out.println("Indica la cantidad a ingresar, por favor"); //crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); if (ingreso > 0) { totalAhorrado = totalAhorrado+ingreso; } else {

System.out.println("El importe debe ser mayor que 0: no se hará el ingreso");

}

//muestra al usuario el total actual

System.out.println("El total ahorrado es " + totalAhorrado + "\n::: Gracias por usar la hucha electrónica. :::");

}

}

FOR

La sentencia for nos sirve para programar bucles indicados para aquellos casos en que sabemos el número de veces que debemos iterar (dar vueltas al bloque de código).

que debemos iterar (dar vueltas al bloque de código). Para ello, se define una variable con

Para ello, se define una variable con un valor numérico inicial, otra con el valor máximo a alcanzar y se indica que cada vez que se ejecuta el bloque, se suma uno a la primera. Cuando ha sumado tantos como el máximo, deja de iterar. Por ejemplo, el juego del escondite. A Juan le toca buscar a sus 6 amigos:

Variable niñosEncontrados: al inicio es 0juego del escondite. A Juan le toca buscar a sus 6 amigos: Variable niñosJugadores = 6

Variable niñosJugadores = 6a sus 6 amigos: Variable niñosEncontrados: al inicio es 0 Juan empieza a jugar. Como niñosEncontrados

Juan empieza a jugar. Como niñosEncontrados vale 0, da una vuelta al patio. Encuentra a María.al inicio es 0 Variable niñosJugadores = 6 Ahora niñosEncontrados es igual a 1. Como aún

Ahora niñosEncontrados es igual a 1. Como aún no vale 6, tiene que dar otra vuelta.vale 0, da una vuelta al patio. Encuentra a María. Juan da otra vuelta al patio

Juan da otra vuelta al patio y encuentra a Miguel.igual a 1. Como aún no vale 6, tiene que dar otra vuelta. Ahora niñosEncontrados es

Ahora niñosEncontrados es igual a 2. Eso tampoco es un 6 así que… tiene que dar otra vuelta.vuelta. Juan da otra vuelta al patio y encuentra a Miguel. Si seguimos así, llegará un

Si seguimos así, llegará un momento en que niñosEncontrados valdrá lo mismo que niñosJugadores: 6 y 6. En ese momento Juan sale de su bucle y deja de buscar.Eso tampoco es un 6 así que… tiene que dar otra vuelta. Y esto, en código

Y esto, en código Java, tiene el siguiente aspecto:

class MiEscondite { public static void main(String[] args){ int niñosJugadores = 6; int niñosEncontrados = 0;

for(niñosEncontrados; niñosEncontrados<niñosJugadores; niñosEncontrados++){ System.out.println("1 vuelta más. Niños encontrados: " + niñosEncontrados);

}

}

}

Fíjate:

Los parámetros del for siempre son 3, en este orden: inicio, término, incremento . Número del que partes, número al que llegar, cuánto sumar en inicio, término, incremento. Número del que partes, número al que llegar, cuánto sumar en cada vuelta.

EL CERO CUENTA. Nunca se empieza a contar desde 1, si quieres que un bucle dé 6 vueltas deberás poner el número 5 como límite.partes, número al que llegar, cuánto sumar en cada vuelta. El parámetro de inicio siempre es

El parámetro de inicio siempre es una variable que se inicializa DENTRO del bucle for. Si la inicializas al principio del programa queda fuera del bucle y no compilará (veremos esto más adelante)dé 6 vueltas deberás poner el número 5 como límite. El parámetro de término siempre es

El parámetro de término siempre es una comparación aritmética, cuando ésta sea false es cuando se detendrá el buclefuera del bucle y no compilará (veremos esto más adelante) El parámetro de incremento se ejecuta

El parámetro de incremento se ejecuta cada vez que se recorre el bucle entero (no al principio)cuando ésta sea false es cuando se detendrá el bucle Muy importante indicar que niñosEncontrados >

Muy importante indicar que niñosEncontrados > que niñosJugadores, ya que si indicases >= el resultado no será false hasta que valga 7 y Juan va a dar una vuelta de más. Es importante que siga el bucle sólo cuando tenga MENOS de 6 niños encontrados. Es importante que siga el bucle sólo cuando tenga MENOS de 6 niños encontrados.

Dentro de las llaves del bucle metemos el código a ejecutar una y otra vez, igual que hacíamos con el if.el bucle sólo cuando tenga MENOS de 6 niños encontrados. TRES EJERCICIOS CON BUCLES FOR 1.

a ejecutar una y otra vez, igual que hacíamos con el if. TRES EJERCICIOS CON BUCLES

TRES EJERCICIOS CON BUCLES FOR

1. Escribe un programa que muestre todos los impares contenidos entre el 0 y 50.

Pista: te recomiendo volver a consultar la tabla de operadores aritméticos, hay uno que sirve exactamente para esto.

2. Escribe un programa que muestre todos los impares contenidos entre el cero y un número que el usuario introduzca.

3. Modifica el programa del ejercicio 2 para que, después de mostrar los números, muestre un mensaje diciendo cuántos impares ha encontrado.

Recuerda: el mensaje sólo debe mostrarse al final de la ejecución del programa.

SOLUCIONES

2. Para realizar el ejercicio simplemente hemos añadido la pregunta al usuario y modificado el

2. Para realizar el ejercicio simplemente hemos añadido la pregunta al usuario y modificado el bucle for. Ahora en vez de tener un número fijo como máximo de vueltas a dar, tiene una variable que contiene el número que el usuario ha dado.

una variable que contiene el número que el usuario ha dado. Fíjate: hemos indicado <= en

Fíjate: hemos indicado <= en el for. El motivo es que si sólo indicas i < num y el usuario introduce, por ejemplo, un 5, el bucle se detendrá cuando valga 4 y nunca te imprimirá el último. Todo esto depende de lo que se te pida exactamente: todos los impares contenidos entre dos cifras, o todos los impares mayores que una cifra y menores que otra.

3. En este caso, lo único que hemos hecho es:

que otra. 3. En este caso, lo único que hemos hecho es: Crear una variable que

Crear una variable que actúe como contador de imparesque otra. 3. En este caso, lo único que hemos hecho es: Sumarle 1 cada vez

Sumarle 1 cada vez que un número es impar y entre en el bloque ify menores que otra. 3. En este caso, lo único que hemos hecho es: Crear una

Imprimir el mensaje después de salir del bucle for

Imprimir el mensaje después de salir del bucle for

Imprimir el mensaje después de salir del bucle for

¡NUESTRO PRIMER JUEGO!

¡NUESTRO PRIMER JUEGO! JUEGO: Piedra, papel, tijeras Como ya vamos teniendo bastante por la mano esto

JUEGO: Piedra, papel, tijeras

Como ya vamos teniendo bastante por la mano esto de programar, con todo lo que ya sabemos y un par de trucos que ahora aprenderás vamos a crear nuestro primer juego interactivo. ¡Hurra!

Como todos los buenos profesionales, antes de lanzarnos sobre el teclado tenemos que completar un par de fases previas.

En primer lugar, recogeremos los requisitos . Dicho de otra manera, redactaremos la mecánica de

En primer lugar, recogeremos los requisitos. Dicho de otra manera, redactaremos la mecánica de nuestro juego y escribiremos qué funciones debe tener el programa. Normalmente cada requisito se traduce después en una función concreta del código, algo que hay que programar.

A continuación, diseñaremos el algoritmo, es decir, la secuencia de pasos que dará

A

continuación, diseñaremos el algoritmo, es decir, la secuencia de pasos que dará

cuando lo ejecutemos

Seguidamente, por fin, escribiremos el código

Seguidamente, por fin, escribiremos el código

Pondremos a prueba nuestro programa para comprobar que funciona como se espera

Pondremos a prueba nuestro programa para comprobar que funciona como se espera

Refactorizaremos: haremos nuestro código más limpio y profesional para obtener el

Refactorizaremos: haremos nuestro código más limpio y profesional para obtener el

mejor resultado posible.

¡Manos a la obra! ;)

REQUISITOS DEL PROGRAMA

Como es tu primera práctica de videojuego real y nadie nace enseñado, voy a listar directamente los requisitos que debe tener. En las próximas prácticas te sugiero que primero lo intentes por tu cuenta y después compruebes si coincide con la solución o te has dejado algo importante.

Funciones que debe tener el juego:

iniciarse la ejecución el juego mostrará un menúdejado algo importante. Funciones que debe tener el juego: menú tendrá las opciones de jugar partida

menú tendrá las opciones de jugar partida o salir del juegohas dejado algo importante. Funciones que debe tener el juego: iniciarse la ejecución el juego mostrará

Al

El

Los contrincantes serán el programa y el usuarioEl programa mostrará al usuario los comandos: 1 para piedra, 2 para papel, 3 para

El programa mostrará al usuario los comandos: 1 para piedra, 2 para papel, 3 para tijeraLos contrincantes serán el programa y el usuario En cada ronda el usuario elige una tirada

En cada ronda el usuario elige una tirada usando el teclado, y el programa hace una tirada aleatorialos comandos: 1 para piedra, 2 para papel, 3 para tijera Tijera gana a papel, piedra

Tijera gana a papel, piedra gana a tijerausando el teclado, y el programa hace una tirada aleatoria En caso de empate se informa

En caso de empate se informa al usuariotirada aleatoria Tijera gana a papel, piedra gana a tijera En caso de que gane uno

En caso de que gane uno de los jugadores se muestra un mensaje indicando quién ganapiedra gana a tijera En caso de empate se informa al usuario El programa tiene que

El programa tiene que prever que el usuario introduzca un dato incorrecto en cualquier momento, sin que se provoque un errorde los jugadores se muestra un mensaje indicando quién gana En una segunda versión del programa,

En una segunda versión del programa, podría mejorarse para que siga proponiendo rondas mientras el usuario no pida saliren cualquier momento, sin que se provoque un error ALGORITMO DEL PROGRAMA Ahora usa tu imaginación

ALGORITMO DEL PROGRAMA

Ahora usa tu imaginación y recrea toda una secuencia de juego. Mientras lo haces anota cada paso que se produce y exprésalo en forma de lista de sucesos, para componer el algoritmo.

A continuación tienes mi propuesta de algoritmo. Intenta primero hacerlo sin mirar la solución…

1. Se muestra la pantalla de inicio. Opciones 1) Jugar 2) Salir

2. Si el usuario elige 2 se cierra la aplicación

3. Si el usuario elige 1 se muestran las instrucciones: 1 papel 2 piedra 3 tijera

4. Si el usuario teclea cualquier otra cosa se muestra un mensaje “opción incorrecta” y se vuelve al punto 1

5. Se inicia una ronda con la tirada del usuario

6. El programa hace una tirada aleatoria

7. Se comparan los resultados:

a. si inputOrdenador == inputUsuario se muestra el mensaje “EMPATE”

b. si inputOrdenador > inputUsuario se muestra el mensaje “TÚ PIERDES”

c. si inputOrdenador < inputUsuario se muestra el mensaje “TÚ GANAS”

d. si inputUsuario no es un número válido aparece el mensaje “TIRADA INCORRECTA” y se vuelve al punto 3.

¿Verdad que parecía más difícil antes de escribir el algoritmo? Plasmar las cosas de forma organizada nos ayuda a abordar mejor los problemas lógicos.

ESCRIBIENDO EL CÓDIGO

Para escribir el código, mi consejo es que lo vayas construyendo funcionalidad a funcionalidad, comprobando a cada paso que lo que acabas de hacer funciona.

Para facilitártelo, dividimos en pasos las funcionalidades que tenemos que desarrollar. Crea una nueva clase e intenta seguir estos pasos por tu cuenta; después puedes consultar mi solución propuesta (en el código resultante te dejo comentarios con el paso al que refiere cada fragmento de código).

1. Programar el menú inicial. Programa un menú que se muestre por pantalla e indique al usuario las opciones que tiene (salir o jugar).

2. Programa la lógica del menú.

Recoge la respuesta del usuario según lo que haya seleccionado: 1) inicia una ronda 2) sale del programa 3) avisa del error y repite el punto 1. CONSEJO: Para salir del programa puedes usar el comando System.exit(0) que hace justamente eso. Para controlar los errores -es decir, que el usuario introduzca cualquier cosa que no sea 1 o 2- te aconsejo usar algún tipo de estructura de decisión o bucle.

3. Programa la lógica de una ronda.

Recoger el input del usuario. Hacer que el programa haga una tirada aleatoria.

Comparar tiradas de usuario y programa. Informar de empate - victoria programa - victoria usuario - input incorrecto

CONSEJO: En el lenguaje Java, dentro de la clase MATH, existe el método random cuya función es elegir un número al azar entre un rango proporcionado previamente. Te podría ser muy útil para la tirada aleatoria del programa.

Para usarlo tienes que importar la clase Math (igual que haces con la clase Scanner: import java.util.Math). Aquí te dejo un ejemplo de uso de dicho método que hace algo parecido a lo que necesitas:

import java.util.Random; public class random{

public static void main(String []args){ //crea un nuevo objeto random Random random = new Random();

// usando el objeto random, obtiene un número entero //de 0 a 100 y lo guarda en la variable randomInt int randomInt = random.nextInt(100); //lo muestra por pantalla System.out.println(randomInt);

}

}

En mi caso, así es como he preparado la clase para empezar a programar:

SOLUCIONES A continuación tienes la misma imagen, con los fragmentos de código desarrollado. La amplío

SOLUCIONES

A continuación tienes la misma imagen, con los fragmentos de código desarrollado. La amplío por separado para que puedas ver mejor los detalles:

MENÚ PRINCIPAL

para que puedas ver mejor los detalles: MENÚ PRINCIPAL Como ves, se puede decorar un poco

Como ves, se puede decorar un poco el texto para que tenga un aspecto más propio de un juego. Si has llegado hasta aquí, te aconsejo comprobar que de momento el programa compila y se

ejecuta tal como esperas.

LÓGICA DEL MENÚ

ejecuta tal como esperas. LÓGICA DEL MENÚ Para la lógica del menú hemos usado un while

Para la lógica del menú hemos usado un while que se encargará de preguntar al usuario las veces que hagan falta hasta que elija una opción correcta. Una vez la elija saldremos del bucle y entonces manejaremos lo que haya escogido:

Si es la opción 1, iniciará la ronda de juegodel bucle y entonces manejaremos lo que haya escogido: Si es la opción 2, cerraremos el

Si es la opción 2, cerraremos el programa con el método System.exit(0);escogido: Si es la opción 1, iniciará la ronda de juego LÓGICA DE UNA RONDA Esta

LÓGICA DE UNA RONDA Esta es la lógica de UNA ronda de juego. Todavía no hemos llegado a la fase en la que se podrá jugar una y otra vez; como comentábamos en los requisitos esa es una mejora para una segunda versión del programa.

Así que, de momento, metemos la lógica de una ronda de juego dentro del switch.

De nuevo, no había una sola manera de programar esta función. Además, se ha programado

De nuevo, no había una sola manera de programar esta función. Además, se ha programado de la forma más rudimentaria posible, con el objetivo de que veas con claridad el orden en que se ejecutan las sentencias y comprendas qué controla cada una de ellas.

Con las herramientas que hasta ahora hemos aprendido a manejar, ésta es una solución bastante casera, pero aparentemente estable.

La primera versión de nuestro programa está ya lista para la fase de pruebas.

PONEMOS A PRUEBA NUESTRO PROGRAMA

Durante el desarrollo de un programa nuevo, se realizan diversas operaciones para asegurar la calidad del producto.

Éstas consisten en intentar identificar todos los posibles escenarios que se pueden producir al usar el programa, para poder comprobar que responde correctamente a cada uno de ellos. A continuación se escriben todos esos casos en forma de pruebas a realizar, y si alguna fallase se vuelve a trabajar en el código para solucionarla. Las personas que escriben estas pruebas se pueden basar en diversos factores: los requisitos del programa, su experiencia previa, errores ya producidos anteriormente…

Te sugiero que realices estas pruebas jugando con el programa para detectar si hay errores, o si ocurre lo que se espera de él:

Menú principal: elegir salirMenú principal: elegir una opción incorrecta Menú principal: elegir jugar Jugada 1: elegir tijera Jugada

Menú principal: elegir una opción incorrectaMenú principal: elegir salir Menú principal: elegir jugar Jugada 1: elegir tijera Jugada 2: elegir papel

Menú principal: elegir jugarelegir salir Menú principal: elegir una opción incorrecta Jugada 1: elegir tijera Jugada 2: elegir papel

Jugada 1: elegir tijeraelegir una opción incorrecta Menú principal: elegir jugar Jugada 2: elegir papel Jugada 3: elegir piedra

Jugada 2: elegir papelMenú principal: elegir jugar Jugada 1: elegir tijera Jugada 3: elegir piedra Jugada 4: elegir una

Jugada 3: elegir piedraelegir jugar Jugada 1: elegir tijera Jugada 2: elegir papel Jugada 4: elegir una opción incorrecta

Jugada 4: elegir una opción incorrectaelegir tijera Jugada 2: elegir papel Jugada 3: elegir piedra ¿Ha ido todo bien? Si no

¿Ha ido todo bien? Si no ha sido así repasa tu código y compáralo con mi solución propuesta.

REFACTORIZANDO NUESTRO JUEGO

La refactorización es un proceso que consiste en hacer cambios en la estructura de nuestro programa de manera que mejoremos el código sin alterar el funcionamiento del mismo.

Es decir, no se trata de cambiar las cosas que el programa hace, sino de intentar usar un código más sencillo, limpio y seguro para hacer lo mismo.

Refactorizar es una muy buena costumbre que nos ayuda a mejorar nuestros trabajos y seguir aprendiendo.

¿Qué podemos mejorar en nuestro juego?

Si te fijas, la estructura actual del juego es un poco engorrosa.

Tenemos bastantes bucles, incluso algunas estructuras anidadas (como por ejemplo un IF y un WHILE dentro de un SWITCH). Esto hace que sea un poco difícil de leer y que nos resulte delicado hacer cambios en él, porque cuando tenemos tantas sentencias que contienen otras, cambiar un pequeño detalle afecta a todo lo demás.

Lo primero que podemos hacer para limpiar nuestro código es mejorar la estructura IF. Fíjate, nos podríamos haber ahorrado tres líneas si en lugar de comparar 0 con 0, 1 con 1, y 2 con 2

hubiésemos escrito

if(tiradaPrograma==tiradaUsuario)”.

Además hemos escrito varias veces las mismas Strings (para comunicar empate, victoria o derrota) cuando las podríamos haber definido al principio del programa en 3 variables. Haciendo estos dos cambios sencillos, ahora el bloque IF tiene este aspecto:

//comparamos ambas tiradas para encontrar al ganador if(tiradaPrograma==tiradaUsuario){ System.out.println(empate);

} else if (tiradaPrograma==0 && tiradaUsuario==1){

System.out.println(ganaUsuario);

} else if (tiradaPrograma==0 && tiradaUsuario==2){

System.out.println(ganaPrograma);

} else if (tiradaPrograma==1 && tiradaUsuario==0){

System.out.println(ganaPrograma);

} else if (tiradaPrograma==1 && tiradaUsuario==2){

System.out.println(ganaUsuario);

} else if (tiradaPrograma==2 && tiradaUsuario==0){ System.out.println(ganaUsuario);

} else if (tiradaPrograma==2 && tiradaUsuario==1){ System.out.println(ganaPrograma);

}

break;

case 2: System.exit(0); break;

Y además ahora tiene otra ventaja, y es que si en el futuro queremos cambiar el mensaje que aparece cuando ganas o pierdes, sólo tendrás que modificarlo en la declaración de la variable.

Otra cosa útil que podemos hacer es encapsular algunos de nuestros fragmentos, construyendo métodos con ellos. Ya has visto algunos métodos que vienen incluidos en las librerías de Java, como el método Scanner o el método Random. La buena noticia es que tú también puedes crear tus propios métodos a medida, situarlos en una zona separada del código e irlos invocando cada vez que se les necesite.

Para crear un método con el código que controla una ronda, hacemos lo siguiente:

1. Crea un nuevo método fuera del método main (no debes declarar un método dentro de otro). Para saber dónde, fíjate en las llaves que separan cada sección:

public class MiClase{ public static void main(String[]args){ //espacio dentro del método main

}

//espacio DENTRO de la clase MiClase, pero FUERA del método main donde puedes poner el método “ronda”-o cualquier otro que escribas.

}

2. Declaramos el método, como viste en anteriores capítulos: tipo de acceso, tipo de retorno,

nombre del método, parámetro y llaves:

public static void ronda(){}

3. Movemos el código que gestiona toda una ronda de juego, desde el case1 del switch case a

dentro del nuevo método; y en su lugar en ese punto invocamos al método ronda. Te recomiendo muchísimo que en lugar de cortar y pegar, comentes ( // ) las líneas en el switch y las copies al nuevo método. De este modo si algo sale mal y abandonas el intento no perderás lo que ya tenías y funcionaba bien.

4. Ahora la estructura general del programa queda así (yo no he comentado el código, lo he

borrado para que sea más fácil de ver… ¡no soy un ejemplo de cautela!)

import java.util.*; public class PiedraPapelTijera { public static void main (String[]args){ //Menú inicial.

System.out.println(":::::::::::::::::::::::::::\n" +":::PIEDRA, PAPEL, TIJERA:::\n" +"::: BIENVENID@ :::\n" +":::::::::::::::::::::::::::\n\n"

+"Elige una opción:\n 1)JUGAR

2) SALIR ");

//Lógica del menú. Scanner scan = new Scanner(System.in); int opcion = scan.nextInt(); //controla que vuelva a preguntar si el usuario no elige 1 o 2

while

(opcion!= 1 && opcion != 2) {

System.out.print("Por favor, elige una opción válida:\n" + "1)JUGAR opcion = scan.nextInt();

}

2) SALIR");

//una vez tenemos opción válida este switch la gestiona switch(opcion){

case 1: ronda();

break; case 2: System.exit(0); break;

}

}

Fíjate: elimino de ese punto el código, lo sustituyo por una llamada al código que ahora lo contiene. Como el método que hemos creado no necesita ningún parámetro para funcionar, dejamos el paréntesis vacío -pero vacío de verdad, ¡no vayas a dejar un espacio!

5. Movemos el código al método. Cuidado con comerte o añadir llaves ;)

case 2: System.exit(0);

break;

}

}

/*Lógica de una ronda.*/ public static void ronda(){ System.out.print("Elige tu tirada:\n" + "0)PAPEL 1) TIJERA 2) PIEDRA");

Scanner tirada = new Scanner(System.in); int tiradaUsuario = tirada.nextInt();

//con este while controlamos que la tirada del usuario sea válida while (tiradaUsuario!=0 && tiradaUsuario!=1 && tiradaUsuario!=2){ System.out.print("Elige tu tirada:\n" + "0)PAPEL 1) TIJERA 2) PIEDRA\n"); tiradaUsuario = tirada.nextInt();

}

//generamos una tirada aleatoria del programa Random random = new Random(); int tiradaPrograma = random.nextInt(2);

//informamos al usuario de las tiradas elegidas System.out.println("Has elegido " + tiradaUsuario + ". Yo he elegido " + tiradaPrograma + "\n::::::::::::::::::::::::::::::::::::::::\n");

String empate = "empate"; String ganaUsuario = "¡GANASTE!";

String ganaPrograma = "¡PERDISTE!";

//comparamos ambas tiradas para encontrar al ganador if(tiradaPrograma==tiradaUsuario){ System.out.println(empate);

} else if (tiradaPrograma==0 && tiradaUsuario==1){

System.out.println(ganaUsuario);

} else if (tiradaPrograma==0 && tiradaUsuario==2){

System.out.println(ganaPrograma);

} else if (tiradaPrograma==1 && tiradaUsuario==0){

System.out.println(ganaPrograma);

} else if (tiradaPrograma==1 && tiradaUsuario==2){

System.out.println(ganaUsuario);

} else if (tiradaPrograma==2 && tiradaUsuario==0){

System.out.println(ganaUsuario);

} else if (tiradaPrograma==2 && tiradaUsuario==1){ System.out.println(ganaPrograma);

}

}

}

Y

tu

ahora, la prueba definitiva: guarda y comprueba si compila. Si no, revisa las diferencias entre

código y el de este libro.

La última vuelta de tuerca

Separar partes del código que controlan funciones concretas -como una ronda de juego- tiene mucho sentido. Puedes cambiar o ampliar esos métodos sin alterar el main, reutilizarlos… y llamarlos varias veces, cada vez que haga falta.

Cuando recogíamos los requisitos de nuestro videojuego dijimos que en una segunda versión sería genial que pudieses jugar rondas seguidas sin tener que reiniciarlo.

Pues bien, ésa es otra utilidad de separar métodos.

Creamos otro método nuevo, en la misma sección que el anterior (dentro de la clase, fuera del método main) al que llamamos, por ejemplo, menú:

public static void menu(){

Scanner scan = new Scanner(System.in); int opcion = scan.nextInt();

//este bucle controla que se vuelva a preguntar si el usuario no elige 1 o 2

while

(opcion!= 1 && opcion != 2) {

System.out.print("Por favor, elige una opción válida:\n" + "1-JUGAR 2-SALIR"); opcion = scan.nextInt();

}

//una vez tenemos opción válida este switch la gestiona switch(opcion){ case 1: ronda(); System.out.println("¿Quieres jugar otra ronda?\n 1-SI 2-NO");

menu();

break;

case 2: System.exit(0); break;

}

}

Dentro del método, en el case 1, y justo debajo de la llamada a ronda(); volvemos a imprimir por pantalla el mensaje preguntando si quieren jugar. A continuación lanzamos el método menu() de nuevo.

Si sigues el código con atención verás lo que ésto provoca: cada vez que eliges jugar, primero lanza una ronda y luego te devuelve al menú. Así es como encadenamos rondas mientras el usuario quiera seguir eligiendo 1)jugar.

¡Reto conseguido!

5. Siguiendo el rastro Hasta este momento, todos los programas que hemos escrito se ejecutaban

5. Siguiendo el rastro

Hasta este momento, todos los programas que hemos escrito se ejecutaban sin dejar huella en nuestro sistema de archivos.

En este capítulo aprenderemos a escribir programas capaces de buscar archivos en nuestro equipo, crear nuevos y guardar cambios. Esto nos será muy útil si, por ejemplo, queremos que nuestra hucha empiece a recordar qué saldo tenemos de una vez para otra, o si queremos que nuestros video juegos guarden un registro con nuestro historial de victorias.

Algunos conceptos previos sobre archivos

Los archivos no son muy distintos de las variables que manejamos en nuestros programas: son

pequeños espacios asignados en la memoria del ordenador, con un contenido y formato determinado. O, de manera más formal, conjuntos de bits con un nombre asignado y una descripción de la carpeta que los contiene.

Al nombre que identifica el lugar exacto -dentro de nuestro sistema de carpetas- donde vive el archivo le llamamos ruta. Por ejemplo, al archivo .class que contiene el video juego de la práctica anterior lo llamé PiedraPapelTijera.class, ése es su nombre de archivo. Y, como lo guardé directamente en el

es

C:\Users\Nadia\Desktop\PiedraPapelTijera.class.

escritorio de mi equipo,

la

ruta

de

dicho

archivo

Haz la prueba: Abre cualquier carpeta de tu ordenador (la de descargas, la de archivos de programa, una carpeta que tengas con tus documentos…). Observa en la barra de dirección cómo se muestra la ruta hacia ese punto.

de dirección cómo se muestra la ruta hacia ese punto. El aspecto de la ruta varía

El aspecto de la ruta varía un poco entre sistemas operativos (Windows, Ubuntu, MacOS…) pero el concepto es el mismo.

Así pues, ya sabemos que la ruta es la dirección en la memoria que conduce hasta el archivo.

Ahora bien, existen dos tipos de rutas:

Ruta absoluta: Es aquella que empieza desde la letra o nombre de la unidad de memoria, como en el ejemplo anterior. Es decir, muestra toda la dirección completa desde la unidad de origen hasta el archivo.

Ruta relativa: Es aquella que sólo detalla la dirección desde el punto del sistema en el que nos encontremos, hasta el archivo. Por ejemplo, la ruta anterior C:/Users/Nadia/Desktop/Scripts/CoheteEspacial.class se podría expresar como /Desktop/Scripts/CoheteEspacial.class si el usuario o el programa ya están situados en la carpeta /Nadia de mi sistema.

Cuando escribas programas que trabajen con rutas o direcciones de archivos deberás tener en

cuenta siempre si necesitas indicar la ruta relativa o absoluta.

siempre si necesitas indicar la ruta relativa o absoluta. La clase File File (archivo) es una

La clase File

File (archivo) es una clase Java creada para manejar archivos o, mejor dicho, los lugares donde están. Lo cierto es que, aunque el nombre parece claro, lo que esta clase gestiona son las rutas donde se encuentran los ficheros, y no los documentos en sí.

Ayudándote de los métodos que incluye esta clase puedes realizar muchas funciones con archivos, por ejemplo:

Comprobar si un archivo existepuedes realizar muchas funciones con archivos, por ejemplo: Crear carpetas Renombrar, mover, copiar, borrar archivos

Crear carpetascon archivos, por ejemplo: Comprobar si un archivo existe Renombrar, mover, copiar, borrar archivos Fíjate: Con

Renombrar, mover, copiar, borrar archivospor ejemplo: Comprobar si un archivo existe Crear carpetas Fíjate: Con la clase File NO podemos

Fíjate: Con la clase File NO podemos leer qué hay dentro de los archivos, eso lo veremos más adelante.

La forma de invocar esta clase es parecida a lo que ya vimos cuando usamos Scanner y Random (aunque File no es una colección de métodos como lo son estas dos, sino más bien un tipo de dato):

1. Importar java.io.File al principio de la clase, antes de declararla

2. Instanciar File con la sentencia File file = new File(String rutaArchivo); Como siempre, puedes ponerle el nombre que quieras (no necesariamente file) y en el parámetro puedes pasar directamente la dirección del archivo, o bien una variable tipo String que contenga la misma, como yo he hecho

Resumiendo: una vez instanciado File, puedo crear un nuevo objeto File -o dirección de archivo- usando una variable:

String rutaApuntes = c:/Documentos/Deberes/Apuntes/apuntesJueves.doc File misApuntes = new File(rutaApuntes);

O indicar la ruta directamente en el parámetro:

File misApuntes = new File(“c:/Documentos/Deberes/Apuntes/apuntesJueves.doc”);

Algunos métodos útiles para trabajar con la clase File

A continuación tienes una lista de los métodos más útiles y sencillos que puedas usar para

manejar archivos:

.exists() Comprueba si existe el archivo, y es muy útil ejecutarlo como precaución antes de usar otros métodos que puedan dar un error porque el archivo no esté donde esperamos. Este método genera un booleano que adquiere valor true o false según si el archivo existe o no.

File archivo = new File(ruta); bool existeArchivo = archivo.exists(); System.out.println(“¿El archivo existe?: “+ existeArchivo);

.mkdir() (o mkdirs) Crea un nuevo directorio, y genera un booleano con valor true o false según si ha conseguido crearlo o no.

File archivo = new File(ruta); bool crearArchivo = archivo.mkdir(); System.out.println(“¿Se ha creado el directorio?: “+ existeArchivo);

.renameTo() Este método cambia el nombre de un archivo. También podemos usarlo para cambiar el nombre de la ruta, y lo que hará es moverlo a esa nueva ruta. Es decir, no cambiará el nombre de las carpetas que lo contenían, sino que buscará si existen las que ahora hemos indicado y, si es así, lo moverá a esa ubicación. También nos crea el booleano para saber si se ha movido o no.

File a = new File(“C:/Usuario/Escritorio/Maria.jpg”); File b = new File(“C:/Usuario/MisFotos/Maria.jpg”); bool moverArchivo = a.renameTo(b); System.out.println(“¿Se ha movido el archivo? “+ moverArchivo);

Como ves, en este ejemplo lo hemos movido ya que el nombre de archivo es el mismo y la ruta

es la que ha cambiado, ahora está en otra carpeta.

.delete(); Este método borra el archivo en cuestión y genera un booleano informando de si ha podido o no borrarlo.

File file = new File("C:/Users/Ana/Desktop/test.txt"); boolean borrar = file.delete(); System.out.println(borrar);

Alerta: no lo mueve a la Papelera de Reciclaje, lo borra permanentemente. Así que haz tus pruebas con cuidado ;)

TRY/CATCH

Antes de seguir aprendiendo a manejar archivos, hay una técnica que debemos conocer, ya que el compilador de Java nos obligará a usarla cuando queramos gestionarlos.

Es posible que al ejecutar los programas que escribiste en los ejercicios anteriores te hayas encontrado con alguna excepción. Es decir, un error durante la ejecución que se producía cuando ocurría algo excepcional o inesperado y que el programa no sabía manejar.

Por ejemplo, en nuestra primera versión de la hucha ésta no tenía ningún tipo de defensa ante la posibilidad de que intentases ingresar una string en lugar de un int, y si lo intentabas el resultado era algo como:

Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Unknown Source) at java.util.Scanner.next(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at MiHucha.main(MiHucha.java:26)

A la misma vez, terminaba la ejecución del programa.

Pues bien, éso es una excepción, y aunque ahora no profundizaremos en ello (porque es un tema para alumnos más avanzados) debes saber que hay dos tipos de excepciones (checked y unchecked, es decir comprobadas o no) y que cuando sean del primer tipo el compilador nos va a obligar a dejar algo previsto por si ocurren. Ese algo previsto es un bloque Try/Catch (en inglés, intenta o captura).

Resumiendo: siempre que uses un método que lance excepciones de tipo checked, aunque el código esté perfecto, nunca va a compilar a menos que añadas un bloque Try/Catch.

Los bloques gestores de excepciones tienen tres componentes a los que llamamos Try, Catch y

Los bloques gestores de excepciones tienen tres componentes a los que llamamos Try, Catch y Finally (es decir Intenta, Captura y Finalmente). El esquema de uso sería el siguiente:

try {

//aquí ponemos el código que contiene esos métodos que nos obligan a capturar excepciones

} catch (tipoDeExcepción NombreDeExcepción){

//aquí el código que va a gestionar la excepción. Sólo se ejecuta si ésta se produce

} finally {

//código que se ejecuta SIEMPRE, haya excepción o no

}

Es una manera de estructurar el código, indicándole al programa que INTENTE hacer algo, sino funciona CAPTURE la excepción -en lugar de irla lanzando hacia arriba- y FINALMENTE haga algo en concreto.

La sentencia finally es opcional, es decir, no vas a tener un error de compilación por no incluirla. Pero es interesante tenerla en cuenta, ya que normalmente se usar para limpiar o cerrar procesos. Por ejemplo, si en el bloque try hemos abierto un archivo para examinar lo que contiene, es muy buena costumbre añadir un bloque finally que, tanto si try va bien como si se lanza una excepción, cierre correctamente antes de que el programa siga con otra tarea o termine su ejecución. Especialmente por el hecho de que al producirse una excepción lo normal es que el programa deje de ejecutarse, es importante intentar asegurarse de que, dentro de lo que cabe, el programa falle lo mejor posible.

dentro de lo que cabe, el programa falle lo mejor posible. Un ejemplo de uso de

Un ejemplo de uso de try/catch/finally Para acabar de entenderlo, vamos a ver cómo usar esta técnica en el caso de un bloque de código que ya hemos usado antes: el de la cuenta atrás del cohete espacial. Este ejemplo no requeriría usar try/catch (no usamos ningún método que lance excepciones de tipo checked) pero lo vamos a usar porque es un código que entendemos:

public class CoheteEspacial { public static void main (String args[]) { int cuentaAtras = 5; String mensaje = "DESPEGUE";

try{ while (cuentaAtras>0){ System.out.println(cuentaAtras); cuentaAtras--;

}

System.out.println(mensaje);

} catch (Exception e){

System.out.println("Se ha producido una excepción: " + e);

}

}

}

Fíjate: Lo que he hecho es asignarle un nombre a la excepción (la he llamado e porque me parecía intuitivo) y, en el bloque catch, determinar que se muestre un mensaje que incluye la excepción. No se imprimirá la letra e, sino una descripción de lo que ha ocurrido.

Hay mucho más que aprender sobre el manejo de excepciones, pero para lo que pretendemos

(que compile el programa al usar ciertas clases) hasta aquí es suficiente.

Y ahora, volvamos al tema del capítulo: manejar archivos.

La clase Scanner (otra vez)

Tal y como viste en el capítulo 1, la clase Scanner contiene métodos diseñados para leer flujos de datos o mensajes. Hasta ahora hemos practicado con métodos como .nextInt() o nextLine() que nos servían para leer datos introducidos por el usuario en el teclado. Bien, esta clase también sirve para leer flujos de datos que provengan de archivos existentes en tu sistema. Con el método adecuado, Scanner podrá gestionar las cadenas de texto

adecuado, Scanner podrá gestionar las cadenas de texto que tengas en un archivo doc (por ejemplo)

que tengas en un archivo doc (por ejemplo) y manipularlas como

ahora hemos venido haciendo. De hecho, dentro de cualquier archivo, los datos están ordenaditos de forma secuencial, colocados en fila, y cuando se accede a los mismos para trabajar con ellos casi siempre se leen

hasta

justamente así. Por eso se habla de streams o corrientes; puedes imaginarte los pequeños datos circulando uno tras otro como si saliesen por un grifo.

A continuación, veremos cómo la clase Scanner nos proporciona métodos para leer streams de caracteres procedentes de un archivo.

Para indicar a la clase Scanner qué archivo queremos abrir , hacemos uso de la

Para indicar a la clase Scanner qué archivo queremos abrir, hacemos uso de la clase File de la manera que acabamos de aprender: indicándole la ruta. Así, de la misma manera que para leer del teclado hacíamos:

Scanner scanTeclado = new Scanner(System.in);

Para leer de un archivo haremos:

Scanner scanArchivo = new Scanner(File ruta);

Fíjate bien, simplemente se trata de usar Scanner igual que siempre, pero con una ruta como parámetro -en lugar de un teclado.

Y para indicarle que lo lea usamos los mismos métodos que al leer del teclado: nextInt(), nextLine() o lo que consideremos que va a contener el archivo.

Un ejemplo

Crea en tu sistema un documento de texto que contenga esta frase:

(Te aconsejo guardarlo como .txt). Y ahora copia este programa. Cuidado con la ruta, tiene

(Te aconsejo guardarlo como .txt).

Y ahora copia este programa. Cuidado con la ruta, tiene que coincidir con la ubicación real del

archivo en tu máquina.

import java.io.File; import java.util.Scanner;

public class LectorArchivos{

public static void main(String []args){

try{ //creo la ruta File ruta = new File("C:/Users/Desktop/texto.txt"); //abro el lector, con la ruta como parámetro Scanner scanArchivo = new Scanner(ruta);

/*le indico que lea la primera fila, es decir hasta el primer salto de línea*/ String frase = scanArchivo.nextLine();

//muestro por pantalla lo que ha leído System.out.println(frase); scanArchivo.close();

}catch (Exception e){ System.out.println(e);

}

}

}

Fíjate: cuando termino de trabajar con un fichero siempre, siempre, siempre, siempre, SIEMPRE

lo cierro: scanArchivo.close(); Esto es tan importante como lavarse los dientes después de cada

comida.

Si lo has copiado bien, se mostrará en la consola el texto que había en el fichero.

¡Genial! ¡Ahora ya sabemos leer documentos desde un programa!

¡Ahora ya sabemos leer documentos desde un programa! Un par de experimentos 1. En el programa

Un par de experimentos

1. En el programa anterior, sustituye el método nextLine() por Next(). ¿Qué ocurre? ¿Por qué?

2. Ahora sustituye el método next() por nextInt(), ¿qué ocurre?

3. Ahora sustituye la línea String frase = scanArchivo.nextLine(); por este bloque de código:

for(int i=0; i<4; i++){ String frase = scanArchivo.next(); //muestro por pantalla lo que ha leído System.out.println(frase);

}

¿Qué conclusiones puedes sacar?

SOLUCIONES

1. Al sustituir NextLine() por Next() sólo lee la primera palabra de la frase, porque en eso consiste el funcionamiento de estos métodos: leer la siguiente línea o la siguiente palabra -entendiendo palabra como el texto hasta el siguiente espacio.

2. Se lanza una excepción. El motivo es que el método nextInt() espera encontrar uno o varios números enteros separados por espacios o saltos de línea, y en lugar de eso encuentra Strings. Como hemos controlado la excepción en el bloque catch, el fallo es controlado e indicando el motivo.

3. Este experimento nos demuestra de qué manera podemos usar estructuras de decisión o

bucles para leer ciertas partes del documento. Esto nos abre muchas posibilidades, por ejemplo:

a. Leer un documento sólo si incluye ciertas palabras

b. Leer un documento en parte

c. Leer un documento de forma sucesiva mientras vamos manejando su contenido

d. … y cualquier idea que se te ocurra

La clase Printstream

Ahora que sabemos buscar archivos y leerlos, el siguiente paso lógico es escribir en ellos. Y para eso haremos uso de otra clase nueva llamada Printstream (palabrita que viene a significar algo así como imprimir corriente).

Y la buena noticia es que los principales métodos de esta clase, a estas alturas, ya los tenemos dominados: println() y print().

print() escribe el string que incluyamos como parámetro, y nada más println() escribe el string, y a continuación incluye un salto de línea

Ten en cuenta que:

si necesitas incluir espacios entre strings deberás indicarlos tú. Si no lo haces, cada vez que escriba insertará el texto pegado al último . Si no lo haces, cada vez que escriba insertará el texto pegado al último string que encuentre

si usas estos métodos en un archivo que ya existía sobrescribirás su contenido (es decir, perderás lo que había escrito anteriormente en él) (es decir, perderás lo que había escrito anteriormente en él)

igual que hacemos cuando acabamos de leer un fichero, también cerramos el stream cuando acabamos de escribir en él cerramos el stream cuando acabamos de escribir en él

Un ejemplo de uso

Retomo el programa del ejemplo anterior (que leía el contenido de nuestro .txt). Ahora lo he mejorado para que en primer lugar lea el contenido de mi archivo, después escriba un nuevo texto en él y a continuación vuelva a leerlo, para así comprobar que ha podido hacer la modificación.

import java.io.File; import java.util.Scanner; import java.io.PrintStream;

public class LectorArchivos{ public static void main(String []args){

try{ //creo la ruta File ruta = new File("C:/Users/Albert/Desktop/texto.txt");

//PARTE 1: LEER //invoco al Scanner Scanner scanArchivo = new Scanner(ruta); //muestro el texto String frase = scanArchivo.nextLine(); System.out.println(frase); scanArchivo.close();

//PARTE 2: ESCRIBIR //invoco Prinststream PrintStream escritor = new PrintStream(ruta);

//Escribo un texto en mi archivo String texto = "He conseguido escribir el archivo";

//Escribo en el archivo escritor.print(texto); escritor.close();

//PARTE 3: LEER OTRA VEZ Scanner lector = new Scanner(ruta); frase = lector.nextLine(); System.out.println(frase); lector.close();

}catch (Exception e){ System.out.println(e);

}

}

}

Como ves, se cumple lo que te decía más arriba: si usamos los métodos de escritura sobre un archivo que ya existe, se sustituye su contenido antiguo por el nuevo.

ya existe, se sustituye su contenido antiguo por el nuevo. Nuestra hucha electrónica recuerda los cambios

Nuestra hucha electrónica recuerda los cambios

La hucha electrónica, que llevamos varios capítulos desarrollando, tenía un error de diseño que nos impedía ahorrar: cada vez que terminaba de ejecutarse “olvidaba” la cantidad que le habíamos ingresado.

Ahora que podemos leer y escribir en ficheros, es hora de sustituir la variable con el ahorro indicado que siempre usa como base, y empezar a usar un documento a modo de base de datos.

Partiendo de la última versión de nuestra hucha, intenta hacer las siguientes modificaciones: 1. Cambia

Partiendo de la última versión de nuestra hucha, intenta hacer las siguientes modificaciones:

1. Cambia a 0 el valor inicial de la variable totalAhorrado

2. Genera un archivo txt que contenga una cifra (que será el nuevo valor ahorrado)

3. Implementa un método o fragmento de código que lea el contenido del .txt y lo guarde en la variable totalAhorrado. De esta manera cuando muestre el total lo hará siempre a partir de lo que diga el archivo

4. Implementa un método o fragmento de código que, cuando el usuario introduce la cantidad a ingresar, lo sume a totalAhorrado y escriba el resultado en el .txt. De esta manera cuando salgas del programa el total del texto habrá cambiado (si es que has ingresado algo).

No olvides que necesitarás usar Try/Catch para que compile :)

A continuación, y para que te sea más fácil, te copio el código de mi última versión por si quieres

usarlo como punto de partida para el ejercicio. Será más fácil comparar soluciones si partimos de

la misma base.

import java.util.Scanner; public class MiHucha {

public static void main (String []args){ String contrasena; int totalAhorrado = 0; String pideContrasena = "Introduce tu clave para poder operar y pulsa Enter"; String contrasenaOK = "::::Bienvenido a tu hucha securizada.:::"; String total = " >>> El total ahorrado es ";

String gracias = "::: Gracias por usar la hucha electrónica. :::"; String KO = "Contraseña incorrecta. No estás autorizado a usar esta hucha.";

Scanner miScanner = new Scanner(System.in); //abre nuevo Scanner System.out.println(pideContrasena); //pide la contraseña //crea una variable en la que guardar la contraseña que introduzca //el usuario contrasena = miScanner.next();

//ahora comprueba si es correcta para dejarle pasar switch (contrasena) { case "abracadabra":

System.out.println(contrasenaOK + "\n" + total + " " + totalAhorrado); //pregunta al usuario System.out.println("Indica la cantidad a ingresar, por favor"); //crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); if (ingreso > 0) { totalAhorrado = totalAhorrado+ingreso; } else { System.out.println("El importe debe ser mayor que 0."); System.out.println("No se ha realizado el ingreso.");

}

//muestra al usuario el total actual

System.out.println(total + " " + totalAhorrado+ "\n" + gracias); break; default:

System.out.println (KO); break;

}

}

}

SOLUCIÓN

Por partes, para que lo veas más claro.

1. En primer lugar importo las clases necesarias: File y Printstream (Scanner ya estaba importada).

import java.util.Scanner; import java.io.*;

Fíjate: El asterisco después de .io sirve para importar todas las clases que existan en ese paquete. Así me ahorro importar File y Printstream por separado.

2. Cambio el valor inicial de totalAhorrado a 0

3. Declaro la ruta. Lo hago a continuación de declarar las variables de la clase:

File ruta = new File("C:/Users/Desktop/scripts/totalAhorrado.txt");

4. Incluyo el try catch para poder usar Printstream:

try{ switch (contrasena) { case "abracadabra":

Scanner scanTxt = new Scanner(ruta); //nuevo Scanner archivo totalAhorrado = scanTxt.nextInt();

System.out.println(contrasenaOK + "\n" + total + " " + totalAhorrado);

//pregunta al usuario System.out.println("Indica la cantidad a ingresar, por favor");

//crea una variable en la que guardar la cantidad a ingresar int ingreso = miScanner.nextInt(); if (ingreso > 0) { totalAhorrado = totalAhorrado+ingreso; } else { System.out.println("El importe debe ser mayor que 0."); System.out.println("No se ha realizado el ingreso.");

}

//muestra al usuario el total actual

System.out.println(total + " " + totalAhorrado+ "\n" + gracias); break; default:

System.out.println (KO); break;

}

}catch(Exception e){

}

Fíjate: - He metido el bloque del switch dentro del try/catch. He creado un nuevo objeto Scanner (llamado scanTxt) específico para leer en el archivo.

(llamado scanTxt) específico para leer en el archivo. He indicado que t otalAhorrado adoptará el valor
He indicado que t otalAhorrado adoptará el valor que lea scanTxt en mi archivo He
He indicado que t otalAhorrado adoptará el valor que lea scanTxt en mi archivo He

He indicado que totalAhorrado adoptará el valor que lea scanTxt en mi archivo He preparado el bloque catch pero aún no he puesto código en él

adoptará el valor que lea scanTxt en mi archivo He preparado el bloque catch pero aún

En este punto, me aseguro de que el programa compile de nuevo.Ahora ya tengo la primera modificación importante: mi hucha ya no parte siempre del mismo valor, sino del que encuentre en su archivo. Lo siguiente es conseguir que también escriba en él.

Ahora me ocupo de la segunda parte, que escriba los cambios. Para ello:

1. Dentro del bloque if, después de actualizar el valor de totalAhorrado creo el objeto Printstream con la misma ruta como parámetro. Le indico que escriba el valor de totalAhorrado en ese archivo:

if (ingreso > 0) { totalAhorrado = totalAhorrado+ingreso;

//invoco Prinststream PrintStream escritor = new PrintStream(ruta); escritor.print(totalAhorrado); escritor.close();

2. En la línea donde muestra el total actual tengo muchas posibles opciones, éstas son algunas:

1. No modificar nada, pues el valor a mostrar (totalAhorrado) es el mismo que se escribe en el fichero, con lo cual implícitamente ya confirmo que ha escrito lo correcto

genere un booleano. Si el booleano es false, que me avise. Un poco enrevesado.

3. Modificar el parámetro de System.out.println para que el saldo final que muestra lo lea de nuevo del archivo, así también compruebo lo que se ha escrito en él.

Yo he optado por la versión a, pero si te sientes aventurero/a te sugiero que intentes codificarlas todas, sólo por experimentar y ver si eres capaz.

Por último, me ocupo de algunos detalles finales:

1. Dentro del bloque catch incluyo esta sentencia para que, en caso de lanzar excepción, la pueda manejar informando al usuario de lo ocurrido:

}catch(Exception e){ System.out.println(e);

}

2. Me aseguro de que los streams estén cerrados. Si te fijas ya indicamos escritor.close() después de escribir en el archivo, pero nunca hicimos lo mismo con scanTxt. Así que añado esta línea después de mostrar el total al usuario:

scanTxt.close();

Y por último, vuelvo a comprobar que mi programa compile :) Por fin tenemos una hucha real, que recuerda las cantidades que vamos ingresando.

documento secreto PRÁCTICA FINAL: El Te propongo una práctica final que usa prácticamente todo lo

documento secreto

PRÁCTICA FINAL: El

Te propongo una práctica final que usa prácticamente todo lo que hemos visto en este libro. Verás que la dificultad es más elevada -por eso es una práctica final-, puedes intentar resolver el reto por tu cuenta o usar los fragmentos de código que te daré.

Vamos a crear un nuevo juego que nos servirá para cifrar y descifrar mensajes. Así podremos guardar contraseñas, frases secretas o cualquier otra cosa que nos gustaría tener a salvo de espías indeseados, e incluso intercambiar mensajes cifrados con nuestros amigos si les pasamos nuestro programa.

¿Cómo funciona el cifrado del texto?

Un texto cifrado es el que está escrito con caracteres que sólo pueden comprenderse si se dispone de la clave, es decir, de la guía que indica lo que en realidad significa cada uno. Existen muchos tipos de cifrados y estándares de encriptación. De hecho, Java dispone de algunas librerías específicas para este tipo de prácticas… pero como su uso aún nos resultaría un poco complicado, vamos a aprovechar para bucear en la historia y conocer uno de los sistemas de cifrado más antiguos que se conocen.

El Cifrado del César Julio César Augusto fue el primero de los emperadores de la

El Cifrado del César

Julio César Augusto fue el primero de los emperadores de la antigua Roma. Precisamente a él se le atribuye el sistema de Cifrado César -o cifrado por desplazamiento-, que, según parece, utilizaba para enviar mensajes secretos a sus tropas. El sistema es muy simple: consiste en sustituir cada letra del alfabeto, con la que le corresponde si la desplazamos un número de veces concreto. Por ejemplo, en un sistema de Cifrado César de 2 posiciones, ésta sería la correspondencia de letras:

de 2 posiciones , ésta sería la correspondencia de letras: Éste es el caso de un

Éste es el caso de un alfabeto inglés, no recoge algunas letras como la ñ o la ç. Entonces, si tenemos un string “programa”, después de cifrarlo con este sistema el string contendría la palabra “npmepyky”.

Basándonos en este sistema, vamos a construir un programa que cifra y descifra mensajes. El programa usa siempre un archivo de trabajo en una ubicación fija del sistema de archivos del ordenador.

Así, puedes distribuir este programa a alguno de tus amigos, y enviaros mensajes cifrados que sólo vosotros, usando el programa, podréis convertir a texto legible.

Requisitos del programa

1. Muestra un menú al usuario para que elija opción (cifrar o descifrar)

2. Lee el mensaje y lo procesa en el sentido solicitado

3. Guarda el nuevo contenido en el archivo

4. Muestra por pantalla el contenido resultante

5. Nuestro programa siempre va asociado a un archivo específico que ya existe

Por lo tanto, la forma de usar el programa sería ejecutarlo, introducir el mensaje y pedirle que lo procese, eligiendo la opción de encriptar o desencriptar.

Algoritmo del programa

Trata de escribir el algoritmo de este programa. A continuación tienes mi propuesta.

Propuesta de Algoritmo

1. Inicio del programa

2. Solicita al usuario que escriba el mensaje a procesar

3. Solicita al usuario qué hacer con el mensaje: 1 Encriptar 2 Desencriptar

4. Usuario elige 1:

a. Se encripta el mensaje

b. Se guarda el mensaje encriptado en el archivo preexistente

5. Usuario elige 2:

a. Se desencripta el mensaje

b. Se guarda el mensaje desencriptado en el archivo preexistente

¡Programando!

Para facilitarte la organización de lo que tienes que ir haciendo, aquí tienes la imagen de la clase tal y como yo misma la he preparado para empezar a trabajar:

tal y como yo misma la he preparado para empezar a trabajar: Como ves, te propongo

Como ves, te propongo hacerlo más limpio desde el principio, creando métodos específicos para encriptar y desencriptar a los que podamos llamar según sea necesario.

Algunos consejos:

que podamos llamar según sea necesario. Algunos consejos: Crea un array de chars a modo de

Crea un array de chars a modo de diccionario. Lo definimos FUERA de main porque queremos que sea de acceso global (nuestros métodos para cifrar y descifrar lo usarán). No te preocupes si no sabes trabajar con arrays, te facilitaré los métodos más adelante

Deberás definir un int con el número de posiciones a desplazar. Puedes dejarlo como un dato permanente o pedírselo cada vez al usuario, yo he preferido Puedes dejarlo como un dato permanente o pedírselo cada vez al usuario, yo he preferido dejarlo fijado en 5.

Éste es el array de caracteres que he usado como diccionario:

es el array de caracteres que he usado como diccionario: Cómo programar los métodos para cifrar

Cómo programar los métodos para cifrar y descifrar

El funcionamiento de los métodos es sencillo, aunque trabajoso de codificar:

Vuelca el string que ha introducido el usuario en un array de chars que ha introducido el usuario en un array de chars

Por cada char en el array, lo busca en el diccionario recorriéndolo lo busca en el diccionario recorriéndolo

Cuando lo encuentra, lo transforma por el que se encuentre a x posiciones transforma por el que se encuentre a x posiciones

Te animo a que intentes programarlo por tu cuenta. Lo consigas o no, es un ejercicio interesante que te obligará a diseñar bien el método y hacer pruebas.

Si no quieres intentarlo o no lo consigues, aquí tienes dos métodos de encriptar y desencriptar que funcionan. De todos modos, tendrás que encajarlos en tu código y comprobar que funcione todo junto :)

Encriptar:

static String encriptar(String texto, int desplazamiento)

{

char[] arraylegible = texto.toCharArray();

for (int i = 0; i < arraylegible.length; i++) { for (int j = 0; j < chars.length; j++) { if (j <= chars.length - desplazamiento) { if (arraylegible[i] == chars[j]) { arraylegible[i] = chars[j + desplazamiento]; break;

}

}

else if (arraylegible[i] == chars[j]) { arraylegible[i] = chars[j - (chars.length - desplazamiento + 1)];

}

}

}

return String.valueOf(arraylegible);

}

Desencriptar:

static String desencriptar(String cifrado, int desplazamiento)

{

char[] arrayCifrado = cifrado.toCharArray(); for (int i = 0; i < arrayCifrado.length; i++) { for (int j = 0; j < chars.length; j++) { if (j >= desplazamiento && arrayCifrado[i] == chars[j]) { arrayCifrado[i] = chars[j - desplazamiento]; break;

}

if (arrayCifrado[i] == chars[j] && j < desplazamiento) { arrayCifrado[i] = chars[(chars.length - desplazamiento +1) + j];

break;

}

}

}

return String.valueOf(arrayCifrado);

}

Resultado final

A modo de solución, éste es mi código final. Recuerda que lo importante no es que el tuyo sea igual, sino que realice las mismas funciones.

import java.io.File; import java.util.Scanner; import java.io.PrintStream;

public class Encryption

{

static char[] chars = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^', '&', '(', ')', '+', '-', '*', '/', '[', ']', '{', '}', '=', '<', '>', '?', '_', '"', '.', ',', ' '

}; public static void main(String[] args) {

//define posiciones a mover int desplazamiento = 5; System.out.println("Por favor, escribe el mensaje secreto y pulsa Enter"); Scanner reader = new Scanner(System.in); String texto = reader.nextLine();

System.out.println("Q HACER?"); int opcion = reader.nextInt();

switch (opcion) { //ENCRIPTAR

case 1: //llama a encriptador y guarda resultado en variable String enc = encriptar(texto, desplazamiento); try { File f = new File("C:/Users/Albert/Desktop/scripts/secreto.txt"); PrintStream writer = new PrintStream(f); writer.print(enc); writer.close();

} catch (Exception e) {}

//escribe el resultado en pantalla y archivo System.out.println("Encrypted text: " + enc);

break;

//DESENCRIPTAR case 2:

String dec = desencriptar(texto, desplazamiento); System.out.println("Decrypted text: " + dec); break;

}

}

static String encriptar(String texto, int desplazamiento) { char[] arraylegible = texto.toCharArray();

for (int i = 0; i < arraylegible.length; i++) { for (int j = 0; j < chars.length; j++) { if (j <= chars.length - desplazamiento) { if (arraylegible[i] == chars[j]) { arraylegible[i] = chars[j + desplazamiento]; break;

}

}

else if (arraylegible[i] == chars[j]) {

arraylegible[i] = chars[j - (chars.length - desplazamiento + 1)];

}

}

}

return String.valueOf(arraylegible);

}

static String desencriptar(String cifrado, int desplazamiento) { char[] arrayCifrado = cifrado.toCharArray();

for (int i = 0; i < arrayCifrado.length; i++) { for (int j = 0; j < chars.length; j++) { if (j >= desplazamiento && arrayCifrado[i] == chars[j]) { arrayCifrado[i] = chars[j - desplazamiento]; break;

}

if (arrayCifrado[i] == chars[j] && j < desplazamiento) {

arrayCifrado[i] = chars[(chars.length - desplazamiento + 1) + j]; break;

}

}

}

return String.valueOf(arrayCifrado);

}

}

PROBAR

Es el momento de hacer pruebas con nuestro programa.

Diseña todos los escenarios de uso posibles y comprueba qué ocurre. Algunos podrían ser:

Introducir un texto legible, cifrarlouso posibles y comprueba qué ocurre. Algunos podrían ser: Introducir el texto anterior, descifrarlo Introducir un

Introducir el texto anterior, descifrarloAlgunos podrían ser: Introducir un texto legible, cifrarlo Introducir un texto con números, mayúsculas, minúsculas

Introducir un texto con números, mayúsculas, minúsculaslegible, cifrarlo Introducir el texto anterior, descifrarlo MEJORAR Aunque no se encuentran en el alcance de

MEJORAR

Aunque no se encuentran en el alcance de esta práctica, hay bastantes detalles que podrían mejorarse en este programa y que puedes realizar como proyecto más adelante. Por ejemplo:

El número de posiciones a desplazar los caracteres podría ser variable (ahora está hardcodeado , y ya sabes que eso es un poco chapucero). Es más, (ahora está hardcodeado, y ya sabes que eso es un poco chapucero). Es más, si lo pidiese al usuario al iniciar el cifrado, podrías usar este programa con varios amigos y tener un número clave con cada uno, así nadie podría leer mensajes que son para otra persona

Una versión posterior del programa podría leer de un archivo en lugar del teclado . Así podría leer de un archivo en lugar del teclado. Así

te podrían enviar el archivo por mensajería o email y al cargar el programa lo encontraría

y descifraría. Incluso puedes incorporar una función que liste los archivos para que elija uno, o que busque por nombre de archivo en un directorio.

No hemos añadido protección ante errores de usuario … como por ejemplo, que elija la opción 3 añadido protección ante errores de usuario… como por ejemplo, que elija la opción 3 (que no existe) o similares.

6. ¿Por dónde seguir? Mi más sincera enhorabuena por llegar hasta aquí. Ya has sentado

6. ¿Por dónde seguir?

Mi más sincera enhorabuena por llegar hasta aquí.

Ya has sentado una buena base de conocimiento, pero sobre todo has demostrado tenacidad y paciencia.

Programar es una actividad capaz de sacar lo mejor de nosotros (perseverancia, lógica, reflexión) pero también lo peor cuando las cosas no salen (frustración, impotencia, inseguridad…). Todos nos atascamos en algún momento de nuestro aprendizaje -de hecho, en muchos momentos, y

no sólo cuando aprendemos. Los profesionales se equivocan todos los días.

Si quieres seguir profundizando en la programación en Java y te estás preguntando qué hacer a continuación, tengo dos consejos básicos:

1.

Repasa otra vez lo que hasta ahora has aprendido e incorpora buenas prácticas

2.

Cuando lo hayas dominado, adéntrate en la programación modular y orientada a objetos

Este libro no puede ayudarte en lo segundo, pues el objetivo del mismo era que entrases en contacto con las principales estructuras y tipos de datos y adoptases el pensamiento algorítmico.

Respecto al primer punto, quería cerrar el libro con una serie de buenas prácticas o patrones que

te sugiero apliques en tu día a día. Aunque expresadas aquí pueden parecer un poco abstractas, te animo a que reflexiones sobre ellas mientras repasas los programas que has producido hasta ahora. Con el tiempo verás que tienen mucho, muchísimo margen de mejora -pocas veces en la vida se puede asegurar que un programa está terminado y en su mejor versión posible- y tal vez

te atrevas a retomarlos, darles una vuelta siguiendo estos enfoques y encontrar formas de

hacerlos más limpios, más simples, más eficientes. Hay pocas satisfacciones más grandes que programar bonito.

DRY (Don’t repeat yourself) “No te repitas”. Un principio importantísimo que estoy segura de que

DRY (Don’t repeat yourself)

DRY (Don’t repeat yourself) “No te repitas”. Un principio importantísimo que estoy segura de que ya

“No te repitas”. Un principio importantísimo que estoy segura de que ya puedes empezar a interiorizar. Intenta evitar el código duplicado; cuando notes que estás copiando y pegando sentencias probablemente sea el momento de extraer ese código a un método que puedas reutilizar. Esta norma persigue un código más estable y mantenible:

siempre será más sencillo cambiar algo UNA SOLA vez, que tener que retocarlo todas las veces que aparece en un programa.

YAGNI (You Aren’t Gonna Need It)

“No lo vas a necesitar”. ¿Sabes eso que nos pasa a todos cuando nos vamos de vacaciones y metemos en la maleta el doble de cosas que al final usamos? Programando tendemos a hacer lo mismo. Este principio nos dice que no añadamos funcionalidades “por si acaso”; porque un programa que hace más cosas es más propenso a errores y complicado de mantener. Cuando diseñes tus aplicaciones, programa únicamente lo que necesitas en este momento. Siempre hay tiempo de actualizar un programa si necesitas que haga más cosas.

La regla del Boy Scout

Los Boy Scouts tienen la norma de dejar siempre el bosque más limpio de lo que lo encontraron. Aplícate este lema siempre que mejores un programa que ya existía, sobre todo si no lo creaste tú. Como dijimos hace un par de capítulos, refactoriza una y otra vez.

No te lances sobre el teclado

Antes de empezar a programar escribe, proyecta, diseña. Dibuja y borra mil veces lo que quieres construir hasta que tengas un esquema claro. Te ahorrarás muchas horas de rehacer métodos y algoritmos :)

Testea SIEMPRE

Aunque sea tentador darlo por hecho cuando compila, un programa no está terminado hasta que hayas hecho las pruebas necesarias (y éstas hayan salido bien). Que el compilador no se queje no significa que nuestro programa no tenga errores o haga cosas inesperadas cuando se use… Intenta enumerar siempre todas las posibilidades y probarlas; no sólo debes probar los casos que deben funcionar sino también los que deben fallar. Y recuerda que los usuarios son casi imprevisibles… seguro que hay formas de usar tu aplicación en las que no has pensado.

Muchas gracias…

a ti, por leer este libro.

Tanto si te ha gustado como si no, me haría muy feliz que dejases tu crítica en la página de producto de Amazon. Las opiniones de mis lectores me ayudan a mejorar mi trabajo y a que este proyecto siga adelante.

Recuerda también que puedes encontrar el código completo de todas las prácticas de este libro en mi cuenta de GitHub: https://github.com/nadieta

Si quieres apuntarte a mi lista de correo para recibir noticias sobre mis próximas publicaciones o lanzamientos, puedes hacerlo en este enlace:

http://eepurl.com/c9qObn

A Saïda y Leila, mi ikigai.

A Albert, por la fe.

Nadia Ameziane Garcia Octubre de 2017.