Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Ejercicios de Mumuki1
Ejercicios de Mumuki1
Lecciones
1. Funciones y tipos de datos
3. Variables y procedimientos
1. ¿Y el tablero?
2. Impresión por pantalla
3. Martin Fierro
4. ¿Y los procedimientos?
5. ¿Y el program?
6. Coerciones
7. El círculo de la vida
8. PIenso que así es más fácil
9. Esto no tiene valor
10. Variables globales
11. La buena fortuna
12. ¿Y esto cuánto vale?
4. Lógica booleana
6. Registros
7. Recorridos
Apéndice
¿Querés saber más? Consultá el apéndice de este capítulo
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?
¡Acompañanos!
Ejercicios
Sin embargo, como siempre que aprendas un lenguaje nuevo, te vas a topar
con un pequeño detalle: tiene una sintaxis diferente . La buena noticia es
que el cambio no será tan terrible como suena, así que veamos nuestra
primera función JavaScript:
function doble(numero) {
return 2 * numero;
}
function doble(numero) {
return (2* numero)
}
...notarás que los paréntesis en el return no son necesarios, y que la última
línea la terminamos con ; .
Veamos si se va entendiendo: definí ahora la función mitad, que tome un número
por parámetro y retorne su mitad. Tené en cuenta que el operador de división en
JavaScript es /.
¡Dame una pista!
10/2
5
2/10
0.2
CONSOLA
function mitad(numero){ return(1/2*numero)}
=> <function>
Solución
function mitad(numero){ return(1/2*numero)}
¡Muy bien! Tu solución pasó todas las pruebas
doble(3)
function doble(numero) {
return 2 * numero;
}
function siguienteDelDoble(numero) {
return doble(numero) + 1;
}
O incluso mejor:
function doble(numero) {
return 2 * numero;
}
function siguiente(numero) {
return numero + 1;
}
function siguienteDelDoble(numero) {
return siguiente(doble(numero));
}
function anteriorDelTriple(numero) {
return triple(numero) - 1;
}
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:
anteriorDelTriple debe utilizar anterior
anterior anterior(1) es 0
anterior anterior(10) es 9
triple triple(1) es 3
triple triple(3) es 9
anteriorDelTriple anteriorDelTriple(1) es 2
anteriorDelTriple anteriorDelTriple(3) es 8
anteriorDelTriple anteriorDelTriple(10) es 29
anteriorDelTriple debe utilizar triple
anteriorDelTriple debe utilizar anterior
la solución debe declarar anteriorDelTriple
Detalles
Resultados de las pruebas:
2 == 0
29 == 9
triple triple(1) es 3
triple triple(3) es 9
anteriorDelTriple anteriorDelTriple(1) es 2 Ver detalles
function doble(numero) {
return 2 * numero;
}
function siguiente(numero) {
return numero + 1;
}
function siguienteDelDoble(numero) {
return siguiente(doble(numero));
}
extraer(100, 120)
0 //Ups, quisimos sacar más plata de la que teníamos.
//Nos quedamos con $0
Math.max(100 - 30, 0)
70 // da el máximo entre 70 y 0, que es 70
Math.max(100 - 120, 0)
0 // da el máximo entre -20 y 0, que es 0
Solución
1. function extraer(saldo, monto) {
2. return Math.max(..completar.., ..completar..);
3. }
solucion.js:2
return Math.max(saldo-monto), 0);
^
Hola, hice bien el ejercicio (ahi le puse a proposito la "F" mayuscula para
poder ingresar acá) pero no entendi como probarlo en la consola
Solución correcta
Ah, y si estás pensando “en Gobstones podría haber hecho esto con un if”,
¡tenés razón!. Pero esta solución es mucho más breve y simple .
Solución correcta
function esDiaFavorito(diaDelMes) {
return diaDelMes === 1 ;
}
esDiaFavorito(13)
false
esDiaFavorito(1)
true
leGustaLeer(15)
false
leGustaLeer(45)
true
Tu solución no pasó las pruebas PORQUE NO LEI BIEN LA CONSIGNA QUE ES IGUAL O
MAYOR A 20.
Resultados de las pruebas:
CONSOLA
leGustaLeer(15)
=> false
leGustaLeer(20)
=> true
leGustaLeer(30)
=> false
SOLUCION MIA CORRECTA
function leGustaLeer(librosLeidos) {
return librosLeidos >= 20 ;
}
Consola
leGustaLeer(20)
=> true
leGustaLeer(80)
=> true
leGustaLeer(15)
=> false
¡Muy bien! Tu solución pasó todas las pruebas
¡Bien hecho!
Ejercicio 8: Booleanos
Ahora miremos a los booleanos con un poco más de detalle:
Se pueden negar, mediante el operador !: !hayComida
Se puede hacer la conjunción lógica entre dos booleanos (and,
también conocido en español como y lógico), mediante el
operador &&: hayComida && hayBebida
Se puede hacer la disyunción lógica entre dos booleanos (or, también
conocido en español como o lógico), mediante el
operador ||: unaExpresion || otraExpresion
Veamos si se entiende; definí las siguientes funciones:
estaEntre, que tome tres números y diga si el primero es mayor al segundo y
menor al tercero.
estaFueraDeRango: que tome tres números y diga si el primero es menor al
segundo o mayor al tercero
Ejemplos:
estaEntre(3, 1, 10)
true
estaEntre(90, 1, 10)
false
estaEntre(10, 1, 10)
false
estaFueraDeRango(17, 1, 10)
true
Resultados:
solucion.js:1
function estaEntre(60, 40, 75) {
^^
SyntaxError: Unexpected number
false == true
false == true
estaFueraDeRango(67, 0, 100) es false
estaFueraDeRango(2, 0, 100) es false
estaEntre devuelve siempre algo
estaFueraDeRango devuelve siempre algo
OOTRA SOLUCIONDE LA CONSULT CON ERROR
function estaEntre(num, rangoMin, rangoMax){
return (num>rangoMin) && (num<rangoMax);
}
function estaFueraDeRango(num, rangoMin, rangoMax){
return !((num > rangoMin) && (num < rangoMax));
}
El problema está en los operadores de la función estaFueraDeRango, fijate que la
consigna nos dice : que tome tres números y diga si el primero es menor al segundo O
mayor al tercero , por lo tanto el único operador que necesitamos será el or.
También fijate que el num debe ser menor al rangoMin (<) y mayor al rangoMax
(>). Intentá con esas modificaciones
SOLUCION CORRECTA
function estaEntre(num1, num2, num3){
return(num1 > num2 && num1 < num3)
}
function estaFueraDeRango(num1, num2, num3){
return(num1 > num2 && num1 > num3)
}
CONSOLA
true
estaEntre(40, 30, 60)
=> true
estaFueraDeRango(3, 1, 10)
=> false
estaFueraDeRango(60, 40, 30)
=> true
¡Muy bien! Tu solución pasó todas las pruebas
¡Bien hecho!
esFinDeSemana("sábado")
true
esFinDeSemana("martes")
false
esFinDeSemana("sábado")
esFinDeSemana("domingo")
esFinDeSemana("lunes")
esFinDeSemana("jueves")
CONSOLA
esFinDeSemana ("sabado")
=> true
esFinDeSemana ("lunes")
=> false
esFinDeSemana ("domingo")
=> true
longitud("biblioteca")
10
longitud("babel")
5
"aa" + "bb"
"aabb"
"sus anaqueles " + "registran todas las combinaciones"
"sus anaqueles registran todas las combinaciones"
longitudNombreCompleto("Cosme", "Fulanito")
14
solucion.js:2
return longitud ("nombre" + "apellido");
^^^^^^
SyntaxError: Unexpected token return
Biblioteca
/**/
SOLUCION CORRECTA
function longitudNombreCompleto(nombre,apellido){
return longitud(nombre+apellido+1) ESTE MAS 1 ES POR EL ESPACIO DE SEPARACION
} que seria la coma
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
longitudNombreCompleto("juan" , "perez")
=> 10
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!"
"todo" + "terreno"
"todoterreno"
BIBLIOTECA
/**/
function longitud(unString) /* ... */
// Retorna cuan largo es un string
//
// Por ejemplo:
//
// longitud("hola")
// 4
Ver detalles
solucion.js:1
function convertirEnMayuscula("gritar"){
^^^^^^^^
SyntaxError: Unexpected string
function gritar(nombre){
return "¡"+ convertirEnMayuscula (nombre)+ "!";
}
Nuestro return está perfecto, lo único que tenemos que hacer es modificar
ConvertirEnMayuscula por convertirEnMayuscula y terminamos
Modificado
function gritar(nombre) {
return ("¡"+convertirEnMayuscula(gritar)+"!")}
Da error
gritar("miguel") Ver detalles
unString.toUpperCase is not a function
gritar("gritar") Ver detalles
unString.toUpperCase is not a function
gritar("minuto") Ver detalles
unString.toUpperCase is not a function
SOLUCION CORRECTA
function gritar(nombre){
return "¡"+ convertirEnMayuscula (nombre)+ "!";
}
¡Muy bien! Tu solución pasó todas las pruebas
Consola
gritar("pepe")
=> "¡PEPE!"
gritar("bandera")
=> "¡BANDERA!"
//Equivalente a Math.abs
function valorAbsoluto(unNumero) {
if (unNumero >= 0) {
return unNumero;
} else {
return -unNumero;
}
}
//Equivalente a Math.abs
function valorAbsoluto(unNumero) {
if (unNumero >= 0) {
return unNumero;
} else {
return -unNumero;
}
}
CONSOLA
maximo(50, 30)
=> 50
maximo(30, 50)
=> 50
maximo(10, 60)
=> 60
OTRA RESPUESTA CORRECTA DADA POR EJERCICIOS RESUELTO POR LA PAGINA
Respuesta:
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
¡Dame una pista!
Un número es positivo cuando es mayor a 0 y negativo cuando
es menor a 0.
function signo(numero) {
if (numero > 0){
return "1";
} else if (numero < 0){
return "-1";
}
}
Tu solución no pasó las pruebas
Ver detalles
function signo(numero) {
if (numero > 0) {
return 1 ;
} else {
if (numero = 0) {
return 0 ;
} } else{
if (numero < 0) {
return -1 ;
}}
}
lorencia Agustina P. hace 10 meses
Hola! se ve que estoy escribiendo algo mal, nueva sintaxis puede fallar, no sé
si deberia sacar los "else" o como hacer para que me tome los 3 "if", porque
si pongo solamente los "if" me da error tambien. Desde ya muchas gracias.
}else{
lineas del else grande
if(condicion){
}else{
Ahora vamos a sacar las llaves de los ifs, que abren y cierran los return
else {
else {
Fijate que los else no logran cerrar sus llaves. Como el primero encierra los
dos ultimos ifs y al else y, a su vez, el else encierra al ultimo if, hay que
insertar dos } al final del ultimo if.
function signo(numero) {
if (numero > 0) {
return 1 ;
} else {
if (numero = 0) {
return 0 ;
} } else{
if (numero < 0) {
return -1 ;
}}
}
function signo(numero) {if (numero > 0) return 1 else {if (numero == 0) return 0 else if
(numero < 0) return -1 } }
SOLUCION QUE FUNCIONA CON COSAS A MEJORAR
function signo(numero) {if (numero > 0) return 1; else {if (numero == 0) return 0; else if
(numero < 0) return -1; } }
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:
signo debería usar los operadores de equivalencia === y !== en lugar de
los operadores de similitud == y !=
Resultados de las pruebas:
El signo de 10 es 1 por ser positivo
El signo de 1 es 1 por ser positivo
El signo de 0 es 0
El signo de -65 es -1 por ser negativo
signo no devuelve strings
SOLUCION CORRECTA
function signo(numero) {
if (numero > 0) return 1; else {if (numero === 0) return 0; else if (numero < 0) return -1;
}}
¡Muy bien! Tu solución pasó todas las pruebas
function signo(numero) { if (numero > 0){ return 1; } else if (numero < 0){ return -1;
else if (numero === 0) falta agregar esto
} } NO VAN FALTA ACA {
function esMayorDeEdad(edad) {
if (edad >= 18) {
return true;
} else {
return false;
}
}
function esMayorDeEdad(edad) {
return edad >= 18;
}
/**/
solucion.js:2
return positivo; <100; !== 15;
^
SyntaxError: Unexpected token <
SOLUCION CORRECTA
function esNumeroDeLaSuerte(numero){
return (numero > 0) && (numero < 100) && (numero !== 15); }
¡Muy bien! Tu solución pasó todas las pruebas
medallaSegunPuesto(1)
"oro"
medallaSegunPuesto(5)
"nada"
function medallaSegunPuesto(lugar){
if(lugar === 1){
return("oro")
} else if(lugar === 2) {
return("plata")
} else if(lugar === 3) {
return("bronce")
} else {
return("nada")
}
}
Muy bien! Tu solución pasó todas las pruebas
CONSOLA
medallaSegunPuesto(1)
=> "oro"
medallaSegunPuesto(3)
=> "bronce"
medallaSegunPuesto(5)
=> "nada"
Ejempl
Tipo de dato Representa Operaciones
o
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, por
ejemplo:
CONSOLA
=> false
8 > 6
=> true
!true
=> false
false / true
=> 0
Ejercicio 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.
4 + 4 vale 8
"4" + "4" vale "44"
4 + 4 vale "44"
"on" + "ce" vale "once"
5 >= 6 vale false
! true vale false
La respuesta no es correcta
4 + 4 vale 8
"4" + "4" vale "44"
4 + 4 vale "44"
"on" + "ce" vale "once"
5 >= 6 vale false
! true vale false
Hola, no entiendo en cual estaría fallando, leí otra pregunta hecha y entendí
que lo que hago estaría bien puesto que •la 1ra que marqué son dos
numeros y se pueden sumar •la 2da y la 3ra que marqué son strings por lo
cual se "adhieren" •la 4ta que marqué afirma que una misma cosa o es cierta
y es falsa a la vez por lo que es una contradicción •la ultima que marqué
indica con su "!" que no es cierto. Ayuda :/
Felipe Hernán B. hace 10 meses
"4" + "4" vale "44"
4 + 4 vale "44"
"on" + "ce" vale "once"
5 >= 6 vale false
! true vale fals
Hola! tengo el ejercicio bien resuelto porque abrí consultas anteriores pero
hay algo que no entiendo: ¿por qué true && false vale false? ¿es porque son
opuestos entonces no podrían ir juntos? Gracias!
Claudio Fabián B. hace 23 días
Hola Carolina.
true && false es false, porque el operador que estás usando "&&" es el Y
lógico o cunjunción, su tabla de verdad es la siguiente:
A B resultado true true true true false false false true false false false false
sólo es verdadero cuando ambas proposiciones (A y B) son verdaderas (true)
Antes de terminar un último desafío: ¿Cuál es el valor de las siguientes expresiones?
¡Marcá todas las correctas!
SOLUCION CORRECTA
4 + 4 vale 8
"4" + "4" vale "44"
4 + 4 vale "44"
"on" + "ce" vale "once"
5 >= 6 vale false
! true vale fals
Ejercicios
cuantoCuesta(25, 8)
4100
SOLUCION CORRECTA
function cuantoCuesta( pulgada, memoria) {
return (pulgada * 60 + memoria * 200 + 1000)
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
cuantoCuesta(25, 8)
=> 4100
meConviene(25, 8)
false // porque el monitor es demasiado chico
meConviene(42, 12)
true // cumple las tres condiciones
meConviene(25, 8) es falso
X meConviene(40, 8) es verdadero Ver detalles
ojo, también vale si tiene 8GB
X meConviene(40, 10) es verdadero Ver detalles
false == true
X meConviene(32, 10) es verdadero Ver detalles
ojo, también vale si tiene 32 pulgadas
meConviene(40, 4) es falso
meConviene(50, 16) es falso
SOLUCION DADA EN LA CONSULTA CON ERROR
function meConviene (pulgadas,memoria){
return cuantoCuesta(32,8) > 6000 + (memoria>8) && (pulgadas>32);
}
Micaela Denise I. hace 10 meses
hola, buenas noches, solo me toma 3 como correctas. como podria
arreglarlo? gracias
SOLUCION CORRECTA
function meConviene (pulgadas,memoria){
return cuantoCuesta(pulgadas, memoria) < 6000 && (memoria>=8) &&
(pulgadas>=32); }
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
meConviene(25,8)
=> false
meConviene(35,8)
=> true
meConviene(35,12)
=> true
meConviene(35,6)
=> false
Ejercicio 3: Triangulos
¡Hora de hacer un poco de geometría! Queremos saber algunas cosas sobre
un triángulo:
Resultados:
solucion.js:2
return perimetro(lado1 + lado2 + lado3);
^^^^^^ NO DEBE LLEVAR PERIMETRO Y LOS PARENTESIS
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!
Recordá que:
el perímetro de un cuadrado se calcula como 4 veces su lado;
el área de un cuadrado se calcula como su lado multiplicado por sí
mismo.
SOLUCION MIA CORRECTA
function perimetroCuadrado(lado){
return lado * 4;
}
function areaCuadrado(lado){
return lado * lado;
}
¡Muy bien! Tu solución pasó todas las pruebas
estaAfinado(440)
true
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(rango){
rango >= && rango <=;
}
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.js:2
rango >= && rango <=;
^^
function estaCerca(frecuencia){
return 437<=frecuencia<=443 && frecuencia!==440;
}
function estaCerca(frecuencia){
return frecuencia>=437 && frecuencia<=443 && frecuencia!==440;
}
SOLUCION CORRECTA
function estaCerca(frecuencia){
return frecuencia>=437 && frecuencia<=443 && frecuencia!==440;
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
estaCerca(450)
=> false
estaCerca(420)
=> false
estaCerca(439)
=> true
Ejercicio 7: Cartelitos
Para una importante conferencia, el comité organizador nos pidió que
escribamos cartelitos identificatorios que cada asistente va a tener.
Para eso, tenemos que juntar su nombre, su apellido, y su título (dr., dra., lic.,
etc) y armar un único string.
¡Dame una pista! LEER SIMPRE LA CONSIGNA Y DEFINIRLA EN ESE ORDEN EN function
Tené en cuenta que los espacios para separar las palabras también son
caracteres. ¡No te olvides de incluirlos al armar los cartelitos!
Por ejemplo:
solucion.js:1
function escribirCartelito("titulo", "apellido", "nombre"){
^^^^^^^^
SyntaxError: Unexpected string
SOLUCION CORRECTA
function escribirCartelito(titulo, nombre, apellido){
return(titulo + " " + nombre + " " + apellido)
}
¡Muy bien! Tu solución pasó todas las pruebas
es para concatenar stings iguales (no usar el string con parámetros con comillas pq
nos devuelve el parámetro en vez del nombre que queremos)
CONSOLA
escribirCartelito('licenciado','juan','Perez')
=> "licenciado juan Perez"
// cartelito corto
escribirCartelito("Lic.", "Tomás", "Peralta", true)
"Lic. Peralta"
// cartelito largo
escribirCartelito("Ing.", "Dana", "Velázquez", false)
"Ing. Dana Velázquez"
CONSOLA
escribirCartelitoOptimo("Licenciado", "Pedro", "Perez")
=> "Licenciado Pedro Perez"
TAMBIEN ESTA BIEN ESTA RESPUESTA
function escribirCartelitoOptimo(titulo, nombre, apellido){
return escribirCartelito(titulo, nombre, apellido, longitud(nombre+apellido)> 15)
}
CONSOLA
escribirCartelitoOptimo("licenciado", "Juan", "Perez")
=> "licenciado Juan Perez"
Es allí que tomamos una moneda y decimos: si sale cara, comemos pizzas, si
no, empanadas.
Definí una función decisionConMoneda, que toma tres parámetros y retorna el
segundo si el primero es "cara", o el tercero, si sale "ceca". Por ejemplo:
solucion.js:2
if cara
^^^^
valorEnvido(12)
0
valorEnvido(3)
3
Asumí que sólo te vamos a pasar cartas con valores dentro de los rangos
del 1 al 7 y del 10 al 12
function valorEnvido(valores){
return valores !==0 && valores <=7;
}
Resultados de las pruebas:
valorEnvido(1) es 1
valorEnvido(5) es 5 Ver detalles
true == 5
valorEnvido(12) es 0
valorEnvido(11) es 0
valorEnvido(10) es 0
valorEnvido no devuelve strings
SOLUCION CORRECTA
function valorEnvido(numero) {
if(numero >= 1 && numero <= 7){
return numero;}
else if(numero >= 10 && numero <= 12) {
return 0;
}
}
¡Muy bien! Tu solución pasó todas las pruebas
OTRA SOLUCION CORRECTA
function valorEnvido(numero){
if(numero >= 1 && numero <= 7)
{return numero}
if(numero >= 10 && numero <= 12)
{return 0}
}
¡Muy bien! Tu solución pasó todas las pruebas
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.
solucion.js:2
return Math.max((valorenvido * 2), palos;
^^^^^
function puntosDeEnvidoTotales(num,palo,num2,palo2){
if(palo===palo2){
return valorenvido(num + num2 + 20);
}
else{
return Math.max(num,num2);
}
}
SOLUCION DE LA CONSULTA CON ERROR
return
algo;
function unaFuncion(){
return 5;
hacer_algo();
hacer_otra_cosa();
}
Nunca nunca existirá una chance de que la computadora ejecute las líneas
hacer_algo() y hacer_otra_cosa(); por lo que vimos antes, una vez que lee el
retorno, se olvida de la función y sigue con otra cosa. Por esto es que
llamamos a ese código inalcanzable. ¿Y qué pasa si tengo el retorno pero en
otra línea como el primer ejemplo? Justamente, la computadora como
dijimos piensa que le estamos diciendo que retorne nada, y eso hace,
retorna nada y corta la ejecución, haciendo que lo que realmente queríamos
que fuera el retorno, nunca se ejecute.
En cuanto a separar por líneas en otros casos, esto más que nada lo hacemos
por una cuestión de orden. Es más entendible un código si lo tenemos
organizado e indentado (con sangrías que nos permitan ver más fácilmente
a qué bloque de código pertenecen las llaves). Una ventaja de tenerlo en
distintas líneas es que podemos ver los errores más fáciles. Por ejemplo
veamos este código:
function funcionLoca(parametro1){
let variable = parametro1 + 5;
if(variable < 10){
return 10;
}else{
return 5;
}
¿Notaste el error de sintaxis que tenemos? ¡Nos falta una llave! En el primer
ejemplo está muy complicado darnos cuenta, tenemos que estar contando
las llaves para ver cuál pertenece a cuál; mientras que en el segundo ejemplo
podemos ver que cada llave de cierre está alineada con el comienzo del
bloque, fijate que no hay ninguna llave alineada con el bloque de la función,
es decir que ninguna llave está alineada con la palabra function -> ¡es la llave
que nos falta!
function funcionLoca(parametro1){
let variable = parametro1 + 5;
if(variable < 10){
return 10;
}else{
return 5;
}
} //la llave queda alineada con el bloque que cierra
solucion.js:4
else {
^^^^
SyntaxError: Unexpected token else
Nos dice que no esperaba el else porque si tenemos alguna llave abierta, la
computadora va a esperar que se cierre en algún punto (lo mismo con
paréntesis), y si no lo hacemos y en lugar de eso le abrimos otra estructura la
computadora dice "che para, ¿qué es este else? Yo esperaba una llave, no
esperaba un else". Si bien no nos menciona explicitamente que es un error
de llaves, nos da a entender que cerca del else tenemos un errore de sintaxis,
por lo que nos conviene prestar atención al buscarlo en especial en las líneas
que estén por arriba o debajo.
SOLUCION CORRECTA
function puntosDeEnvidoTotales (numero1, palo1, numero2, palo2){
if (palo1 === palo2) {
return valorEnvido(numero1) + valorEnvido(numero2) + 20;}
else {return Math.max(valorEnvido(numero1), valorEnvido(numero2))
}
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
puntosDeEnvidoTotales(2, "palo", 5, "palo")
=> 27
truco 2
retruco 3
vale
4
cuatro
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")
SOLUCION MIA CON ERROR
function valorCantoTruco(canto, puntosenjuego){
return if puntosenjuego === 3, "retruco";
}
¡Ups! Tu solución no se puede ejecutar
Resultados:solucion.js:2
SOLUCION DE LA CONSULTA
function valorCantoTruco (canto) {
if("truco"===canto) {
return 2 }
if ("retruco" ===canto) {
return 3}
else { return "valecuatro" }
}
Luz Candela D. hace 10 meses
Lo unico que me falta es la parte del vale cuatro y no sé porque sale que está
mal.
SOLUCION DE LA CONSULTA
valorCantoTruco("retruco") es 3
valorCantoTruco("truco") es 2
valorCantoTruco("vale cuatro") es 4 Ver detalles
undefined == 4
OTRA SOLUCION CON ERROR
function valorCantoTruco(canto){
if(canto==="truco"){return 2;}
else if(canto==="retruco"){return 3;}
if(canto==="vale cuatro"){return 4;}
}
Angel Eduardo M. hace 17 días
buenas, una duda ¿ cuando es conveniente usar if o else if?o no inside nada el else antes
del if como ejemplo function valorCantoTruco(canto){ if(canto==="truco"){return 2;} else
if(canto==="retruco"){return 3;} if(canto==="vale cuatr"){return 4;} }
if(condicion){
algo;
}else{
otra_cosa;
}
Por más que a nivel ejecución sean lo mismo, está bueno tener presente la
diferencia conceptual.
¡Saludos!
SOLUCION CORRECTA
function valorCantoTruco(canto){
if(canto==="truco"){return 2;}
else if(canto==="retruco"){return 3;}
if(canto==="vale cuatro"){return 4;}
}
Variables y procedimientos
JavaScript, como la mayoría de los lenguajes comerciales (es decir, lenguajes
que se usan para desarrollar software "real"), no es tan puro en su
separación de funciones y procedimientos. Veamos por qué...
Ejercicios
1. ¿Y el tablero?
2. Impresión por pantalla
3. Martin Fierro
4. ¿Y los procedimientos?
5. ¿Y el program?
6. Coerciones
7. El círculo de la vida
8. PIenso que así es más fácil
9. Esto no tiene valor
10. Variables globales
11. La buena fortuna
12. ¿Y esto cuánto vale?
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.
¿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!
funcionMisteriosa(5, 2)
=> "woooooww!"
funcionMisteriosa(2, 1)
=> "woow!"
funcionMisteriosa(2, 5)
=> "woowwwww!"
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.
funcionEgocentrica()
soy una función que imprime por pantalla
y estoy por devolver el valor 5
=> 5
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:
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.
Esta function debe retornar 0
¡Dame una pista!
SOLUCION CORRECTA
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");
return 0;
}
¡Muy bien! Tu solución pasó todas las pruebas
¡Bien hecho!
Sin embargo, ¿tiene sentido que versosMartinFierro devuelva 0? ¿Usamos para
algo este resultado?
Acá parecería que llamamos a esta function porque nos interesa su efecto de
imprimir líneas; nos da igual lo que retorna. Quizás más que una función,
necesitamos definir un procedimiento. ¿Se podrá hacer esto en JavaScript?
La respuesta, ¡en el siguiente ejercicio!
CONSOLA
versosMartinFierro()
Aquí me pongo a cantar
Al compás de la vigüela;
Que el hombre que lo desvela
Una pena extraordinaria
=> 0
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());
Ejercicio 6: Coerciones
Volvamos un momento al código anterior. ¿Notás algo extraño en esta
expresión?
elefantesEquilibristas(3)
"3 elefantes se balanceaban"
elefantesEquilibristas(462)
"462 elefantes se balanceaban"
SOLUCION MIA CON ERROR
function elefantesEquilibristas(numero){
"elefantes se balanceaban" + numero
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
elefantesEquilibristas(3) Ver detalles
undefined == '3 elefantes se balanceaban'
elefantesEquilibristas(30) Ver detalles
undefined == '30 elefantes se balanceaban'
elefantesEquilibristas(4356) Ver detalles
elefantesEquilibristas(128) Ver detalles
SOLUCION CORRECTA
function elefantesEquilibristas(numero){
return(numero + " " + "elefantes se balanceaban");
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
elefantesEquilibristas(5)
=> "5 elefantes se balanceaban"
Detalles
Resultados de las pruebas:
SOLUCION CORRECTA
function perimetroCirculo(radio){
return 3.14159265358979*(radio*2);
}
function areaCirculo(radio){
return 3.14159265358979*(radio*radio);
}
CONSOLA
perimetroCirculo(20,3.14159265358979)
=> 125.6637061435916
areaCirculo(20, 3.14159265358979)
=> 1256.637061435916
let pi = 3.14159265358979;
function perimetroCirculo(radio){
return(3.14159265358979 * 2 * radio)
}
function areaCirculo(radio) {
return(3.14159265358979 * radio * radio)
}
SOLUCION MODIFICADA CORRECTA
let pi = 3.14159265358979;
function perimetroCirculo(radio){
return(pi * 2 * radio)
}
function areaCirculo(radio) {
return(pi * radio * radio)
}
¡Muy bien! Tu solución pasó todas las pruebas
function sumaSinSentido() {
return numero + 8;
}
Probala en la consola y fijate qué sucede.
CONSOLA
15
=> 15
15 + 8
=> 23
2 + 8
=> 10
function cuentaExtravagante(unNumero) {
let elDoble = unNumero * 2;
if (elDoble > 10) {
return elDoble;
} else {
return 0;
}
}
function ascensorSobrecargado(pesoPromedioPersonaEnKilogramos){
let cargaMaximaEnKilogramos=300
function ascensorSobrecargado(personas){
let pesoPromedioPersonaEnKilogramos = 90
return (pesoPromedioPersonaEnKilogramos*personas)>=cargaMaximaEnKilogramos
let cargaMaximaEnKilogramos=300
function ascensorSobrecargado(personas){
return
(pesoPromedioPersonaEnKilogramos*personas)>=cargaMaximaEnKilogramos;
}
¡Muy bien! Tu solución pasó todas las pruebas
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 variable, ya lo hicimos por vos (con una cantidad
secreta de dinero) .
¡Dame una pista!
Ver detalles
¡Corrijamos el problema!
Resultados de las pruebas:
100 == 200
30 == 240
OTRA CON ERROR MIA
pesosEnMiBilletera * 2;
100 == 200
30 == 240
Consulta con error
function aumentarFortuna() {
(pesosEnMiBilletera*2);
x += y; //equivalente a x = x + y;
x *= y; //equivalente a x = x * y;
x -= y; //equivalente a x = x - y;
x++; //equivalente a x = x + 1;
CONSOLA
pesosEnMiBilletera
=> 0
aumentarFortuna()
=> undefined
pesosEnMiBilletera // ¡aumento!
=> 0
Ejercicio 12: ¿Y esto cuánto vale?
Vimos que una variable solo puede tener un valor, entonces cada vez que le
asignamos uno nuevo, perdemos el anterior. Entonces, dada la función:
function cuentaExtravagante() {
let numero = 8;
numero *= 2;
numero += 4;
return numero;
}
¡La respuesta es correcta!
¿Qué retorna cuentaExtravagante?
"numero"
8
16
20
true
Enviar
Lógica booleana
Como ya viste a lo largo de varios ejercicios, cuando programamos
trabajamos con booleanos que representan valores de verdad. Podemos
operar con ellos mediante lo que denominamos operadores lógicos, como la
conjunción y la disyunción. ¡Vamos a aprender un poco más sobre ellos!
Ejercicios
function apretarInterruptor() {
lamparaPrendida = !lamparaPrendida;
}
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.
SOLUCION MIA CON ERROR
function esMayorDeEdad(edad){
return !esMenorDeEdad(edad); El error es que inverti lo que va en function
}
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:
SOLUCION CORRECTA
function esMayorDeEdad (edad){
return edad >= 18;
}
function esMenorDeEdad(edad){
return(!esMayorDeEdad(edad));
}
¡Muy bien! Tu solución pasó todas las pruebas
Cada una de las funciones representa un estado de dos posibles: ser mayor o
ser menor de edad. No se puede ser ambos al mismo tiempo y tampoco se
puede evitar pertenecer a alguno de los dos grupos. Es decir, ¡siempre sos
uno u otro!
Por eso decimos que son complementarios y que juntos forman el conjunto
universal.
esPeripatetico("filósofo", "griego", 5)
true
esPeripatetico("profesor", "uruguayo", 1)
false
SOLUCION MIA CON ERROR
solucion.js:2
return profesion = filosofo && nacionalidad = griego && kilometrospordia = 2;
^^^^^^^^^^^^^^^^^^^^^^^^
SOLUCION CORRECTA
CONSOLA
esPeripatetico("contador", "ruso", 3)
=> false
esPeripatetico("filosofo", "griego", 3)
=> true
gano(true, 25)
gano(false, 30)
gano(false, 20)
gano(true, 31)
gano(true, 25)
=> true
gano(false, 30)
=> true
gano(false, 20)
=> false
gano(true, 31)
=> true
Para evitar que le ocurra nuevamente, vamos a definir una función que
ayude a la gente despistada como ella.
Es feriado, o
Es fin de semana, o
No estamos dentro del horario bancario.
La función dentroDeHorarioBancario ya la definimos por vos: recibe un
horario (una hora en punto que puede ir desde las 0 hasta las 23) y nos dice
si está comprendido en la franja de atención del banco.
function esFinDeSemana(dia) {
return dia === "sabado" || dia === "domingo"
}
function estaCerrado(esFeriado, dia, horario) {
return esFeriado || dentroDeHorarioBancario(horario) || esFinDeSemana(dia)
}
Julian Gonzalo A. hace 10 meses
Me sale error en: un jueves corriente a las 13hs el banco no está cerrado un
martes corriente a las 16hs el banco está cerrado
No entiendo que estoy haciendo mal.
Sergio Sebastian S. hace 10 meses
Hola Julian... los comparadores || son para O en este caso estas diciendo si es
Feriado O esta dentro del horario bancario O es fin de semana .. .devolver
TRUE Es feriado esta genial.. si es feriado el banco esta cerrado... es fin de
semana... esta bien... si es fin de semana el banco esta cerrado... ahora el
horario... da TRUE si ES HORARIO BANCARIO vos necesitas lo contrario..
y por segundo.. revisa sabado creo que lleva tilde.-
SOLUCION DE LA CONSULTA CON ERROR
function esFinDeSemana(dia) {
return dia === "sabado" || dia === "domingo"
}
function estaCerrado(esFeriado, dia, horario) {
return esFeriado || dentroDeHorarioBancario(!horario) || esFinDeSemana(dia)
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
false == true
SOLUCION CORRECTA
function esFinDeSemana(dia) {
return dia === "sabado" || dia === "domingo"
}
function estaCerrado(esFeriado, dia, horario) {
return esFeriado || !dentroDeHorarioBancario(horario) || esFinDeSemana(dia)
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
estaCerrado ("sabado")
=> "sabado"
esFinDeSemana("sabado")
=> true
esFinDeSemana("martes")
=> false
padreDe(aurelianoJose)
"Coronel Aureliano"
madreDe(aurelianoSegundo)
"Sofía De La Piedad"
solucion.js:35
});
^
false == true
false == true
function tienenElMismoPadre(nom1,nom2){
return padreDe(nom1) === padreDe(nom2)
}
sonMediosHermanos(arcadio, aurelianoJose)
sonMediosHermanos(aurelianoSegundo, remedios)
sonMediosHermanos(aurelianoJose, remedios)
A B A⊻B
V V F
V F V
F V V
F F F
solucion.js:3
function A ⊻ B( hijo1 , hijo2 ) {
^
solucion.js:3
function A xor B( hijo1 , hijo2 ) {
^^^
function xor(A,B){
function xor(A,B){
(A === B)
return (false);}{
else (true);}
solucion.js:4
else (true);}
^^^^
function xor(A,B){
if (A !== B) {
return true;
} else (false);
function xor(A,B){
(A !== B) {
return true;
} else (false);
solucion.js:2
(A !== B) {
^
solucion.js:2
return (a && !b)||&(!a && b);
^
SOLUCION CORRECTA
function xor(a, b){
return (a && !b)||(!a && b);
}
¡Muy bien! Tu solución pasó todas las pruebas
OTRA SOLUCION CORRECTA
function xor(a, b){
return(a !== b)
}
¡Muy bien! Tu solución pasó todas las pruebas
5 * 3 + 8 / 4 - 3 = 14
pagaConTarjeta(true, "crédito", 320)
=> false
pagaConTarjeta(false, "crédito", 80)
=> true
pagaConTarjeta(true, "débito", 215)
=> false
pagaConTarjeta(true, "débito", 32)
=> true
solucion.js:2
return !edad && sexo && añosAporte=>30 || añosAporte < 30;
^
return edad >= 60 && "mujer" && ap >= 30 || edad > 65 && "hombre" && ap >= 30;
}
solucion.js:2
return edad >= 60 && sexo ="mujer" && ap >= 30 || edad > 65 && sexo="hombre" &&
ap >= 30;
^^^^^^^^^^^^^^^^^^
puedeJubilarse(67, "M", 29)
=> false
puedeJubilarse(67, "M", 32)
=> true
puedeJubilarse(59, "F", 30)
=> false
puedeJubilarse(60, "F", 25)
=> false
puedeJubilarse(60, "F", 30)
=> true
¿Y si delegamos? Podríamos separar la lógica de la siguiente manera:
true == false
true == false
function puedeSubirse(altura, acompañante, afección) { return ((altura>=1.5
&& acompañante==="no") || (altura>=1.2 && acompañante==="si")) && !
afección ; }
CON LA MODIFICACIÓN
SOLUCION CORRECTA
function puedeSubirse(alturamínima, acompañadaadulto, afeccióncardíaca){
return alturamínima >= 1.5 && !afeccióncardíaca || alturamínima >= 1.2
&& acompañadaadulto;
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
puedeSubirse(1.5, false, false)
=> true
puedeSubirse(1.7, true, false)
=> true
puedeSubirse(1.7,false, true)
=> false
Listas
La programación no sería tan divertida y poderosa si sólo pudieramos
trabajar con una cosa por vez: muchas veces no vamos a querer
simplemente operar un string, un booleano o un número, sino varios a la vez.
Ejercicios
seriesFavoritasDeAna
seriesFavoritasDeHector
["hola","mundo!"]
["hola","hola"]
CONSOLA
["hola", "mundo!"]
=> ["hola","mundo!"]
[seriesFavoritasDeAna]
=> [["Game of Thrones","Breaking Bad","House of Cards"]]
[seriesFavoritasDeHector]
=> [["En Terapia","Recordando el Show de Alejandro Molina"]]
["hola","hola"]
=> ["hola","hola"]
¿Acaso hay una cantidad máxima de elementos? ¡No, no hay límite! Las listas
pueden tener cualquier cantidad de elementos.
BIBLIOTECA
/**/
function longitud(unString) /* ... */
// Retorna cuan largo es un string
//
// Por ejemplo:
// longitud("hola")
// 4
function convertirEnMayuscula(unString) /* ... */
// Convierte una palabra en mayúsculas
//
// Por ejemplo:
// convertirEnMayuscula("hola")
// "HOLA"
function comienzaCon(unString, otroString) /* ... */
// Retorna un booleano que nos dice si unString empieza con otroString
//
// Por ejemplo:
// comienzaCon("hola todo el mundo", "hola todo")
// true
/**/
function imprimir(unString) /* ... */
// Imprime por pantalla unString
// Por ejemplo:
// imprimir("¡estoy imprimiendo!")
// ¡estoy imprimiendo!
function tirarDado( ) /* ... */
// Retorna un número al azar entre 1 y 6
//
// Por ejemplo:
// tirarDado()
// 5
// tirarDado()
// 1
// tirarDado()
// 2
numerosDeLoteria
salioCara
[[1, 2, 3], [4, 5, 6]]
CONSOLA
numerosDeLoteria
=> [2,11,17,32,36,39]
salioCara
=> [false,false,true,false]
[[1, 2, 3], [4, 5, 6]]
=> [[1,2,3],[4,5,6]]
BIBLIOTECA
/**/
function longitud(unString) /* ... */
// Retorna cuan largo es un string
//
// Por ejemplo:
//
// longitud("hola")
// 4
/**/
/**/
function imprimir(unString) /* ... */
// Imprime por pantalla unString
//
// Por ejemplo:
//
// imprimir("¡estoy imprimiendo!")
// ¡estoy imprimiendo!
/**/
function listasIguales(unArray, otroArray) /* ... */
// Retorna un booleano que nos dice si dos listas son iguales
//
// Por ejemplo:
//
// listasIguales([1, 2, 3], [1, 2, 3])
// true
// listasIguales([1, 2, 3], [4, 5, 3])
// false
let unaListaVacia = [ ]
longitud([ ])
longitud(numerosDeLoteria)
longitud([4, 3])
CONSOLA
longitud([])
=> 0
longitud(numerosDeLoteria)
=> 6
longitud([4, 3])
=> 2
CONSOLA
agregar (pertenencias, "ballesta")
=> 4
remover(pertenencias, "ballesta")
=> "ballesta"
Ejercicio 7: Trasladar
Bueno, ya hablamos bastante; ¡es hora de la acción !
trasladar(unaLista, otraLista);
Ver detalles
¡Intentemos de nuevo!
Resultados:
solucion.js:5
trasladar
function trasladar(a, b) {
remover(a)
agregar(b, !a)
}
Leandro C. hace 10 meses
Buenas tardes. No logro comprender cómo manipular el elemento de la lista
que saca "remover" para utilizarlo como parámetro en "agregar" :-/ Sé que
"remover" lo devuelve, pero ¿Cómo lo utilizo? Desde ya, muchas gracias.
[ 4, 5, 6, 7, undefined ] deepEqual [ 4, 5, 6, 7, 40 ]
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?
posicion(diasLaborales, "osvaldo")
posicion(diasLaborales, "osvaldo")
=> -1
Ejercicio 9: Contiene
¡Ahora te toca a vos!
return
Resultados:
solucion.js:1
function contiene ([1, 6, 7, 6], 7){
^
lista[1, 6, 7, 6] ;
posicion[lista] ;
solucion.js:2
return posicion(lista, numero) > = 0;
^
SyntaxError: Unexpected token =
modificado
SOLUCION CORRECTA
function contiene(lista, numero) {
return posicion(lista, numero) >= 0; }
function contiene(lista, numero) {
return posicion(lista, numero) !== -1; }
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
contiene([1, 6, 7, 6], 7)
=> true
contiene([], 7)
=> false
contiene([9, 4], 3)
=> false
¡Bien hecho!
mesesDelAnio[0]
"enero"
["ese", "perro", "tiene", "la", "cola", "peluda"][1]
"perro"
medallaSegunPuesto(1)
"oro"
medallaSegunPuesto(2)
"plata"
medallaSegunPuesto(3)
"bronce"
medallaSegunPuesto(4)
"nada"
medallaSegunPuesto(5)
"nada"
¿En qué nos puede ser útil una lista aquí? Pensá que la medalla que recibe la
persona está directamente relacionada con la posición en la que sale en la
competencia.
solucion.js:2
if posición(numero === 1)
^^^^^^^^
function medallaSegunPuesto(puesto){
if (1 <= puesto <= 3) {
return medallas[(puesto - 1)]
} else {
return "nada"
}
}
Sofia R. hace 10 meses
Hola, cuando envio me dice que el codigo funciona bien con los puestos 1, 2
y 3, pero cuando es un numero fuera de esos, me resulta en undefined. No
se que estoy haciendo mal, hace una que estoy pobando cosas. Ayuda :(
// hacer algo
}
SOLUCION CORRECTA
let medalla= ["oro", "plata", "bronce"];
function medallaSegunPuesto (puesto) {
if (puesto >=1 && puesto <=3) {
return medalla[puesto-1];
}
else {
return "nada"
}
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
medallaSegunPuesto(1)
=> "oro"
medallaSegunPuesto(3)
=> "bronce"
medallaSegunPuesto(5)
=> "nada"
function saludar(personas) {
for(let persona of personas) {
}
}
SOLUCION MIA CON ERROR
function saludar(personas) {
for(let persona of personas) {["Don Pepito", "Don Jose"]; }
{for(let persona of personas)["Elena", "Hector", "Tita"];
}
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
function saludar(personas) {
for(let persona of ["Elena", "Hector", "Tita"]) {
saludar() = "hola " + "persona" ;
}
}
function imprimirAUnaPersona(unaPersona) {
imprimir(persona+ "!");
}
imprimirAUnaPersona("Diana")
imprimir("hola"+ "Elena")
Ya que es nuestra primera persona en la lista de personas.
Espero que te sirva ¡saludos!
function saludar(personas) {
for(let persona of personas) {
imprimir ("hola" + " " + persona)
}
}
Stefano Domenico P. hace 5 meses
Hola, ya resolví el problema y estuve leyendo las consultas pero quisiera
sacarme una duda para ver si estoy entendiendo. Con respecto al uso del
for.. No me queda del todo claro cómo la función deduce a cada “persona” si
yo no las defino. Es porque al usar el for, las declaro ahí antes del let? O sea
que el for vendría a ser como un let dentro de let. No sé si se entiende mi
pregunta. Es una duda similar a la de Catalina Mozotegui. Gracias!
saludar(["Diana", "Stefano"])
Estoy elegiendo yo usar la función con esa lista que acabo de inventar.
La computadora, como siempre hace con los parámetros, va a
reemplazar en cada lugar donde dice personas (el nombre que le dimos
al parámetro) por la lista que inventamos:
Ahora, lo que hicimos con let persona of, fue darle un nombre a cada
elemento de la lista, para que la computadora pueda iterar lo que esté
dentro del for, es decir que va a "agarrar" un elemento, le pondrá el
nombre persona (que declaramos) y ejecutará reemplazando persona por
el elemento. Es decir, por ejemplo si toma el primer elemento: "Diana",
reemplazará en todo lugar donde diga persona:
Una vez que ejecutó eso, ahora le asignará a persona el valor del siguiente
elemento, en ese caso: "Stefano", entonces reemplazará otra vez en donde
decía persona y ejecutará:
Lo mismo hará si tuvieramos más elementos, irá reemplazando uno por uno
y ejecutando.
Cualquier cosa que sigan dudas, lo volvemos a ver 😊.
SOLUCION CORRECTA
function saludar(personas) {
for(let persona of personas) {
imprimir ("hola" + " " + persona)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
saludar(["Don Pepito", "Don Jose"])
hola Don Pepito
hola Don Jose
=> undefined
¡Terminaste Listas!
¡Felicitaciones!
Acabas de conocer una estructura de datos que te permite agruparlos: ¡la
lista!
También aprendiste qué datos puede tener dentro, cómo agregarle o sacarle
elementos, conocer sus posiciones, obtener su longitud y los elementos por
posición.
Por último viste una introducción a cómo recorrerla, aunque este tema lo
profundizaremos un poco más adelante.
Registros
Muchas veces, cuando representamos cosas de la vida real en nuestros
programas, necesitamos poder agrupar múltiples características de esas
cosas de alguna forma.
Ejercicios
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
CONSOLA
estatuaDeLaLibertad
=> {nombre:"Estatua de la Libertad",locacion:"Nueva York,
Estados Unidos de América",anioDeConstruccion:1886}
cristoRedentor
=> {nombre:"Cristo Redentor",locacion:"Rio de Janeiro,
Brasil",anioDeConstruccion:1931}
torreEiffel
=> {nombre:"Torre Eiffel",locacion:"París,
Francia",anioDeConstruccion:1889}
tajMahal
=> {nombre:"Taj Mahal",locacion:"Agra,
India",anioDeConstruccion:1653}
coliseo
=> {nombre:"Coliseo",locacion:"Roma,
Italia",anioDeConstruccion:80}
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.
solucion.js:2
let monumentoNacionalALaBandera = {nombre: "monumento Nacional A La Bandera", locacion:
"Rosario", "Argentina", anioDeConstruccion: 1957;
^^^
SOLUCION CORRECTA
tajMahal
{ nombre: "Taj Mahal", locacion: "Agra, India", anioDeConstruccion: 1653 }
tajMahal.locacion
"Agra, India"
tajMahal.anioDeConstruccion
1653
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"
¡Prestá atención a los strings que devuelven los ejemplos! Sólo la parte
correspondiente a cada planeta varía, como el nombre y la temperaturaPromedio.
Además, tenés que dejar espacios entre las palabras que rodean
a nombre y temperaturaPromedio. Mirá...
Por ejemplo
mercurio.nombre
CCON ERROR
function temperaturaDePlaneta(planeta){
return (planeta.nombre + " tiene una temperatura promedio de " +
"grados");
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
function temperaturaDePlaneta(planeta){
return (planeta).nombre +' tiene una temperatura promedio de '+
(planeta).temperaturaPromedio +' grados';
}
no hace falta ponerle los parentesis
SOLUCION CORRECTA
function temperaturaDePlaneta(planeta){
return (planeta).nombre +' tiene una temperatura promedio de '+
(planeta).temperaturaPromedio +' grados';
}
¡Muy bien! Tu solución pasó todas las pruebas
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")
leeme
{ ruta: "C:\documentos\leeme.txt", creacion: "23/09/2004" }
solucion.js:2
moverArchivo(registro, "C:\documentos\registro.txt)"}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
registro.ruta
// y
registro.creacion
¿Te imaginás cómo debería verse el código con alguno o ambos cambios?
Intentalo y si no sale, podés volver a compartir la solución por acá y lo
revisamos. Estamos para despejar las dudas. Saludos
SOLUCION CORRECTA
function moverArchivo(registro, nuevaRuta){
registro.ruta = nuevaRuta;
}
¡Muy bien! Tu solución pasó todas las pruebas
anio("04/11/1993")
1993
solucion.js:2
let leeme = registro.ruta = "D:\fotonacimiento.jpg", anio "04/11/1993";
^^^^^^^^^^^^
SyntaxError: Unexpected string
CON ERROR
function esDelMilenioPasado(registro, nuevaRuta){
}
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.js:2
let leeme = registro.ruta = "D:\fotonacimiento.jpg", creacion: "04/11/1993";
^
SyntaxError: Unexpected token :
SOLUCION CORRECTA
function esDelMilenioPasado(registro){
return anio(registro.creacion) < 2000;}
Muy bien! Tu solución pasó todas las pruebas
CONSOLA
"1993"
=> "1993"
esDelMilenioPasado({ruta: "D:\fotonacimiento.jpg", creacion: "4/11/19
93" })
=> true
masDificilDeCocinar(flanCasero, cheesecake)
{ ingredientes: ["huevos", "leche", "azúcar", "vainilla"], tiempoDeCoccion: 50 }
CONSOLA
masDificilDeCocinar(cheesecake, lemonPie)
=> {ingredientes:["jugo de limón","almidón de
maíz","leche","huevos"],tiempoDeCoccion:65}
masDificilDeCocinar(lemonPie, flanCasero)
=> {ingredientes:
["huevos","leche","azúcar","vainilla"],tiempoDeCoccion:50}
masDificilDeCocinar(flanCasero, lemonPie)
=> {ingredientes:["jugo de limón","almidón de
maíz","leche","huevos"],tiempoDeCoccion:65}
Toma el registro 2 o ultimo
¡Sí! Así como trabajamos con listas de números, booleanos, strings o más
listas, también podemos listar registros. Se puede hacer todo lo que hacías
antes, como por ejemplo remover, saber su longitud o preguntar por el
elemento de cierta posición utilizando los corchetes [ ].
OTRA SOLUCION
function agregarAPostresRapidos(lista, postre){
if(postre.tiempoDeCoccion <= 60){
agregar(lista, postre)
}
}
¡Muy bien! Tu solución pasó todas las pruebas
Por ejemplo, el siguiente es un menú con bife de lomo como plato principal, una ensalada
de papa, zanahoria y arvejas como acompañamiento y un cheesecake de postre. Como el
registro es un poco extenso, y para que sea más legible, lo vamos a escribir de la siguiente
forma:
let menuDelDia = {
platoPrincipal: "bife de lomo",
ensalada: ["papa", "zanahoria", "arvejas"],
postre: { ingredientes: ["queso crema", "frambuesas"], tiempoDeCoccion: 80
}
};
Averiguá qué devuelve el campo ingredientes del campo postre del registro menuInfantil.
¡Está un registro adentro del otro! La sintaxis es la siguiente:
menuInfantil.postre.ingredientes
CONSOLA
menuInfantil.postre.ingredientes
=> ["galletitas","dulce de leche","crema"]
Recordá que cada menú tiene un postre y que cada postre tiene ingredientes.
solucion.js:2
if postre = ingredientes
^^^^^^
SyntaxError: Unexpected identifier
agregar(menu.postre.ingredientes, "azúcar");
SOLUCION CORRECTA
function endulzarMenu (menu) {
agregar (menu.postre.ingredientes, "azúcar");
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
¡Terminaste Registros!
Durante la lección aprendiste cuál es la utilidad de esta estructura de datos
llamada registro, cómo acceder a sus campos y modificarlos, y hasta viste
que pueden anidarse (es decir, que haya un registro dentro de otro).
¡Felicitaciones!
Recorridos
En lecciones anteriores definimos funciones, usamos registros y listas. Ahora
que tenemos todas esas herramientas, llega el momento de combinarlas y
aprender a correr las listas y hacer cosas más complejas. ¡Acompañanos!
Ejercicios
"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:
Y nos preguntó: "¿Podría usar esta función que me dieron para calcular las
ganancias del primer trimestre?".
function gananciaSemestre(balances) {
return balances[0].ganancia + balances[1].ganancia +
balances[2].ganancia + balances[3].ganancia +
balances[4].ganancia + balances[5].ganancia;
}
CONSOLA
balancesPrimerTrimestre
=> [{mes:"enero",ganancia:80},{mes:"febrero",ganancia:453},
{mes:"marzo",ganancia:1000}]
balancesCuartoTrimestre
balancesCuartoTrimestre;
^
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;
}
SOLUCIONCORRECTA
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;
}
¡Muy bien! Tu solución pasó todas las pruebas
¡Bien hecho!
function gananciaTotalN(unPeriodo) {
let sumatoria = 0; // esto siempre está
//... etc
return sumatoria; //esto siempre está
}
function gananciaTotal(balancesDeUnPeriodo) {
let sumatoria = 0;
for (let balance of balancesDeUnPeriodo) {
sumatoria = sumatoria + balance.ganancia;
}
return sumatoria;
}
Como ves, el for...of nos permite visitar y hacer algo con cada elemento de
una lista; en este caso, estaremos visitando
cada balance de balancesDeUnPeriodo.
¿Aún no te convenciste? Nuevamente, probá las siguientes expresiones en la consola:
gananciaTotal([])
gananciaTotal([
{ mes: "noviembre", ganancia: 5 }
])
gananciaTotal([
{ mes: "marzo", ganancia: 8 },
{ mes: "agosto", ganancia: 10 }
])
gananciaTotal([
{ mes: "enero", ganancia: 2 },
{ mes: "febrero", ganancia: 10 },
{ mes: "marzo", ganancia: -20 }
])
gananciaTotal([
{ mes: "enero", ganancia: 2 },
{ mes: "febrero", ganancia: 10 },
{ mes: "marzo", ganancia: -20 },
{ mes: "abril", ganancia: 0 },
{ mes: "mayo", ganancia: 10 }
])
BIBLIOTECA
function gananciaTotal(balancesDeUnPeriodo) {
let sumatoria = 0;
for (let balance of balancesDeUnPeriodo) {
sumatoria = sumatoria + balance.ganancia;
}
return sumatoria; }
CONSOLA
gananciaTotal([])
=> 0
gananciaTotal([ {mes: "noviembre", ganancia: 5} ])
=> 5
gananciaTotal([ {mes: "marzo", ganancia: 8}, {mes: "agosto", ganancia
: 10} ])
=> 18
gananciaTotal([ {mes: "enero", ganancia: 2}, {mes: "febrero", gananci
a: 10}, {mes: "marzo", ganancia: -20} ])
=> -8
gananciaTotal([ {mes: "enero", ganancia: 2}, {mes: "febrero", ganancia
: 10}, {mes: "marzo", ganancia: -20}, {mes: “abril”, ganancia: 0},
{mes: “mayo”, ganancia: 10} ])
=> 2
SOLUCION A CORREGIR
function cantidadDeBalancesPositivos(balancesDeUnPeriodo) {
let cantidad = ????;
for (let balance of balancesDeUnPeriodo) {
????
}
return cantidad;
}
3 deepEqual 1
3 deepEqual 2
3 deepEqual 0
3 deepEqual 0
3 deepEqual 0
SOLUCION DE LA CONSULTA
function cantidadDeBalancesPositivos(balancesDeUnPeriodo){
let cantidad = 0;
for (let balance of balancesDeUnPeriodo) {
if(balance.ganancia > 0){
cantidad= cantidad + 1}
}
return cantidad;
}}
Michelle L. hace 10 meses
Hola! El ejercicio me salió pero le agregue una llave al final para poder
consultar porque no me quedo muy clara la lógica. En la linea 5, cantidad
sumaria 1, por cada vez que en la linea anterior, la ganancia de cada balance
sea mayor a 0, no? Y podemos acceder a los balances gracias al for/of que
nos permite modificar o contar un solo elemento de una lista, no? Perdón
quiero estar segura porque si no lo entiendo bien no se si me saldría
aplicarlo en otro ejercicio... gracias desde ya!
function cantidadDeBalancesPositivos(balancesDeUnPeriodo){
let cantidad = 0;
for (let balance of balancesDeUnPeriodo) {
if(balance.ganancia > 0){
cantidad= cantidad + 1} esto es lo correcto
}
return cantidad;
}}
Hola como estan? Le saque "{" para hacer una consulta, no termino de
comprender como funciona este codigo, sobre todo el " for (let balance of
balancesDeUnPeriodo)"... me podrian explicar?
Juan Carlos O. hace 9 meses
}
return cantidad;
}
?
Amilcar Daniel F. hace 17 días
El ejercicio los "resolví" copiando y pegando de algunas respuestas, y con la
ayuda de alguien que programa en EXCEL, pero NO USANDO /
ENTENDIENDO la lógica, lo cual ya en el ejercicio 5 y ejer. 6 me impide
progresar debido a NO ENTIENDO LA LOGICA. Asumiendo que usamos lo
que vamos aprendiendo en los ejercicios anteriores:
En los anteriores ejercicios se definió que:
(EJERCICIO 4) gananciaTotal([ { mes: "enero", ganancia: 2 }, { mes: "febrero",
ganancia: 10 }, { mes: "marzo", ganancia: -20 } ])
(EJERCICIO 5) Y es este ejercicio aparece "balance.ganancia" (lo puse en
mayúsculas para que se vea, no así en el ejercicio RESUELTO) cuando
entiendo que debería ser "gananciaTotal.ganancia":
function cantidadDeBalancesPositivos(balancesDeUnPeriodo) { let cantidad =
0 ; for (let balance of balancesDeUnPeriodo) { if BALANCE.GANANCIA > 0)
cantidad = cantidad + 1
} return cantidad; }
¿Hay algún vídeo o algún tutor que me ayude a razonar este ejercicio en
vistas de los próximos? ¡Desde ya muchas gracias!
Diana L. MENTORÍA hace 16 días
gananciaTotal([
{ mes: "enero", ganancia: 2 },
{ mes: "febrero", ganancia: 10 },
{ mes: "marzo", ganancia: -20 }
])
[
{ mes: "enero", ganancia: 2 },
{ mes: "febrero", ganancia: 10 },
{ mes: "marzo", ganancia: -20 }
]
PonerYMover(Rojo, Este)
La computadora reemplazaba color por Rojo y direccion por Este, es decir que
llenaba esos "agujeros" con valores concretos, y ejecutaba entonces:
Poner(Rojo)
Mover(Este)
Y de la misma forma, podríamos crear una lista de registros inventados, respetando esa
sintaxis:
[{mes: "febrero", ganancia: 9999}, {mes: "marzo", ganancia: 159}, {mes: "diciembre",
ganancia: 444}]
Esta lista, o cualquier otra que inventemos, ¡puede ser usada en nuestras funciones! Así
como usabamos el procedimiento dandole los valores concretos como Rojo o Este,
podemos darle a nuestra función un valor concreto como la lista que vimos recién (que no
definimos en ningún lugar):
¿Y ahora cómo sabe qué es registro? Ahí viene la magia del for, cuando
hacemos for(let nombre of lista), estamos definiendo una variable (nombre) que
nos permitirá iterar por cada elemento de la lista lista, que en este caso es
nuestra lista inventada de registros. ¿Cómo lo hace? Por cada elemento de
la lista, el for ejecutará reemplazando en cada lugar que diga registro (que es
el nombre que le dimos) por el elemento. Sigamos viendo qué se ejecutaría
con el ejemplo anterior. La primera vez, el for tomará el primer elemento:
{mes: "febrero", ganancia: 9999} que es un registro. Reemplaza entonces en cada
lugar que diga registro por {mes: "febrero", ganancia: 9999} y ejecuta:
SOLUCION CORRECTA
function cantidadDeBalancesPositivos(balancesDeUnPeriodo){
let cantidad = 0;
for (let balance of balancesDeUnPeriodo) {
if(balance.ganancia > 0){
cantidad= cantidad + 1}
}
return cantidad;
}
¡Muy bien! Tu solución pasó todas las pruebas
gananciaPromedio([
{ mes: "marzo", ganancia: 8 },
{ mes: "agosto", ganancia: 10 }
])
9
solucion.js:2
if gananciaPromedio = gananciaTotal/sumatoria.ganancia;
^^^^^^^^^^^^^^^^
Con eso en mente, al igual que nosotros podiamos tener una lista de
strings, por ejemplo:
let balancesDeUnPeriodo = [
{ mes: "julio", ganancia: 50 },
{ mes: "agosto", ganancia: 500 },
{ mes: "enero", ganancia: 85 }
]
Fijate que seguimos separando los elementos con comas, pero ahora los
elementos son registros.
longitud([1,2,3])
longitud(balancesDeUnPeriodo)
=> 3
function gananciaPromedio(balancesDeUnPeriodo) {
let sumatoria=0;
{
sumatoria=gananciaTotal(balancesDeUnPeriodo)/
longitud(balancesDeUnPeriodo);
}
return sumatoria;}
SOLUCION CORRECTA
function gananciaPromedio(balancesDeUnPeriodo) {
let sumatoria=0;
{
sumatoria=gananciaTotal(balancesDeUnPeriodo)/
longitud(balancesDeUnPeriodo);
}
return sumatoria;}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
gananciaPromedio
=> <function>
gananciaPromedio([ {mes: "marzo", ganancia: 8}, {mes: "agosto", ganan
cia: 10}])
=> 9
gananciaPromedio([ {mes: "marzo", ganancia: 8}, {mes: "agosto", ganan
cia: 10}])
=> 9
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.
BIBLIOTECA
function cantidadDeBalancesPositivos(balancesDeUnPeriodo){
let cantidad = 0;
for (let balance of balancesDeUnPeriodo) {
if(balance.ganancia > 0){
cantidad= cantidad + 1}
}
return cantidad;
}
SOLUCION MIA CON ERROR
function gananciaPositiva (balancesDeUnPeriodo){
let sumatoria = 0;
for (let balance of balancesDeUnPeriodo) {
if(balance.ganancia > 0){
sumatoria= sumatoria + 1}
}
return sumatoria;
}
function promedioGananciasPositivas (gananciaPositiva){
if gananciaPositiva = cantidadDeBalancesPositivos / sumatoria
}
return gananciaPositiva;
}
Ups! Tu solución no se puede ejecutar
Resultados:
solucion.js:11
if gananciaPositiva = cantidadDeBalancesPositivos / sumatoria
^^^^^^^^^^^^^^^^
}
}
return sumatoria;
}
function promedioGananciasPositivas(balancesDeUnPeriodo){
return
gananciaPositiva(balancesDeUnPeriodo)/cantidadDeBalancesPositivos(balanc
esDeUnPeriodo)
}
Ignacio Z. hace 10 meses
Hola, que tal? Vengo observando las dudas de mis compañeros, que casi
siempre son las mismas que las que tengo yo, afortunadamente, y las
respuestas son muy buenas. Aun asi , estos ultimos ejercicios de este
capitulo me vienen costando mucho y vengo consultando las dudas casi a
diario para poder resolver cada uno, y eso no se si esta muy bueno. En este
caso fui construyendo el codigo a partir de lo que observe sobre las dudas
de mis compañeros, pero aun así, no se me ocurre mas nada para mejorarlo
o arreglarlo y me sigue tirando error. Si alguien me puede dar una mano les
agradeceria mucho. Saludos.
}
function promedioGananciasPositivas(balancesDeUnPeriodo) {
return gananciaPositiva(balancesDeUnPeriodo) /
cantidadDeBalancesPositivos(balancesDeUnPeriodo);
}
¡Muy bien! Tu solución pasó todas las pruebas
function promedio(listaDeNumeros) {
return sumatoria(listaDeNumeros) / longitud(listaDeNumeros);
}
function sumatoria(listaDeNumeros) {
let sumatoria = 0;
for (let numero of listaDeNumeros) {
sumatoria = sumatoria + numero;
}
return sumatoria;
}
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.mes)
}
return ganancias;
}
Tu solución no pasó las pruebas MI ERROR ES QUE PUSE MES EN VEZ DE GANANCIA
Resultados de las pruebas:
function ganancias(balancesDeUnPeriodo) {
let ganancias = [ ];
for (let balance of balancesDeUnPeriodo) {
agregar(ganancias,balance.ganancia)
}
return ganancias; }
SOLUCION CORRECTA
function ganancias(balancesDeUnPeriodo) {
let ganancias = [ ];
for (let balance of balancesDeUnPeriodo) {
agregar(ganancias, balance.ganancia)
}
return ganancias;
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
ganancias([{ mes: "enero", ganancia: 40}, {mes: "febrero", ga
nancia: 12}, {mes: "marzo", ganancia: 8}])
=> [40,12,8]
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.
function balancesPositivos(balancesDeUnPeriodo) {
let balances = [];
for (let balance of balancesDeUnPeriodo) {
if (balance.periodo > 0)
}
return balances;
}
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.js:5
}
^
function balancesPositivos(balancesDeUnPeriodo) {
let balances = [ ];
SOLUCION CORRECTA
function balancesPositivos(balancesDeUnPeriodo) {
let balances = [ ];
agregar(balances, balance);
}
}
return balances;
}
¡Muy bien! Tu solución pasó todas las pruebas
Para poder tener la lista que recibe por parámetro promedio vas a tener que
definir gananciasDeBalancesPositivos. Esta función primero filtra los balances
positivos y luego los mapea a ganancias. Recordá que función hace cada una
de estas cosas.
BIBLIOTECA
function ganancias(balancesDeUnPeriodo) {
let ganancias = [ ];
for (let balance of balancesDeUnPeriodo) {
agregar(ganancias, balance.ganancia)
}
return ganancias;
}
function balancesPositivos(balancesDeUnPeriodo) {
let balances = [ ];
agregar(balances, balance);
}
}
return balances;
}
function promedio(listaDeNumeros) {
return sumatoria(listaDeNumeros) / longitud(listaDeNumeros);
}
function sumatoria(listaDeNumeros) {
let sumatoria = 0;
for (let numero of listaDeNumeros) {
sumatoria = sumatoria + numero;
}
return sumatoria;
}
promedioDeBalancesPositivos debe utilizar promedio
gananciasDeBalancesPositivos debe utilizar ganancias
gananciasDeBalancesPositivos debe utilizar balancesPositivos
La solución parece tener un error de tipeo: debe usar ganancias, pero
usa ganancia. ¿Quizás quisiste decir ganancias?
Detalles
Resultados de las pruebas:
function gananciasDeBalancesPositivos(balancesDeUnPeriodo){
return ganancias( balancesPositivos(balancesDeUnPeriodo));
}
function promedioDeBalancesPositivos(balancesDeUnPeriodo){
let promedio = [ ]
for(let ganancias of gananciaPositivos){
promedio(gananciaPositivos)
}
return ganancias
}
function promedioDeBalancesPositivos(balancesDeUnPeriodo){
return promedio(gananciasDeBalancesPositivos(......));
Respondiendo a tu pregunta:
Si, en promedioDeBalancesPositivos al pasarle por parámetro a balancesDeUnPeriodo
estaríamos pasando una lista que no esta afectada por la función que
creamos anteriormente, pero no hay problema ya que dentro de
promedioDeBalancesPositivos vamos a utilizar nuestra nueva función
gananciasDeBalancesPositivos la cual va a modificar a balancesDeUnPeriodo y nos va
a devolver la ganancia de los balances positivos. Y luego utilizamos a
promedio para devolver el promedio de ganancia de los balances positivos.
Por ejemplo:
SOLUCION CORRECTA
function gananciasDeBalancesPositivos(balancesDeUnPeriodo)
{
return ganancias(balancesPositivos(balancesDeUnPeriodo));
}
function promedioDeBalancesPositivos(balancesDeUnPeriodo){
return promedio(gananciasDeBalancesPositivos(balancesDeUnPeriodo));
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
promedio([ {mes: "enero", ganancia: 40}, {mes: "febrero", ganancia: 12
}, {mes: "marzo", ganancia: 8}])
=> null ESTO ESTA MAL
VA ESTO EN LA CONSOLA
promedioDeBalancesPositivos([ {mes: "enero", ganancia: 40}, {mes: "fe
brero", ganancia: 12}, {mes: "marzo", ganancia: 8}])
=> 20
maximaGanancia debe utilizar maximo
maximaGanancia no debe usar foreach
[ 0, -13, -19, -5 ] == 0
me arroja que no debo usar el FOR pero no le veo otra amnera de realizarlo.
maximaGanancia no debe usar foreach .
dice que funcionó, pero no comprendo la manera correcta de realizarlo.
alguna ayuda.
Estamos creando una lista con las ganancias, ¿no teníamos una función que
hacía esto? ¡Claro! ganancias, esta función si le dabamos una lista de balances,
nos retornaba una lista de números que representan las ganancias:
ganancias([{mes: "abril", ganancia: 50}, {mes: "octubre", ganancia: 700}])
=> [50,700]
SOLUCION CORRECTA
function maximaGanancia(balancesDeUnPeriodo){
return maximo(ganancias(balancesDeUnPeriodo))
CONSOLA
maximaGanancia([ {mes: "enero", ganancia: 87}, {mes: "febrero", ganan
cia: 12}, {mes: "marzo", ganancia: 95}])
=> 95
Si hay una función para calcular el máximo de una lista también hay una para
calcular el mínimo. ¿Te imaginás como se llama?
Ejercicio 12: Como mínimo
Suponemos que adivinaste el nombre. En caso que no, es minimo.
minimaGananciaPositiva([
{ mes: "enero", ganancia: -40 },
{ mes: "febrero", ganancia: 42 },
{ mes: "marzo", ganancia: 8},
{ mes: "abril", ganancia: -5}
])
8
BIBLIOTECA
function ganancias(balancesDeUnPeriodo) {
let ganancias = [];
for (let balance of balancesDeUnPeriodo) {
agregar(ganancias, balance.ganancia)
}
return ganancias;
}
function balancesPositivos(balancesDeUnPeriodo) {
let balances = [];
agregar(balances, balance);
}
}
return balances;
}
function gananciasDeBalancesPositivos(balancesDeUnPeriodo)
{
return ganancias(balancesPositivos(balancesDeUnPeriodo));
}
function promedioDeBalancesPositivos(balancesDeUnPeriodo){
return promedio(gananciasDeBalancesPositivos(balancesDeUnPeriodo));
}
function minimaGananciaPositiva(balancesPositivos ){
return minimo(ganancias(balancesPositivos));
}
function minimaGananciaPositiva(balancesDeUnPeriodo){
return minimo(gananciasDeBalancesPositivos(balancesDeUnPeriodo));
}
Tu solución no pasó las pruebas
Resultados de las pruebas:
SOLUCION CORRECTA
function minimaGananciaPositiva(balancesDeUnPeriodo){
return minimo(gananciasDeBalancesPositivos(balancesDeUnPeriodo));
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
minimaGananciaPositiva([ {mes: "enero", ganancia: -40}, {mes: "febrer
o", ganancia: 42}, {mes: "marzo", ganancia: 8}, {mes: "abril", gananci
a: 3}])
=> 3
Muy bien! Solo queda un ejercicio por delante.
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"]
Para poder tener la lista que recibe por parámetro promedio vas a tener que
definir gananciasDeBalancesPositivos. Esta función primero filtra los balances
positivos y luego los mapea a ganancias. Recordá que función hace cada una
de estas cosas.
function gananciasDeBalancesPositivos(balancesDeUnPeriodo)
{
return ganancias(balancesPositivos(balancesDeUnPeriodo));
}
function promedioDeBalancesPositivos(balancesDeUnPeriodo){
return promedio(gananciasDeBalancesPositivos(balancesDeUnPeriodo));
}
}
function afortunados ()
function mesesAfortunados()
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.js:7
function mesesAfortunados()
^^^^^^^^
function meses(balancesDeUnPeriodo) {
let meses = [];
for(let balance of balancesDeUnPeriodo) {
agregar(meses, balance.mes);
}
return meses;
}
function afortunados(balancesDeUnPeriodo) {
let afortunados = [];
for(let balance of balancesDeUnPeriodo) {
if (balance.ganancia > 1000) {
afortunados = afortunados + balance.ganancia;
}
}
return afortunados;
}
function mesesAfortunados(balanceDeUnPeriodo) {
return meses(afortunados(balanceDeUnPeriodo));
}
function afortunados(balancesDeUnPeriodo) {
let afortunados = [];
for(let balance of balancesDeUnPeriodo) {
if (balance.ganancia > 1000) {
afortunados = afortunados + balance.ganancia;
SOLUCION CORRECTA
function meses(balancesDeUnPeriodo){
let meses= [];
for (let balance of balancesDeUnPeriodo){
agregar (meses,balance.mes);
}
return meses;
}
function afortunados(balancesDeUnPeriodo){
let afortunados = [];
for (let balance of balancesDeUnPeriodo){
if (balance.ganancia>1000){
agregar (afortunados,balance);
}
}
return afortunados;
}
function mesesAfortunados(balancesDeUnPeriodo){
return meses(afortunados(balancesDeUnPeriodo));
}
¡Muy bien! Tu solución pasó todas las pruebas
CONSOLA
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"]
¡Terminaste Recorridos!
En esta última lección te reencontraste con el for...of y resolviste problemas
más complejos con él . Más especificamente creaste funciones para filtrar y/o
transformar los elementos de una lista.
Lecciones
1. Objetos y mensajes
3. Polimorfismo y encapsulamiento
4. Referencias
1. Variables
2. Las variables son referencias
3. Referencias implícitas
4. Múltiples referencias
5. Identidad, revisada
6. Equivalencia
7. Objetos bien conocidos
8. Atributos y parámetros
9. Lo 100to
10. Objetos compartidos
11. Para cerrar
5. Colecciones
6. Clases e Instancias
7. Herencia
8. Excepciones
Apéndice
¿Querés saber más? Consultá el apéndice de este capítulo
Ejercicio 1: Fijando nuestro objetivo
Anteriormente hablamos de los paradigmas de programación. En este
capítulo vamos a ver otra forma de pensar el mundo de la programación.
En este video te contamos qué son esos famosos objetos y cómo interactúan
entre sí.
Pepita, además de ser un ave que come y vuela (como todo pájaro), es un
objeto, que vive en el mundo de los objetos, al cual conocemos
como ambiente.
La consola es el recuadro que tenés a la derecha del texto, y sirve para hacer
pruebas rápidas.
Pepita
=> Pepita
Pepita
Norita
87
'hola mundo'
true
Pepita == Norita
¡Intentalo por tu propia cuenta! Ejecutá las siguientes pruebas en la consola:
Pepita == Norita
Norita == Pepita
Norita == Norita
"hola" == "chau"
CONSOLA
Pepita == Norita
=> false
Norita == Pepita
=> false
Norita == Norita
=> true
"hola" == "chau"
=> false
Pero esto no parece ser muy útil. ¿Qué cosas sabrá hacer una golondrina
como Pepita? ¿Sabrá, por ejemplo, cantar!?
Pepita.cantar!
CONSOLA
Pepita.cantar!
=> "pri pri pri"
Pepita.bailar!
Ejercicio 7: No entendí...
¡Buu, Pepita no sabía bailar!
Descubramos qué otras cosas sabe hacer Pepita. Probá enviarle los siguientes
mensajes y fijate cuáles entiende y cuales no ¡y anotalos! Este conocimiento
nos servirá en breve.
Pepita.comer_lombriz!
=> nil
Pepita.volar_en_circulos!
=> nil
Pepita.se_la_banca?
undefined method `se_la_banca?' for Pepita:Module (NoMethodError)
Es importante respetar la sintaxis del envío de mensajes. Por ejemplo, las
siguientes NO son colaboraciones validas, porque no funcionan o no hacen
lo que deben:
CONSOLA
energia
Pepita energia
Pepita..energia
volar( )
volar.pepita( )
pepita volar( )
pepita.volar
Ejercicio 9: Interfaz
Como vimos, un objeto puede entender múltiples mensajes; a este conjunto
de mensajes que podemos enviarle lo denominamos interfaz. Por ejemplo,
la interfaz de Pepita es:
CONSOLA
Pepita.energia
=> 100
Pepita.cantar!
=> "pri pri pri"
Pepita.comer_lombriz!
=> nil
Pepita.volar_en_circulos!
=> nil
Pepita.energia
energia
SOLUCION CORRECTA
1. Pepita.comer_lombriz!
2. Pepita.volar_en_circulos!
3. Pepita.comer_lombriz!
4. Pepita.volar_en_circulos!
5. Pepita.comer_lombriz!
6. Pepita.volar_en_circulos!
7. Pepita.comer_lombriz!
¡Muy bien! Tu solución pasó todas las pruebas
interfaz_norita = %w(
#...completar acá...
)
interfaz_mercedes = %w(
#...completar acá... )
SOLUCION MIA MAL
interfaz_pepita = %w(
energia
cantar!
comer_lombriz!
volar_en_circulos!
)
interfaz_norita = %w(
#...completar acá...cantar!
)
interfaz_mercedes = %w(
#...completar acá...cantar!
comer_lombriz!
volar_en_circulos!
)
¡Buen día, Julieta! En >_Consola la idea es que probemos enviarles los mensajes que
entiende Pepita a Norita y Mercedes, sabemos que los mensajes que entiende Pepita son
los que menciona su interfaz, es decir energia, cantar!, comer_lombriz! y
volar_en_circulos!, entonces son estos los que tendremos que probar, por ejemplo:
Lo mismo tendrías que probar con el resto de mensajes, es decir enviando Norita.mensaje
y Mercedes.mensaje.
interfaz_norita = %w(
cantar!
comer_lombriz!
volar_en_circulos!
)
interfaz_mercedes = %w(
cantar!
)
¡Muy bien! Tu solución pasó todas las pruebas
¡Así es! Puede haber más de un objeto que entienda el mismo mensaje. Notá que sin
embargo no todos los objetos están obligados a reaccionar de igual forma ante el mismo
mensaje:
Pepita.cantar!
=> "pri pri pri"
Norita.cantar!
=> "priiiip priiiip"
Mercedes.cantar!
=> "♪ una voz antigua de viento y de sal ♫"
Esto significa que dos o más objetos pueden entender un mismo mensaje, pero pueden
comportarse de formas diferentes. Ya hablaremos más de esto en próximas lecciones.
CONSOLA
Pepita.cantar!
=> "pri pri pri"
Norita.cantar!
=> "priiiip priiiip"
Mercedes.cantar!
=> "♪ una voz antigua de viento y de sal ♫"
Esto significa que comparten algunos mensajes y otros no. ¿Qué interfaces comparten entre
ellas?
Completá el código en el editor.
Recordá que la interfaz es el conjunto de mensajes que un objeto entiende. Por lo tanto, si
queremos ver cual interfaz comparten dos objetos, tenemos que pensar en la intersección
entre los conjuntos de mensajes de cada uno (es decir, aquellos que son iguales).
SOLUCION CORRECTA
# ¿Qué interfaz comparten Mercedes y Norita?
interfaz_compartida_entre_mercedes_y_norita = %w(
cantar!
)
# ¿Qué interfaz comparten Pepita y Norita?
interfaz_compartida_entre_pepita_y_norita = %w(
cantar!
comer_lombriz!
volar_en_circulos!
)
# ¿Qué interfaz comparten Mercedes, Norita y Pepita?
interfaz_compartida_entre_todas = %w(
cantar!
)
SOLUCION CORRECTA
Pepita.comer_alpiste! (500)
Pepita.volar_hacia!(Iruya)
Pepita.volar_hacia!(Obera)
Solución no valida
pepita.volarHacia(buenosAires)
pepita.comerAlpiste(500/10)
Tu solución no pasó las pruebas
Resultados de las pruebas:
pepita con energia inicial 10000 Ver detalles
pepita con energia inicial 1000 Ver detalles
pepita con energia inicial 560 Ver detalles
https://mumuki.io/wollok/chapters/31-programacion-con-
objetos
BIBLIOTECA
/**/
function longitud(unString) /* ... */
// Retorna cuan largo es un string
//
// Por ejemplo:
// longitud("hola")
// 4
function convertirEnMayuscula(unString) /* ... */
// Convierte una palabra en mayúsculas
//
// Por ejemplo:
// convertirEnMayuscula("hola")
// "HOLA"
function comienzaCon(unString, otroString) /* ... */
// Retorna un booleano que nos dice si unString empieza con otroString
//
// Por ejemplo:
// comienzaCon("hola todo el mundo", "hola todo")
// true
/**/
function imprimir(unString) /* ... */
// Imprime por pantalla unString
// Por ejemplo:
// imprimir("¡estoy imprimiendo!")
// ¡estoy imprimiendo!
function tirarDado( ) /* ... */
// Retorna un número al azar entre 1 y 6
//
// Por ejemplo:
// tirarDado()
// 5
// tirarDado()
// 1
// tirarDado()
// 2
function listasIguales(unArray, otroArray) /* ... */
// Retorna un booleano que nos dice si dos listas son iguales
//
// Por ejemplo:
// listasIguales([1, 2, 3], [1, 2, 3])
// true
// listasIguales([1, 2, 3], [4, 5, 3])
// false
function longitud(unStringOLista) /* ... */
// Retorna el largo de un string o una lista
//
// Por ejemplo:
// longitud("hola")
// 4
// longitud([5, 6, 3])
// 3
function agregar(unaLista, unElemento) /* ... */
// Inserta unElemento al final de unaLista.
// Este es un procedimiento que no retorna nada pero modifica a unaLista:
//
// let cancionesFavoritas = ["La colina de la vida", "Zamba por vos"]
// agregar(cancionesFavoritas, "Seminare")
// cancionesFavoritas
// ["La colina de la vida", "Zamba por vos", "Seminare"]
function remover(unaLista) /* ... */
// Quita el último elemento de unaLista y lo retorna.
//
// let listaDeCompras = ["leche", "pan", "arroz", "aceite", "yerba"]
// remover(listaDeCompras)
// "yerba"
// listaDeCompras
// ["leche", "pan", "arroz", "aceite"]
function posicion(unaLista, unElemento) /* ... */
// Retorna la posición se encuentra un elemento.
// Si el elemento no está en la lista, retorna -1
//
// let premios = ["dani", "agus", "juli", "fran"]
// posicion(premios, "dani")
// 0
// posicion(premios, "juli")
// 2
// posicion(premios, "feli")
// -1
let unaListaVacia = [ ];
Pero aún queda mucho más por aprender. ¡Te esperamos en la próxima lección!
Ya aprendiste que en un ambiente hay objetos que hacen cosas, y que nos comunicamos
con ellos mediante el envío de mensajes.
En la lección anterior, creamos por vos todos los objetos. Peeeero esto no siempre será así:
en general, programar con objetos se trata también de crearlos (es decir, traerlos al mundo)
y decirles cómo se deben comportar.
Ejercicios
1. Creando a Pepita
2. Pepita, ¿me entendés?
3. Los mejores, los únicos, los métodos en objetos
4. Perdiendo energía
5. Atributos
6. Conociendo el país
7. Leyendo el estado
8. Cuestión de estado
9. ¿Dónde estás?
10. Volando alto
11. Delegar es bueno
12. ¿Es mi responsabilidad?
SOLUCION
module Pepita
end
CONSOLA
=> Pepita
Pepita.energia
undefined method `energia' for Pepita:Module (NoMethodError)
Pepita.energia!
undefined method `energia!' for Pepita:Module (NoMethodError)
Un método es, entonces, la descripción de qué hacer cuando se recibe un mensaje del
mismo nombre.
Dos cosas muy importantes a tener en cuenta :
Todos los métodos comienzan con def y terminan con end. Si nos falta alguna de
estos dos la computadora no va a entender nuestra solución.
Todos los métodos que pertenezcan al mismo objeto van dentro del mismo
module.
Agregale a la definición de Pepita los métodos necesarios para que pueda responder a los
mensajes cantar!, comer_lombriz! y volar_en_circulos!.
¡Dame una pista!
No te olvides de que el ! forma parte del nombre del mensaje y por lo tanto tenés que
escribirlo.
Recordá también que podés usar la consola para ir probando tu solución.
end
module Pepita
def self.volar_en_circulos!
end
end
module Pepita 2
def self.comer_lombriz!
end
end
Cristian Gabriel R. hace alrededor de 2 meses
hola hice esto y me dice que falta nombrar solo una vez el modulo pepita como hago eso?
Ignacio L. hace alrededor de 1 mes
Hola Cristian!
Lo que significa es que no tenes que escribir 'module Pepita' más de una vez, tenés que
encerrar todo lo que hace Pepita dentro de ese módulo y darle final con la palabra 'end'.
Ojalá te sirva! Saludos!
Cristian Gabriel R. hace alrededor de 1 mes
como lo encierro me re perdi ya osea adelante lo que mas pude ya que a mi la vacante me
llego nueve dias mas tarde desde que arranco el programa
Ignacio L. hace alrededor de 1 mes
Con encerrar me refiero a que todo lo que hace y recibe Pepita tiene que estar entre
'module Pepita' y su correspondiente 'end'
No es necesario volver a abrir otro modulo.
David Ignacio D. Mentoría hace alrededor de 1 mes
¡Hola Cristian! ¿Cómo va? Tal y como te expresó Ignacio y repasando el segundo ítem de
la consigna, "todos los métodos que pertenezcan al mismo objeto van dentro del mismo
module", cumpliendo con la siguiente estructura para cada objeto:
module ObjetoPrueba
def self.metodo_1
...
end
def self.metodo_2
...
end
end
Diana L. Mentoría hace 10 meses
¡Hola Maria!
Como dice Felipe, solamente tenemos que declarar a Pepita una sola vez, te dejo un
ejemplo de la sintaxis que usamos a modo de orientación:
module Objeto
def self.metodo1
...
end
def self.metodo2
...
end
def self.metodo3
...
end
end
Fijate que solamente declaré una vez el Objeto, y dentro puse todos los métodos.
SOLUCION CORRECTA
module Pepita
def self.cantar!
end
def self.volar_en_circulos!
end
def self.comer_lombriz!
end
end
def self.volar_en_circulos!
@energia = @energia - 10
end
end
Una vez más, ya definimos a Pepita por vos. Probá, en orden, las siguientes consultas:
Pepita.volar_en_circulos!
Pepita.volar_en_circulos!
Pepita.energia
Puede que los resultados te sorprendan, en breve hablaremos de esto.
CONSOLA
Pepita.volar_en_circulos!
=> 90
Pepita.volar_en_circulos!
=> 80
Pepita.energia
undefined method `energia' for Pepita:Module (NoMethodError)
Ejercicio 5: Atributos
Analicemos el código que acabamos de escribir:
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia = @energia - 10
end
end
Decimos que Pepita conoce o tiene un nivel de energía, que es variable, e inicialmente
toma el valor 100. La energía es un atributo de nuestro objeto, y la forma de asignarle un
valor es escribiendo @energia = 100.
Por otro lado, cuando Pepita recibe el mensaje volar_en_circulos!, su energía disminuye:
se realiza una nueva asignación del atributo y pasa a valer lo que valía antes (o sea,
@energia), menos 10.
Como la operación @energia = @energia - 10 es tan común, se puede escribir @energia -=
10. Como te imaginarás, también se puede hacer con la suma.
Sabiendo esto:
cambiá la definición del método volar_en_circulos! para que utilice la
expresión simplificada;
definí la versión correcta del método comer_lombriz!, que provoca que
Pepita gane 20 puntos de energía;
SOLUCION PARA MODIFICAR
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia = @energia - 10
end
reemplazar ………..
end
end
SOLUCION CORRECTA
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia = @energia - 10
end
def self.volar_en_circulos!
@energia -= 10
end
end
module Pepita
def self.comer_lombriz!
@energia += 20
end
end
¡Muy bien! Tu solución pasó todas las pruebas
Acabamos de aprender un nuevo elemento del paradigma de objetos: los atributos (los
cuales escribiremos anteponiendo @), son objetos que nos permiten representar una
característica de otro objeto. Un objeto conoce a todos sus atributos por lo que puede
enviarles mensajes, tal como hicimos con @energia.
Entonces, si le pude enviar mensajes a @energia, ¿eso significa que los números también
son objetos?
¡Claro que sí! ¡Todo-todo-todo es un objeto!
Ejercicio 6: Conociendo el país
Hasta ahora los métodos que vimos solo producían un efecto. Si bien solo pueden
devolver una cosa, ¡pueden producir varios efectos!
Solo tenés que poner uno debajo del otro de la siguiente forma:
def self.comprar_libro!
@plata -= 300
@libros += 1
end
Como te dijimos, Pepita podía volar a diferentes ciudades. Y cuando lo hace, cambia su
ciudad actual, además de perder 100 unidades de energía. Las distintas ciudades vas a
poder verlas en la Biblioteca.
Con esto en mente:
Creá un atributo ciudad en Pepita: la ciudad donde actualmente está nuestra
golondrina.
Hacé que la ciudad inicial de pepita sea Iruya.
Definí un método volar_hacia! en Pepita, que tome como argumento otra ciudad y
haga lo necesario.
¡Dame una pista!
Al parámetro de volar_hacia! tenés que darle un nombre. Podrías llamarlo ciudad, pero
eso colisionaría con el nombre del atributo ciudad. Así que te proponemos otros nombres:
una_ciudad o, mejor, destino;
SOLUCION INICIAL A MODIFICAR
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia = @energia - 10
end
def self.volar_en_circulos!
@energia -= 10
end
end
module Pepita
def self.comer_lombriz!
@energia += 20
end
end
SOLUCION MIA MAL
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia = @energia - 10
end
def self.volar.hacia!
@ciudad = Iruya
def self.volar_en_circulos!
@energia -= 10
end
end
module Pepita
def self.comer_lombriz!
@energia += 20
end
end
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.rb:7: syntax error, unexpected '.', expecting ';' or '\n' (SyntaxError)
def self.volar.hacia!
^
SOLUCION DE LA CONSULTA A CORREGIR
module Pepita
@energia = 100
@ciudad = Iruya
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_hacia!(destino)
@energia -= 100
@ciudad = @destino
end
end
Mauro M. hace 11 meses
hola, no entiendo muy bien si la forma de definir el parametro es la correcta, o que esta
haciendo que el ejercicio no este bien.
Adelqui M. hace 11 meses
Hola! El parametro destino no lleva @ al usarse para asignarlo a @ciudad. Solo debes
quitarle el @ para que quede asi: @ciudad = destino
Diana L. Mentoría hace 11 meses
¡Hola Mauro!
En la línea 14 al usar el parámetro, lo hacemos sin el @, ya que la arroba la usamos con
nuestros atributos, no con los parámetros. Probá usar solamente destino.
BIBLIOTECA
module Iruya
end
module Obera
end
module GralLasHeras
end
module Calamuchita
end
module Ushuaia
end
SOLUCION CORRECTA
module Pepita
@energia = 100
@ciudad = Iruya
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_hacia!(destino)
@energia -= 100
@ciudad = destino
end
end
def energia
@energia
end
end
Ya agregamos el método energia por vos. Probá en la consola ahora las siguientes
consultas:
Pepita.energia
Pepita.energia = 120
energia
#...etc...
end
Lo que podemos observar es que su estado está conformado por ciudad y energia, dado
que son sus atributos.
El estado es siempre privado, es decir, solo el objeto puede utilizar sus atributos, lo que
explica por qué las siguiente consultas que hicimos antes fallaban:
Pepita.energia = 100
energia
Veamos si se entiende: mirá los objetos en la solapa Biblioteca y escribí el estado de cada
uno.
BIBLIOTECA
module Obera
#...más cosas que ahora no interesan...
end
module Pepita
@energia = 100
@ciudad = Obera
module Kiano1100
#...más cosas que ahora no interesan...
end
module RolamotoC115
#...más cosas que ahora no interesan...
end
module Enrique
@celular = Kiano1100
@dinero_en_billetera = 13
@frase_favorita = 'la juventud está perdida'
end
SOLUCION MIA CON ERROR
estado_pepita = %w(
energia = 100
ciudad = Obera
)
end
estado_kiano1100 = %w(
#... más cosas que ahora no interesan...
)
end
estado_rolamotoC115 = %w(
#...más cosas que ahora no interesan...
)
end
estado_enrique = %w(
@celular = Kiano1100
@dinero_en_billetera = 13
@frase_favorita = 'la juventud está perdida'
)
end
end
estado_kiano1100 =
#... más cosas que ahora no interesan...
estado_rolamotoC115 =
#...más cosas que ahora no interesan...
estado_enrique =
@celular = Kiano1100 EL ERROR ES QUE CELULAR NO LLEVA NADA
@dinero_en_billetera = 13 BILLETERA TAMPOCO
@frase_favorita = 'la juventud está perdida' Y FRASE FAVORITA TAMPOCO LLEVA NADA
Tu solución no pasó las pruebas
Resultados de las pruebas:
Estado de Pepita
Estado de Kiano1100
Estado de RolamotoC115
Estado de Enrique Ver detalles
expected collection contained: ["celular", "dinero_en_billetera", "frase_favorita"]
actual collection contained: ["'la", "13", "=", "=", "=", "@celular",
"@dinero_en_billetera", "@frase_favorita", "Kiano1100", "está", "juventud",
"perdida'"]
the missing elements were: ["celular", "dinero_en_billetera", "frase_favorita"]
the extra elements were: ["'la", "13", "=", "=", "=", "@celular",
"@dinero_en_billetera", "@frase_favorita", "Kiano1100", "está", "juventud",
"perdida'"]
belen C. hace 10 meses
si soloelestado se define con el atritus o ea @loque sea,no entiendo porque me da
error enrique
Daniela M. Mentoría hace 10 meses
¡Hola Belen! ¿Como andas? En si lo que tenes que escribir aca son todos aquellos
estados que utiliza. Si bien coincide con los atributos, se usa el @ solo para
definirlos dentro del objeto o clase demostrando que ahi se almacena algo, mientras
que en estos tipos de ejercicio se busca que se diga que es lo que entiende. Mas que
nada el error te dan por los @.
belen C. hace 10 meses
SE EL ERROR DEL EJERCICIO , pero antes de corregirlo entonces,para definir un
objeto utilizo un @" lo que sea" , pero no se usa el@ dentro de un estado?? por lo
que entendi un estado es un conjuntto de aributos y justamente los atributos vienen
definidos con el @.. parece una tontera lo que pregunto pero estoy tratando de
comprender esto del estado, para que no me haga una mezcla de conceptos
Guillermo Ignacio B. Mentoría hace 10 meses
¡Hola Belén! Claro, dentro del estado solo tiene que ir el nombre del atributo, pero
cuando se define o se usa/modifica si lleva el @.
estado_kiano1100 = %w(
estado_rolamotoC115 = %w(
estado_enrique = %w(
celular
dinero_en_billetera
frase_favorita
)
¡Muy bien! Tu solución pasó todas las pruebas
def self.energia
@energia
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= 100
@ciudad = destino
end
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
Pepita entiende el mensaje ciudad Ver detalles
expected Pepita to respond to :ciudad
Pepita comienza en Oberá Ver detalles
undefined method `ciudad' for Pepita:Module
SOLUCION DE LA CONSULTA CON ERROR
module Pepita
@energia = 100
@ciudad = Obera
def self.ciudad
@Obera
end
def self.energia
@energia
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= 100
@ciudad = destino
end
end
Cristian T. hace 2 días
Hola que tal, se cual es el error, de hecho le agregue el arroba a propósito para poder
hacer una consulta. por que en la definición de energía utilizamos el @ para saber el
estado, pero en ciudad no colocamos el @ para saber el estado de ciudad?...
Candela S. Mentoría hace 2 días
¡Buenos días, Cristian! El método ciudad debería funcionar de la misma forma en la que
funciona energia ya que va a ser un getter es decir, un método que retorna el valor de un
atributo. Utilizamos el @ para los atributos, como en el getter vamos a querer retornar el
valor del atributo lo vamos a escribir siempre con @. El detalle es que en lugar de definir
el método ciudad para que retorne siempre Obera debemos definirlo para que retorne el
valor que tenga el atributo @ciudad. Esto es así porque la ciudad no siempre va a ser
Obera ya que por ejemplo si hacemos que Pepita vuele hacia otra ciudad el método
ciudad debería retornar esta nueva ciudad y no Obera.
SOLUCION CORRECTA
module Pepita
@energia = 100
@ciudad = Obera
def self.ciudad
@ciudad
end
def self.energia
@energia
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= 100
@ciudad = destino
end
end
¡Muy bien! Tu solución pasó todas las pruebas
A estos métodos que sirven para conocer el valor de un atributo los llamamos métodos de
acceso o simplemente accessors, por su nombre en inglés.
Por ejemplo, si Pepita está en Obera y quiere volar a Iruya debe recorrer 670 kilómetros,
por lo que perderá 335 unidades de energía.
¿Y si Pepita está en Iruya y quiere volar a Obera? ¡También! La distancia entre dos
ciudades siempre es un valor positivo . Para resolver esto contamos con el mensaje abs
que entienden los números y nos retorna su valor absoluto:
17.abs
=> 17
(-17).abs
=> 17
(1710 - 1040).abs
=> 670
(1040 - 1710).abs
=> 670
(1040 - 1710).abs / 2
=> 335
Sabiendo esto:
Definí el objeto que representa a BuenosAires.
Definí en Obera, Iruya y BuenosAires un método kilometro que retorne la
altura a la que se encuentran, según el esquema. ¡Cuidado! No tenés que
guardar el valor en un atributo @kilometro sino simplemente retornar el
número que corresponde.
Modificá el método volar_hacia! de Pepita para hacer el cálculo de la
distancia y alterar su energía. Para acceder al kilometro inicial de Pepita
tenes que hacer @ciudad.kilometro.
Para que el ejemplo tenga sentido, vamos a hacer que Pepita arranque con la energía en
1000. ¡Dame una pista!
Tené en cuenta que el ejemplo que vimos nos muestra el cálculo de la distancia entre
Obera e Iruya. Sin embargo, Pepita tiene que poder volar desde su ciudad hasta cualquier
destino.
module Obera
def self.kilometro
# completar acá...
end
end
module Iruya
def self.kilometro
# completar acá...
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= # completar acá...
@ciudad = destino
end
end
module Iruya
def self.kilometro
1710
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= 335
@ciudad = destino
end
end
module Iruya
def self.kilometro
1710
end
end
module BuenosAires
def self.kilometro
0
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= (@ciudad.kilometro.abs - destino.kilometro.abs) / 2
@ciudad = destino
end
end
SOLUCION CORRECTA
module Obera
def self.kilometro
1040
end
end
module Iruya
def self.kilometro
1710
end
end
module BuenosAires
def self.kilometro
0
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@energia -= (@ciudad.kilometro-destino.kilometro).abs/2
@ciudad = destino
end end
def self.volar_hacia!(destino)
@energia -= (@ciudad.kilometro - destino.kilometro).abs / 2
@ciudad = destino
end
end
Esto se conoce como delegar una responsabilidad, o simplemente, delegar: la
responsabilidad de saber en qué kilómetro se encuentra es de la ciudad, y no de Pepita.
A veces nos va a pasar que un objeto tiene un método muy complejo, y nos gustaría
subdividirlo en problemas más chicos que el mismo objeto puede resolver. Pero, ¿cómo
se envía un objeto mensajes a sí mismo?
Un objeto puede enviarse un mensaje a sí mismo fácilmente usando self como receptor
del mensaje.
module Pepita
# ...etc...
def self.volar_hacia!(destino)
self.gastar_energia! destino #¡Ojo! No hicimos Pepita.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= (@ciudad.kilometro - destino.kilometro).abs / 2
end
end
Pero esto se puede mejorar un poco más. Delegá el cálculo de la distancia en un método
distancia_a, que tome un destino y devuelva la distancia desde la ciudad actual hasta el
destino.
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= (@ciudad.kilometro - destino.kilometro).abs / 2
end
end
BIBLIOTECA
module Obera
def self.kilometro
1040
end
end
module Iruya
def self.kilometro
1710
end
end
module BuenosAires
def self.kilometro
0
end
end
SOLUCION MIA CON ERROR
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.distancia_a(destino) / 2
end
def self.distancia_a(destino)
(@ciudad.kilometro - destino.kilometro).abs
end end
def self.volar_hacia!(destino)
self.distancia_a(destino) (esto es lo que esta mal)
@ciudad = destino
end
def self.distancia_a(destino)
@energia -= (@ciudad.kilometro - destino.kilometro).abs / 2
end
end
Tu solución no pasó las pruebas
Ver detalles Objetivos que no se cumplieron:
gastar_energia! debe utilizar distancia_a
distancia_a no debe realizar asignaciones
Eh, ¿qué pasó acá ?
distancia_a debe retornar la distancia entre la ciudad de Pepita y su destino, no debe
guardar ese valor en una variable.
Pero a no desesperar, intentemos otra vez
Resultados de las pruebas:
Pepita entiende gastar_energia! Ver detalles
expected Pepita to respond to :gastar_energia!
Pepita entiende distancia_a
Pepita puede calcular la distancia hasta Iruya, estando en Oberá Ver detalles
Pepita no pierde energía si está en Oberá y vuela a Oberá
Pepita pierde 520 unidades de energía si está en Buenos Aires y vuela a Oberá
Pepita pierde 520 unidades de energía si está en Oberá y vuela a Buenos Aires
Pepita pierde 335 unidades de energía si está en Iruya y vuela a Oberá
Pepita cambia de ciudad cuando vuela
Nahuel Alejandro S. hace 10 meses
hola 👋 al principio no entendia el enunciado, pero viendo las demás consultas creo que lo
entendi, pero el codigo no cumple con las consignas, me podrian ayudar? gracias!
Guillermo Ignacio B. Mentoría hace 10 meses
¡Hola Nahuel! El código está casi bien, pero hay una cosa que hay que modificar, y una
además te quiero dar una sugerencia al respecto. En primer el lugar, la causa del error
está en que en la línea 31 estás usando el método distancia_a el cual requiere un
argumento, pero no le estás pasando ninguno. En este caso el argumento debería ser
destino. En este mismo método fijate que estás usando distancia_a sin aclarar a quién
pertenece, pero como está dentro del módulo Pepita ejecuta el método que está en este
módulo, sin embargo sería conveniente hacer esta aclaración, ya que puede ocurrir que se
utilicen métodos de otros módulos (como cuando hacés @ciudad.kilometro). En este caso
como el método es del mismo módulo deberías usar self, por lo que te debeía quedar:
@energia -= self.distancia_a(destino) / 2. Corrigiendo esto el programa debería funcionar
bien.
SOLUCION CORRECTA
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.distancia_a(destino) / 2
end
def self.distancia_a(destino)
(@ciudad.kilometro - destino.kilometro).abs
end
end
¡Muy bien! Tu solución pasó todas las pruebas
La delegación es la forma que tenemos en objetos de dividir en subtareas: separar un
problema grande en problemas más chicos para que nos resulte más sencillo resolverlo.
A diferencia de lenguajes sin objetos, aquí debemos pensar dos cosas:
1. cómo dividir la subtarea, lo cual nos llevará a delegar ese comportamiento en
varios métodos;
2. qué objeto tendrá la responsabilidad de resolver esa tarea.
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(@ciudad.kilometro - destino.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(@ciudad.kilometro - destino.kilometro).abs
end
end
module BuenosAires
def self.kilometro
end
def self.distancia_a(destino)
(@ciudad.kilometro - destino.kilometro).abs
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.distancia_a(destino) / 2
end
end
Podemos hacer que sea Pepita quien tenga este metodo. También recordá que cada vez que
hacemos self.algo ese algo tiene que ser un metodo de ese self, es decir de ese objeto donde
estemos declarando el otro metodo. Asi que en vez de poner @energia -=
self.distancia_a(destino)/2 (ya que Pepita no sabe de distancias, pero si sabe de ciudades, y
las ciudades, si saben de distancia ) podemos hacer algo asi como
self.ciudad.distancia_a(destino). Espero haber ayudado, pero si no quedó muy claro, no
dudes en volver a consultar las veces que lo necesites. ¡Suerte!
Jose Ignacio Federico A. hace 11 meses
Buenas el codigo final te deberia quedar asi
vanesa monica B. hace 11 meses
Entiendo que pepita no comprende distancia pero si ciudades lo que quiza no comprendo es
por que no me toma la distancia
module Obera
def self.kilometro 1040 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs
end def self.gastar_energia!(destino) @energia -= self.distancia_a(destino) / 2 end end
module Iruya def self.kilometro 1710 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
end
module BuenosAires def self.kilometro 0 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
def self.gastar_energia!(destino) @energia -= self.distancia_a(destino) / 2 end end
module Pepita @energia = 1000 @ciudad = Obera
def self.energia @energia end
def self.ciudad @ciudad end
def self.cantar! 'pri pri pri' end
def self.comer_lombriz! @energia += 20 end
def self.volar_en_circulos! @energia -= 10 end
def self.volar_hacia!(destino) self.gastar_energia!(destino) @ciudad = destino end def
self.gastar_energia!(destino) @self.ciudad.distancia_a(destino).abs end end
Mayra M. hace 11 meses
¡Hola Vanesa! buenas noches. Lo que está pasando es que en gastar_energia de Pepita no
le estás restando la energia, deberia ser algo como volar_en_circulos! que haces @energia
-=. Por otro lado las ciudades no deberian entender gastar_energia! sino solo Pepita que
es quien vuela y gasta energia (cuidado acá en el el gastar_energia! de Pepita falta el /2 )
¡Ya casi está! Si sigue sin salir, no dudes en volver a consultar las veces que lo necesites.
¡Saludos!
vanesa monica B. hace 11 meses
No estoy pudiendo... module Obera
def self.kilometro 1040 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs
end
end
module Iruya def self.kilometro 1710 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
end
module BuenosAires def self.kilometro 0 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
end
module Pepita @energia = 1000 @ciudad = Obera
def self.energia @energia end
def self.ciudad @ciudad end
def self.cantar! 'pri pri pri' end
def self.comer_lombriz! @energia += 20 end
def self.volar_en_circulos! @energia -= 10 end
def self.volar_hacia!(destino) self.gastar_energia!(destino) @ciudad = destino end def
self.gastar_energia! self.volar_en_circulos!.abs/2 end end
Mayra M. hace 11 meses
¡Hola Vanesa! Perdón tal vez no me exprese muy bien, lo que quise poner con respecto a
gastar_energia! que deberia ser como volar_en_circulos! me referia a la forma en la que
se resuelve volar_en_circulos. Ya que lo que tenemos que hacer es a la energia restarle la
distancia que hay entre la ciudad actual y el destino que deberia recibir gastar_energia!
por parametro. Deberia quedar como lo habias puesto en tu resolución anterior. def
self.gastar_energia!(destino) @energia -= self.distancia_a(destino) / 2 end Solo que dentro
de Pepita. ¡Ya casi está! Cualquier cosita nos volves a escribir
vanesa monica B. hace 11 meses
Hola!! perdon, claramente no lo estoy ocmprendiendo y ya me trabe, me da incorrecto la
segunda parte module Obera
def self.kilometro 1040 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs
end
end
module Iruya def self.kilometro 1710 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
end
module BuenosAires def self.kilometro 0 end def self.distancia_a(destino) (self.kilometro -
destino.kilometro).abs end
end
module Pepita @energia = 1000 @ciudad = Obera
def self.energia @energia end
def self.ciudad @ciudad end
def self.cantar! 'pri pri pri' end
def self.comer_lombriz! @energia += 20 end
def self.volar_en_circulos! @energia -= 10 end
def self.volar_hacia!(destino) self.gastar_energia!(destino) @ciudad = destino end def
self.gastar_energia!(destino) @energia -= self.distancia_a(destino) / 2 end
end
vanesa monica B. hace 11 meses
ahora si ya esta, no estaba trayendo @ciudad que si lo tenia deifinido.
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - Obera.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(destino.kilometro - Iruya.kilometro).abs
end
end
module BuenosAires
def self.kilometro
0
end
def self.distancia_a(destino)
(destino.kilometro - BuenosAires.kilometro).abs
end
end
module Pepita
@energia = 1000
@ciudad = Obera
@distancia=0
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.distancia_a(destino) / 2
end
def self.distancia_a(destino)
(@ciudad.kilometro-destino.kilometro).abs
end
end
module Pepita
@energia = 1000
@ciudad = Obera
@distancia=0
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.distancia_a(destino) / 2
end
def self.distancia_a(destino)
unaCiudad.distancia_a(otraCiudad)
end
end
OTRA CONSULTA CON ERROR
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - Obera.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(destino.kilometro - Iruya.kilometro).abs
end
end
module BuenosAires
def self.kilometro
0
end
def self.distancia_a(destino)
(destino.kilometro - BuenosAires.kilometro).abs
end
end
module Pepita
@energia = 1000
@ciudad = Obera
@distancia=0
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.ciudad.distancia_a(destino) / 2
end
end
Juan José M. hace alrededor de 1 mes
Hola! Pude resolver el ejercicio basado en consultas de otr@s compañer@s pero no
quedo del todo perfecto y no alcanzo a comprender donde esta el error, especificamente
no entiendo cuando dice:
Objetivos que no se cumplieron: BuenosAires debería usar self en lugar de una referencia
global Iruya debería usar self en lugar de una referencia global Obera debería usar self en
lugar de una referencia global
Agradezco de antemano si me pueden sacar esa duda!
end
Pero viene alguien y nos dice que nos confundimos y que en realidad no se llama Obera si
no que se llama Pepitalandia, entonces tenemos que cambiarle el nombre al objeto:
module Pepitalandia
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - Obera.kilometro).abs
end
end
Pero nos tira error cuando lo usamos 😢. Claro, pasa que nos olvidamos de que teníamos
que cambiar el nombre también en el método distancia_a:
module Pepitalandia
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - Pepitalandia.kilometro).abs
end
end
Tuvimos que hacer dos cambios, ¡y nos olvidamos de uno en un momento! Si tuvieramos
más métodos usando Obera, hubieramos tenido que cambiar el nombre en cada uno de
ellos.
Ahora, si tenemos en lugar de eso lo siguiente:
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
end
¡Y no tenemos que preocuparnos más! No tenemos ningún otro Obera dando vueltas
dentro de nuestro objeto, hicimos menos cambios, por lo que estamos menos propensos
a tener errores.
SOLUCION CORRECTA
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module BuenosAires
def self.kilometro
0
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Pepita
@energia = 1000
@ciudad = Obera
@distancia=0
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
'pri pri pri'
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
@energia -= self.ciudad.distancia_a(destino) / 2
end
end
Con lo que aprendiste en esta lección, ya podés crear un programa completo, creando los
objetos que te sean necesarios.
Vimos además dos de los conceptos más poderosos del paradigma: la delegación y la
distribución de responsabilidades. Estas herramientas son el principio básico para la
división en subtareas y seguirán acompañándonos en todas las lecciones.
Polimorfismo y encapsulamiento
Ya que te vas familiarizando con este paradigma, aprovecharemos para hacer algunas
reflexiones sobre cómo los objetos interactúan entre sí.
A partir de los conceptos que ya conocés, veremos algunas herramientas conceptuales que
nos ayudarán a contestar algunas preguntas:
¿Puede un objeto interactuar con otros sin saber quiénes son?
Si quiero poder hacer algo con dos objetos distintos ¿necesito que entiendan exactamente
los mismos mensajes?
¿Se puede modificar el estado de un objeto "desde afuera"?
Esto, y algunas cosas más sobre aves, entrenamientos y gauchos, en esta lección.
¡Empecemos!
Ejercicios
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
end
¡Muy bien! Tu solución pasó todas las pruebas
En Ruby, es una convención que los mensajes que devuelven booleanos (o sea, verdadero
o falso) terminen con un ?.
Intentá respetarla cuando crees tus propios mensajes, acordate que uno de los objetivos
del código es comunicar nuestras ideas a otras personas... y las convenciones, muchas
veces, nos ayudan con esto.
CONSOLA
100 > 500
=> false
100 < 1000
=> true
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
end
ESTO ES LO QUE SE LE DEBIA AGREGAR
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
end
end
end
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
end
end
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
end
end
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
end
end
end
SOLUCION CORRECTA
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
else
3.times { self.volar_en_circulos!}
end
end
end
¡Muy bien! Tu solución pasó todas las pruebas
Ahora que vimos estas condiciones anidadas que poco tienen que ver con el nido de
Pepita , vamos a conocer el comportamiento definitivo de Pepita cuando hace lo que
quiere:
Si está débil, come diez gramos de alpiste, para recuperarse.
Si no está debil pero sí feliz, vuela en círculos cinco veces.
Si no está feliz ni débil, vuela en círculos 3 veces.
Modificá a Pepita para que el método hacer_lo_que_quiera! se comporte como
mencionamos más arriba.
SOLUCION CORRECTA
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
else
if self.feliz?
5.times { self.volar_en_circulos!}
else
3.times { self.volar_en_circulos!}
end
end
end
end
En Ruby, podemos simplicar la manera de escribir un if dentro un else con elsif. Por
ejemplo este código:
def self.nota_conceptual(nota)
if nota > 8
"Sobresaliente"
else
if nota > 6
"Satisfactoria"
else
"No satisfactoria"
end
end
end
Lo podemos escribir:
def self.nota_conceptual(nota)
if nota > 8
"Sobresaliente"
elsif nota > 6
"Satisfactoria"
else
"No satisfactoria"
end
end
Antes de seguir, ¿te animás a editar tu solución para que use elsif?
SOLUCION DE LA CONSULTA CON ERROR
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!(10)
elsif self.feliz?
5.times {volar_en_circulos!}
else
3.times {volar_en_circulos!}
end
end
en d
Camila Mora S. hace 10 meses
hola! estoy muy perdida con los END. en este caso lleva 2 y si hago else if (en vez de ilsif)
lleva 3. creo que no estoy entendiendo bien que cierra cada uno. lo puse mal para poder
consultar. saludos y gracias!
Diana L. Mentoría hace 10 meses
¡Buenas Camila!
Esto es porque if elsif else es una estructura que vamos a querer agrupar como tal (como
una sola), pero si hacemos else if estamos haciendo un if dentro de otro:
Caso elsif:
if(condicion1)
...
elsif (condicion2)
...
else
...
end #cierro la estructura entera
Caso else if:
if(condicion1) #abro una estructura de if1
...
else #else del if1
if(condicion2) #abro una estructura de if2 dentro del caso else del primer if (if1)
...
else #else del if2
...
end #cierro la estructura del if2 que sigue estando dentro del else del primer if (if1)
end #cierro la estructura del if1
Podemos pensarlo como "un end por cada if", en el primera caso tenemos un solo if (el
elsif no es un if, es su propio caso), en el segundo caso tenemos dos if, por ende tenemos
que cerrar cada uno de estos y tenemos dos end.
El end extra que aparece luego de estos es el end del método, recordemos que cada
método tiene su propio end porque también es una estructura por su parte:
def self.metodo
...
end
Si dentro de este tenemos un if, vamos a respetar lo que dijimos arriba, si tenemos un
solo if:
def self.metodo
if(condicion1)
...
elsif (condicion2)
...
else
...
end #cierro la estructura entera
end #cierro el método
Si tenemos dos if:
def self.metodo
if(condicion1) #abro una estructura de if1
...
else #else del if1
if(condicion2) #abro una estructura de if2 dentro del caso else del primer if (if1)
...
else #else del if2
...
end #cierro la estructura del if2 que sigue estando dentro del else del primer if (if1)
end #cierro la estructura del if1
end #cierro el método
SOLUCION CORRECTA MIA
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
elsif
self.feliz?
5.times { self.volar_en_circulos!}
else
3.times { self.volar_en_circulos!}
end
end
end cuando lo hice con cuatro end me dio error de sintaxis porque van de acuerdo a los
if por eso solo lleva 3 end
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
elsif
self.feliz?
5.times { self.volar_en_circulos!}
else
3.times { self.volar_en_circulos!}
end
end
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!10
elsif
self.feliz?
5.times { self.volar_en_circulos!}
else
3.times { self.volar_en_circulos!}
end
end
end
def self.energia
@energia
end
def self.pesado?
@energia>1000
end
def self.volar_en_circulos!
if self.pesado?
@energia -=15
else
@energia -=5
end
def self.comer_alpiste!(gramos)
@energia += gramos / 2
end
def self.hacer_lo_que_quiera!
self.comer_alpiste!(120)
end
end
end
def self.volar_en_circulos!
if @energia > 1100
@energia -= 15
else
@energia -= 5
end
end
module Pepo
@energia = 1000
def self.energia
@energia
end
def self.pesado?
@energia>1000
end
def self.volar_en_circulos!
if @energia > 1100
@energia -= 15
else
@energia -= 5
end
def self.comer_alpiste!(gramos)
@energia += gramos / 2
end
def self.hacer_lo_que_quiera!
self.comer_alpiste!(120)
end
end
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
Pepo existe
Pepo gana 25 de energía cuando come 50 gramos de alpiste Ver detalles
undefined method `comer_alpiste!' for Pepo:Module
Pepo gana 30 de energía cuando come 60 gramos de alpiste Ver detalles
undefined method `comer_alpiste!' for Pepo:Module
Pepo gasta 15 de energía cuando vuela y está pesado
Pepo gasta 5 de energía cuando vuela y no está pesado
Pepo come 120 gramos de alpiste cuando hace lo que quiere
def self.energia
@energia
end
def self.volar_en_circulos!
if @energia > 1100
@energia -= 15
else
@energia -= 5
end
end
def self.comer_alpiste!(gramos)
@energia += gramos / 2
end
def self.hacer_lo_que_quiera!
comer_alpiste!(120)
end
end
SOLUCION CORRECTA
module Pepo
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
if @energia > 1100
@energia -= 15
else
@energia -= 5
end
end
def self.comer_alpiste!(gramos)
@energia += gramos / 2
end
def self.hacer_lo_que_quiera!
comer_alpiste!(120)
end
end
¡Muy bien! Tu solución pasó todas las pruebas
Genial, ya tenemos dos aves con las cuales trabajar y que además comparten una
interfaz: ambas entienden los mensajes comer_alpiste!(gramos), volar_en_circulos! y
hacer_lo_que_quiera!.
Veamos qué podemos hacer con ellas...
Ejercicio 6: ¡A entrenar!
Nuestras aves quieren presentarse a las próximas Olimpíadas, y para eso necesitan
ejercitar un poco.
Para ayudarnos en esta tarea conseguimos a Pachorra, un ex entrenador de fútbol que
ahora se dedica a trabajar con aves. Él diseñó una rutina especial que consiste en lo
siguiente:
Volar en círculos 10 veces.
Comer un puñado de 30 gramos de alpiste.
Volar en círculos 5 veces.
Como premio, que el ave haga lo que quiera.
Creá a Pachorra, el entrenador de aves, y hacé que cuando reciba el mensaje
entrenar_ave! haga que Pepita realice su rutina (si, solo puede entrar a Pepita , pero lo
solucionaremos pronto).
Para que no moleste, movimos el código de Pepita a la Biblioteca.
¡Dame una pista!
Recordá que la que entrena es Pepita, su entrenador solo le dice lo que tiene que hacer.
¡Ah! Y para que un objeto pueda mandarle mensajes a otro debe conocerlo. Por ejemplo,
llamándolo por su nombre como ya hemos hecho:
Pepita.energia
BIBLIOTECA
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module BuenosAires
def self.kilometro
0
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
@energia < 100
end
def self.feliz?
@energia > 1000
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!(10)
end
if self.feliz?
5.times { self.volar_en_circulos! }
end
end
end
SOLUCION DE LA CONSULTA CON ERROR
module Pachorra
def self.entrenar_ave!
def self.volar_en_circulos!
10.times {Pepita.volar_en_circulos!}
end
def self.volar_en_circulos!
5.times {Pepita.volar_en_circulos}
end
def hacer_lo_que_quiera!
Pepita.comer_alpiste(10)
end
end
end
María Esperanza I. hace 11 meses
Hola, no entiendo cómo tengo que hacer para que Pachorra le mande el msj a Pepita. O
sea, pensé que en vez de poner self.comer.... ponía Pepita.comer... y estaba pero no
Gabriela C. hace 11 meses
Hola María. vas bien encaminada. un par de cosas: Pachorra no necesita método para
comer, volar en círculos o hacer lo que quiera. Porque esas son cosas que hace Pepita y no
Pachorra. Dentro de la definición de entrenar_ave! no hace falta volver a poner "def", si
no que directamente hacés las lista de las cosas que tienen que hacer Pepita (Pepita.esto,
Pepita.aquello).
Mayra M. hace 11 meses
¡Hola Maria! Como bien comenta Gabriela, lo que Pachorra tiene que hacer es
simplemente enviarle "mensajes" a Pepita para decirle que es lo que tiene que hacer,
¿Como? Como bien hiciste por ejemplo acá 10.times {Pepita.volar_en_circulos!} pero si
ponemos def y end lo que estamos haciendo es declarar esos metodos dentro de
Pachorra y el no sabe por ejemplo volar_en_circulos! . Asi que en entrenar_ave! deberia
quedar una secuencia de este estilo:
def self.entrenar_ave! 10. times {Pepita.volar_en_circulos! } ....... y los demás metodos
que sean del entrenamiento de Pepita end
Espero haber ayudado, si sigue sin salir no dudes en consultarnos que gusto de damos una
mano. ¡Suerte!
María Esperanza I. hace 10 meses
Hola, creo haber hecho lo q me sugirieron pero aún así me sale rojo " Pachorra hace
entrenar a Pepita cuando recibe entrenar_ave! Ver detalles"
Lo que hice es:
module Pachorra def self.entrenar_ave! 10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste! (30) 5.times {Pepita.volar_en_circulos} Pepita.comer_alpiste(10)
end end
Guillermo Ignacio B. Mentoría hace 10 meses
¡Hola María Esperanza! El código está casi bien, sin embargo hay dos cosas para modificar.
Primero, acordate que el método para que Pepita vuele en círculos termina con un signo de
admiración !, pero la línea 5 te faltó agregarlo. Y segundo, luego de volar en círculos 5
veces Pepita tiene que hacer lo que quiera, no volver a comer alpiste. Corrigiendo esas dos
cosas el programa debería funcionar bien.
10.times {Pepita.volar_en_circulos!}
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!(10)
end
end
SOLUCION CORRECTA
module Pachorra
def self.entrenar_ave!( )
10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste! 30
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
end
Antes de empezar a entrenar, debe firmar un contrato con el ave. Esto, por ejemplo, lo
haríamos de la siguiente manera:
Pachorra.firmar_contrato! Pepita # ahora el ave de Pachorra es Pepita
Cada vez que firmamos un contrato cambiamos el ave que entrenará Pachorra, por lo
cual es necesario recordar cuál es ya que a ella le enviaremos mensajes:
Pachorra.entrenar_ave! # acá entrena a Pepita
Pachorra.firmar_contrato! Pepo # ahora el ave de Pachorra es Pepo
Pachorra.entrenar_ave! # ahora entrena a Pepo
Agregale a Pachorra el método firmar_contrato!(ave), de forma tal que cuando le
enviemos el mensaje entrenar_ave! haga entrenar al último ave con el que haya firmado
contrato.
¡Dame una pista!
El método firmar_contrato! solo cambia el ave de Pachorra, no hay que hacer nada más
en ese método.
SOLUCION DADA POR MUMUKI A MODIFICAR
module Pachorra
def self.entrenar_ave!()
10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste! 30
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
end
SOLUCION MIA CON ERROR
module Pachorra
def self.entrenar_ave!()
10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste! 30
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
def self.firmar_contrato! ()
end
def self.entrenar_ave!()
end
end
Tu solución no pasó las pruebas
Objetivos que no se cumplieron:
la solución no debe utilizar Pepita
Resultados de las pruebas:
Pachorra entiende firmar_contrato!
Pachorra firma contrato con Pepita y la entrena Ver detalles
def self.firmar_contrato!(ave)
def self.entrenar_ave!
10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste!(30)
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
end
end
Facundo B. hace 10 meses
Hola. No termino de entender cómo declarar el atributo para que se pueda llevar a cabo la
accion de entrenar ave sin importar qué ave sea
Guillermo Ignacio B. Mentoría hace 10 meses
¡Hola Facundo! Antes que nada fijate que te quedó la definición de un método dentro de
otro y esto no debería pasar. Antes de empezar la definición de un método tenés que cerrar
el anterior con un end. En cuanto al método firmar_contrato!(ave) la idea es que le asignes
esta ave (que es un parámetro) a un atributo llamado @ave y luego en el método
entrenar_ave! tenés que usar este atributo en lugar de Pepita, ya que así como está solo
serviría para Pepita y no para cualquier ave. Probá modificar el código con esto en mente y
cualquier cosa si seguís con dudas podés volver a consultar y lo seguimos viendo.
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
Pachorra entiende firmar_contrato!
Pachorra firma contrato con Pepita y la entrena Ver detalles
wrong number of arguments (given 1, expected 0)
Pachorra firma contrato con Pepo y lo entrena Ver detalles
wrong number of arguments (given 1, expected 0)
SOLUCION DE LA CONSULTA CON ERROR
module Pachorra
def self.firmar_contrato!(ave)
ave = @ave
end
def self.entrenar_ave!
10.times {Pepita.volar_en_circulos!}
Pepita.comer_alpiste!(30)
5.times {Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
end
Valeria Fernanda M. hace 5 meses
Hola, me pone que mi solución paso las pruebas, pero que hay cosas por mejorar. Hice
modificaciones pero no funcionó y esta es la que más se le acerca. Ya no se me ocurre que
detalle cambiar para que finalmente quede bien, me podrían ayudar?
Diana L. Mentoría hace 5 meses
¡Hola Valeria! ¿Cómo te va?
Si nos fijamos en lo que nos dice que se puede mejorar: "_ la solución no debe utilizar_
Pepita", es por que Pachorra cuando entrene a un ave, no siempre será Pepita la que
entrene, puede tener otra ave como atributo y queremos que pueda entrenarla, como por
ejemplo Pepo en el ejemplo. Esto nos da el pie para que usemos el atributo en donde
guardamos el ave: @ave, para entrenar al ave, es decir que en lugar de hacer
Pepita.volar_en_circulos! podemos hacer @ave.volar_en_circulos!, ahí no nos estamos
atando a que siempre usemos a Pepita.
Por otro lado, veamos que sucede acá:
ave = @ave
Si @ave es el atributo y ave el parámetro, ¿no tendrá más sentido que el atributo guarde
el valor del parámetro? Esto lo hacemos al revés: @atributo = parametro para asignarle el
valor que nos viene como parámetro.
SOLUCION CORRECTA
module Pachorra
def self.firmar_contrato! (ave)
@ave = ave
end
def self.entrenar_ave!()
10.times {@ave.volar_en_circulos!}
@ave.comer_alpiste! (30)
5.times {@ave.volar_en_circulos!}
@ave.hacer_lo_que_quiera!
end
end
def self.volar_en_circulos!
@energia -= 30
end
def self.comer_alpiste!(gramos)
@energia -= gramos
end
end
Pero, ¿podrá entrenar con Pachorra?
Probalo en la consola, enviando los siguientes mensajes:
Pachorra.firmar_contrato! Norita
Pachorra.entrenar_ave!
CONSOLA
Pachorra.firmar_contrato! Norita
=> Norita
Pachorra.entrenar_ave!
undefined method `hacer_lo_que_quiera!' for Norita:Module (NoMethodError)
norita_puede_entrenar_con_pachorra = false
norita_puede_entrenar_con_emilce = false
pepita_puede_entrenar_con_pachorra = false
pepita_puede_entrenar_con_emilce = false
pepo_puede_entrenar_con_pachorra = false
pepo_puede_entrenar_con_emilce = false
Damaris Gisela M. hace 10 meses
no entiendo que hay que hacer. tengo que crear un modulo para emilce? en la consola o
en solucion? estoy volada, perdon
Diana L. Mentoría hace 10 meses
¡Hola Damaris!
Emilce ya está creada, al igual que Pepita, Pepo, Norita y Pachorra. Lo que tenemos que
hacer es analizar cada sentencia que se nos da y decir si es verdadera o falsa.
Por ejemplo, veamos el valor de verdad de la primera sentencia:
"norita_puede_entrenar_con_pachorra". Tenemos entonces que fijarnos si Norita
entienden los mensajes suficientes para que Pachorra pueda entrenarla. ¿Cómo hacemos
eso? Primero vamos a tener que decirle a Pachorra en la consola que firme contrato con
Norita, ya que Pachorra solamente puede entrenar aves que hayan firmado contrato.
Entonces en la consola hacemos:
Pachorra.firmar_contrato!(Norita)
=> Norita
Ahora que Pachorra ya firmo contrato con Norita, vamos a ver si puede entrenarla, para
eso usamos el mensaje entrenar_ave!, otra vez en la consola probamos:
Pachorra.entrenar_ave!
=> undefined method `hacer_lo_que_quiera!' for Norita:Module (NoMethodError)
Nos tiró un error 🤔 Este error no está diciendo que Norita no entiende uno de los
mensajes que usa Pachorra para entrenarla, por ende Pachorra no puede entrenar a
Norita.
Con esto en mente, podemos decir que "norita_puede_entrenar_con_pachorra" es una
afirmación falsa, entonces colcamos el false donde corresponde:
norita_puede_entrenar_con_pachorra = false
¿Te animás a analizar las demás afirmaciones? Sabemos que si da un error va a ser falso,
entonces si no nos da un error es porque será verdadero 🧐
Pachorra.firmar_contrato! (Norita)
=> Norita
Pachorra.entrenar_ave!
undefined method `hacer_lo_que_quiera!' for Norita:Module (NoMethodError)
Norita_puede_entrenar_con_Pachorra = false
=> false
Pachorra.firmar_contrato! (Emilce)
=> Emilce
Pachorra.entrenar_ave!
solution.rb:48:in `block in entrenar_ave!': undefined method `volar_en_circulos!' for
Emilce:Module (NoMethodError)
Emilce_puede_entrenar_con_Pachorra = false
=> false
Emilce.firmar_contrato! (Norita)
=> Norita
Emilce.entrenar_ave!
=> -1578
Norita_puede_entrenar_con_Emilce = false
=> false
Norita_puede_entrenar_con_Emilce = true
solution.rb:195: warning: already initialized constant Norita_puede_entrenar_con_Emilce
solution.rb:190: warning: previous definition of Norita_puede_entrenar_con_Emilce was
here
=> true
pepita_puede_entrenar_con_pachorra = true
pepita_puede_entrenar_con_emilce = true
pepo_puede_entrenar_con_pachorra = true
pepo_puede_entrenar_con_emilce = true
¡Muy bien! Tu solución pasó todas las pruebas
Según las rutinas que definen, cada entrenador/a solo puede trabajar con ciertas aves:
Pachorra puede entrenar a cualquier ave que entienda volar_en_circulos!,
comer_alpiste!(gramos) y hacer_lo_que_quiera!.
Emilce puede entrenar a cualquier ave que entienda volar_en_circulos! y
comer_alpiste!(gramos).
Dicho de otra manera, la rutina nos define cuál debe ser la interfaz que debe respetar un
objeto para poder ser utilizado.
def self.volar_en_circulos!
@energia -= 30
end
def self.comer_alpiste!(gramos)
@energia -= gramos
end
module Pachorra
def self.firmar_contrato!(ave)
@ave = ave
End ESTE ES EL ERROR NO VA NADA ACA
def self.entrenar_ave!
@ave.hacer_lo_que_quiera!
end
end
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
Norita entiende hacer_lo_que_quiera! Ver detalles
expected Norita to respond to :hacer_lo_que_quiera!
Norita no hace nada cuando hace lo que quiere Ver detalles
undefined method `hacer_lo_que_quiera!' for Norita:Module
Norita puede entrenar con Pachorra Ver detalles
undefined method `hacer_lo_que_quiera!' for Norita:Module
SOLUCION CORRECTA
module Norita
@energia = 500
def self.hacer_lo_que_quiera!
end
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 30
end
def self.comer_alpiste!(gramos)
@energia -= gramos
end
end
¡Muy bien! Tu solución pasó todas las pruebas
Aunque parezca que no tiene mucho sentido, es común que trabajando con objetos
necesitemos forzar el polimorfismo y hagamos cosas como estas.
En este caso le agregamos a Norita un mensaje que no hace nada, con el único objetivo de
que sea polimórfica con sus compañeras aves.
def self.entrenar_ave!
53.times { @ave.volar_en_circulos! }
@ave.comer_alpiste!(8)
end
end
¿Te animás a cambiar el código de Pachorra para que siga esta convención?
module Pachorra
def self.firmar_contrato!(un_ave)
@ave = un_ave
end
def self.entrenar_ave!
10.times { @ave.volar_en_circulos! }
@ave.comer_alpiste! 30
5.times { @ave.volar_en_circulos! }
@ave.hacer_lo_que_quiera!
end
end
SOLUCION CORRECTA
module Pachorra
def self.ave=(ave_nueva)
@ave = ave_nueva
end
def self.entrenar_ave!
10.times { @ave.volar_en_circulos! }
@ave.comer_alpiste! 30
5.times { @ave.volar_en_circulos! }
@ave.hacer_lo_que_quiera!
end
end
¡Muy bien! Tu solución pasó todas las pruebas
Como ya te habíamos contado en una lección anterior, a estos métodos que solo sirven
para acceder o modificar un atributo los llamamos métodos de acceso o accessors.
Repasando, los setters son aquellos métodos que establecen el valor del atributo.
Mientras que los getters son aquellos que devuelven el valor del atributo.
La convención en Ruby para estos métodos es:
Los setters deben llevar el mismo nombre del atributo al que están asociados,
agregando un = al final.
Los getters usan exactamente el mismo nombre que el atributo del cual devuelven
el valor pero sin el @.
Aquellos getters que devuelven el valor de un atributo booleano llevan ? al final.
atributos_con_getter = %w(
# completá acá...
)
atributos_con_setter = %w(
# completá acá...
)
BIBLIOTECA
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module BuenosAires
def self.kilometro
0
end
def self.distancia_a(destino)
(destino.kilometro - self.kilometro).abs
end
end
module Pehuajo
end
module Malaquita
end
module Paris
end
module Manuelita
@energia = 100
@ciudad = Pehuajo
@mineral_preferido = Malaquita
@donde_va = Paris
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.mineral_preferido=(mineral)
@mineral_preferido = mineral
end
def self.mineral_preferido
@mineral_preferido
end
def self.donde_va=(ciudad)
@donde_va = ciudad
end
end
SOLUCION MIA CON ERROR
atributos = %w(
energia
ciudad
mineral_preferido
donde_va
)
atributos_con_getter = %w(
def self.mineral_preferido
@mineral_preferido
end
atributos_con_setter = %w(
def self.mineral_preferido=(mineral)
@mineral_preferido = mineral
end
)
Tu solución no pasó las pruebas
Resultados de las pruebas:
Atributos con getter Ver detalles
expected collection contained: ["ciudad", "energia", "mineral_preferido"]
actual collection contained: ["@mineral_preferido", "def", "end",
"self.mineral_preferido"]
the missing elements were: ["ciudad", "energia", "mineral_preferido"]
the extra elements were: ["@mineral_preferido", "def", "end",
"self.mineral_preferido"]
Atributos con setter Ver detalles
expected collection contained: ["donde_va", "mineral_preferido"]
actual collection contained: ["=", "@mineral_preferido", "def", "end", "mineral",
"self.mineral_preferido=(mineral)"]
the missing elements were: ["donde_va", "mineral_preferido"]
the extra elements were: ["=", "@mineral_preferido", "def", "end", "mineral",
"self.mineral_preferido=(mineral)"
SOLUCION CON ERROR EN LA CONSULTA
atributos = %w(
energia 100
ciudad Pehuajo
mineral_preferido
donde_va paris
)
atributos_con_getter = %w(
energia
cuidad
mineral_preferido
donde_va
)
atributos_con_setter = %w(
energia = energia
cuidad = cuidad
mineral_preferido = mineral_preferido
donde_va = donde_va
)
) ESTE ESTA DE MAS
Teniendo en cuenta esto, a partir del código de Manuelita, vamos a fijarnos primero qué
atributos tiene, en tu solución los pusiste muy bien, solo que queremos saber los nombres
y nada más, es decir que queremos escribir por ejemplo energia solo, sin el 100, lo mismo
con ciudad, no nos interesa el valor asi que Pehuajo lo vamos a sacar.
Luego de esto, aplica lo mismo para los atributos_con_getter y los atributos_con_setter,
queremos simplemente mencionar los nombres de estos atributos (que cumplen con la
condición de tener un setter o un getter). Analicemos por ejemplo el atributo energia:
Podemos ver que tiene un getter en el código:
def self.energia
@energia
end
Entonces podemos decir que energia es un atributo con getter, ¡perfecto! Lo colocamos
en la lista:
atributos_con_getter = %w(
energia )
¿Tiene un setter? Lo que vimos en la consulta linkeada arriba es que el setter debe tener
el mismo nombre que el atributo pero debe asignarle un nuevo valor, podríamos pensar
entonces que tenemos que buscar un método que se llame energia=(nuevo_valor) o algo
por el estilo 🧐 Pero si leemos el código no hay ningún método que cumpla eso, entonces
podemos decir que energia no tiene un setter, por ende no vamos a colocarlo entre los
atributos con setter. Hasta ahora tenemos:
atributos_con_getter = %w(
energia
)
atributos_con_setter = %w(
)
¿Te animás a analizar los demás atributos e ir agregandolos donde deban?
Por último, hay un error de sintaxis que puede traer problemas, está sobrando un ) al final
de todo (línea 21).
SOLUCION DE LA CONSULTA CON ERROR
atributos = %w(
energia
ciudad
mineral_preferido
donde_va
)
atributos_con_getter = %w(
energia
ciudad
mineral_preferido
)
atributos_con_setter = %w(
mineral_preferido
donde_va
)
aaaaaaaaaaaaaaa
Nahuel Alejandro S. hace 10 meses
hola 👋 tengo una duda, no es sobre este ejercicio, sino algo específico, por eso puse esas
"a" al final para poder consultarles.
- No entiendo cual es la diferencia entre esto:
def self.mineral_preferido=(mineral) @mineral_preferido = mineral end
- Y esto:
def self.mineral_preferido(mineral) @mineral_preferido = mineral end
Siento que es lo mismo, y me termino confundiendo, espero puedan ayudarme, gracias!!!
Juan B. hace 10 meses
permiso, me cuelgo de tu consulta nahuel! quiero leer la respuesta
Diana L. Mentoría hace 10 meses
¡Buenas Nahuel y Juan!
El nombre que le ponemos es una simple convención, digamos que nos pusimos de
acuerdo para que sea así y por eso lo hacemos de esa forma. Esto nos sirve para
diferencias más fácil cuál es el setter y cuál el getter de un atributo, ya que sabemos que
tanto los setter como getter llevan el mismo nombre que el atributo. Si tenemos:
def self.mineral_preferido(mineral) #setter
@mineral_preferido = mineral
end
atributos_con_getter = %w(
energia
ciudad
mineral_preferido
)
atributos_con_setter = %w(
mineral_preferido
donde_va
)
¡Muy bien! Tu solución pasó todas las pruebas
Si hacemos bien las cosas, quien use nuestros objetos sólo verá lo que necesite para poder
interactuar con ellos. A esta idea la conocemos como encapsulamiento, y es esencial para
la separación de responsabilidades de la que veníamos hablando.
Será tarea tuya (y de tu equipo de trabajo, claro) decidir qué atributos exponer en cada
objeto.
CONSOLA
@energia
=> nil
@ciudad
=> nil
@mineral_preferido = preferido
undefined local variable or method `preferido' for main:Object (NameError)
@mineral_preferido = Malaquita
=> Malaquita
@mineral_preferido
=> Malaquita
@adonde_va = ciudad
undefined local variable or method `ciudad' for main:Object (NameError)
@donde_va = ciudad
undefined local variable or method `ciudad' for main:Object (NameError)
module Eulogia
@enojada = false
# completá acá...
end
module Mendieta
@ganas_de_hablar = 5
# completá acá...
end
https://mumuki.io/argentina-programa/exercises/10887/discussions/18344
EJERCICIO 14 VAMOS TERMINANDO
module Inodoro
@cafeina_en_sangre = 90
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche=(compinche_nuevo)
@compinche = compinche_nuevo
end
def self.tomar_mate!
@compinche
end
module Eulogia
@enojada = false
end
def self.enojada=(enojada)
@enojada = enojada
end
end
module Mendieta
@ganas_de_hablar = 5
end
def self.hablar=(ganas_de_hablar)
@ganas_de_hablar = ganas_de_hablar
end
def self.mas_hablar!
@ganas_de_hablar *5
end
end
Julian Gonzalo A. hace 11 meses
Mmmmm, me tira error. Ayuda(?
Santiago C. hace 11 meses
Mira bien los end, despues de los atributos no hace falta poner end. A cada module, def le
corresponde un end.
Diana L. Mentoría hace 11 meses
¡Hola Julian!
Como dice Santiago, el error se debe a que faltan/sobran end.
Además de eso, en Inodoro queremos saber quién es el compinche, por lo que
necesitamos un getter, recordemos que a estos les colocamos el mismo nombre que el
atributo que queremos consultar, pero en la solución el nombre es: tomar_mate!.
Por la parte de Eulogia también queremos consultar si está enojada, por lo que
necesitamos un getter en lugar de un setter.
Por último Mendieta necesita tanto un getter como un setter. El getter en este caso se
llama: hablar y el atributo es ganas_de_hablar, ocurre lo mismo que con tomar_mate!. En
cuando al setter, queremos que podamos por parámetro cambiar las ganas de hablar, de
la misma forma que por ejemplo podemos cambiar al compinche de Inodoro.
Julian Gonzalo A. hace 11 meses
Me podria explicar exactamente que diferencia hay entre el getter y el setter? Me cuesta
entender eso.
Diana L. Mentoría hace 11 meses
¡Por supuesto!
El getter es el método que nos sirve para consultar un atributo. Por ejemplo si
tenemos un atributo:
module Persona
@edad
end
Si queremos saber el valor de ese atributo, es decir queremos saber la edad de la
persona, creamos el método getter con el mismo nombre:
def self.edad
@edad
end
Si fuese un booleano, por ejemplo la persona es mayor de edad:
module Persona
@mayor_de_edad
end
module Eulogia
@enojada = false
def self.enojada=(enojada)
@enojada = enojada
end
module Mendieta
@ganas_de_hablar = 5
end
def self.hablar=(ganas_de_hablar)
@ganas_de_hablar = ganas_de_hablar
end
def self.mas_hablar!
@ganas_de_hablar *5
end
end
¡Ups! Tu solución no se puede ejecutar
Resultados:
solucion.rb:12: module definition in method body (SyntaxError)
module Eulogia
^~~~~~~~~~~~~~
OTRA SOLUCION CON ERROR
module Inodoro
@cafeina_en_sangre = 90
@compinche =
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche
@compinche
end
def self.compinche= (compinche_nuevo)
@compinche = (compinche_nuevo)
end
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar= (valor)
@ganas_de_hablar = (valor)
end
end
Alvaro Gabriel L. hace 10 meses
Hola buenas, me dice que está bien el ejecicio pero podría mejorar. Que debo definir un
metodo cafeina_en_sangre Para mi ya está definido, que puedo tener mal? Gracias
end
def self.compinche
@compinche
end
def self.compinche= (compinche_nuevo)
@compinche = (compinche_nuevo)
end
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar= (valor)
@ganas_de_hablar = (valor)
end
end
¡Muy bien! Tu solución pasó todas las pruebas
¡Excelente! Parece que los getters y setters quedaron claros.
Para finalizar esta lección vamos a repasar lo que aprendimos de polimorfismo.
module Inodoro
@cafeina_en_sangre = 90
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche
@compinche
end
def self.compinche= (compinche_nuevo)
@compinche = (compinche_nuevo)
end
Inodoro.tomar_mate!
@tomar_mate
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar= (valor)
@ganas_de_hablar = (valor)
end
end
module Inodoro
@cafeina_en_sangre = 90
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche
@compinche
end
def self.compinche=(compa)
@compinche=compa
end
def self.tomar_mate!
@cafeina_en_sangre+=10
end
end
module Eulogia
@recibir_mate=false
def self.recibir_mate!
if Inodoro.compinche="Eulogia"
@recibir_mate!=true
else
@recibir_mate!=false
end
end
@enojada = false
def self.enojada?
if @recibir_mate!=true
@enojada=true
else
@enojada=false
end
end
end
module Mendieta
@recibir_mate!=false
def self.recibir_mate!
if Inodoro.compinche="Mendieta"
@recibir_mate!=true
else
@recibir_mate!=false
@ganas_de_hablar = 5
def self.ganas_de_hablar
if recibir_mate!-true
@ganas_de_hablar=0
else
@ganas_de_hablar=5
end
end
end
Buenas, cuando pruebo esta solución, me devuelve esto: solucion.rb:61: module definition
in method body (SyntaxError) module Eulogia ^~~~~~~~~~~~~~
No entiendo cuál es el error... por lo que entiendo cerré bien inodoro y module está bien
escrito. También probé agregándole y sacandole un end a Eulogia por si me estaba
quedando abierto eso, pero no varía.
Más allá de ese problema en concreto, creo que tengo otros errores porque estos últimos
ejercicios me costaron bastante, así que si lo pueden revisar entero, buenisimo!
Diana L. Mentoría hace 4 meses
¡Hola Ángeles! ¿Cómo estás?
Primero veamos por qué se da el error de sintaxis, veamos el objeto Mendieta:
def self.recibir_mate! #abrimos un método, ¿lo estamos cerrando?
if Inodoro.compinche="Mendieta"#abrimos un if, ¿lo estamos cerrando?
@recibir_mate!=true
else
@recibir_mate!=false
@ganas_de_hablar = 5
def self.ganas_de_hablar #acá comenzamos un metodo nuevo, ¿pero cerramos el
anterior?
Están faltando dos end, uno que cierre el if y otro que cierre el método.
Con esto resuelto, veamos el ejercicio en sí:
Veamos esto que nos menciona la pista sobre Inodoro al tomar mate:
Cuando Inodoro toma mate, su compinche recibe un mate:
Inodoro.compinche= Mendieta
Mendieta.ganas_de_hablar
=> 5
Esto nos da el pie a pensar que vamos a necesitar hacer que el compinche de Inodoro (sea
quien sea, no nos interesa especificamente quien es) reciba un mate cuando Inodoro
tome mate, dentro del método tomar_mate!. Recordemos que el valor que tiene el
atributo @compinche ¡es un objeto! Y podemos enviarle mensajes, por ejemplo podemos
hacer @compinche.recibir_mate!.
Algo que tenemos que tener en cuenta, es que cuando Inodoro cambie su
compinche, lo hará usando los objetos Mendieta o Eulogia, no lo hará usando
strings. Veamos un ejemplo:
Inodoro.compinche=Eulogia
Si hicieramos
Persona.comida_favorita=Ensalada
Persona.comer!
Fijate como resolvimos esto sin la necesidad de usar un if. Algo similar ocurre con
tomar_mate! y recibir_mate!. Podríamos tener los tres objetos mínimos que
necesitabamos:
Un objeto que envie el mensaje -> Inodoro al enviar recibir_mate!
Dos objetos que entiendan el mensaje -> Tanto Eulogia como Mendieta entienden
recibir_mensaje!
¿Se te ocurre como resolverlo usando polimorfismo? Pista: no necesitamos usar ningún if
module Inodoro
@cafeina_en_sangre = 90
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche=(com)
@compinche=com
end
def self.compinche
@compinche
end
def self.tomar_mate!
@cafeina_en_sangre+=10
(Inodoro.compinche).recibir_mate!
end
end
module Eulogia
def self.enojada?
@enojada
end
def self.recibir_mate!
@enojada=true
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar=(gan)
@ganas_de_hablar=gan
end
def self.recibir_mate!
@ganas_de_hablar= 0
end
end
module Inodoro
@cafeina_en_sangre = 90
@compinche
@tomar_mate
def self.tomar_mate!
@tomar_mate
end
def self.tomar_mate!
@cafeina_en_sangre+=10
end
def self.compinche=(un_compinche)
@compinche = un_compinche
end
def self.compinche
@compinche
end
@compinche.recibir_mate!
def self.cafeina_en_sangre
@cafeina_en_sangre
end
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
def self.recibir_mate!
@recibir_mate
@enojada = true
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.recibir_mate!
if (ganas_de_hablar==5)
@recibir_mate
@ganas_de_hablar = 0
end
end
def self.ganas_de_hablar=(valor)
@ganas_de_hablar = valor
end
end
SOLUCION CORRECTA
module Inodoro
@cafeina_en_sangre = 90
@compinche
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.tomar_mate!
@cafeina_en_sangre= +10
@compinche.recibir_mate!
end
def self.compinche= compinche_nuevo
@compinche = compinche_nuevo
end
end
module Eulogia
def self.enojada?
@enojada
end
def self.recibir_mate!
@enojada=true
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar=(gan)
@ganas_de_hablar=gan
end
def self.recibir_mate!
@ganas_de_hablar= 0
end
end
¡Muy bien! Tu solución pasó todas las pruebas
En esta lección le dimos nombre al polimorfismo una idea con la que ya venías trabajando,
pero sobre la que todavía no habíamos reflexionado. Este principio fundamental del
paradigma de objetos nos permite que podamos interactuar de igual manera con diferentes
objetos, con el único requisito de que todos ellos entiendan el o los mensajes que
necesitamos enviarles.
En el caso de los atributos, esta exposición se logra implementando un getter (método que
nos permite ver su valor) o un setter (método que nos permite modificar su valor). Y que
nuestro código sea entendido fácilmente por otras personas, elegimos utilizar una
convención para darle nombre a estos métodos.
Referencias
Hasta ahora venimos hablando mucho de objetos y mensajes. Pero ocasionalmente se nos
escapó una palabra: referencia. ¿Qué es? ¿Cómo se relacionan las referencias con los
objetos y los atributos?
Ejercicios
1. Variables
2. Las variables son referencias
3. Referencias implícitas
4. Múltiples referencias
5. Identidad, revisada
6. Equivalencia
7. Objetos bien conocidos
8. Atributos y parámetros
9. Lo 100to
10. Objetos compartidos
11. Para cerrar
Ejercicio 1: Variables
Hasta ahora, en objetos, un programa es simplemente una secuencia de envíos de
mensajes. Por ejemplo, éste es un programa que convierte en mayúsculas al string "hola".
"hola".upcase
=> "HOLA"
Sin embargo, podemos hacer algo más: declarar variables. Por ejemplo, podemos
declarar una variable saludo, inicializarla con "hola", enviarle mensajes...
saludo = "hola"
saludo.upcase
=> "HOLA"
...y esperar el mismo resultado que para el programa anterior.
Veamos si queda claro: agregá al programa anterior una variable saludo_formal,
inicializada con "buen día"
SOLUCION
saludo = "hola"
...lo que estamos haciendo es crear una referencia saludo que apunta al objeto "hola",
que representamos mediante una flechita:
Y cuando tenemos...
saludo.upcase
...le estamos enviando el mensaje upcase al objeto "hola", a través de la referencia saludo,
que es una variable.
Veamos si se entiende hasta acá: creá una variable llamada despedida que apunte al
objeto "adiós", y luego enviale el mensaje size().
¡Dame una pista!
¡No olvides que adiós va con tilde en la ó!
SOLUCION MIA CON ERROR
despedida = "adiós"
Tu solución funcionó, pero hay cosas que mejorar
Objetivos que no se cumplieron:
SOLUCION CORRECTA
despedida = "adiós"
despedida.size()
¡Bien! Acabás de crear este ambiente, en criollo, el lugar donde viven los objetos con los
cuales podemos interactuar:
“hola” “adiós”
”
SALUDO DESPEDIDA
También podemos hacer cosas como "hola".size. Allí no hay ninguna variable: ¿dónde está
la referencia en ese caso? ¡Allá vamos!
saludo.upcase.size
^
+-- Y acá, otra referencia implícita a "HOLA"
“hola”
”
<anónima>
Por eso, si luego te interesa hacer más cosas con ese objeto, tenés que crear una
referencia explícita al mismo . Las referencias explícitas son las que vimos hasta ahora. Por
ejemplo:
saludoEnChino = "ni hao"
Probá las siguientes consultas en la consola y pensá en dónde hay referencias implícitas:
"ni hao".upcase
4.abs.even?
(4 + 8).abs
CONSOLA
"ni hao".upcase
=> "NI HAO"
4.abs.even?
=> true
(4 + 8).abs
=> 12
Ejercicio 4: Múltiples referencias
Supongamos que tenemos el siguiente programa:
otro_saludo = "buen día"
despedida = otro_saludo
Como vemos, estamos asignando otro_saludo a despedida. ¿Qué significa esto?
¿Acabamos de copiar el objeto "buen día", o más bien le dimos una nueva etiqueta al
mismo objeto? Dicho de otra forma: ¿apuntan ambas variables al mismo objeto?
¡Averigualo vos mismo! Declará las variables otro_saludo y despedida como en el ejemplo
de más arriba, y realizá las siguientes consultas utilizando equal?:
"buen día".equal? "buen día"
despedida.equal? "buen día"
otro_saludo.equal? otro_saludo
despedida.equal? otro_saludo
¡Ahora sacá tus conclusiones viendo que responde en cada caso!
CONSOLA
"buen día".equal? "buen día"
=> false
despedida.equal? "buen día"
undefined local variable or method `despedida' for main:Object (NameError)
otro_saludo.equal? otro_saludo
undefined local variable or method `otro_saludo' for main:Object (NameError)
despedida.equal? otro_saludo
undefined local variable or method `despedida' for main:Object (NameError)
"adiós".equal? "adiós"
=> false
“HOLA” “BUENDIA”
SALUDO DESPEDIDA
OTRO_SALUDO
“BUENDIA
”
“HOLA”
“BUENDIA
”
SALUDO DESPEDIDA
Veamos si se entiende, dadas las siguientes asignaciones:
persona = "Graciela"
hija_de_hector = "Graciela"
hermana_de_tito = persona
hija_de_elena = "Gracielita"
hermana_de_ana = hermana_de_tito
mama_de_gustavo = "hermana_de_ana"
tia_de_gonzalo = hija_de_hector
Elegí cuáles de estas opciones referencian al mismo objeto que persona.
hija_de_hector
hermana_de_tito
hija_de_elena
hermana_de_ana
mama_de_gustavo
tia_de_gonzalo
Mensajes
Eric J. hace 5 meses
buenos dias, me clavé aca, no me sale. estuve leyendo la unica consulta y no lo entiendo..
no se si soy muy burro, o es feriado y temprano. si me pueden dar una mano... desde ya
gracias.
Diana L. Mentoría hace 5 meses
¡Hola Eric!
Analicemos juntos lo que nos plantean. Sabemos que cada vez que usemos un string,
estamos creando un nuevo objeto, esto quiere decir que si hacemos:
nombre1 = "Eric" #creamos una referencia a objeto nuevo
nombre2 = "Eric" #creamos una referencia a objeto nuevo
Por más que sea lo mismo lo que escribimos entre las comillas, nombre1 y nombre2
referencian a objetos distintos, por que "Eric" y "Eric" **son objetos distintos.
Probemos en la consola:
nombre1.equal? nombre2
=> false
"Eric".equal? "Eric"
=> false
Podemos probar con cualquier otro string, y nunca nos dará true:
"Diana".equal? "Diana"
=> false
"hola".equal? "hola"
=> false
"asdasdd".equal? "asdasdd"
=> false
Ahora si hacemos:
nombre1.equal? nombre2
=> true
Porque tenemos dos variables que apuntan al mismo objeto, ya no son dos objetos
diferentes, si no uno solo.
Veamos entonces las opciones que nos dan. Tenemos que ver cuales referencian al mismo
objeto que persona:
persona = "Graciela" #creamos una referencia a un objeto nuevo
Dijimos que por cada string tendremos un objeto nuevo, por lo que hija_de_hector no
referencia al mismo objeto que Persona, si no que referencia a un objeto nuevo.
La segunda opción es:
hermana_de_tito = persona #creamos una referencia a objeto que ya existe -> el objeto al
que referencia persona
Vemos que estamos creando una nueva referencia que apunta al mismo objeto que
apunta Persona, ¡genial! Esto es lo que buscabamos, podemos decir que hermana_de_tito
referencia al mismo objeto que Persona. ¡Ya tenemos una opción correcta! De todas
formas veamos si hay más.
La tercera opción es:
hija_de_elena = "Gracielita" #creamos una referencia a un objeto nuevo
Sucede lo mismo que con la hija_de_hector, tenemos una referencia a un objeto nuevo, un string nuevo.
Por lo tanto esta opción tampoco es correcta.
¿Te animás a seguir el mismo análisis con las opciones que quedan?
SOLUCION CORRECTA
hija_de_hector
hermana_de_tito
hija_de_elena
hermana_de_ana
mama_de_gustavo
tia_de_gonzalo
Ejercicio 6: Equivalencia
Entonces, ¿qué pasa si lo que quiero es comparar los objetos no por su identidad, sino por
que representen la misma cosa?
Pensemos un caso concreto. ¿Hay forma de saber si dos strings representan la misma
secuencia de caracteres más allá de que no sean el mismo objeto? ¡Por supuesto que la
hay! Y no debería sorprendernos a esta altura que se trate de otro mensaje:
"hola" == "hola"
=> true
"hola" == "adiós"
=> false
"hola".equal? "hola"
=> false
El mensaje == nos permite comparar dos objetos por equivalencia; lo cual se da
típicamente cuando los objetos tienen el mismo estado. Y como vemos, puede devolver
true, aún cuando los dos objetos no sean el mismo.
Elegí cuál de las siguientes opciones contiene 3 referencias distintas que apunten a
objetos equivalentes entre sí, pero no idénticos.
@@@@
@ FELICIDAD
100
FITO
def self.comer!(calorias)
@felicidad += calorias * 0.001
end
def self.felicidad
@felicidad
end
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
AbuelaClotilde alimenta a su nieto dos veces Ver detalles
wrong number of arguments (given 0, expected 1)
Cuando AbuelaClotilde alimenta a su nieto su felicidad aumenta 3 puntos Ver
detalles
wrong number of arguments (given 0, expected 1)
def self.alimentar_nieto!(calorias)
@Fito.comer!(2000)
@Fito.comer!(1000)
end
end
Manuel Kevin M. hace 4 meses
Buenas! bajo la logica **objeto.mensaje(argumentos) **tengo como objeto a Fito, el
mensaje es comer! (que ya lo entiende porque esta definido anteriormente, no tengo que
desarrollarlo) y entre parentesis le especifico la cantidad. No entiendo mi error. Desde ya
muchas gracias!
Catalina F. Mentoría hace 4 meses
¡Hola Manuel!
Nuestra solución está encaminada, lo que sucede es que estamos tratando de enviarle un
mensaje a @Fito cuando deberíamos de enviarselo a Fito, y que alimentar_nieto! no
recibe (calorias), porque nunca usamos ese parámetro, así que el método que debemos
usar es alimentar_nieto! (sin (calorias) ).
SOLUCION CORRECTA
#Ya declaramos a Fito por vos.
#¡Desarrollá a la AbuelaClotilde acá!
module AbuelaClotilde
def self.alimentar_nieto!
Fito.comer!(2000)
Fito.comer!(1000)
end
end
def self.volar_en_circulos!
@energia -= 10
end
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
def self.ciudad
@ciudad
end
end
Y en algún momento esta pasa a ser Iruya, el diagrama de objetos será el siguiente:
Iruya
@ciudad
@
100
@energia
Pepita
Nuevamente, acá vemos otro caso de múltiples referencias: el objeto que representa a la
ciudad de Iruya es globalmente conocido como Iruya, y también conocido por Pepita
como ciudad.
Escribí un programa que defina la ciudad de Pepita de forma que apunte a Iruya. Y pensá:
¿cuántas referencias a Iruya hay en este programa?
BIBLIOTECA
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia -= 10
end
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
def self.ciudad
@ciudad
end
end
module Iruya
end
SOLUCION MIA CON ERROR
module Iruya
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
def self.ciudad
@ciudad
end
end
Tu solución no pasó las pruebas
Resultados de las pruebas:
La ciudad de Pepita se inicializa con Iruya Ver detalles
expected: Iruya
got: nil
(compared using ==)
SOLUCION MAL DE LA CONSULTA
def self.ciudad= Iruya
@ciudad = Iruya
end
Pepita.ciudad
Camila G. hace 5 meses
Hola, no entiendo cómo resolverlo, ya leí laas preguntas y respuestas de los anteriores
ejercicios y no dan una respuesta muy entendible que digamos, si oueden explicarme en
qué me estoy equivocando y qué es lo que hay que resolver se los agradecería.
David Ignacio D. Mentoría hace 5 meses
¡Hola Camila! El ejercicio actual nos pide escribir un programa que sólo defina la ciudad de
Pepita de modo que apunte hacia el objeto Iruya. En este capítulo estamos aprendiendo
sobre las referencias como etiquetas que apuntan hacia un determinado objeto, y en este
caso podemos asignarles estas mismas a los ya vistos atributos mediante setters. Un
ejemplo casi idéntico a lo que se nos pide podemos ejemplificarlo del siguiente modo:
Se define la ciudad de Pepita de modo que apunta hacia el objeto Buenos Aires=
Pepita.ciudad = BuenosAires
Y sin más, ahora te aliento a que pruebes lo mismo pero con Iruya.
SOLUCION CORRECTA
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
End
Esto esta en la Biblioteca
def self.ciudad
@ciudad
end
Iruya
@ciudad
@
100
@energia
Pepita
Luego, la operación de asignación cambia ese apuntador, que pasa a referenciar al 90:
Iruya
@ciudad
@
90
100
@energia
Pepita
Dada las siguientes definiciones:
module Pepita
@energia = 100
def volar_en_circulos!
@energia -= 10
end
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
end
module Iruya
end
¿Cuáles de las siguientes opciones son referencias?
SOLUCION DE LA CONSULTA CON ERROR
Pepita
@energia
una_ciudad
@ciudad
Iruya
Carolina P. hace 6 meses
Buenas, muchachxs! Me siento una goma con esta pregunta! Estaba convencida...y
después ya no supe qué probar. Todos los intentos están mal y ahora estoy perdida. No
entiendo en qué la pifio. Podrían desasnarme? Muchas gracias de antemano!
Diana L. Mentoría hace 6 meses
¡Hola Carolina!
Para este tipo de ejercicio está bueno analizar una por una las opciones, ya que puede ser
más de una (hasta podrían ser todas 🧐). Veamos una por una:
1. Pepita -> es un objeto que conocemos, es decir un objeto bien conocido, te invito
a que releas qué decía el Ejercicio 7 sobre ellos, ¿son referencias? Si lo son, lo
marcamos.
2. @energia -> es un atributo que conoce Pepita, ¿qué nos decía el Ejercicio 8 sobre
los atributos? ¿Son referencias?
3. una_ciudad -> es un parámetro del método ciudad=, ¿qué nos decía el Ejercicio 8
sobre los parámetros? ¿Son referencias?
¿Te animás a ver que son @ciudad e Iruya?
SOLUCION CORRECTA
Pepita
@energia
una_ciudad
@ciudad
Iruya
¡La respuesta es correcta!
¡Exacto! Si bien:
Pepita e Iruya son objetos bien conocidos;
@energiay @ciudad son atributos;
y una_ciudad es un parámetro;
¡Todas son referencias!
def self.es_feliz_como_su_amigo?
@amigo.felicidad > 105
end
end
Creá un programa que inicialice al amigo de Fito y al nieto de AbueloGervasio de forma
que ambos conozcan al mismo objeto (Juli).
Luego, hacé que el abuelo alimente a su nieto 3 veces. ¿Qué pasará con Fito? ¿Se pondrá
feliz?
¡Dame una pista!
¡Recordá que los números entienden el mensaje times, que recibe un bloque y lo ejecuta
tantas veces como el valor del número!
También recordá que para que el abuelo alimente a su nieto tenés que enviarle el
mensaje alimentar_nieto!.
SOLUCION MIA CON ERROR
module AbueloGervasio
def self.alimentar_nieto!
Juli.comer!()
3.times {@alimentar}
if Fito.feliz!
else
!not
end
end
def alimentar_nieto!
3.times{AbueloGervasio.alimentar_nieto!}
end
Pablo Nicolás S. hace 4 meses
hola, me quede trabado rn la parte de alimentar nieto
Catalina F. Mentoría hace 4 meses
¡Hola Pablo!
La lógica de lo que estamos intentando hacer está muy bien, lo que sucede es que no
debemos de definir con def end. Por ejemplo, para declarar el amigo de Fito solamente
deberíamos de hacer Fito.amigo = Juli. Deberíamos de hacer lo mismo con las tres
declaraciones.
¿Lo modificamos? ¡Adelante!
Pablo Nicolás S. hace 4 meses
Poerdon pero nk me doy cuenta como modificar
Catalina F. Mentoría hace 4 meses
¡Hola Pablo!
Tendríamos que sacar todos los def y los end porque el ejercicio dice que Juli, Fito y
AbueloGervasio ya están declarados. Solamente hay que inicializalos y enviales mensajes.
¿Cómo lo hacemos?:
Fito.amigo = **acá va el amigo de Fito**
AbueloGervasio.nieto = **acá va el nieto del abuelo Gervasio**
3.times{AbueloGervasio.alimentar_nieto!} **esto es lo que pusimos en la línea 9, que está
perfecto**
SOLUCION CORRECTA
Fito.amigo = Juli
AbueloGervasio.nieto = Juli
3.times { AbueloGervasio.alimentar_nieto! }
Si Jor picantea su plato dos veces y Luchi luego suaviza en 1 ají, los Fideos quedan picantes
Ver detalles
Luchi descarta la salsa cuando tiene más de 10 ajíes Ver detalles
module Luchi
def self.suavizar!(plato, cantidad)
if (plato.ajies > 10)
plato.descartar_la_salsa!
else
plato.suavizarse!(cantidad)
module Luchi
module Luchi
def self.suavizar!(plato, cantidad)
if plato.ajies > 10
plato.descartar_la_salsa!
else
plato.suavizarse!
end
end
end
module Jor
def self.plato_del_dia=(plato)
@plato_del_dia = (plato)
end
def self.picantear!
@plato_del_dia.agregar_ajíes(5)
end
end
module Fideos
@ajies = 0
def self.picantear!(cantidad)
@ajíes += (cantidad)
end
def self.picantes?
@ajies > 2
end
def self.agregar_ajíes!(cantidad)
@ajíes += (cantidad)
end
def self.sacar!(cantidad)
@ajíes -= (cantidad)
end
def self.descartar_la_salsa!(cantidad)
@descartar_la_salsa > 10
end
end
module Luchi
def self.suavizar!(plato, cantidad)
if (plato.ajíes > 10)
@plato.descartar_la_salsa!
else
@plato.sacar!(cantidad)
end end end
SOLUCION CORRECTA
module Jor
def self.plato_del_dia=(un_plato)
@plato_del_dia = un_plato
end
def self.picantear!
@plato_del_dia.agregar_picante! 5
end
end
module Fideos
@ajies = 0
def self.picantes?
@ajies > 2
end
def self.descartar_la_salsa!
@ajies = 0
end
def self.agregar_picante!(unos_ajies)
@ajies += unos_ajies
end
def self.quitar_picante!(unos_ajies)
@ajies -= unos_ajies
end
def self.ajies
@ajies
end
end
module Luchi
def self.suavizar!(un_plato,unos_ajies)
if un_plato.ajies > 10
un_plato.descartar_la_salsa!
else
un_plato.quitar_picante!unos_ajies
end
end
end
¡Muy bien! Tu solución pasó todas las pruebas
¡Terminaste Referencias!
Para un objeto pueden existir múltiples nombres: cuando le damos uno nuevo, no estamos
creando una copia del objeto ni modificándolo realmente, sino que estamos creando una
nueva referencia que apunta al objeto. Así que ¡ojo!, si compartís un objeto con otros, y lo
mutás, ¡todos los que tengan una referencia al mismo verán los cambios!
Finalmente, en objetos, todo lo que se parezca a una variable es una referencia, y hay de
muchos tipos:
variables de un programa
variables locales de un método
parámetros de un método
atributos de un objeto
y el nombre global de un objeto bien conocido.
CONSOLA
Fideos.picantes?
=> false
Luchi.suavizar! Fideos, 3
=> -3
Fideos.descartar_la_salsa!
=> 0
Jor.picantear!
undefined method `agregar_picante!' for nil:NilClass (NoMethodError)
Fideos
=> Fideos
Procedimientos Práctica Repetición simple
En la celda a continuación, poné 1976 bolitas Negras, representando el año.
Expresion literal
EXPRESION
COMANDO PALABRA CLAVE
Si hay bolitas verdes, no hace nada
Si no hay bolitas verdes, agrega una
A lo que acabás de hacer, en lógica se lo llama negación y al anteponer
el not decimos que se está negando una expresión. Cualquier expresión
booleana (o sea, que devuelve True o False) se puede negar.
Recordá que la estructura de la alternativa condicional es la siguiente:
[...]
if(condicion) {
//código si se cumple condicion
}
else {
//código si no se cumple condición
}
if(condicion)
{
//hacemos algo
}
else
{
//hacemos otra cosa
}
FUNCIONES
Te recordamos 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( ).
function doble(numero) {
return 2 * numero;
}
Diferente, pero no tanto. Si la comparás con su equivalente Gobstones...
function doble(numero) {
return (2* numero)
}
: Coerciones
Volvamos un momento al código anterior. ¿Notás algo extraño en esta expresión?
x += y; //equivalente a x = x + y;
x *= y; //equivalente a x = x * y;
x -= y; //equivalente a x = x - y;
x++; //equivalente a x = x + 1;
function cuentaExtravagante() {
let numero = 8;
numero *= 2;
numero += 4;
return numero;
}
"numero"
8
16
20
true
¡La respuesta es correcta!
¡Terminaste Variables y procedimientos!
A lo largo de esta lección hiciste muchas cosas nuevas:
imprimiste por pantalla;
conociste los procedimientos en el lenguaje JavaScript, que si bien se
definen igual que las funciones son bien distintos;
utilizaste los dos tipos de variables, locales y globales, y aprendiste sus
diferencias.
LÓGICA BOOLEANA
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.
Ejemplo Mochila abierta o mochila cerrada con abrir o cerrar cierre
let mochilaAbierta = true;
function usarCierre ( ){
mochilaAbierta = !mochilaAbierta; }
A B A⊻B
V V F
V F V
F V V
F F F
Nuestros parámetros color y direccion no tenían ningún valor, pero cuando invocábamos el
procedimiento con argumentos :
PonerYMover(Rojo, Este)
La computadora reemplazaba color por Rojo y direccion por Este, es decir que llenaba esos
"agujeros" con valores concretos, y ejecutaba entonces:
Poner(Rojo)
Mover(Este)
Y de la misma forma, podríamos crear una lista de registros inventados, respetando esa
sintaxis:
[{mes: "febrero", ganancia: 9999}, {mes: "marzo", ganancia: 159}, {mes: "diciembre",
ganancia: 444}]
Esta lista, o cualquier otra que inventemos, ¡puede ser usada en nuestras funciones! Así
como usabamos el procedimiento dandole los valores concretos como Rojo o Este,
podemos darle a nuestra función un valor concreto como la lista que vimos recién (que no
definimos en ningún lugar):
¿Y ahora cómo sabe qué es registro? Ahí viene la magia del for, cuando hacemos
for(let nombre of lista), estamos definiendo una variable (nombre) que nos permitirá
iterar por cada elemento de la lista lista, que en este caso es nuestra lista inventada
de registros. ¿Cómo lo hace? Por cada elemento de la lista, el for ejecutará
reemplazando en cada lugar que diga registro (que es el nombre que le dimos) por
el elemento. Sigamos viendo qué se ejecutaría con el ejemplo anterior. La primera
vez, el for tomará el primer elemento: {mes: "febrero", ganancia: 9999} que es un
registro. Reemplaza entonces en cada lugar que diga registro por {mes: "febrero",
ganancia: 9999} y ejecuta: