Program (Autoguardado)

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 126

program {

Mover(Norte)

SOLUCION PARA MOVERSE DE LADO.

Entendamos qué es lo que acabamos de hacer: ¡crear un programa!

Todo programa tiene exactamente un program: una sección del código que
declara los comandos (acciones) que queremos que la máquina realice
sobre el tablero inicial. Al ejecutar un programa obtendremos un
tablero final.

La sintaxis de un program es bastante simple:

1. escribimos una línea (renglón) que diga program, seguido de una


llave de apertura: {
2. a continuación, los comandos: uno por línea
3. y finalmente, una última llave que cierra la que abrimos
anteriormente }

Vamos a ver algunos ejemplos de programs:

 uno que no hace nada

program {
}

 uno que mueve el cabezal una posición hacia el norte

program {
Mover(Norte)
}

 uno que mueve el cabezal dos posiciones hacia el norte

program {
Mover(Norte)
Mover(Norte)
}

program {

Mover(Norte)

Mover(Este)

Genial, ya entendiste cómo mover el cabezal del tablero usando la


operación Mover y las direcciones (Sur, Oeste, etc). Vayamos un paso más
allá: las bolitas.

En cualquier celda de nuestro tablero podemos poner bolitas. Las hay de


distintos colores:

 rojas (Rojo);
 azules (Azul);
 negras (Negro);
 y verdes (Verde).

Por ejemplo, este es un tablero con una bolita roja y una negra:

0 1
1
1 1

0 0
1

0 1

Además de moverse, el cabezal también puede poner bolitas en la celda


actual. Para eso contamos con la operación Poner, que le dice al cabezal
que deposite una bolita del color dado:

program {
Poner(Rojo)
}

program {

Poner(Rojo)

Poner(Rojo)

Poner(Azul)
procedure PonerNegroYRojo() {

Poner(Negro)

Poner(Rojo)

program {

PonerNegroYrojo()

Como viste en el ejemplo del cuadrado, se puede empezar a diferenciar


dos tipos de comandos dentro de un programa:

 los que vienen definidos por el lenguaje y nos sirven para


expresar operaciones básicas, como Mover, Poner y Sacar. A estos los
llamaremos comandos primitivos, o simplemente primitivas;
 y los que definimos nosotros, que nos sirven para expresar tareas
más complejas. Como el nombre de esta lección sugiere, estos son
los procedimientos.

Cuando definimos un procedimiento estamos "enseñándole" a la


computadora a realizar una tarea nueva, que originalmente no estaba
incluida en el lenguaje.

Prestale atención a la sintaxis del ejemplo para ver bien cómo definimos
un procedimiento y cómo lo invocamos en un program.

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

program {
Poner3Rojas()
}

Ahora que ya probamos cómo funcionan, podemos ver las diferencias


entre las sintaxis de programas y procedimientos.

El procedimiento se define con la palabra procedure seguida por un nombre


y paréntesis (). Luego escribimos entre llaves {} todas las acciones que
procedure PonerNegroYRojo() {

Poner(Negro)

Poner(Rojo)

program {

PonerNegroYrojo()

Como viste en el ejemplo del cuadrado, se puede empezar a diferenciar


dos tipos de comandos dentro de un programa:

 los que vienen definidos por el lenguaje y nos sirven para


expresar operaciones básicas, como Mover, Poner y Sacar. A estos los
llamaremos comandos primitivos, o simplemente primitivas;
 y los que definimos nosotros, que nos sirven para expresar tareas
más complejas. Como el nombre de esta lección sugiere, estos son
los procedimientos.

Cuando definimos un procedimiento estamos "enseñándole" a la


computadora a realizar una tarea nueva, que originalmente no estaba
incluida en el lenguaje.

Prestale atención a la sintaxis del ejemplo para ver bien cómo definimos
un procedimiento y cómo lo invocamos en un program.

procedure Poner3Rojas() {
Poner(Rojo)
Poner(Rojo)
Poner(Rojo)
}

program {
Poner3Rojas()
}

Ahora que ya probamos cómo funcionan, podemos ver las diferencias


entre las sintaxis de programas y procedimientos.

El procedimiento se define con la palabra procedure seguida por un nombre


y paréntesis (). Luego escribimos entre llaves {} todas las acciones que
Ejercicio 14: Colores, colores, colores
Vamos a darle un poco más de color a todo esto haciendo líneas
multicolores como esta:

0 1 2 3 4
1 1 1 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1

0 0

0 1 2 3 4

Como se ve en la imagen, cada celda de la línea debe tener una bolita de


cada color (una roja, una negra, una verde y una azul).

¿Cómo podemos dibujarla? ¿Cuál es la tarea que se repite? ¿Se puede


definir un nuevo procedimiento para resolverla y aprovecharlo para
construir nuestra solución?

Definí un procedimiento DibujarLineaColorida que dibuje una línea multicolor de


cuatro celdas hacia el Este y al finalizarla ubique el cabezal en la celda inicial. Tené
en cuenta que siempre partimos del extremo Oeste. Invocá el nuevo procedimiento
en un program.

¡Dame una pista!

1
procedure DibujarLineaColorida(){
2
Poner(Azul)
3
Poner(Negro)
4
Poner(Rojo)
5
Poner(Verde)
6
}
7
program {
8
DibujarLineaColorida()
9
Mover(Este)
A esta altura ya sabemos que para programar siempre tenemos que tener
en cuenta la sintaxis y que para definir nuevos procedimientos también
tenemos reglas:

 empezamos con la palabra reservada procedure;


 elegimos un nombre que lo describa y lo escribimos con mayúscula
seguido de paréntesis ();
 encerramos las acciones que queremos que haga entre llaves {}.

Entonces, un procedimiento que se mueve cuatro celdas al Norte se va a


definir así:

procedure Mover4AlNorte() {
Mover(Norte)
Mover(Norte)
Mover(Norte)
Mover(Norte)
}

Y si lo queremos utilizar, tenemos que invocarlo dentro


del program escribiendo su nombre tal cual y sin olvidar los
paréntesis() ¡Prestá atención a la sintaxis!

program {
Mover4AlNorte()
}

procedure RojoAlBorde() {

IrAlBorde(Norte)

IrAlBorde(Oeste)

Poner(Rojo)

program {

RojoAlBorde()

}
Ejercicio 14: Colores, colores, colores
Vamos a darle un poco más de color a todo esto haciendo líneas
multicolores como esta:

0 1 2 3 4
1 1 1 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1

0 0

0 1 2 3 4

Como se ve en la imagen, cada celda de la línea debe tener una bolita de


cada color (una roja, una negra, una verde y una azul).

¿Cómo podemos dibujarla? ¿Cuál es la tarea que se repite? ¿Se puede


definir un nuevo procedimiento para resolverla y aprovecharlo para
construir nuestra solución?

Definí un procedimiento DibujarLineaColorida que dibuje una línea multicolor de


cuatro celdas hacia el Este y al finalizarla ubique el cabezal en la celda inicial. Tené
en cuenta que siempre partimos del extremo Oeste. Invocá el nuevo procedimiento
en un program.

¡Dame una pista!

1
procedure DibujarLineaColorida(){
2
Poner(Azul)
3
Poner(Negro)
4
Poner(Rojo)
5
Poner(Verde)
6
}
7
program {
8
DibujarLineaColorida()
9
Mover(Este)
10
DibujarLineaColorida()
11
Mover(Este)
12
DibujarLineaColorida()
13
Mover(Este)
14
DibujarLineaColorida()
15
IrAlBorde(Oeste)
16
}
Enviar
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:


 Hay que dividir en subtareas. Tené en cuenta qué partes de tu
código se repiten y trasladalas a un nuevo procedimiento.

procedure Poner4Bolitas(){

Poner(Azul)

Poner(Negro)

Poner(Rojo)

Poner(Verde)

procedure DibujarLineaColorida(){

Poner4Bolitas()

Mover(Este)

Poner4Bolitas()

Mover(Este)

Poner4Bolitas()

Mover(Este)

Poner4Bolitas()
IrAlBorde(Oeste)

program {

DibujarLineaColorida()

Definí un procedimiento DibujarCuadradoColorido que dibuje un cuadrado de 4×4


celdas en el que cada celda tenga una bolita de cada color e invocalo en el program.
El cabezal debe quedar en la celda inicial.

procedure DibujarCuadradoColorido(){

DibujarLineaColorida()

Mover(Norte)

DibujarLineaColorida()

Mover(Norte)

DibujarLineaColorida()

Mover(Norte)

DibujarLineaColorida()

IrAlBorde(Sur)

program {

DibujarCuadradoColorido()

REPETICION SIMPLE
Ejercicio 2: La computadora repite por
nosotros
Como te adelantamos en el ejercicio anterior, en Gobstones existe una
forma de decir "quiero que estos comandos se repitan esta cantidad de
veces".

Entonces, cuando es necesario repetir un comando


(como Mover, Poner, DibujarLineaNegra, etc) un cierto número de veces, en
lugar de copiar y pegar como veníamos haciendo hasta ahora, podemos
utilizar la sentencia repeat.

Sabiendo esto, así es como quedaría MoverOeste10 usando repeat:

procedure MoverOeste10() {
repeat(10) {
Mover(Oeste)
}
}

Pero no tenés por qué creernos: ¡escribí este código en el editor y fijate si funciona!

procedure MoverOeste5() {

repeat(5) {

Mover(Oeste)

Los ejemplos que hiciste en los ejercicios anteriores se solucionaban


simplemente repitiendo cosas. Pero no todo es repetir, también podemos
poner comandos tanto antes como después del repeat, al igual que
veníamos haciendo hasta ahora.

Por ejemplo, este es un programa que se mueve al Sur, luego pone 4


bolitas de color Rojo y por último vuelve a moverse al Norte:

program {
Mover(Sur)
repeat(4) {
Poner(Rojo)
}
Mover(Norte)
}

Fijate que Mover(Sur) lo pusimos antes del repeat y Mover(Norte) lo


pusimos después. Por lo tanto cada movimiento se ejecuta solo una vez.
Teniendo en cuenta esto:

Definí el procedimiento Poner3AlNoreste(), que ponga 3 bolitas negras en la primera


celda al Noreste del cabezal.
Inicial Final
0 1 2 0 1 2
3
2 2 2 2

1 1 1 1

0 0 0 0

0 1 2 0 1 2

¡Dame una pista!

procedure Poner3AlNoreste() {

Mover(Norte)

Mover(Este)

repeat(3) {

Poner(Negro)

Es muy común, al principio, olvidarse de colocar las llaves o incluso pensar


que no son importantes. Pero tené mucho cuidado: poner las llaves en el
lugar erróneo puede cambiar por completo lo que hace tu programa.
Mirá qué distinto sería el resultado si hubieras puesto
el Mover(Este) adentro del repeat:

procedure Poner3AlNoreste() {
Mover(Norte)

repeat(3) {
Mover(Este)
Poner(Negro)
}
}

Siguiente Ejercicio: También vale después

procedure PonerAzulLejos() {

repeat(4){

Mover(Este)

Poner(Azul)

Hasta el momento los ejemplos que vimos sólo repetían un comando,


pero como mencionamos al comenzar es posible repetir
cualquier secuencia de comandos - en definitiva lo que se repite es
un bloque y, como ya sabíamos, en un bloque puede haber tantos
comandos como se nos ocurra.

Miremos el código de DibujarLineaNegra6 que podríamos haber hecho sin


usar repeat, con algunos espacios en blanco para ayudarnos a reconocer la
secuencia que se repite:

procedure DibujarLineaNegra6() {
Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)

Poner(Negro)
Mover(Este)
}
¿Notás qué es lo que se repite y cuántas veces? Bueno, eso es lo que
tenés que poner en el repeat.

Definí una versión superadora de DibujarLineaNegra6, esta vez usando repeat.


procedure DibujarLineaNegra6() {

repeat(6){

Poner(Negro)

Mover(Este)

Definí un procedimiento Diagonal4Azul que dibuje una diagonal de longitud 4 hacia


el Noreste, donde cada celda tenga una bolita azul. El cabezal debe quedar donde
muestra la imagen

procedure Diagonal4Azul() {

repeat(4){

Poner(Azul)

Mover(Norte)

Mover(Este)

Ahora vamos a hacer lo mismo, pero en versión "pesada".

¿Qué quiere decir esto? Que en vez de poner 1 bolita en cada celda,
ahora hay que poner 21. Mirá la imagen:

0 1 2 3 4

4 4

21
3 3

21
2 2

21
1 1
21
0 0

0 1 2 3 4
Definí un procedimiento DiagonalPesada4Azul que resuelva el problema.

procedure Bolas21() {

repeat(21){

Poner(Azul)

procedure DiagonalPesada4Azul() {

repeat(4){

Bolas21()

Mover(Norte)

Mover(Este)

procedure LineaNegra4Este() {

repeat(3) {

Poner(Negro)

Mover(Este)

Poner(Negro)

procedure MoverOeste(){

repeat(3){
Mover(Oeste)

procedure CuadradoNegro(){

repeat(3){

LineaNegra4Este()

Mover(Norte)

MoverOeste()

procedure CuadradoNegro4(){

CuadradoNegro()

LineaNegra4Este()

Definí el procedimiento DibujarLineaNegra3 que, como su nombre lo indica, dibuje una


línea poniendo 3 bolitas negras consecutivas hacia el Este y dejando el cabezal donde
comenzó. Invocalo en un program.
En la Biblioteca vas a encontrar el procedimiento VolverAtras. ¡Eso significa que podés
invocarlo sin tener que definirlo!

 Solución
 Biblioteca

1
procedure DibujarLineaNegra3(){
2
procedure DibujarCuadradoNegroDeLado3(){
repeat(2){

DibujarLineaNegra3()

Mover(Norte)

DibujarLineaNegra3()

program{

DibujarCuadradoNegroDeLado3()

Ya sabemos como dibujar una línea negra con 3 bolitas . Usemos esa
lógica para dibujar una línea verde.

Definí el procedimiento DibujarLineaVerde3 e invocalo en el program.

procedure DibujarLineaVerde3(){

repeat(2){

Poner(Verde)

Mover(Este)

Poner(Verde)

VolverAtras()

program{

DibujarLineaVerde3()

Solo nos faltan dos colores: Rojo y Azul .

Definí los procedimientos DibujarLineaRoja3 y DibujarLineaAzul3.


procedure DibujarLineaRoja3(){

repeat(2){

Poner(Rojo)

Mover(Este)

Poner(Rojo)

VolverAtras()

procedure DibujarLineaAzul3(){

repeat(2){

Poner(Azul)

Mover(Este)

Poner(Azul)

VolverAtras()

¡Empecemos con algo fácil! Supongamos que tenemos un procedimiento


llamado Poner3Verdes, que pone 3 bolitas verdes en un casillero, y lo
queremos generalizar para que funcione con cualquier color que
queramos (pero uno solo por vez). Lo que necesitamos es agregarle al
procedimiento una especie de agujero...

procedure Poner3(color) {

repeat(3) {

Poner(color)

program {

Poner3(Negro)
En la guía anterior, vimos que se podía usar repeat para hacer algo muchas veces.
Hicimos un ejemplo que se llamaba Diagonal4Azul, que era más o menos así:

procedure Diagonal4Azul(){
repeat(4){
Poner(Azul)
Mover(Este)
Mover(Norte)
}
}

¿Te animás a definir el procedimiento Diagonal4AzulVolviendo? Este procedimiento


debería hacer lo mismo que Diagonal4Azul, pero tiene que dejar el cabezal en la posición
inicial. Recordá que podés invocar todo lo que está en la Biblioteca sin necesidad de volver
a definirlo.
0 1 2 3 4

4 4

1
3 3

1
2 2

1
1 1

1
0 0

0 1 2 3 4

Poner3(Rojo)

Entendamos qué acabamos de hacer.

Lo primero que hicimos fue definir un procedimiento, pero con una


pequeña diferencia: toma un parámetro, llamado color.

procedure Poner3(color) {
Poner(color)
Poner(color)
Poner(color)
}
¿Y qué es un parámetro? Son esos nombres que van entre paréntesis para
ser reemplazados por valores concretos cuando invocamos al
procedimiento. Por ejemplo, si lo invocamos así..

program {
Poner3(Negro)
}

...lo que se ejecuta es:

Poner(Negro)
Poner(Negro)
Poner(Negro)

Y si lo invocamos así...

program {
Poner3(Rojo)
}

lo que se ejecuta es:

Poner(Rojo)
Poner(Rojo)
Poner(Rojo)

Fijate como cada vez que aparece color se reemplaza por el valor que
le pasamos a Poner . Veamos si se entiende:

Creá un programa que ponga tres bolitas verdes. No te olvides de invocar el


procedimiento Poner3.

¡Ahora te toca a vos!

Ya hicimos cuatro procedimientos para dibujar líneas de cada color, pero


si usamos parámetros podría ser sólo uno.

Definí el procedimiento DibujarLinea3 que reciba un color y dibuje una línea de ese
color. Despreocupate por los programs para invocarlo con cada uno de los colores,
van por nuestra parte.

procedure DibujarLinea3(color){

repeat(2){
Poner(color)

Mover(Este)

Poner(color)

VolverAtras()

En vez de escribir color podríamos haber escrito c, col o incluso pepe,


porque a la computadora no le importa el nombre que le demos a las
cosas... pero a nosotros sí (y mucho ), así que por eso elegimos usar
nombres que expresen bien lo que queremos decir.

Fijate también que elegimos un nuevo nombre para nuestro nuevo


procedimiento porque ahora sirve para cualquier color. Esto tampoco es
estrictamente necesario para la computadora, pero es super importante
para los humanos que van a leer y escribir el código. Imaginate que si le
pusieramos DibujarLineaNegra3 (o DibujarLineaAzul3) al usarlo para dibujar
una línea roja quedaría DibujarLineaNegra3(Rojo). Si bien va a funcionar, no
se entendería bien qué es lo que hace: ¿una línea negra? ¿una línea roja?
¿una línea negra y roja?.

¡Es importantísimo poner buenos nombres para programar bien!

Siguiente Ejercicio: DibujarCuadradoDeLado3

¡Hora del último pasito! Ya definimos un procedimiento para poder


dibujar cuadrados negros (DibujarCuadradoNegroDeLado3), pero todo este
asunto de los parámetros surgió cuando quisimos hacer cuadrados de
distintos colores.

Invocando DibujarLinea3, definí el procedimiento DibujarCuadradoDeLado3 que recibe


un color y dibuja un cuadrado de 3x3 de ese color.
¡Dame una pista!

procedure DibujarCuadradoDeLado3(color){

repeat(2){

DibujarLinea3(color)
Mover(Norte)

DibujarLinea3(color)

Y si queremos que DibujarLinea3 sirva también para dibujar líneas en


cualquier dirección? Sin dudas tenemos que decirle al procedimiento,
además del color, en qué direccion debe dibujar la línea; y para eso vamos a
necesitar un nuevo parámetro . Por suerte, ¡los procedimientos también
pueden tener más de un parámetro!

¿Y cómo se hace esto? Muy fácil, al igual que como hacemos al escribir,
vamos a separar cada parámetro usando comas de esta manera:

procedure DibujarLinea3(color, direccion) {


Poner(color)
Mover(direccion)
Poner(color)
Mover(direccion)
Poner(color)
}

program {

DibujarLinea3(Verde,Este)

Mover (Este)

DibujarLinea3(Rojo,Norte)

Mover (Norte)

DibujarLinea3(Negro,Oeste)

Mover (Oeste)

DibujarLinea3(Azul,Sur)

Mover (Sur)

}
Ejercicio 12: La tercera es la vencida
Para terminar esta lección vamos a definir un procedimiento
llamado Triada ¡que recibe tres parámetros!

Triada recibe tres colores por parámetro y pone tres bolitas, una al lado de
la otra hacia el Este, en el mismo orden en que se reciben. El cabezal
empieza en el origen y debe terminar sobre la última bolita de la tríada.

Por ejemplo: Triada(Rojo, Azul, Verde) nos da como tablero resultante:

0 1 2
1
0 0
1 1

0 1 2

mientras que Triada(Azul, Verde, Rojo):

procedure Triada(color1,color2,color3){

Poner(color1)

Mover(Este)

Poner(color2)

Mover(Este)

Poner(color3)

procedure Diagonal4AzulVolviendo(){

Diagonal4Azul()

repeat(4){

Mover(Sur)

Mover(Oeste)

}

 1. Fundamentos
 6. Práctica Repetición simple
 2. Una diagonal más ancha

Ejercicio 2: Una diagonal más ancha


Sigamos probando tus habilidades para reutilizar...

Ahora, tenés que


ue hacer este dibujo:

0 1 2 3 4

6 6

1
5 5

1 1
4 4

1 1 1
3 3

1 1 1
2 2

1 1
1 1

1
0 0

0 1 2 3 4

procedure BandaDiagonal4(){

repeat(3){

Diagonal4AzulVolviendo()

Mover (Norte)

}
}

Ejercicio 2: La suma de las partes


Juguemos un poco más con esto de hacer cuentas.

Definí un procedimiento PonerSuma(x, y) que reciba dos parámetros y ponga la cantidad de


bolitas rojas que surge de sumar x e y.
Ejemplo: PonerSuma(4, 2) debería poner 6 bolitas rojas en la celda actual (porque 6 es el
resultado de sumar 4 y 2).

0 1

1 1

0 0
6

0 1

procedure PonerSuma(x, y){

PonerN(x+y, Rojo)


 1. Fundamentos
 7. Expresiones
 3. ¿Qué se hace antes?

Ejercicio 3: ¿Qué se hace antes?


De un conocido diario (no podemos revelar su nombre por temas de
confidencialidad) nos pidieron definir un procedimiento para contar,
aproximadamente, cuánta gente asistió a una determinada movilización.

Contamos con la información de cuántos micros, autos y bicicletas


asistieron y desde allí podemos hacer un cálculo siguiendo estas reglas:

 en cada micro viajan 40 personas;


Ejercicio 4: Día de la Memoria
Muchas veces vamos a usar el tablero de Gobstones como memoria, o
sea, para recordar algo importante que vamos a necesitar más adelante.

¿Qué podríamos representar con bolitas? Por ejemplo una fecha. Una
fecha que debemos recordar es el 24 de marzo de 1976, hoy
constituido Día de la Memoria por la Verdad y la Justicia en Argentina.

El objetivo, entonces, es definir un procedimiento DiaDeLaMemoria():

 En la celda actual, poné 24 bolitas Azules, que representan el día.


 En la celda inmediatamente al Este, poné 3 bolitas Verdes,
que representan el mes.
 En la celda a continuación, poné 1976 bolitas Negras, representando el año.

procedure DiaDeLaMemoria(){

PonerN(24,Azul)

Mover (Este)

PonerN(3,Verde)

Mover (Este)

PonerN(1976,Negro)

Ahora que ya escribimos una fecha particular, hagamos un procedimiento


que sirva para escribir cualquier fecha.

Definí el procedimiento Fecha(dia, mes, anio), que recibe los tres


valores correspondientes, y escribe la fecha que representan, de esta manera:

 En la celda actual, tantas bolitas azules para representar el día.


 En la celda inmediatamente al Este, tantas bolitas Verdes
para representar el mes.
 En la celda a continuación, tantas bolitas Negras para representar el año.

Por ejemplo, Fecha(12, 8, 1990) produciría algo así:

procedure Fecha(dia,mes,anio){
PonerN(dia,Azul)

Mover(Este)

PonerN(mes,Verde)

Mover(Este)

PonerN(anio,Negro)

Definí un procedimiento MoverN(cantidad,


MoverN( direccion) que haga que el cabezal se desplace la
cantidad especificada de veces en la dirección indicada.
Por ejemplo, MoverN(3, Oeste) provocaría:

Inicial Final
0 1 2 3
0 1 2 3
2 2
2 2

1 1
1 1

0 0
0 0
0 1 2 3
procedure MoverN(cantidad,direccion){

repeat(cantidad){

Mover (direccion)


 1. Fundamentos
 6. Práctica Repetición simple
 7. Los números del reloj

Ejercicio 7: Los
L números del reloj
¡Ya sabés Kung Fu!
Ahora, tenés que mostrarnos que podés dibujar un reloj. Lo que haremos por ahora es
solamente poner los números que aparecen en un típico reloj de agujas:

 El 12 arriba,
 El 3 a la derecha,
 El 9 a la izquierda, y
 el 6 abajo.

Definí un procedimiento DibujarReloj(radio) que ponga los números del reloj como se indica
arriba: alrededor del casillero actual. El tamaño del reloj se indica con el radio que recibís
como parámetro: mientras más grande es el radio, más alejados están los números del
centro.
Dado el siguiente program:

program {
DibujarReloj(2)
}

El reloj resultante es así:

0 1 2 3 4

4 4
12

3 3

2 2
9 3

1 1

0 0
6

0 1 2 3 4

procedure DibujarReloj(radio){

MoverN(radio,Norte)

PonerN(12,Rojo)

MoverN(radio,Sur)

MoverN(radio,Sur)

PonerN(6,Rojo)
procedure Ele(direccion){

Linea(direccion,Azul,3)

Linea(siguiente(direccion),Azul,3)

Ejercicio 9: Previo a lo siguiente


Ya te presentamos las funciones opuesto, previo y siguiente que nos permiten
desplazarnos en forma relativa a alguna dirección . Antes de seguir
utilizándolas, vamos a conocerlas un poco mejor.

Si partimos de este tablero inicial:

Y luego ejecutamos Mover(siguiente(Norte)) el tablero obtenido será así:

Porque siguiente(Norte) es Este. Si luego


ejecutamos Mover(previo(Oeste)) lograremos el siguiente tablero:

 1. Fundamentos
 6. Práctica Repetición simple
 9. Guarda con la guarda

Ejercicio 9: Guarda con la guarda


Bueno, estamos en tiempo para algún ejercicio integrador...

Definí un procedimiento GuardaDe5(), que haga una "guarda" de 5 azulejos (como las que
decoran las paredes). Cada azulejo está conformado por 1 bolita verde, 5 negras y 9 rojas.
0 1 2 3 4 5

1 1

5 5 5 5 5

0 0
9 1 9 1 9 1 9 1 9 1

0 1 2 3 4 5

procedure Ponerla(){

PonerN(1,Verde)

PonerN(5,Negro)

PonerN(9,Rojo)

procedure GuardaDe5() {

repeat (4){

Ponerla()

Mover (Este)

Ponerla()
Mover(siguiente(direccion))


 1. Fundamentos
 7. Expresiones
 11. Copiando bolitas

Ejercicio 11: Copiando bolitas


Supongamos ahora que queremos "copiar" las bolitas verdes, haciendo
que haya la misma cantidad de rojas y pensemos cómo podría ser ese
procedimiento.

Una tarea que seguro tenemos que hacer es poner muchas bolitas, y para
eso ya sabemos que existe el procedimiento PonerN que construimos
varios ejercicios atrás. El color de las bolitas que tenemos que poner
también lo sabemos: Rojo, pero... ¿cómo sabemos cuántas poner?

Miremos algunos ejemplos:

 Si hay 4 bolitas verdes, hay que poner 4 bolitas rojas.


 Si hay 2 bolitas verdes, hay que poner 2 bolitas rojas.
 Si no hay bolitas verdes, no hay que poner ninguna roja.

Lo que nos está faltando es una forma de contar cuántas bolitas verdes
hay,, y para eso necesitamosnecesitamos otra función que nos da
Gobstones: nroBolitas(color). Lo que hace es simple: nos retorna la cantidad
de bolitas de un color determinado en la posición actual.

Invocando nroBolitas, definí el procedimiento CopiarVerdesEnRojas.

procedure CopiarVerdesEnRojas(){
nRojas(){
Mover(Norte)

PonerAzulejo()

procedure GuardaEnL(){

Base()

Volver()

Alto()

Volver2()

Ejercicio 1: Muchas formas de decir lo


mismo
Cuando nos comunicamos con alguien más, usamos palabras o frases
para describir una idea. Por ejemplo, todas las
siguientes expresiones hablan de lo mismo, aunque lo hacen de distintas
formas:

 el número 5;
 la cantidad de dedos de una mano;
 la suma entre 3 y 2;
 el número de continentes que existen en el planeta, según la ONU.

Todas las frases anteriores hablan del valor cinco, aunque no lo digan de
forma explícita.

Con esta idea e invocando PonerN, creá un programa que ponga cinco bolitas
negras, PERO sin escribir el número 5.

program{

PonerN(1+4,Negro)
}

Ejercicio 2: La suma de las partes


Juguemos un poco más con esto de hacer cuentas.

Definí un procedimiento PonerSuma(x, y) que reciba dos parámetros y ponga la cantidad de


bolitas rojas que surge de sumar x e y.
Ejemplo: PonerSuma(4, 2) debería poner 6 bolitas rojas en la celda actual (porque 6 es el
resultado de sumar 4 y 2).

0 1

1 1

0 0
6

0 1

procedure PonerSuma(x, y){

PonerN(x+y, Rojo)


 1. Fundamentos
 7. Expresiones
 3. ¿Qué se hace antes?

Ejercicio 3: ¿Qué se hace antes?


De un conocido diario (no podemos revelar su nombre por temas de
confidencialidad) nos pidieron definir un procedimiento para contar,
aproximadamente, cuánta gente asistió a una determinada movilización.

Contamos con la información de cuántos micros, autos y bicicletas


asistieron y desde allí podemos hacer un cálculo siguiendo estas reglas:

 en cada micro viajan 40 personas;


 en cada auto viajan 4 personas;
 en cada bicicleta viaja 1 persona.

procedure ContarGente(micros, autos, bicicletas) {


PonerN(40*micros+4*autos+1*bicicletas,Verde)

Ejercicio 4: La carrera del salmón


Bueno, basta de números (por un ratito). Ahora vamos a aprender a hacer
"cuentas" con las direcciones.

Para hacer esto, simularemos el movimiento de un salmón: en contra de


la corriente. Nuestro objetivo será definir un
procedimiento MoverComoSalmon(direccion) que reciba una dirección y se
mueva exactamente una vez en la dirección opuesta. Veamos en una
tabla cómo debería comportarse este procedimiento:

 MoverComoSalmon(Norte) se mueve hacia el Sur.


 MoverComoSalmon(Este) se mueve hacia el Oeste.
 MoverComoSalmon(Sur) se mueve hacia el Norte.
 MoverComoSalmon(Oeste) se mueve hacia el Este.

Como la dirección va a ser un parámetro de nuestro procedimiento,


necesitamos una forma de decir "la dirección opuesta a X" para poder
luego usar esto como argumento de Mover. Gobstones nos provee un
mecanismo para hacer esto, la primitiva opuesto(dir). En criollo: opuesto (¡sí,
en minúsculas!) nos dice la dirección contraria a la dir que nosotros le
pasemos.

Sabiendo esto, podríamos definir fácilmente el procedimiento que


queríamos:

procedure MoverComoSalmon(direccion) {
Mover(opuesto(direccion))
}
procedure MoverComoSalmon(direccion) {

Mover(opuesto(direccion))

Ejercicio 5: Dos pasos adelante, un paso


atrás
Tenemos un amigo llamado Carlos, que es bastante desconfiado. En su
vida, eso se manifiesta en muchos aspectos, pero el más notorio es su
forma de caminar: sólo camina hacia el Este y siempre que da dos pasos
hacia adelante automáticamente da un paso hacia atrás.

Por ejemplo, si le pidiéramos que diera 2 pasos, terminaría dando 1; si le


pidiéramos 4, daría 2; y así sucesivamente. En definitiva, lo que termina
pasando es que nuestro amigo da la mitad de los pasos que le pedimos.

Importante: en Gobstones usamos el operador div para dividir; por


ejemplo "4 dividido 2" se escribe 4 div 2.

Definí el procedimiento CaminarDesconfiado(pasos) que simule el caminar de Carlos:


debe recibir la cantidad de pasos que debería dar y recorrer la mitad. Siempre se
mueve al Este.
procedure CaminarDesconfiado(pasos){

MoverN(pasos div 2,Este)

Ejercicio 6: Poner al lado


Para ver si entendiste lo anterior, te toca ahora resolver por tu cuenta.

Queremos definir un procedimiento que nos sirva para poner una bolita al lado de
donde se encuentre el cabezal, dejándolo en la posición original. Por ejemplo, al
invocar PonerAl(Norte, Verde) debería poner una bolita verde una posición hacia el
Norte, sin mover el cabezal (bueno, ya sabemos que en realidad sí se mueve, pero el
punto es que en el resultado final esto no se tiene que ver).

Inicial Final
0 1 0 1
Inicial Final
1 1 1 1
1

0 0 0 0

0 1 0 1

procedure PonerAl(direccion, color){

Mover (direccion)

Poner (color)

Mover (opuesto(direccion))


 1. Fundamentos
 7. Expresiones
 7. La línea que vuelve

Ejercicio 7: La línea que vuelve


Ahora que sabés usar la función opuesto, podemos finalmente resolver el
problema de definir un procedimiento que dibuje una línea en cualquier
dirección y deje el cabezal en la posición inicial.
inicial

La versión que sabíamos hacer hasta ahora era esta:

procedure Linea(direccion, color,


color longitud) {
repeat(longitud) {
Poner(color)
Mover(direccion)
Entonces, lo que le estamos diciendo a la computadora es "si hay bolitas
azules, sacá una bolita azul"
azul", que dicho así suena un poco tonto ¡y lo es!.
Ya te dijimos que la computadora sólo sabe cumplir órdenes.

¡Ahora te toca a vos! Modificá el procedimiento que te dimos para que saque una
bolita roja, sólo si hay alguna.
¡Dame una pista!

procedure SacarRojoConMiedo() {

if (hayBolitas(Rojo)) {

Sacar(Rojo)


 1. Fundamentos
 8. Alternativa Condicional
 4. Un ejemplo medio rebuscado

Ejercicio 4: Un ejemplo medio


rebuscado
Vamos a ponerle nombre a las partes del if.

En primer lugar, tenemos la condición.. Por ahora siempre


fue hayBolitas(color) pero podría ser cualquier otra cosa, ya veremos más
ejemplos. Lo importante acá es que eso es lo que decide si la acción se
va a ejecutar o no.

¿Y qué es la acción?? Básicamente, cualquier cosa que queramos hacer


sobre el tablero. Al igual que en el repeat, podemos hacer cuantas cosas se
nos ocurran, no necesariamente tiene que ser una sola.
Ele(Norte)

0 1 2 3

Indudablemente, una L consta de dos líneas y dibujar una línea es la tarea


que ya resolviste en el ejercicio anterior. Así que por ese lado, tenemos la
mitad del problema resuelto.

La primera línea es fácil, porque coincide con la dirección que recibimos


como argumento... ¿pero la segunda? Bueno, ahí viene lo interesante:
además de opuesto, Gobstones nos provee dos funciones más para operar
sobre las direcciones, siguiente y previo. siguiente(direccion) retorna la dirección
siguiente a la especificada, mientras que previo(direccion) retorna la anterior,
siempre pensándolo en el sentido de las agujas del reloj:

Descubrí cuál de las funciones nuevas tenés que invocar y definí el


procedimiento Ele(direccion)
on). No te preocupes por la posición inicial del cabezal,
nosotros nos encargaremos de ubicarlo en el lugar correspondiente para que la L
se pueda dibujar.
procedure Ele(direccion){

Linea(direccion,Azul,3)

Linea(siguiente(direccion),Azul,3)

Ejercicio 9: Previo a lo siguiente


Ya te presentamos las funciones opuesto, previo y siguiente que nos permiten
desplazarnos en forma relativa a alguna dirección . Antes de seguir
utilizándolas, vamos a conocerlas un poco mejor.

Si partimos de este tablero inicial:

Y luego ejecutamos Mover(siguiente(Norte)) el tablero obtenido será así:

Porque siguiente(Norte) es Este. Si luego


ejecutamos Mover(previo(Oeste)) lograremos el siguiente tablero:
Definí un procedimiento AsegurarUnaBolitaVerde() que se asegure que en la celda
actual hay al menos una bolita verde. Esto es: si ya hay bolitas verdes no hay que
hacer nada, pero si no hay tendría que poner una.

procedure AsegurarUnaBolitaVerde(){

if (not hayBolitas(Verde)){

Poner (Verde)


 1. Fundamentos
 8. Alternativa Condicional
 8. Dos caminos distintos

Ejercicio 8: Dos caminos distintos


En lo cotidiano, se presentan muchas situaciones donde debemos elegir
entre dos acciones diferentes, dependiendo de si se cumple una cierta
condición o no.

 Si la remera está limpia me la pongo, si no la lavo.


 Si tengo aceite para freir las milanesas lo uso, si no le pongo un
poco de manteca.
 Si me puedo mover al Este lo hago, si no me muevo al Norte.

Para estos casos, en Gobstones tenemos una nueva palabra clave que nos
ayuda a cumplir nuestra tarea: el else.. En castellano significa si no y hace
justamente lo que necesitamos: ejecuta una serie de acciones si no se
cumple la condición que pusimos en el if.

Supongamos que queremos definir un procedimiento que se mueva al


Oeste y, en caso de que no pueda, lo haga hacia el Norte. Haciendo uso
del else, podemos definirlo de la siguiente manera:
}

Funciones
Cuando introdujimos la noción de procedimientos,, dijimos que:

 son una forma de darle nombre a un grupo de comandos,


logrando así que nuestros programas fueran más entendibles;
 nos posiblitan la división en subtareas: para resolver un problema
grande, basta con dividirlo en problemas más chicos y luego
combinarlos;
 nos ayudan a no repetir código,
código, no volver a escribir lo mismo
muchas veces.

Al trabajar con expresiones complejas, rápidamente surge la necesidad de


contar con
on un mecanismo similar, por los motivos que acabamos de
esbozar.

¿Querés saber cuál es ese mecanismo? ¡Empecemos!


 1. Fundamentos
 9. Funciones
 1. Y esto, ¿con qué se come?

Ejercicio 1: Y esto, ¿con qué se come?


Tomate unos pocos minutos y tratá de entender qué hace este
procedimiento:

procedure MoverSegunBolitas() {
if (nroBolitas(Azul) + nroBolitas(Negro)
nroBolitas + nroBolitas(Rojo) + nroBolitas(Verde) > 10
10) {
Mover(Este)
} else {
Mover(Norte)
}
PonerN(nroBolitas(Verde),Rojo)

Ejercicio 12: Sacando bolitas


Siguiendo con esto de contar las bolitas, te toca ahora definir un
procedimiento que sirva para sacar todas las bolitas de un color
color.

Pensemos las subtareas necesarias:

1. Poder sacar muchas bolitas: ya está resuelto con SacarN.


2. Contar cuántas bolitas hay que sacar: se puede hacer con nroBolitas.
3. Sacar todas las bolitas de un color: hay que combinar las 2
anteriores.

Definí SacarTodas(color), que recibe un color y saca todas las bolita


bolitass que hay de ese
color (no debe hacer nada con el resto de los colores).
procedure SacarTodas(color){

SacarN(nroBolitas(color),color)


 1. Fundamentos
 8. Alternativa Condicional

Alternativa Condicional
Hasta ahora, todos los programas y procedimientos que hicimos fueron
sobre tableros conocidos
conocidos,, sabíamos exactamente de qué tamaño era el
tablero, dónde estaba el cabezal y cuántas bolitas había en cada celda.

 1. Fundamentos
 9. Funciones
 6. En libertad

Ejercicio 6: En libertad
Queremos definir la función esLibreCostados(), que determine si el cabezal
tiene libertad para moverse hacia los costados (es decir, Este y Oeste).

Antes que nada, pensemos, ¿de qué tipo tiene que ser el valor que
retorna nuestra función? Será...

 ... ¿un color?? No.


 ... ¿un número?? Tampoco.
 ... ¿una dirección
dirección?? Podría, pero no. Fijate que lo que pide es "saber
si puede moverse" y no hacia dónde.
 ... ¿un booleano?? ¡Sí! Cómo nos dimos cuenta: lo que está pidiendo
tiene pinta de pregunta que se responde con sí o no, y eso es
exactamente lo que podemos representar con un valor
booleano: Verdadero o Falso.

Pero, ups, hay un problema más; hay que hacer DOS preguntas:
¿se puede mover al Este? Y ¿se puede mover al Oeste?.

Bueno, existe el operador && que sirve


e justamente para eso: toma dos
expresiones booleanas y devuelve True solo si ambas son verdaderas. Si
sabés algo de lógica, esto es lo que comunmente se
denomina conjunción y se lo suele representar con el símbolo ∧.

Por ejemplo, si quisieramos saber si u


unn casillero tiene más de 5 bolitas y
el Rojo es el color dominante podríamos escribir:

function esUnCasilleroCargadoConRojoDominante()
esUnCasilleroCargadoConRojoDominante {
return (nroBolitasTotal() > 5 && rojoEsDominante())
}
 2. Sacar con miedo, segundo intento

Ejercicio 2: Sacar con miedo, segundo


intento
Ahora probá esta segunda versión que agrega una alternativa
condicional.. No te preocupes por la sintaxis, ya te lo vamos a explicar.

procedure SacarAzulConMiedo()
() {
if (hayBolitas(Azul)) {
Sacar(Azul)
}
}

Copiá el código anterior en el editor y apretá Enviar.


 1. Fundamentos
 8. Alternativa Condicional
 3. Eliminando la bolita roja

Ejercicio 3: Eliminando
Eliminando la bolita roja
Analicemos el procedimiento del ejercicio anterior:

procedure SacarAzulConMiedo()
() {
if (hayBolitas(Azul)) {
Sacar(Azul)
}
}

Como notarás, introdujimos una nueva estructura de control: el if, que en


castellano significa si;; entendiendo al si como condicional ("si tuviera
hambre me comería una empanada") y no como afirmación (" ("sí, yo rompí
el teléfono").
Entonces, lo que le estamos diciendo a la computadora es "si hay bolitas
azules, sacá una bolita azul"
azul", que dicho así suena un poco tonto ¡y lo es!.
Ya te dijimos que la computadora sólo sabe cumplir órdenes.

¡Ahora te toca a vos! Modificá el procedimiento que te dimos para que saque una
bolita roja, sólo si hay alguna.
¡Dame una pista!

procedure SacarRojoConMiedo() {

if (hayBolitas(Rojo)) {

Sacar(Rojo)


 1. Fundamentos
 8. Alternativa Condicional
 4. Un ejemplo medio rebuscado

Ejercicio 4: Un ejemplo medio


rebuscado
Vamos a ponerle nombre a las partes del if.

En primer lugar, tenemos la condición.. Por ahora siempre


fue hayBolitas(color) pero podría ser cualquier otra cosa, ya veremos más
ejemplos. Lo importante acá es que eso es lo que decide si la acción se
va a ejecutar o no.

¿Y qué es la acción?? Básicamente, cualquier cosa que queramos hacer


sobre el tablero. Al igual que en el repeat, podemos hacer cuantas cosas se
nos ocurran, no necesariamente tiene que ser una sola.
Resumiendo: La acción que está dentro de la estructura del if podrá
realizarse solo cuando la condición sea verdadera.

Para ejercitar esto ultimo, te vamos a pedir que definas un


procedimiento CompletarCelda() que, si ya hay alguna bolita negra, complete la celda
poniendo una roja, una azul y una verde.

procedure CompletarCelda(){

if(hayBolitas(Negro)){

Poner (Rojo)

Poner (Azul)

Poner (Verde)


 1. Fundamentos
 8. Alternativa Condicional
 5. ¿Y sólo sirve para ver si hay bolitas?

Ejercicio 5: ¿Y sólo sirve para ver si hay


bolitas?
Claro que no, ¡por suerte!

La condición puede ser cualquier expresión booleana.. En criollo: cualquier


cosa que represente una "pregunta" que se pueda responder con sí o no.
En Gobstones el sí se representa con el valor True (Verdadero en
castellano) y el no con el valor False (Falso en castellano).

En los ejercicios anteriores te mostramos una de las expresiones que trae


Gobstones, hayBolitas(color), que recibe un color y retorna True o False.
Otra que trae True o False (y que vas a tener que usar ahora)
es puedeMover(direccion) que nos sirve para saber si el cabezal puede
moverse en una cierta dirección.

Por ejemplo, si tenemos este tablero:

0 1

2 2

1 1

0 0

0 1

 puedeMover(Norte) será True.


 puedeMover(Sur) será True.
 puedeMover(Este) será True.
 Pero puedeMover(Oeste) será False

program{

if(puedeMover(Este)){

Mover(Este)

Ejercicio 6: Un poquito de matemática


Otra cosa que se puede hacer adentro de un if es comparar números,
como seguramente alguna vez hiciste en matemática.

Por suerte, esto se escribe en Gobstones igual que en la matemática


tradicional, con un < para el menor y un > para el mayor.
Ejemplo: nroBolitas(Verde) > 5 nos indica si hay más de 5 bolitas verdes.

Sabiendo esto, intentá crear un programa que ponga 1 bolita negra sólo si hay
menos de 5 bolitas negras.
program{

if(nroBolitas(Negro)<5 ){

Poner (Negro)


 1. Fundamentos
 8. Alternativa Condicional
 7. Cómo decirle que no...

Ejercicio 7: Cómo decirle que no...


En todos los problemas que hicimos hasta ahora, siempre preguntamos si
una cierta condición se cumplía: ¿hay alguna bolita roja? ¿me puedo
mover al Este? ¿hay más de 3 bolitas azules?

Algo que también se puede hacer es negar una condición, algo que en
castellano puede sonar medio raro pero que en programación se hace un
montón.n. Los ejemplos anteriores quedarían: ¿¿no hay alguna bolita roja?
¿no me puedo mover al Este? ¿no
¿ hay más de 3 bolitas azules?

¿Y cómo se hace en Gobstones? Fácil, se agrega la palabra clave not antes


de la expresión que ya teníamos.

Original Negada

hayBolitas(Rojo) not hayBolitas(Rojo)

puedeMover(Este) not puedeMover(Este)

nroBolitas(Azul) > 3 not nroBolitas(Azul) > 3


Definí un procedimiento AsegurarUnaBolitaVerde() que se asegure que en la celda
actual hay al menos una bolita verde. Esto es: si ya hay bolitas verdes no hay que
hacer nada, pero si no hay tendría que poner una.

procedure AsegurarUnaBolitaVerde(){

if (not hayBolitas(Verde)){

Poner (Verde)


 1. Fundamentos
 8. Alternativa Condicional
 8. Dos caminos distintos

Ejercicio 8: Dos caminos distintos


En lo cotidiano, se presentan muchas situaciones donde debemos elegir
entre dos acciones diferentes, dependiendo de si se cumple una cierta
condición o no.

 Si la remera está limpia me la pongo, si no la lavo.


 Si tengo aceite para freir las milanesas lo uso, si no le pongo un
poco de manteca.
 Si me puedo mover al Este lo hago, si no me muevo al Norte.

Para estos casos, en Gobstones tenemos una nueva palabra clave que nos
ayuda a cumplir nuestra tarea: el else.. En castellano significa si no y hace
justamente lo que necesitamos: ejecuta una serie de acciones si no se
cumple la condición que pusimos en el if.

Supongamos que queremos definir un procedimiento que se mueva al


Oeste y, en caso de que no pueda, lo haga hacia el Norte. Haciendo uso
del else, podemos definirlo de la siguiente manera:
procedure MoverComoSea() {
if (puedeMover(Oeste)) {
Mover(Oeste)
} else {
Mover(Norte)
}
}

Escribí ese código en el editor y fijate cómo resuelve el problema.


 1. Fundamentos
 8. Alternativa Condicional
 9. Un tablero de luces

Ejercicio 9: Un tablero de luces


Como ejemplo final, imaginemos que nuestro tablero está lleno de luces
que están prendidas o apagadas. Vamos a decir que las celdas con una
bolita verde están prendidas y las celdas con una bolita negra están
apagadas.

Definí un procedimiento PrenderOApagarLuz() que se encargue de prender las luces


que estén apagadas o apagar las luces encendidas, según corresponda. Tené en
cuenta que en cada celda solo puede haber bolitas de color verde o negro.

procedure PrenderOApagarLuz(){

if (not hayBolitas(Verde)){

Poner (Verde)

Sacar (Negro)

}else{

Poner (Negro)

Sacar (Verde)

}
}

Funciones
Cuando introdujimos la noción de procedimientos,, dijimos que:

 son una forma de darle nombre a un grupo de comandos,


logrando así que nuestros programas fueran más entendibles;
 nos posiblitan la división en subtareas: para resolver un problema
grande, basta con dividirlo en problemas más chicos y luego
combinarlos;
 nos ayudan a no repetir código,
código, no volver a escribir lo mismo
muchas veces.

Al trabajar con expresiones complejas, rápidamente surge la necesidad de


contar con
on un mecanismo similar, por los motivos que acabamos de
esbozar.

¿Querés saber cuál es ese mecanismo? ¡Empecemos!


 1. Fundamentos
 9. Funciones
 1. Y esto, ¿con qué se come?

Ejercicio 1: Y esto, ¿con qué se come?


Tomate unos pocos minutos y tratá de entender qué hace este
procedimiento:

procedure MoverSegunBolitas() {
if (nroBolitas(Azul) + nroBolitas(Negro)
nroBolitas + nroBolitas(Rojo) + nroBolitas(Verde) > 10
10) {
Mover(Este)
} else {
Mover(Norte)
}
}

Ejercicio 2: La importancia de nombrar


las cosas
Como vimos, el problema de lo anterior era la falta de división en
subtareas: la expresión que cuenta la cantidad de bolitas que hay en la
celda es demasiado compleja
compleja,, y cuesta entender a simple vista que hace
eso.

Entonces, lo que nos está faltando es algún mecanismo para poder darle
un nombre a esa expresión compleja;; algo análogo a
los procedimientos pero que sirva para encapsular expresiones.

La buena noticia es que Gobstones nos permite hacer esto, y la


herramienta para ello es definir una función,, que se escribe así:

function nroBolitasTotal() {
return (nroBolitas(Azul) + nroBolitas(Negro)
nroBolitas + nroBolitas(Rojo) + nroBolitas(Verde))
))
}

Algunas aclaraciones sobre las funciones:

 son un caso particular de las expresiones,, y por lo tanto siguen las


mismas reglas que ellas: se escriben con la primera letra
minúscula y siempre denotan algún valor (en este caso, un
número);
 en la última línea de su definición siempre va un return, seguido de
una expresión entre paréntesis:
paréntesis el valor que la función va a
retornar.

Siguiente Ejercicio: MoverSegunBolitas, versión 2


 1. Fundamentos
 9. Funciones
 3. MoverSegunBolitas, versión 2
Ejercicio 3: MoverSegunBolitas, versión
2
Ahora que ya logramos mover la cuenta de las bolitas a una subtarea,
podemos mejorar el procedimiento que habíamos hecho antes.

Modificá la primera versión de MoverSegunBolitas para que use la


función nroBolitasTotal() en vez de la expresión larga.

procedure MoverSegunBolitas() {

if (nroBolitasTotal() > 10) {

Mover(Este)

} else {

Mover(Norte)


 1. Fundamentos
 9. Funciones
 4. todasExcepto

Ejercicio 4: todasExcepto
Te toca ahora definir tu primera función: todasExcepto(color). Lo que tiene
que hacer es sencillo, contar cuántas bolitas hay en la celda actual sin
tener en cuenta las del color recibido por parámetro.

Por ejemplo, todasExcepto(Verde) debería contar todas las bobolitas azules,


negras y rojas que hay en la celda actual (o dicho de otra forma: todas las
bolitas que hay menos las verdes).
function todasExcepto(color){

return (nroBolitasTotal()-nroBolitas(color))

Ejercicio 5: Una función de otro tipo


Como ya sabés, las expresiones no sólo sirven para operar con números.
Vamos a definir ahora una función que retorne un
valor booleano (True / False).

Lo que queremos averiguar es si el color Rojo es dominante dentro de una


celda. Veamos algunos ejemplos.

En este casillero:

0
4 3
0 0
2 1

rojoEsDominante() retorna False (hay 2 bolitas rojas contra 8 de otros


colores). Pero en este otro:

0
4 3
0 0
9 1

0
rojoEsDominante() retorna True (hay 9 bolitas rojas contra 8 de otros colores)

Definí la función rojoEsDominante() que nos diga si la cantidad de bolitas rojas es


mayor que la suma de las bolitas de los otros colores. En
la Biblioteca está todasExcepto(color) lista para ser invocada.
function rojoEsDominante(){

return (todasExcepto(Rojo) < nroBolitas (Rojo))

}

 1. Fundamentos
 9. Funciones
 6. En libertad

Ejercicio 6: En libertad
Queremos definir la función esLibreCostados(), que determine si el cabezal
tiene libertad para moverse hacia los costados (es decir, Este y Oeste).

Antes que nada, pensemos, ¿de qué tipo tiene que ser el valor que
retorna nuestra función? Será...

 ... ¿un color?? No.


 ... ¿un número?? Tampoco.
 ... ¿una dirección
dirección?? Podría, pero no. Fijate que lo que pide es "saber
si puede moverse" y no hacia dónde.
 ... ¿un booleano?? ¡Sí! Cómo nos dimos cuenta: lo que está pidiendo
tiene pinta de pregunta que se responde con sí o no, y eso es
exactamente lo que podemos representar con un valor
booleano: Verdadero o Falso.

Pero, ups, hay un problema más; hay que hacer DOS preguntas:
¿se puede mover al Este? Y ¿se puede mover al Oeste?.

Bueno, existe el operador && que sirve


e justamente para eso: toma dos
expresiones booleanas y devuelve True solo si ambas son verdaderas. Si
sabés algo de lógica, esto es lo que comunmente se
denomina conjunción y se lo suele representar con el símbolo ∧.

Por ejemplo, si quisieramos saber si u


unn casillero tiene más de 5 bolitas y
el Rojo es el color dominante podríamos escribir:

function esUnCasilleroCargadoConRojoDominante()
esUnCasilleroCargadoConRojoDominante {
return (nroBolitasTotal() > 5 && rojoEsDominante())
}
function esLibreCostados(){

return(puedeMover(Este)&&puedeMover(Oeste))
return(puedeMover(Este)&&


 1. Fundamentos
 9. Funciones
 7. Cualquier bolita nos deja bien

Ejercicio 7: Cualquier bolita nos deja


bien
Definí la función hayAlgunaBolita() que responda a la pregunta ¿hay alguna bolita en
la celda actual?
Otra vez una pregunta, por lo tanto hay que retornar un booleano.
Además, podemos ver que acá también hay que hacer más de una
pregunta,, en particular cuatro: una por cada una de los colores.

A diferencia del ejercicio anterior, lo que queremos saber es si alguna de


ellas es verdadera, por lo tanto hay que usar otro operador:
la disyunción,, que se escribe || y retorna verdadero
o si al menos alguna de
las dos preguntas es verdadera.

De nuevo, si sabés algo de lógica, esta operación suele representarse con


el símbolo ∨.

function hayAlgunaBolita(){

return(hayBolitas(Rojo)||hayBolitas(Verde)||hayBolitas(Negro)||hayBolitas(Azul))

}

 1. Fundamentos
 9. Funciones
 8. Siempre al borde...

Ejercicio 8: Siempre al borde...


Te recordamoss los operadores lógicos que vimos hasta ahora:

 Negación: "da vuelta" una expresión booleana - ejemplo: not


hayBolitas(Rojo).
 Conjunción: determina si se cumplen ambas condiciones -
ejemplo: puedeMover(Norte) && puedeMover(Sur).
 Disyunción: determina si se cumple alguna de las condiciones -
ejemplo: esInteligente() || tieneBuenaOnda().

Con la ayuda de esa tablita, definí la función estoyEnUnBorde() que determine si el


cabezal está parado en algún borde.

function estoyEnUnBorde(){

return (not puedeMover(Norte)||not


orte)||not puedeMover(Sur)||not puedeMover(Este)||not
puedeMover(Oeste))


 1. Fundamentos
 9. Funciones
 9. Las compañeras ideales

Ejercicio 9: Las compañeras ideales


Vamos a ver ahora funciones que hacen cosas antes de retornar un
resultado. Para ejemplificar esto, vamos a querer que definas una función
que nos diga si hay una bolita de un color específico, pero en la celda de
al lado.

Definí la función hayBolitasAl(direccion, color) que informe si hay alguna bolita del color
especificado en la celda vecina hacia la dirección dada.
Ojo: como ya dijimos, la última línea siempre tiene que tener un return.

function hayBolitasAl(direccion, color){

Mover (direccion)

return (nroBolitas(color)>0)

Ejercicio 10: Lo ideal también se puede


romper
Como en la definición de hayBolitasAl se usa Mover, es obvio que hay casos
en los cuales podría romperse: basta con posicionar el cabezal en el
origen y preguntar si hayBolitas de algún color al Oeste.

Pero, ¿no era que las funciones eran puras y no tenían efecto real? ¿Qué
pasa si una función hace BOOM?

Hagamos la prueba: vamos a probar la función hayBolitasAl del ejercicio anterior con
casos donde no pueda moverse el cabezal. Presioná Enviar y mirá el resultado.

Ejercicio 11: ¿Hay bolitas lejos?


Ejercitemos un poco más esto de las funciones con procesamiento.

Te toca programar una nueva versión de hayBolitasAl que mire si hay


bolitas a cierta distancia de la celda actual. A esta función la vamos a
llamar hayBolitasLejosAl y recibirá tres parámetros: una dirección hacia
donde deberá moverse, un color por el cual preguntar y
una distancia que será la cantidad de veces que habrá que moverse.
Por ejemplo: hayBolitasLejosAl(Norte, Verde, 4) indica si hay alguna bolita
Verde cuatro celdas al Norte de la posición actual.

Definí la función hayBolitasLejosAl(direccion, color, distancia).


function hayBolitasLejosAl(direccion,
sLejosAl(direccion, color, distancia){

MoverN(distancia,direccion)

return(hayBolitas(color))


 1. Fundamentos
 9. Funciones
 12. Estoy rodeado de viejas bolitas

Ejercicio 12: Estoy rodeado de viejas


bolitas
Valiéndote de hayBolitasAl, definí la función estoyRodeadoDe(color) que indica si
s el
cabezal está rodeado de bolitas de ese color.
Decimos que el cabezal "está rodeado" si hay bolitas de ese color en las cuatro
direcciones: Norte, Este, Sur y Oeste.

function estoyRodeadoDe(color){
return(hayBolitasAl(Norte,color)&&hayBolitasAl(Sur,co
return(hayBolitasAl(Norte,color)&&hayBolitasAl(Sur,color)&&hayBolitasAl(Este,color)&&hayBo
lor)&&hayBolitasAl(Este,color)&&hayBo
litasAl(Oeste,color))

Ejercicio 13: Sin límites


Para cerrar, vamos a definir la función hayLimite(), que determina si hay
algún tipo de límite a la hora de mover el cabezal.

El límite puede ser por alguno de dos factores: porque estoy en un


borde y entonces no me puedo mover en alguna dirección, o
porque estoy rodeado de bolitas rojas que me cortan el paso. Si
ocurre alguna de esas dos condiciones, quiere decir que hay un límite.

Usando estoyEnUnBorde y estoyRodeadoDe, definí hayLimite.


function hayLimite(){

return (estoyRodeadoDe(Rojo)||estoyEnUnBorde())


 2. Programación Imperativa

Capítulo 2: Programación Imperativa


¿Ya estás para salir del tablero? ¡Acompañanos a aprender más
sobre programación imimperativa y estructuras de datos de la mano del
lenguaje JavaScript!


 2. Programación Imperativa
 1. Funciones y tipos de datos

Funciones y tipos de datos


¡Hola! Quizás no te diste cuenta pero ya tenés las bases de la
programación: ya sabés declarar funciones y procedimientos, tomar
decisiones empleando la estructura de control if, hacer tareas múltiples
veces.

Sin embargo, en los programas "reales" rara vez trabajamos con tableros
y bolitas de colores: la programación va más allá de eso. ¿Cómo es
entonces esto de vivir fuera del tablero?

Para responder esta pregunta, primero nos adentraremos en el mundo d de


JavaScript, un lenguaje muy popular que no tiene tablero,, pero en el que
de todas formas podremos aplicar todo lo visto hasta ahora y descubrir
nuevas ideas y formas de resolver problemas

¡Acompañanos!


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 1: Introducción a JavaScript


¿Ya te cansaste de jugar con bolitas de colores? Tenemos una buena
noticia. En este capítulo vamos a aprender programación imperativa de
la mano de uno de los lenguajes de programación más utilizados de la
industria del software.

JavaScript, usualmente abreviado Js, es muy parecido a Gobstones en


su sintaxis.. Es decir, en la forma en que se escribe . Pero es mucho más
poderoso y está presente en casi todas las páginas que solés visitar.

Ya aprendimos a utilizar números y booleanos, en este capítulo también


vamos a usar palabras y conjuntos para trabajar con muchos datos a la
vez .

¿Ya te preparaste para salir del tablero?

¡Acompañanos!
function versosMartinFierro() {
imprimir("Aquí me pongo a cantar");
imprimir("Al compás de la vigüela;");
imprimir("Que el hombre que lo desvela");
imprimir("Una pena extraordinaria");
}

function versosMartinFierro() {

imprimir("Aquí me pongo a cantar");

imprimir("Al compás de la vigüela;");

imprimir("Que el hombre que lo desvela");

imprimir("Una pena extraordinaria");

Ejercicio 5: ¿Y el program?
Ahora bien, más allá de que podamos consultar el resultado de una
función a través de la consola, también aprendimos anteriormente que los
programas tienen un punto de entrada: el program. ¿Dónde quedó?

La respuesta es tan simple como sorprendente: en JavaScript todo lo que


escribamos fuera de una function será, implícitamente, dicho punto de
entrada. Por ejemplo, si queremos un programa que imprime por pantalla
el clásico "Hola, mundo!", lo podremos escribir así:

imprimir("Hola, mundo!");

O si queremos un programa que tire tres veces los dados e imprima sus
resultados, podemos escribirlo así:

imprimir("Tirando dados");
imprimir("La primera tirada dio " + tirarDado());
imprimir("La segunda tirada dio " + tirarDado());
imprimir("La tercera tirada dio " + tirarDado());

imprimir("Tirando dados");

imprimir("La primera tirada dio " + tirarDado());

imprimir("La segunda tirada dio " + tirarDado());


imprimir("La tercera tirada dio " + tirarDado());


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 6: Coerciones
Volvamos un momento al código anterior. ¿Notás algo extraño en esta
expresión?

"La primera tirada dio " + primeraTirada

Utilizamos el operador + de una forma diferente, operando un string y un


número, y lo que hizo fue concatenar al string con la representación
textual del número. Es decir que:

 si operamos dos números con +, se suman


 si operamos dos strings con +, se concatenan
 si operamos un string y un número +, se convierte implícitamente el
número a string, y luego se concatenan, al igual que antes

En JavaScript, estas conversiones implícitas, también llamadas coerciones,


ocurren mucho.

¡Quizás incluso más de lo que nos gustaría!


gustaría

Veamos si queda claro, definí una función elefantesEquilibristas, que tome un número
de elefantes y devuelva una rima de una conocida canción:

> elefantesEquilibristas(3)
"3 elefantes se balanceaban"
> elefantesEquilibristas(462)
"462 elefantes se balanceaban"

function elefantesEquilibristas(numero){

return numero+" elefantes se balanceaban";


Las variables nos permiten nombrar y reutilizar valores. Similar a cómo los
procedimientos y funciones nos permiten dar nombres y reutilizar
soluciones a problemas más pequeños. Por ejemplo, si hacemos...

let primerMes = "enero"

...estamos asignándole el valor "enero" a la variable primerMes. En criollo,


estamos dándole ese valor a la variable.

Cambiá los lugares donde aparece 3.14159265358979 por la variable pi en las


funciones que tenemos definidas.
let pi = 3.14159265358979;

function perimetroCirculo (radio){

return 2*pi*radio;

function areaCirculo(radio){

return pi*radio*radio;

Ejercicio 9: Esto no tiene valor


Ya que vas entendiendo cómo se asignan las variables, te traemos algo
para pensar: ¿qué pasa si intento usar una variable a la que nunca le
asigné un valor?

Tenemos esta función definida:

function sumaSinSentido() {
return numero + 8;
}

Ejercicio 10: Variables globales


Entonces, ¿es necesario darle valor a nuestras variables antes de usarlas?
}

Ejercicio 11: La buena fortuna


for
Las variables no serían tan interesantes si no se pudieran modificar.
Afortunadamente, JavaScript nos da nuevamente el gusto y nos lo
permite:

function pasarUnDiaNormal() {
diasSinAccidentesConVelociraptores = diasSinAccidentesConVelociraptores + 1
}

function tenerAccidenteConVelociraptores() {
diasSinAccidentesConVelociraptores = 0;
}

¡Ahora vamos a hacer algo de dinero !


Definí el procedimiento aumentarFortuna que duplique el valor de la variable
global pesosEnMiBilletera. No declares la variabl
variable,
e, ya lo hicimos por vos (con una
cantidad secreta de dinero) .
function aumentarFortuna() {

pesosEnMiBilletera=pesosEnMiBilletera*2;


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 12: ¿Y esto cuánto vale?


Vimos que una variable solo puede tener un valor, entonces cada vez que
le asignamos
namos uno nuevo, perdemos el anterior. Entonces, dada la función:

function cuentaExtravagante() {
let numero = 8;
numero *= 2;
numero += 4;
Necesitamos una función que diga cuánta plata queda en tu cuenta (que
tiene un cierto saldo) si extráes un cierto monto:

// el saldo es $100, el monto a extraer, $30


> extraer(100, 30)
70 //quedan $70 ($100 - $30 = $70)

Pero como no queremos quedarnos en negativo, si el monto a extraer es


mayor al saldo, nuestro saldo debe quedar en cero.

> extraer(100, 120)


0 //Ups, quisimos sacar más plata de la que teníamos.
//Nos quedamos con $0

Como ves, esto es casi una resta entre saldo y monto, con la salvedad de
que estamos poniendo un tope inferior:: no puede dar menos de cero .

En otras palabras (¡preparate!, esto te puede volar la


cabeza ) extraer devuelve el máximo entre la resta saldo - monto y 0.

¿Te animás a completar la solución que está en el editor?


function extraer(saldo, monto) {

return Math.max(saldo-monto,0);
monto,0);


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 7: Libros de la buena memoria


¡Veamos más operadores! Dani ama el primer día de cada mes , y por eso
definió esta función...

function esDiaFavorito(diaDelMes
diaDelMes) {
return diaDelMes === 1 ;
}

...y la usa así (y la dejó en la biblioteca para que la pruebes):

> esDiaFavorito(13)
false
> esDiaFavorito(1)
true

Como ves, en JavaScript contamos con operadores


como ===, >=, >, <,<= que nos dicen si dos valores son iguales, mayores-o-
iguales, mayores, etc. Los vamos a usar bastante .

¡Ahora te toca a vos! Dani también dice que a alguien leGustaLeer, cuando la
cantidad de libros que recuerda haber leído es mayor a 20. Por ejemplo:

> leGustaLeer(15)
false

> leGustaLeer(45)
true

Definí y probá en la consola la función leGustaLeer.

function leGustaLeer(cantLibros){

return cantLibros>20;

> estaEntre(3, 1, 10)

true

> estaEntre(90, 1, 10)

false

> estaEntre(10, 1, 10)

false

> estaFueraDeRango(17, 1, 10)

True

Ejercicio 9: Palabras, sólo palabras


Muchas veces queremos escribir programas que trabajen con texto :
queremos saber cuántas palabras hay en un libro, o convertir minúsculas
a mayúsculas, o saber en qué parte de un texto está otro.

Para este tipo de problemas tenemos los strings


strings, también
llamados cadenas de caracteres:
caracteres

 "Ahora la bebé tiene que dormir en la cuna"


 'El hierro nos ayuda a jugar'
 "¡Hola Miguel!"

Como se observa, todos los strings están encerrados entre comillas


simples o dobles. ¡Da igual usar unas u otras! Pero sé consistente: po por
ejemplo, si abriste comilla doble, tenés que cerrar comilla doble. Además,
un string puede estar formado por (casi) cualquier carácter: letras,
números, símbolos, espacios, etc.

¿Y qué podemos hacer con los strings? Por ejemplo, compararlos, como a
cualquier otro valor:

> "hola" === "Hola"


false

> "todo el mundo" === "todo el mundo"


true

Veamos si queda claro: definí la función esFinDeSemana que tome un string que
represente el nombre de un día de la semana, y nos diga si es "sábado" o "domingo".

> esFinDeSemana("sábado")
true
> esFinDeSemana("martes")
false

function esFinDeSemana(dia){

return dia==="sábado" || dia==="domingo"


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 10: Operando strings


¿Y qué podemos hacer con los strings, además de compararlos? ¡Varias
cosas! Por ejemplo, podemos preguntarles cuál es su cantidad de letras:

> longitud("biblioteca")
10
> longitud("babel")
5

O también podemos concatenarlos, es decir, obtener uno nuevo que


junta dos strings:

> "aa" + "bb"


"aabb"
> "sus anaqueles " + "registran todas las combinaciones"
"sus anaqueles registran todas las combinaciones"

O podemos preguntarles si uno comienza con otro:

> comienzaCon("una página", "una")


true
> comienzaCon("la biblioteca", "todos los fuegos")
false

Veamos si queda claro: definí la función longitudNombreCompleto, que tome un nombre


y un apellido, y retorne su longitud total, contando un espacio extra para separar a
ambos:

> longitudNombreCompleto("Cosme", "Fulanito")


14

function longitudNombreCompleto(nombre,apellido){

return longitud(nombre)+longitud(apellido)+1;

}
Ejercicio 11: ¡GRITAR!
Una conocida banda, para agregar gritos varios a su canción, nos pidió
definir la función gritar, que toma un string y lo devuelve en mayúsculas y
entre signos de exclamación.

Por ejemplo:

> gritar("miguel")
"¡MIGUEL!"

> gritar("benito")
"¡BENITO!"

Definí la función gritar. Te dejamos para que uses la función convertirEnMayuscula, que,
ehm... bueno... básicamente convierte en mayúsculas un string .
function gritar(palabra){

return "¡"+convertirEnMayuscula(palabra)+"!";


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 12: ¿Y qué tal si...?


Ninguna introducción al lenguaje JavaScript estaría completa sin mostrar
al menos una estructura de control que ya conocemos: la alternativa
condicional. Veamos un ejemplo:

//Equivalente a Math.abs
function valorAbsoluto(unNumero
unNumero) {
if (unNumero >= 0) {
return unNumero;
} else {
return -unNumero;
}
}

Veamos si se entiende: definí la función maximo, que funcione como Math.max (¡no
vale usarla!) y retorne el máximo entre dos números. Por ejemplo, el máximo entre
4 y 5 es 5, y el máximo entre 10 y 4, es 10.

Ejercicio 13: ¿De qué signo sos?


Ya utilizamos la alternativa condicional para realizar una acción específica
cuando se cumple una condición y para cuando debemos elegir entre dos
acciones diferentes (según se cumpla o no).

Pero... ¿Si necesitamos más de dos alternativas? Veamos un ejemplo:

Agus se olvida siempre de como tiene que cuidar sus plantas , por eso
definió la función cuidadoSegun(dia) que le recuerda que los lunes tiene que
fertilizarlas, los viernes las tiene que fumigar y el resto de los días las tiene
que regar.

function cuidadoSegun(dia) {
if (dia === "lunes") {
return "fertilizar";
} else if (dia === "viernes") {
return "fumigar";
} else {
return "regar";
}
}

¡Ahora te toca a vos! Definí la función signo, que dado un número nos retorne:

 1 si el número es positivo
 0 si el número es cero
 -1 si el número es negativo

function signo(numero){

if (numero<0){

return -1;

else if (numero===0){
return 0;

else {

return 1;


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 14: El retorno del booleano


Para cerrar, ahora que ya vimos cómo escribir la alternativa condicional,
es momento de un pequeño recordatorio: si usás adecuadamente las
expresiones booleanas, ¡no es necesario utilizar esta estructura de control!

Supongamos que queremos desarrollar una función esMayorDeEdad, que


nos diga si alguien tiene 18 años o más. Una tentación
tentación es escribir lo
siguiente:

function esMayorDeEdad(edad) {
if (edad >= 18) {
return true;
} else {
return false;
}
}

Sin embargo, este if es totalmente innecesario,, dado que la


expresión edad >= 18 ya es booleana:

function esMayorDeEdad(edad) {
return edad >= 18;
}
Mucho más simple, ¿no?

Para Ema un número es de la suerte si:

 es positivo, y
 es menor a 100, y
 no es el 15.

Definí la función esNumeroDeLaSuerte que dado un número diga si cumple la lógica


anterior. ¡No vale usar if!
function esNumeroDeLaSuerte(numero){

return numero>0&&numero<100&&numero!==15;


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 15: Los premios


El jurado de un torneo nos pidió la función medallaSegunPuesto que retorne
la medalla que le corresponde a los primeros puestos, según la siguiente
lógica:

 primer puesto: le corresponde "oro"


 segundo puesto: le corresponde "plata"
 tercer puesto: le corresponde "bronce"
 otros puestos: le corresponde "nada"

Ejemplo:

> medallaSegunPuesto(1)
"oro"
> medallaSegunPuesto(5)
"nada"

Definí, y probá en la consola, la función medallaSegunPuesto


function medallaSegunPuesto(puesto){

if (puesto===1){

return "oro"

else if (puesto===2){

return "plata"

else if(puesto===3){

return "bronce"

else {

return "nada"


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio 16: Tipos de datos


Como acabamos de ver, en JavaScript existen números, booleanos y
strings:

Tipo de dato Representa Ejemplo Operaciones


Tipo de dato Representa Ejemplo Operaciones

Números cantidades 4947 +, -, *, %, <, etc

Boolean valores de verdad true &&, !, etc

Strings texto "hola" longitud, comienzaCon, etc

Además, existen operaciones que sirven para todos los tipos de datos
datos, por
ejemplo:

 ===: nos dice si dos cosas son iguales


 !==: nos dice si dos cosas son diferentes

Es importante usar las operaciones correctas con los tipos de datos


correctos,, por ejemplo, no tiene sentido sumar dos booleanos o hacer
operaciones booleanas con los números. Si usas operaciones que no
corresponden, cosas muy raras y malas pueden pasar.
pasar

Probá en la consola las siguientes cosas:

 5 + 6 (ok, los números


número se pueden sumar)
 5 === 6 (ok, todas las cosas se pueden comparar)
 8 > 6 (ok, los números se pueden ordenar)
 !true (ok, los booleanos se pueden negar)
 false / true (no está bien, ¡los booleanos no se pueden dividir!)


 2. Programación Imperativa
 1. Funciones y tipos de datos

Ejercicio
jercicio 17: Datos de todo tipo
Uff, ¡vimos un montón de cosas! Aprendimos sobre la sintaxis de las
funciones en JavaScript, los tipos de datos y sus operaciones, e incluso
conocimos uno nuevo: los strings.

¡Para finalizar veamos algunos ejemplos!


 4 + 4 vale 8.
 "4" + "4" vale "44".
 "on" + "ce" vale "once".
 true && false vale false.
 5 >= 6 vale false.


 2. Programación Imperativa
 1. Funciones y tipos de datos

Funciones y tipos de datos


¡Hola! Quizás no te diste cuenta pero ya tenés las bases de la
programación: ya sabés declarar funciones y procedimientos, tomar
decisiones empleando la estructura de control if, hacer tareas múltiples
veces.

Sin embargo, en los programas "reales"


"reales" rara vez trabajamos con tableros
y bolitas de colores: la programación va más allá de eso. ¿Cómo es
entonces esto de vivir fuera del tablero?

Para responder esta pregunta, primero nos adentraremos en el mundo de


JavaScript, un lenguaje muy popular que no tiene tablero,, pero en el que
de todas formas podremos aplicar todo lo visto hasta ahora y descubrir
nuevas ideas y formas de resolver problemas

¡Acompañanos!


 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 1: Comprando Hardware
Queremos comprar una computadora nueva , y nos gustaría saber cuánto
nos va a salir. Sabemos que:

 Los monitores cuestan $60 por cada pulgada


 La memoria cuesta $200 por cada GB
 El precio base estimado del resto de los componentes es de $1000

Definí la función cuantoCuesta que tome el númeroo de pulgadas del monitor y la


cantidad de memoria, y calcule el costo estimado de nuestra computadora.

> cuantoCuesta(25, 8)
4100

function cuantoCuesta(pulgadas,memoria){

return (pulgadas*60)+(memoria*200)+1000;


 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 2: ¿Me conviene?


Ahora que sabemos cuantoCuesta una computadora, queremos saber si una
computadora me conviene
conviene. Esto ocurre cuando:

 sale menos de $6000, y


 tiene al menos un monitor de 32 pulgadas, y
 tiene al menos 8GB de memoria

Definí la función meConviene, que nuevamente tome el número de pulgadas y


cantidad de memoria y nos diga si nos conviene comprarla :

> meConviene(25, 8)
false // porque el monitor es demasiado chico
> meConviene(42, 12)
true // cumple las tres condiciones

En la Biblioteca ya está definida la función cuantoCuesta lista para ser invocada.


function meConviene(pulgadas,memoria){

return cuantoCuesta(pulgadas,memoria)<6000&&pulgadas>=32&&memoria>=8;


 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 3: Triangulos
¡Hora de hacer un poco de geometría! Queremos saber algunas cosas
sobre un triángulo:

 perimetroTriangulo: dado los tres lados de un triángulo, queremos


saber cuánto mide su perímetro.
 areaTriangulo: dada la base y altura de un triángulo, queremos saber
cuál es su área.

Definí las funciones perimetroTriangulo y areaTriangulo


function perimetroTriangulo(base,altura,hipotenusa){

return base+altura+hipotenusa;

function areaTriangulo(base,altura){

return (base*altura)/2;

}
Ejercicio 4: Cuadrados
Y ahora es el turno de los cuadrados; queremos saber

 perimetroCuadrado: dado un lado, queremos saber cuánto mide su


perímetro.
 areaCuadrado: dado un lado, queremos saber cuál es su area

Definí las funciones perimetroCuadrado y areaCuadrado


¡Dame una pista!

function perimetroCuadrado(lado){

return lado*4;

function areaCuadrado(lado){

return lado*lado;


 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 5: ¿Está afinado?


Cuando presionamos una tecla de un piano, éste produce un sonido que
tiene una cierta frecuencia
frecuencia. Y cuando presionamos el la central del piano,
si está afinado, vamos a escuchar una nota cuya frecuencia
ecuencia es 440Hz
440Hz.
Definí una función estaAfinado, que reciba la frecuencia (un número) del la central, y
retorne si dicha frecuencia es igual a 440Hz.

> estaAfinado(440)
true

function estaAfinado (frecuencia){

return frecuencia===440;

Ejercicio 6: ¿Está cerca?


Ahora queremos saber si el la central del piano está cerca de estar
afinado. Esto ocurre cuando está entre 437Hz y 443Hz, pero NO es
exactamente 440Hz. Por ejemplo:

estaCerca(443)
true //está en el rango 437-443
estaCerca(442)
true //ídem caso anterior
estaCerca(440)
false //está en el rango,
//pero es exactamente 440
estaCerca(430)
false //está fuera del rango

Definí la función estaCerca

function estaCerca(frecuencia){

return frecuencia<444&&frecuencia>436&&frecuencia!==440;

> escribirCartelito("Dra.", "Ana", "Pérez")

"Dra. Ana Pérez"

function escribirCartelito(titulo,nombre,apellido){

return titulo+" "+nombre+" "+apellido;

Ejercicio 8: Más Cartelitos


Ah, ¡pero no tan rápido! Algunas veces en nuestro cartelito sólo
queremos el título y el apellido, sin el nombre. Por eso ahora nos toca
mejorar nuestra función escribirCartelito de forma que tenga 4 parámetros:

1. el título;
2. el nombre;
3. el apellido;
4. un booleano que nos indique si queremos un cartelito corto con
sólo título y apellido, o uno largo, como hasta ahora.

Modificá la función escribirCartelito, de forma que se comporte como se describe


arriba. Ejemplo:

// cartelito corto
> escribirCartelito("Lic.", "Tomás", "Peralta", true)
"Lic. Peralta"

// cartelito largo
> escribirCartelito("Ing.", "Dana", "Velázquez", false)
"Ing. Dana Velázquez"

 Solución
 Biblioteca
 Consola

1
//modificá esta función
2
function escribirCartelito(titulo,nombre,apellido,booleano){
3
if (!booleano){
4
return titulo+" "+nombre+" "+apellido;
5
} else {
6
return titulo+" "+apellido;
7
}
8
}
Enviar
¡Muy bien! Tu solución pasó todas las pruebas

Siguiente Ejercicio: Cartelitos óptimos

//modificá esta función

function escribirCartelito(titulo,nombre,apellido,booleano){

if (!booleano){

return titulo+" "+nombre+" "+apellido;

} else {

return titulo+" "+apellido;

}
}


 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 9: Cartelitos óptimos


Ahora que ya podemos escribir nuestros cartelitos identificatorios
grandes y chicos, queremos una nueva función que nos dé el cartelito de
tamaño óptimo:

 si nombre y apellido tienen, en total, más de 15 letras, queremos un


cartelito corto;
 de lo contrario, queremos un cartelito largo.

Definí la función escribirCartelitoOptimo que tome un título, un nombre y un apellido, y


utilizando escribirCartelito genere un cartelito corto o largo, según las reglas
anteriores. Ejemplo:

> escribirCartelitoOptimo("Ing."", "Carla", "Toledo")


"Ing. Carla Toledo"
> escribirCartelitoOptimo("Dr.",, "Estanislao", "Schwarzschild")
"Dr. Schwarzschild"

Te dejamos en la biblioteca la función escribirCartelito definida. ¡Usala cuando


necesites!

function escribirCartelitoOptimo(titulo,nombre,apellido){

return escribirCartelito(titulo,nombre,apellido,longitud(nombre)+longitud(apellido)>15)
escribirCartelito(titulo,nombre,apellido,longitud(nombre)+longitud(apellido)>15)

}

 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 10: Cara o ceca


Hay veces en las que tenemos difíciles decisiones que tomar en nuestra
nuestras
vidas (como por ejemplo, si comer pizzas o empanadas ),, y no tenemos
más remedio que dejarlas libradas a la suerte.

Es allí que tomamos una moneda y decimos: si sale cara, comemos pizzas,
si no, empanadas.

Definí una función decisionConMoneda, que toma tres res parámetros y retorna el segundo
si el primero es "cara", o el tercero, si sale "ceca". Por ejemplo:

> decisionConMoneda("cara", "pizzas


pizzas", "empanadas")

function decisionConMoneda(suerte,opcion1,opcion2){

if (suerte==="cara"){

return opcion1;

}else {

return opcion2;

}

 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 11: ¡Envido!


Queremos saber el valor de las cartas de truco cuando jugamos al envido.
Sabemos que:

 todas las cartas del 1 al 7, inclusive, valen su numeración


 las cartas del 10 al 12, inclusive, valen 0
 no se juega con 8s ni con 9s

Definí una función valorEnvido, que tome


me un número de carta y retorne su valor de
envido.

> valorEnvido(12)
0
> valorEnvido(3)
3

Ejercicio 11: ¡Envido!


function valorEnvido(carta){

if(carta>=1&&carta<=9){

return carta;

} else {

return 0;

}

 2. Programación Imperativa
 2. Práctica Funciones y Tipos de Datos

Ejercicio 12: ¡Quiero retruco!


Bueno, ehm, no, pará, primero queremos calcular cuántos puntos de
envido suma un jugador. Sabemos que:

 Si las dos cartas son del mismo palo, el valor del envido es la suma
de sus valores de envido más 20.
 De lo contrario, el valor del envido es el mayor valor de envido
entre ellas.

Utilizando la función valorEnvido (que ya definimos por vos), definí la


función puntosDeEnvidoTotales que tome los valores y palos de dos cartas y diga
cuánto envido suman en total. Ejemplo:

> puntosDeEnvidoTotales(1, "espadas


espadas", 4, "espadas")
25
> puntosDeEnvidoTotales(2, "copas
copas", 3, "bastos")
3

function puntosDeEnvidoTotales(valor1,palo1,valor2,palo2){

if (palo1===palo2){

return valorEnvido(valor1)+valorEnvido(valor2)+20;

} else {

return Math.max(valorEnvido(valor1),valorEnvido(valor2));

}
Ejercicio 13: ¡Quiero vale cuatro!
Cuando se juega al truco, los equipos oponentes alternativamente
pueden subir la apuesta. Por ejemplo, si un jugador canta truco, otro
jugador puede cantarle retruco.. Obviamente, los puntos que están en
juego son cada vez mayores:

Canto Puntos en juego


truco 2
retruco 3
vale cuatro 4
Definí la función valorCantoTruco, que tome el canto y retorne cuántos puntos vale.

> valorCantoTruco("retruco")
3

Asumí que sólo te van a pasar como argumento un string que represente un canto
de truco. Por ejemplo, no vamos a probar la función para el
caso valorCantoTruco("zaraza")
function valorCantoTruco(canto){

if (canto==="truco"){

return 2;

} else if (canto==="retruco"){

return 3;

} else {

return 4;


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 1: ¿Y el tablero?
Hasta ahora en esta película hay un gran personaje que está faltando: el
tablero. Seguro está por aparecer, de forma triunfal y rimbombante...,
¿no?

No. En JavaScript, lamentamos informarte, no hay tablero .

Pero tampoco es tan grave: en JavaScript no hay tablero, ¡porque no lo


necesitás! Suceden dos cosas:

1. El tablero nos servía para ver lo que nuestro programa hacía y qué
resultados generaba. Nos permitía también observar los cambios
de estado a causa del programa. Pero ahora ya tenemos
experiencia suficiente como para lanzarnos a programar sin tener
que "ver" lo que sucede.
2. Ahora contamos con la consola: una herramienta poderosa que
nos permite hacer pruebas más detalladas y flexibles.

¿No nos creés? Te presentamos un desafío: usando la consola, decí con tus propias
palabras qué hace la función funcionMisteriosa, que recibe dos números enteros como
argumentos.
¡Vas a ver que podés averiguarlo sin tener un tablero!

>

Ejercicio 2: Impresión por pantalla


Ahora que ya te convencimos de que no necesitamos al tablero, vamos a
mostrarte que sí hay algo parecido en JavaScript : la impresión por
pantalla. Veamos un ejemplo:

function funcionEgocentrica() {
imprimir("soy una función que imprime por pantalla");
imprimir("y estoy por devolver el valor 5");
return 5;
}

Probá funcionEgocentrica en la consola.



 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 3: Martin Fierro


¿Qué acabamos de hacer con esto? Al igual que Poner(bolita), imprimir es
una funcionalidad que siempre está disponible. Si llamamos a la función
anterior, veremos que, además de devolver el valor 5, imprime dos líneas:

soy una función que imprime por pantalla


y estoy por devolver el valor 5

Sin embargo, sólo podemos escribir strings y, una vez que escribimos en
la pantalla, no hay vuelta atrás: no hay forma de retroceder o deshacer.

Veamos si va quedando claro, definí la function versosMartinFierro que imprima por


pantalla los primeros versos del Martín Fierro:

Aquí me pongo a cantar


Al compás de la vigüela;
Que el hombre que lo desvela
Una pena extraordinaria

Esta function debe retornar 0


¡Dame una pista!

 Solución
 Consola

1
function versosMartinFierro() {
2
imprimir ("Aquí me pongo a cantar\nAl compás de la vigüela;\nQue el hombre que lo desvela\nUna
pena extraordinaria");
3
return 0;
4

5
}
6

Enviar

¡Muy bien! Tu solución pasó todas las pruebas


function versosMartinFierro() {

imprimir ("Aquí me pongo a cantar\nAl compás de la vigüela;\nQue el hombre que lo


desvela\nUna pena extraordinaria");

return 0;

Ejercicio 4: ¿Y los procedimientos?


En el ejercicio anterior, construiste una function que se ejecutaba con el
sólo fin de imprimir por pantalla. Y por ello, tuvimos que devolver un
valor cualquiera. ¿No te huele mal?

Además, hagamos memoria: cuando queremos reutilizar código,


podíamos declarar:

 funciones, que siempre retornan algo y no producen ningún efecto


 procedimientos, que no retornan nada, y producen efectos

Entonces versosMartinFierro, no es una función... ¡sino un procedimiento!


¿Cómo se declaran procedimientos en JavaScript?

¡De la misma forma que las funciones!: usando la palabra clave function.
function versosMartinFierro() {
imprimir("Aquí me pongo a cantar");
imprimir("Al compás de la vigüela;");
imprimir("Que el hombre que lo desvela");
imprimir("Una pena extraordinaria");
}

function versosMartinFierro() {

imprimir("Aquí me pongo a cantar");

imprimir("Al compás de la vigüela;");

imprimir("Que el hombre que lo desvela");

imprimir("Una pena extraordinaria");

Ejercicio 5: ¿Y el program?
Ahora bien, más allá de que podamos consultar el resultado de una
función a través de la consola, también aprendimos anteriormente que los
programas tienen un punto de entrada: el program. ¿Dónde quedó?

La respuesta es tan simple como sorprendente: en JavaScript todo lo que


escribamos fuera de una function será, implícitamente, dicho punto de
entrada. Por ejemplo, si queremos un programa que imprime por pantalla
el clásico "Hola, mundo!", lo podremos escribir así:

imprimir("Hola, mundo!");

O si queremos un programa que tire tres veces los dados e imprima sus
resultados, podemos escribirlo así:

imprimir("Tirando dados");
imprimir("La primera tirada dio " + tirarDado());
imprimir("La segunda tirada dio " + tirarDado());
imprimir("La tercera tirada dio " + tirarDado());

imprimir("Tirando dados");

imprimir("La primera tirada dio " + tirarDado());

imprimir("La segunda tirada dio " + tirarDado());


imprimir("La tercera tirada dio " + tirarDado());


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 6: Coerciones
Volvamos un momento al código anterior. ¿Notás algo extraño en esta
expresión?

"La primera tirada dio " + primeraTirada

Utilizamos el operador + de una forma diferente, operando un string y un


número, y lo que hizo fue concatenar al string con la representación
textual del número. Es decir que:

 si operamos dos números con +, se suman


 si operamos dos strings con +, se concatenan
 si operamos un string y un número +, se convierte implícitamente el
número a string, y luego se concatenan, al igual que antes

En JavaScript, estas conversiones implícitas, también llamadas coerciones,


ocurren mucho.

¡Quizás incluso más de lo que nos gustaría!


gustaría

Veamos si queda claro, definí una función elefantesEquilibristas, que tome un número
de elefantes y devuelva una rima de una conocida canción:

> elefantesEquilibristas(3)
"3 elefantes se balanceaban"
> elefantesEquilibristas(462)
"462 elefantes se balanceaban"

function elefantesEquilibristas(numero){

return numero+" elefantes se balanceaban";


}

Ejercicio 7: El círculo de la vida


En programación buscamos que resolver nuestros problemas usando…
programas . Y entre los problemas que casi nadie quiere resolver están los
matemáticos. Sobre todo aquellos que aparecen números como pi con
infinitos decimales imposibles de recordar.

Considerando
erando al número pi igual a 3.14159265358979 (no es infinito pero lo
suficientemente preciso para nuestros cáculos):

Definí las funciones perimetroCirculo y areaCirculo que reciben el radio de un círculo y a


partir del mismo nos retornan su perímetro y su área.
¡Dame una pista!

function perimetroCirculo (radio){

return 2*3.14159265358979*radio;

function areaCirculo(radio){

return 3.14159265358979*radio*radio;


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 8: PIenso que así es más fácil


Por suerte existe una herramienta que va a simplificar nuestra tarea de
ahora en adelante: las variables
variables.
Las variables nos permiten nombrar y reutilizar valores. Similar a cómo los
procedimientos y funciones nos permiten dar nombres y reutilizar
soluciones a problemas más pequeños. Por ejemplo, si hacemos...

let primerMes = "enero"

...estamos asignándole el valor "enero" a la variable primerMes. En criollo,


estamos dándole ese valor a la variable.

Cambiá los lugares donde aparece 3.14159265358979 por la variable pi en las


funciones que tenemos definidas.
let pi = 3.14159265358979;

function perimetroCirculo (radio){

return 2*pi*radio;

function areaCirculo(radio){

return pi*radio*radio;

Ejercicio 9: Esto no tiene valor


Ya que vas entendiendo cómo se asignan las variables, te traemos algo
para pensar: ¿qué pasa si intento usar una variable a la que nunca le
asigné un valor?

Tenemos esta función definida:

function sumaSinSentido() {
return numero + 8;
}

Ejercicio 10: Variables globales


Entonces, ¿es necesario darle valor a nuestras variables antes de usarlas?
¡Sí! Cuando declarás una variable tenés que darle un valor inicial, lo cual
se conoce como inicializar la variable.

¡Y sorpresa! Podemos declarar variables tanto directamente en el


programa, como dentro de una function:

function cuentaExtravagante(unNumero) {
let elDoble = unNumero * 2;
if (elDoble > 10) {
return elDoble;
} else {
return 0;
}
}

Las variables declaradas dentro de una function, conocidas como variables


locales, no presentan mayor misterio. Sin embargo, hay que tener un
particular cuidado: sólo se pueden utilizar desde dentro de la function en
cuestión. Si quiero referenciarla desde un programa:

let elCuadruple = elDoble * 4;

Kaboom, ¡se romperá!

Sin embargo, las variables declaradas directamente en el programa,


conocidas como variables globales, pueden ser utilizadas desde
cualquier function. Por ejemplo:

let pesoMaximoEquipajeEnGramos = 5000;

function puedeLlevar(pesoEquipaje) {
return pesoEquipaje <= pesoMaximoEquipajeEnGramos;
}

Veamos si queda claro: definí una función ascensorSobrecargado, que toma una
cantidad de personas y retorna si entre todas superan la carga máxima de 300 kg.
Tené en cuenta que nuestra función va a utilizar dos variables globales:

 pesoPromedioPersonaEnKilogramos, la cual ya está declarada,


 cargaMaximaEnKilogramos que vas a tener que declarar.

let cargaMaximaEnKilogramos = 300;

function ascensorSobrecargado(cantper){

return pesoPromedioPersonaEnKilogramos*cantper>cargaMaximaEnKilogramos;
}

Ejercicio 11: La buena fortuna


for
Las variables no serían tan interesantes si no se pudieran modificar.
Afortunadamente, JavaScript nos da nuevamente el gusto y nos lo
permite:

function pasarUnDiaNormal() {
diasSinAccidentesConVelociraptores = diasSinAccidentesConVelociraptores + 1
}

function tenerAccidenteConVelociraptores() {
diasSinAccidentesConVelociraptores = 0;
}

¡Ahora vamos a hacer algo de dinero !


Definí el procedimiento aumentarFortuna que duplique el valor de la variable
global pesosEnMiBilletera. No declares la variabl
variable,
e, ya lo hicimos por vos (con una
cantidad secreta de dinero) .
function aumentarFortuna() {

pesosEnMiBilletera=pesosEnMiBilletera*2;


 2. Programación Imperativa
 3. Variables y procedimientos

Ejercicio 12: ¿Y esto cuánto vale?


Vimos que una variable solo puede tener un valor, entonces cada vez que
le asignamos
namos uno nuevo, perdemos el anterior. Entonces, dada la función:

function cuentaExtravagante() {
let numero = 8;
numero *= 2;
numero += 4;
return numero;
}

Si la invocaramos ¿qué crees que retornaría?

Veamos el paso a paso:

 inicialmente la variable numero vale 8;


 al hacer numero *= 2 la variable pasa a tener su valor multiplicado por
2, es decir, 16;
 al hacer numero += 4 le sumamos 4 a 16 y lo guardamos en número,
por ende la función cuentaExtravagante retorna 20.

Ejercicio 1: ¡Que el último apague la luz!


Empecemos por algo sencillo, ¿te acordás del operador ! ? Se lo
denomina negación, not o complemento lógico y sirve para negar un
valor booleano.

Si tengo el booleano representado por tieneHambre, el complemento


será !tieneHambre.

¿Y esto para qué sirve? Por ejemplo, para modelar casos de alternancia
como prender y apagar una luz :

let lamparaPrendida = true;

function apretarInterruptor() {
lamparaPrendida = !lamparaPrendida;
}

¡Ahora te toca a vos!

Definí el procedimiento usarCierre para que podamos abrir y cerrar el cierre de una
mochila.

let mochilaAbierta= true;

function usarCierre(){
mochilaAbierta= !mochilaAbierta;


 2. Programación Imperativa
 4. Lógica booleana
 2. Negar no cuesta nada

Ejercicio 2: Negar no cuesta nada


Por el momento no parece una idea muy interesante, pero pero nos puede
servir para reutilizar la lógica de una función que ya tenemos definida.

Por ejemplo, si contamos con una función esPar, basta con negarla para
saber si un número es impar.

function esImpar(numero) {
return !esPar(numero);
}

¡Ahora te toca a vos! Definí esMayorDeEdad, que recibe una edad, y


luego esMenorDeEdad a partir de ella.
function esMayorDeEdad(edad){

return edad>=18;

function esMenorDeEdad(edad){

return !esMayorDeEdad(edad);

Ejercicio 3: Los peripatéticos


Otro de los operadores con el que ya te encontraste es la conjunción
lógica (también llamada y lógico, o and por su nombre en inglés), que
sólo retorna verdadero cuando todas las expresiones que opera son
verdaderas.

Podemos encadenar varias de ellas mediante el operador && y alcanza


con que sólo una de ellas sea falsa para que toda la expresión resulte
falsa.

Por ejemplo, si cuento con la función:

function esCantanteProlifico (cdsEditados, recitalesRealizados, graboAlgunDVD) {


return cdsEditados >= 10 && recitalesRealizados > 250 && graboAlgunDVD;
}

y tenemos un cantante que no grabó un DVD, entonces no se lo


considera prolífico, incluso aunque haya editado más de 10 CDs y dado
más de 250 recitales.

Definí una función esPeripatetico que tome la profesión de una persona, su


nacionalidad y la cantidad de kilómetros que camina por día. Alguien es
peripatético cuando es un filósofo griego y le gusta pasear (camina más de 2
kilómetros por día). Ejemplo:

> esPeripatetico("filósofo", "griego", 5)


true
> esPeripatetico("profesor", "uruguayo", 1)
false

function esPeripatetico (prof,nacio,km){

return prof==="filósofo"&&nacio==="griego"&&km>2;

Ejercicio 4: La verdad detrás de la


conjunción
En la lógica booleana, se puede definir el comportamiento de un
operador con una tabla de verdad donde A y B son las expresiones o
valores de verdad a ser operados y el símbolo ^ representa la conjunción.
Cada celda tiene una V si representa verdadero o F si representa falso.
Por ejemplo, supongamos que una casa consume poca energía si se usa
el aire acondicionado a 24 grados y tiene al menos 5 lamparitas bajo
consumo. Podemos representar las expresiones de la siguiente forma:

 A: En la casa se usa el aire acondicionado a 24 grados


 B: La casa tiene al menos 5 lamparitas bajo consumo
 A ^ B: La casa consume poca energía

Como indicamos, la casa consume poca energía (A^B) cuando


tanto A como B son verdaderos. Esto se puede representar mediante la
siguiente tabla de verdad:

A B A^B
V V V
V F F
F V F
F F F
En el mundo de la lógica estas expresiones se llaman proposiciones. Pero…
¿qué cosas pueden ser una proposición? Sólo hace falta que porten un
valor de verdad, es decir, cualquier expresión booleana puede ser una
proposición.

¿No nos creés? Probá en la consola la función consumePocaEnergia, que recibe una
temperatura y una cantidad de lamparitas, y comprobá si se comporta como en la
tabla:

 > consumePocaEnergia(24, 5)
 > consumePocaEnergia(24, 0)
 > consumePocaEnergia(21, 7)
 > consumePocaEnergia(18, 1)

Ejercicio 5: ¡Juguemos al T.E.G.!


¿Y si basta con que una de varias condiciones se cumpla para afirmar que
una expresión es verdadera? Podemos utilizar otro de los operadores que
ya conocés, ¡la disyunción lógica!

Recordá que se lo representa con el símbolo || y también se lo conoce


como el operador or.

En el famoso juego T.E.G., un jugador puede ganar de dos formas:


cumpliendo su objetivo secreto o alcanzando el objetivo general de
conquistar 30 países.
function gano(cumplioObjetivoSecreto, cantidadDePaisesConquistados) {
return cumplioObjetivoSecreto || cantidadDePaisesConquistados >= 30;
}

Probá en la consola las siguientes expresiones:

 > gano(true, 25)


 > gano(false, 30)
 > gano(false, 20)
 > gano(true, 31)

¿Te animás a construir la tabla de verdad de la disyunción lógica?

> estaCerrado(false, "sábado", 10)

true //Porque es fin de semana

> estaCerrado(true, "lunes", 10)

true //Porque es feriado

> estaCerrado(false, "martes", 20)

true //Porque no está dentro del horario bancario

> estaCerrado(false, "jueves", 11)

False

> esTonoClaro('rojo')

false

RESOLUCION

> esTonoClaro('blanco')

True

function tieneContraste (colorletra,colorfondo){

return
(!esTonoClaro(colorletra)&&esTonoClaro(colorfondo))||(esTonoClaro(colorletra)&&!esTonoCl
aro(colorfondo));

}

 2. Programación Imperativa
 4. Lógica booleana
 8. La verdad es que no hay una verdad

Ejercicio 8: La verdad es que no hay una


verdad
Ahora pensemos cómo sería la tabla de verdad que representa el
comportamiento de la función que acabás de hacer.
ha

La proposición es esTonoClaro, y el valor de verdad que porte dependerá


de cada color que esté evaluando.

El booleano final resultará de operar estos colores mediante tieneContraste:

la letra tiene tono claro el fondo tiene tono claro tiene contraste

true true false

true false true

false true true

false false false

Probá tu función tieneContraste con los siguientes valores y comprobá si se comporta


como la tabla:

 > tieneContraste("amarillo", "beige")


 > tieneContraste("azul", "violeta")
 > tieneContraste("blanco", "negro")

 Ejercicio 9: ¡Hola! Mi nombre es Xor


 Ahora cambiemos las proposiciones la letra tiene tono claro y el fondo
tiene tono claro por proposiciones genéricas A y B. Además,
representemos la operación que realiza tiene contraste con el
símbolo ⊻.. Lo que obtenemos es... ¡una nueva tabla!
A B A⊻B
V V F
V F V
F V V
F F F
 Este comportamiento existe como un operador dentro de la lógica
y se lo denomina xor o disyunción lógica excluyente.
 A diferencia del and, or y not, el xor no suele estar definido en los
lenguajes. Sin embargo, ahora que sabés cómo funciona, si alguna
vez lo necesitás podés definirlo a mano.
 Veamos si se entiende: definí la función genérica xor, que tome dos
booleanos y retorne el valor de verdad correspondiente.
function xor (boolean1,boolean2){

return boolean1===!boolean2;


 2. Programación Imperativa
 4. Lógica booleana
 10. Precedencia

Ejercicio 10: Precedencia


Cuando una expresión matemática tiene varios operadores, sabemos que
las multiplicaciones y divisiones
divisiones se efectuarán antes que las sumas y las
restas:

5 * 3 + 8 / 4 - 3 = 14

Al igual que en matemática, cuando usamos operadores lógicos las


expresiones se evalúan en un orden determinado llamado precedencia
precedencia.

¿Cuál es ese orden? ¡Hagamos la prueba!

Teniendo definida la siguiente función, según la cual las tarjetas de débito


ofrecen una única cuota, y las de crédito, seis:
function pagaConTarjeta(seCobraInteres, tarjeta, efectivoDisponible) {
return !seCobraInteres && cuotas(tarjeta) >= 3 || efectivoDisponible < 100;
}

Probala en la consola con los valores:

 > pagaConTarjeta(true, "crédito", 320)


 > pagaConTarjeta(false, "crédito", 80)
 > pagaConTarjeta(true, "débito", 215)
 > pagaConTarjeta(true, "débito", 32)

 Ejercicio 11: Un ejercicio sin


precedentes
 Si prestaste atención a la función anterior, habrás notado que la
operación con mayor precedencia es la negación !, seguida de la
conjunción && y por último la disyunción ||. ¿Pero qué pasa si
quiero alterar el orden en que se resuelven?
 Al igual que en matemática, podemos usar paréntesis para agrupar
las operaciones que queremos que se realicen primero.
 Delfi se puede concentrar cuando programa y toma infusiones,
pero no cualquier infusión. Tiene que ser mate a exactamente 80ºC
o té que esté a por lo menos 95ºC.
 Definí la función sePuedeConcentrar que recibe una bebida, su temperatura y un
booleano que nos dice si Delfi está programando:

 > sePuedeConcentrar('té', 100, true)


 true

 > sePuedeConcentrar('mate', 70, true)
 false

 > sePuedeConcentrar('té', 95, false)
 false

 ¡Intentá resolverlo en una única función! Después vamos a ver cómo


quedaría si delegamos.
function sePuedeConcentrar (bebida,temp,boolean){

return
(bebida==="té"&&temp>=95&&boolean)||(bebida==="mate"&&temp===80&&boolean);

}
> puedeSubirse(1.7, false, true)

false // no puede subirse

// porque aunque tiene mas de 1.5m,

// tiene una afección cardíaca

let alturaminimasola = 1.5;

let alturaminimaacomp =1.2;

function puedeSubirse(altura,boolean1,boolean2){

return
((altura<=alturaminimasola&&altura>=alturaminimaacomp)&&boolean1&&!boolean2)||(altur
a>=alturaminimasola&&!boolean1&&!boolean2);

Ejercicio 1: Series favoritas


Supongamos que queremos representar al conjunto de nuestras series
favoritas. ¿Cómo podríamos hacerlo?

let seriesFavoritasDeAna = ["Game of Thrones", "Breaking Bad", "House of Cards"];


let seriesFavoritasDeHector = ["En Terapia", "Recordando el Show de Alejandro Molina"]

Como ves, para representar a un conjunto de strings, colocamos todos


esos strings que nos interesan, entre corchetes ([ y ]) separados por
comas. Fácil, ¿no?

Probá en la consola las siguientes consultas:

 seriesFavoritasDeAna
 seriesFavoritasDeHector
 ["hola","mundo!"]
 ["hola","hola"]


 2. Programación Imperativa
 5. Listas
 2. Y esto, es una lista
Ejercicio 2: Y esto, es una lista
Lo que acabamos de ver es cómo modelar fácilmente conjuntos de cosas.
Mediante el uso de [], en JavaScript contamos con una manera simple de
agrupar esos elementos en listas.

¿Acaso hay una cantidad máxima de elementos? ¡No, no hay límite! Las
listas pueden tener cualquier cantidad de elementos.

Y no sólo eso, sino que además, el orden es importante. Por ejemplo, no


es lo mismo ["hola", "mundo"] que ["mundo", "hola"]: ambos tienen los mismos
elementos, pero en posiciones diferentes.

Probá en la consola las siguientes consultas:

 listasIguales(["hola", "mundo"], ["mundo", "hola"])


 listasIguales(["hola", "mundo"], ["hola", "mundo"])
 listasIguales(["hola", "mundo"], ["hola", "todo", "el", "mundo"])
 listasIguales(["hola"], ["hola", "mundo"])
 ["hola", "mundo"] === ["mundo", "hola"]
 personas
 ["mara", "julian"] === personas
 personas === personas

¿Qué conclusiones podés sacar?

Ejercicio 6: Agregando sabor


Las listas son muy útiles para contener múltiples elementos. ¡Pero hay
más! También podemos agregarle elementos en cualquier momento,
utilizando la función agregar, que recibe dos parámetros: la lista y el
elemento. Por ejemplo:

let pertenencias = ["espada", "escudo", "antorcha"];


//longitud(pertenencias) devuelve 3;

agregar(pertenencias, "amuleto mágico");


//ahora longitud(pertenencias) devuelve 4

Como vemos, agregar suma un elemento a la lista, lo cual hace que su


tamaño aumente. ¿Pero en qué parte de la lista lo agrega? ¿Al principio?
¿Al final? ¿En el medio?
Averigualo vos: inspeccioná en la consola qué elementos contiene pertenencias,
agregale una "ballesta" y volvé a inspeccionar pertenencias.
Además existe un procedimiento remover, que recibe la lista y un elemento por
parámetro. Investigá en la consola qué hace.
let unaLista = [1, 2, 3];

let otraLista = [4, 5];

trasladar(unaLista, otraLista, 2);

unaLista //debería ser [1, 3]

otraLista //debería ser [4, 5, 2]

function trasladar (unaLista,otraLista, elemento){

remover(unaLista,elemento);

agregar(otraLista,elemento)
otraLista,elemento)


 2. Programación Imperativa
 5. Listas
 8. ¿Y dónde está?

Ejercicio 8: ¿Y dónde está?


Otra cosa que queremos hacer con las listas es saber en qué posición se
encuentra un elemento. Para ello utilizamos la función posicion de la
siguiente manera:

posicion(["a", "la", "grande", "le


le", "puse", "cuca"], "grande"); //devuelve 2
let diasLaborales = ["lunes", "martes", "miercoles", "jueves", "viernes"]
posicion(diasLaborales, "lunes"); //devuelve 0

Como ves, lo curioso de esta función es que pareciera devolver siempre


uno menos de lo esperado. Por ejemplo, la palabra "grande" aparece
tercera, no segunda; y "lunes" es el primer día laboral, no el cero. ¿Es que
los creadores de JavaScript se equivocaron?

¡No! Se trata de que en JavaScript, al igual que en muchos lenguajes, las


posiciones de las listas arrancan en 0: el primer elemento está en la
posición 0, el segundo en la 1, el tercero en la 2, y así.

¿Y qué sucede si le pasás como argumento a posicion un elemento que no tiene?


¡Averigualo!
Probá lo siguiente:

posicion(diasLaborales, "osvaldo")

Ejercicio 9: Contiene
¡Ahora te toca a vos!

Definí la función contiene que nos diga si una lista contiene un cierto elemento.

> contiene([1, 6, 7, 6], 7)


true
> contiene([1, 6, 7, 6], 6)
true
> contiene([], 7)
false
> contiene([8, 5], 7)
false

Ejercicio 10: Enésimo elemento


Así como existe una función para averiguar en qué posición está un
elemento, también puede ocurrir que queramos saber lo contrario: qué
elemento está en una cierta posición.

Para averiguarlo podemos usar el operador de indexación, escribiendo


después de la colección y entre corchetes [] la posición que queremos
para averiguar:

> mesesDelAnio[0]
"enero"
> ["ese", "perro", "tiene", "la", "cola", "peluda"][1]
"perro"

¡Ojo! El número que le pases, formalmente llamado índice índice, debe ser
menor a la longitud de la lista, o cosas malas pueden suceder.

Probalo en la consola: ¿qué sucede si le pedís el elemento 0 a una lista vacía? ¿O si


le pedís el elemento 48 a una lista de 2 elementos?


 2. Programación Imperativa
 5. Listas
 11. Más premios

Ejercicio 11: Más premios


Si le pedís un elemento en una posición igual o mayor al tamaño de la
lista, vas a obtener undefined. No parece algo terrible, pero el problema es
que con undefined no podés hacer nada realmente útil.

Así que la advertencia es: ¡no te pases de índice!

Teniendo
endo esto en cuenta, va un desafío: definí nuevamente la
función medallaSegunPuesto, pero esta vez usando como máximo un único if. Quizás
las listas te pueden ser útiles acá .
Te recordamos qué hace la función: tiene que devolver la medalla que le
correspondende a los primeros puestos de una competencia.

> medallaSegunPuesto(1)
"oro"
> medallaSegunPuesto(2)
"plata"
> medallaSegunPuesto(3)
"bronce"
> medallaSegunPuesto(4)
"nada"
> medallaSegunPuesto(5)
"nada"

let unaLista = ["oro","plata","bronce"];


function medallaSegunPuesto(puesto){

if (puesto<=(longitud(unaLista)) && puesto>=1) {

return unaLista[puesto-1];

} else {return "nada"}

Ejercicio 12: No te olvides de saludar


Vamos a conocer una manera de recorrer los elementos de una lista con
un nuevo amigo: el for.

Imaginémonos que tenemos una lista con los precios de los productos
que compramos en el supermercado y queremos restar cada uno de ellos
a plataEnBilletera . Usando for podemos hacerlo así:

for(let precio of [10, 100, 87 ]) {


plataEnBilletera = plataEnBilletera - precio
}

donde plataEnBilletera es una variable que se va modificando a medida que


recorremos los precios.

Si teníamos $500 en nuestra billetera, después del for nos van a quedar
$303 porque:

 Al principio plataEnBilletera era 500 y el primer precio de la lista es 10.


Luego de hacer 500 - 10, plataEnBilletera es 490.
 A los 490 que quedaron en nuestra billetera, le restamos el
segundo precio de la lista: 100. Ahora plataEnBilletera es 390.
 El último precio a restar es 87, por lo que, al hacer 390 - 87, la
variable plataEnBilletera terminará siendo 303.

Completá el procedimiento saludar que recibe una lista de personas e imprime un


saludo con "hola" para cada una de ellas.

> saludar(["Don Pepito", "Don Jose"])


hola Don Pepito
hola Don Jose

> saludar(["Elena", "Hector", "Tita"])


hola Elena
hola Hector
hola Tita

function saludar(personas) {

for(let persona of personas) {

imprimir ("hola " + persona);


 2. Programación Imperativa
 6. Registros
 1. Los primeros registros

Ejercicio 1: Los primeros registros


Una historiadora está recopilando información acerca de distintos
monumentos a lo largo y ancho del mundo . En principio solo quiso saber
el nombre, ubicación, y año de construcción de cada monumento.

Para eso almacenó cada dato en


e una variable:

nombreEstatuaDeLaLibertad = "Estatua
" de la Libertad";
locacionEstatuaDeLaLibertad = "Nueva York";
anioDeConstruccionEstatuaDeLaLibertad = "1886";
nombreCristoRedentor = "Cristo
Cristo Redentor";
Redentor
locacionCristoRedentor = "Rio
Rio De Janeiro";
Janeiro
anioDeConstruccionCristoRedentor = "1931";

Ahí es cuando se dio cuenta que no era conveniente : si bien la


información entre las variables estaba relacionada, la estaba almacenando
por separado. Entonces pensó: ¿no existirá alguna forma de representar
las distintas características o propiedades de una misma cosa de forma
agrupada?
Luego de investigar un poco, encontró una mejor manera para guardar la
información de los monumentos. Probá en la consola escribiendo:

estatuaDeLaLibertad
cristoRedentor
torreEiffel
tajMahal
coliseo

Ejercicio 2: Tu propio monumento


Los monumentos que probaste en el ejercicio anterior están
representados como registros, y cada una de sus características (nombre,
locación, año de construcción) son campos del registro. Por cierto,
¡podemos crear registros de cualquier cosa, con los campos que
querramos!

Por ejemplo, podríamos almacenar un libro de modo que cada campo del
registro fuese alguna característica: su título, su autor, su fecha de
publicación, y más.

¡Es tu momento del monumento! Guardá en las


variables torreAzadi y monumentoNacionalALaBandera registros de esos monumentos,
oriundos de las ciudades de Teherán, Irán y Rosario, Argentina respectivamente. ¿Te
animás a investigar en qué año se terminaron de construir para completar ese
campo?
let torreAzadi = { nombre: "Torre Azadi", locacion: "Teherán, Irán", anioDeConstruccion: 1971
};

let monumentoNacionalALaBandera = { nombre: "monumento nacional a la bandera",


locacion: "Rosario, Argentina", anioDeConstruccion: 1957};

Ejercicio 3: Accediendo al campo


Cuando consultaste los registros existentes, se veía algo parecido a lo
siguiente:

> tajMahal
{ nombre: "Taj Mahal", locacion: "Agra, India", anioDeConstruccion: 1653 }

Esa consulta era porque estábamos viendo al registro tajMahal completo,


incluyendo todos sus campos. ¡Pero también se puede consultar por un
campo particular! Mirá :

> tajMahal.locacion
"Agra, India"
> tajMahal.anioDeConstruccion
1653

Declaramos los planetas mercurio, marte y saturno como registros con la siguiente
información: nombre, temperaturaPromedio y si tieneAnillos. ¡Probalos en la consola!

Ejercicio 4: Temperatura de planeta


Ahora que agregamos registros de planetas, ¡trabajemos un poco con
ellos!

Definí una función temperaturaDePlaneta que reciba como argumento un registro de


planeta y retorne un string que indique su nombre y su temperatura promedio.
¡Tiene que funcionar para cualquier planeta! Por ejemplo:

> temperaturaDePlaneta(mercurio)
"Mercurio tiene una temperatura promedio de 67 grados"
> temperaturaDePlaneta(saturno)
"Saturno tiene una temperatura promedio de -139 grados"
> temperaturaDePlaneta(venus)
"Venus tiene una temperatura promedio de 462 grados"

function temperaturaDePlaneta (planeta){

return planeta.nombre+" tiene una temperatura promedio de "+


planeta.temperaturaPromedio +" grados"

jercicio 5: Moviendo archivos


Por el momento estuvimos creando y consultando registros. ¿No sería
interesante poder... modificarlos?
La sintaxis para modificar campos de registros es muy similar a lo que
hacemos para cambiar los valores de las variables. Por ejemplo, para
cambiar la temperatura de un planeta:

saturno.temperaturaPromedio = -140;

Ahora imaginá que tenemos un registro para representar un archivo, del


que sabemos su ruta (dónde está guardado) y su fecha de creación. Si
queremos cambiar su ruta podemos hacer...

> leeme
{ ruta: "C:\leeme.txt", creacion: "23/09/2004" }

> moverArchivo(leeme, "C:\documentos\leeme.txt")

Luego el registro leeme tendrá modificada su ruta:

> leeme
{ ruta: "C:\documentos\leeme.txt", creacion: "23/09/2004" }

¡Es tu turno! Definí el procedimiento moverArchivo, que recibe un registro y una


nueva ruta y modifica el archivo con la nueva ruta.
function moverArchivo (registro,ruta){

registro.ruta=ruta

Ejercicio 6: Registros de dos milenios


En el ejercicio anterior modificamos la ruta del registro, pero no
utilizamos su fecha de creación. ¡Usémosla! Queremos saber si un archivo
es del milenio pasado, lo que ocurre cuando su año es anterior a 2000.

Definí la función esDelMilenioPasado, que recibe un archivo y retorna un booleano.

> esDelMilenioPasado({ ruta: "D:\fotonacimiento.jpg", creacion: "14/09/1989" })


true

function esDelMilenioPasado(archivo){

return anio(archivo.creacion)<"2000";

}
Ejercicio 7: Postres complejos
Unos ejercicios atrás te contamos la diferencia entre listas y registros.
¡Pero eso no significa que no podamos usar ambas estructuras a la vez!

Por ejemplo, una lista puede ser el campo de un registro. Mirá estos
registros de postres, de los cuales sabemos cuántos minutos de cocción
requieren y sus ingredientes:

let flanCasero = { ingredientes: ["huevos", "leche", "azúcar", "vainilla"], tiempoDeCoccion: 50 }


let cheesecake = { ingredientes: ["frambuesas", "queso crema"], tiempoDeCoccion: 80 }
let lemonPie = { ingredientes: ["jugo de limón", "almidón de maíz", "leche", "huevos"],
tiempoDeCoccion: 65 }

Definí la función masDificilDeCocinar, que recibe dos registros de postres como


argumentos y retorna el que tiene más ingredientes de los dos.

> masDificilDeCocinar(flanCasero, cheesecake)


{ ingredientes: ["huevos", "leche", "azúcar", "vainilla"], tiempoDeCoccion: 50 }

function masDificilDeCocinar(regPostre1,regPostre2){

if(longitud(regPostre1.ingredientes)>longitud(regPostre2.ingredientes)){

return regPostre1;

}else {

return regPostre2;

Ejercicio 9: 60 dulces minutos


A veces no sólo queremos comer algo rico, sino que queremos comerlo lo
antes posible.

Definí el procedimiento agregarAPostresRapidos, que toma una lista con postres rápidos
y un postre por parámetro. Si el tiempo de cocción es de una hora o menos, se
agrega el registro a la lista.
function agregarAPostresRapidos(lisPost,regPostre){
if (regPostre.tiempoDeCoccion<=60){

agregar(lisPost,regPostre)

Ejercicio 11: ¡Azúcar!


Para terminar, trabajemos una vez más con los menúes.

Definí un procedimiento endulzarMenu, que recibe un registro menú y le


agrega azúcar a los ingredientes de su postre. Si ya tiene azúcar, no importa... ¡le
agrega más

function endulzarMenu(regMenu){

agregar(regMenu.postre.ingredientes,"azúcar");

Ejercicio 1: Las ganancias semestrales


Ana, contadora de una conocida empresa , tiene registros para
representar los balances de cada mes y una lista para guardarlos. Por
ejemplo, para el último semestre del año pasado registró los siguientes:

//En julio ganó $50, en agosto perdió $12, etc


let balancesUltimoSemestre = [
{ mes: "julio", ganancia: 50 },
{ mes: "agosto", ganancia: -12 },
{ mes: "septiembre", ganancia: 1000 },
{ mes: "octubre", ganancia: 300 },
{ mes: "noviembre", ganancia: 200 },
{ mes: "diciembre", ganancia: 0 }
];

Y nos acaba de preguntar: "¿puedo saber la ganancia de todo un


semestre?"
"Obvio, solo tenemos que sumar las ganancias de todos los balances",
dijimos, y escribimos el siguiente código:

function gananciaSemestre(balances) {
return balances[0].ganancia + balances[1].ganancia +
balances[2].ganancia + balances[3].ganancia +
balances[4].ganancia + balances[5].ganancia;
}

"Gracias ", nos dijo Ana, y se fue calcular las ganancias usando la función
que le pasamos. Pero un rato más tarde, volvió contándonos que también
había registrado los balances del primer trimestre de este año:

//En enero la empresa ganó $80, en febrero, $453, en marzo $1000


let balancesPrimerTrimestre = [
{ mes: "enero", ganancia: 80 },
{ mes: "febrero", ganancia: 453 },
{ mes: "marzo", ganancia: 1000 }
];

Y nos preguntó: "¿Podría usar esta función que me dieron para calcular las
ganancias del primer trimestre?".

¿Tiene algún problema la función gananciaSemestre que escribimos anteriormente?


¿Funcionará con los balances trimestrales? ¿Y con los cuatrimestrestrales?
¡Probala en la consola!

Ahora que sabemos la función que necesitamos (gananciaTotal), razonemos


cómo hacerla...

Vamos de a poquito : si la lista no tuviera elementos, ¿cuánto debería ser


la sumatoria? ¡0!

function gananciaTotal0(balancesDeUnPeriodo) {
let sumatoria = 0;
return sumatoria;
}

¿Y si tuviera exactamente 1 elemento? Sería... 0.... ¿más ese elemento?


¡Exacto!

function gananciaTotal1(balancesDeUnPeriodo) {
let sumatoria = 0;
sumatoria = sumatoria + balancesDeUnPeriodo[0].ganancia;
return sumatoria;
}
¿Y si tuviera 2 elementos?

function gananciaTotal2(balancesDeUnPeriodo) {
let sumatoria = 0;
sumatoria = sumatoria + balancesDeUnPeriodo[0].ganancia;
sumatoria = sumatoria + balancesDeUnPeriodo[1].ganancia;
return sumatoria;
}

¿Y si tuviera 3 elementos?

function gananciaTotal3(balancesDeUnPeriodo) {
let sumatoria = 0;
sumatoria = sumatoria + balancesDeUnPeriodo[0].ganancia;
sumatoria = sumatoria + balancesDeUnPeriodo[1].ganancia;
sumatoria = sumatoria + balancesDeUnPeriodo[2].ganancia;
return sumatoria;
}

¿Empezás a ver un patrón? Tratá de escribir gananciaTotal4 que funcione para 4


elementos.

function gananciaTotal4(balancesDeUnPeriodo) {

let sumatoria = 0;

sumatoria = sumatoria + balancesDeUnPeriodo[0].ganancia;

sumatoria = sumatoria + balancesDeUnPeriodo[1].ganancia;

sumatoria = sumatoria + balancesDeUnPeriodo[2].ganancia;

sumatoria = sumatoria + balancesDeUnPeriodo[3].ganancia;

return sumatoria;

Ejercicio 5: Cuentas claras


¡Ana tiene nuevos requirimientos! Ahora nos pidió lo siguiente: "Quiero
saber cuántos balances fueron positivos, es decir, aquellos en los que la
ganancia fue mayor a cero".

Completá la función cantidadDeBalancesPositivos. Si prestás atención, notarás que tiene


una estructura similar al problema anterior.
function cantidadDeBalancesPositivos(balancesDeUnPeriodo) {
let cantidad = 0;

for (let balance of balancesDeUnPeriodo) {

if (balance.ganancia>0){

cantidad=cantidad+1;

return cantidad;

Ejercicio 6: La ganancia promedio


Pasemos al siguiente requerimiento de Ana. Ya podemos calcular una
sumatoria de ganancias y también crear contadores, ahora vamos a
calcular promedios.

Ana quisiera saber dado un conjunto cualquiera de balances cuál es


su gananciaPromedio.

> gananciaPromedio([
{ mes: "marzo", ganancia: 8 },
{ mes: "agosto", ganancia: 10 }
])
9

function gananciaPromedio(balancesDeUnPeriodo){

return (gananciaTotal(balancesDeUnPeriodo)/longitud(balancesDeUnPeriodo));

Ejercicio 7: Quién gana, quién pierde


Viendo que podemos hacer todo lo que nos pide, Ana quiere saber la
ganancia promedio de los balances positivos.

Definí las funciones:


 gananciaPositiva, que es la suma de las ganancias de los balances positivos
 promedioGananciasPositivas invocando gananciaPositiva y cantidadDeBalancesPositivos.

function gananciaPositiva(balancesDeUnPeriodo){

let sumatoria = 0;

for (let balance of balancesDeUnPeriodo){

if (balance.ganancia>0){

sumatoria=sumatoria+balance.ganancia;

return sumatoria;

function promedioGananciasPositivas(balancesDeUnPeriodo){

return
(gananciaPositiva(balancesDeUnPeriodo)/cantidadDeBalancesPositivos(balancesDeUnPeriodo)
)

jercicio 8: Soy el mapa, soy el mapa


Lamentablemente no se puede usar la función promedio con nuestra lista
de registros . Lo que necesitamos es una lista que tenga solo las
ganancias de cada balance. Para ello debemos transformar, o mapear,
cada elemento de la lista.

Completá la función ganancias que toma una lista de balances y devuelve una lista
que solo posea solo las ganancias de cada uno.

> ganancias([
{ mes: "enero", ganancia: 40 },
{ mes: "febrero", ganancia: 12 },
{ mes: "marzo", ganancia: 8}
])
[40, 12, 8]
function ganancias(balancesDeUnPeriodo) {

let ganancias = [];

for (let balance of balancesDeUnPeriodo) {

agregar(ganancias,balance.ganancia);

return ganancias;

Ejercicio 9: A filtrar, a filtrar cada cosa en


su lugar
Con la programación se puede hacer cualquier cosa, o casi . Ya hicimos
una función para poder saber la cantidad de balances positivos
(cantidadDeBalancesPositivos), ahora vamos a ver cómo podemos hacer para
saber cuáles son esos balances.

Completá la función balancesPositivos que toma los balances de un período y devuelve


una lista con aquellos cuya ganancia fue mayor a cero.
function balancesPositivos(balancesDeUnPeriodo) {

let balances = [];

for (let balance of balancesDeUnPeriodo) {

if(balance.ganancia>0){

agregar(balances,balance);

return balances;

}
E jercicio 10: Un promedio más positivo
Ahora que tenemos la función ganancias y balancesPositivos podemos utilizar
la función promedio genérica para saber cuál es el promedio de ganancia
de los balances positivos.

Definí la función gananciasDeBalancesPositivos y luego usala junto a promedio para


definir promedioDeBalancesPositivos.
function gananciasDeBalancesPositivos(balancesDeUnPeriodo){

let ganancias=[];

for

(let balance of balancesPositivos(balancesDeUnPeriodo)){

agregar(ganancias,balance.ganancia );

return ganancias;

function promedioDeBalancesPositivos(balancesDeUnPeriodo){

return promedio(gananciasDeBalancesPositivos(balancesDeUnPeriodo));

Ejercicio 11: Esto es lo máximo


Vamos a conocer una nueva función, maximo, que nos permite conocer
cuál es el mayor valor en una lista de números. Por ejemplo:

> maximo([5, 8, 10, 42, 87, 776])


776

Usando esta nueva función, definí la función maximaGanancia que nos diga cuál es la
ganancia más alta entre los balances de un período de tiempo.

> maximaGanancia([
{ mes: "enero", ganancia: 87 },
{ mes: "febrero", ganancia: 12 },
{ mes: "marzo", ganancia: 8}

function maximaGanancia (balancesDeUnPeriodo){


return maximo(ganancias(balancesDeUnPeriodo));

Suponemos que adivinaste el nombre. En caso que no, es minimo.

Definí la función minimaGananciaPositiva que nos diga cuál es la ganancia más baja de
todos los balances positivos.

> minimaGananciaPositiva([
{ mes: "enero", ganancia: -40 },
{ mes: "febrero", ganancia: 42 },
{ mes: "marzo", ganancia: 8},
{ mes: "abril", ganancia: -5}
])
8

function minimaGananciaPositiva (balancesDeUnPeriodo){

return minimo(gananciasDeBalancesPositivos(balancesDeUnPeriodo));

Ejercicio 13: Los mejores meses del año


¡Vamos a terminar esta lección con todo!

Para eso vamos a hacer las siguientes funciones:

 meses, la cual dada una lista con registros devuelve una lista de
meses ;
 afortunados, que filtra aquellos registros que tuvieron una ganancia
mayor a $1000 ;
 mesesAfortunados, devuelve aquellos meses que fueron afortunados.

> meses([
{ mes: "enero", ganancia: 870 },
{ mes: "febrero", ganancia: 1000 },
{ mes: "marzo", ganancia: 1020 },
{ mes: "abril", ganancia: 2300 },
{ mes: "mayo", ganancia: -10 }
])
["enero", "febrero", "marzo", "abril", "mayo"]

> afortunados([
{ mes: "enero", ganancia: 870 },
{ mes: "febrero", ganancia: 1000 },
{ mes: "marzo", ganancia: 1020 },
{ mes: "abril", ganancia: 2300 },
{ mes: "mayo", ganancia: -10 }
])
[ { mes: "marzo", ganancia: 1020 }, { mes: "abril", ganancia: 2300 }]

> mesesAfortunados([
{ mes: "enero", ganancia: 870 },
{ mes: "febrero", ganancia: 1000 },
{ mes: "marzo", ganancia: 1020 },
{ mes: "abril", ganancia: 2300 },
{ mes: "mayo", ganancia: -10 }
])
["marzo", "abril"]

function meses(regMeses){

let meses=[];

for(let estemes of regMeses){

agregar(meses,estemes.mes);

return meses;

function afortunados(regMeses){

let afortunados=[];

for (let mesrico of regMeses){

if (mesrico.ganancia>1000){

agregar(afortunados,mesrico);

return afortunados;

function mesesAfortunados(regMeses){

let mesesAfortunados=[];

for (let supermes of meses(afortunados(regMeses))){

agregar(mesesAfortunados,supermes);

}
return mesesAfortunados;


 3. Programación con Objetos
 1. Objetos y mensajes
 1. Fijando nuestro
tro objetivo

Ejercicio 1: Fijando nuestro objetivo


Anteriormente mencionamos los paradigmas de programación
programación. En este
capítulo vamos a conocer otra forma de pensar el mundo de la
programación.

El paradigma de programación con objetos o programación orientada


a objetos nos propone tratar con… ¡Adiviná! Sí, nos permite trabajar con
objetos.

Estos objetos pueden ser cualquier cosa, material o abstracta . Un objeto


es cualquier entidad que pueda hacer algo por nosotros para resolver un
problema.

Lo importante es que estos objetos viven dentro de un mismo mundo y


cada uno de ellos va a tener distintas responsabilidades. Además, van a
poder comunicarse entre ellos mandándose mensajes.

Para aprender a hacer todo esto, vamos a utilizar un lenguaje llamado


Ruby.

Pepita.comer_lombriz!

Pepita.comer_lombriz!

Pepita.comer_lombriz!
Pepita.volar_en_circulos!


 3. Programación con Objetos
 1. Objetos y mensajes
 12. ¿Quién te entiende?

Ejercicio 12: ¿Quién te entiende?


Ya vimos que un objeto puede entender múltiples mensajes, y esos
mensajess conforman su interfaz.

¿Pero podría haber más de un objeto que entienda los mismos mensajes?

A Pepita ya la conocemos bien: canta, come, etc. Su amiga Norita, por otro lado, no
aprendió nunca a decirnos su energía. Y Mercedes es una reconocida cantora.
Usando
sando la consola, averiguá cuál es la interfaz de cada una de ellas, y completá el
listado de mensajes que cada una entiende en el editor.
interfaz_pepita = %w(

energia

cantar!

comer_lombriz!

volar_en_circulos!

interfaz_norita = %w(

cantar!

comer_lombriz!

volar_en_circulos!

)
interfaz_mercedes = %w(

cantar!


 3. Programación con Objetos
 1. Objetos y mensajes
 13. Interfaces compartidas

Ejercicio 13: Interfaces compartidas


Veamos si queda claro, siendo que las interfaces
de Norita, Pepita y Mercedesson las siguientes:

Esto significa que comparten algunos mensajes y otros no. ¿Qué


interfaces comparten entre ellas?

Completá el código en el editor.

También podría gustarte