Autor Tema: Código Java transformar horas totales en semanas días y horas operador módulo  (Leído 6489 veces)

CoduJ

  • Sin experiencia
  • *
  • Mensajes: 28
    • Ver Perfil
Buenas, espero que se encuentren bien.

Necesito ayuda para la comprensión de un código, realmente "entiendo" (nótese comillas) lo que está pasando... Pero no del todo:

Código: [Seleccionar]
     
//HorasTotrales es un objeto Scanner
Semanas = HorasTotales / 168;
Dias = HorasTotales%168 / 24;
Horas = HorasTotales%24;

¿Qué está pasando?, ¿por qué se usa el "%"? (¿se usa el resto para reducir valores para lo que son los días y horas? No entiendo), agradecería mucho si es que también me lo podrían explicar con detalle.
« Última modificación: 25 de Octubre 2020, 20:58 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Re:Comprensión de un código
« Respuesta #1 en: 22 de Abril 2020, 17:47 »
Este es un tema más de matemáticas que de programación.
Por cierto, el código de ejemplo no es correcto, las horas no se están calculando bien porque hace directamente módulo entre 24 sobre las horas totales. Y no es correcto.

Pero vamos a verlo poco a poco.


Supón que HorasTotales = 200

Y queremos saber a cuantas semanas, días y horas equivalen esa cantidad de horas.

Si una semana tiene 168 horas, pues es evidente que si dividimos esas HorasTotales entre 168, nos dirá a cuantas semanas equivalen

200 / 168 = 1,19

Vale, con ese resultado sabemos que 200 horas equivale a 1 semana y un poco más.
Esa parte decimal, el 0,19, no es una semana completa, pero equivale a cierta cantidad de días y de horas.
Pero, ¿como transformamos ese 0.19 en días? ¿Dividimos entre 24 porque un día tiene 24 horas?

0,19 / 24 = 0.007916

Buff... estamos obteniendo valores decimales muy pequeños que no nos dicen gran cosa.

Es evidente que el razonamiento matemático que estamos siguiendo no es el bueno.

No podemos coger la parte decimal y seguir haciendo cálculos con ella.

Lo que tenemos que coger es el "resto", que como su propio nombre indica, es lo que "resta" sin computar tras haber hecho la división, es lo que realmente ha sobrado.

Para obtener el resto se usa el operador "módulo", que en muchos lenguajes (no todos) se representa con el símbolo %.
Ojo porque puede confundirnos y pensar que estamos calculando porcentajes. Pero no es así, en Java ese operador lo que nos da es el resto.

Entonces, recapitulemos.
Si hacemos una "división entera" de HorasTotales entre 168 nos dirá las "semanas enteras" equivalentes.
En el código que has puesto no se ve, pero la variable Semanas seguramente será de tipo int. Esto fuerza a que la división sea "entera", es decir, esa variable no va a recoger la parte decimal, solo la parte entera.

Así que:
Semanas = 200 / 168 = 1

Ya tenemos calculado el valor de Semanas.
Ahora queremos calcular el valor de Dias.
Como hemos dicho, necesitamos el resto resultante de dividir entre 168, el valor que nos daba las semanas.
Para ello usamos el operador módulo:

Dias = 200 % 168 = 32

Tenemos el valor 32, pero eso es lo que ha sobrado al transformar en semanas.
Eso que sobra, ahora hay que transformarlo en días

32 / 24 = 1,33333

Similar a como ocurría antes, tenemos 1 día entero y un poco más.
Ese poco más, el 0.3333, no da para un día, pero si equivaldrá a unas horas que hay que calcular.
Así que una vez más, habrá que obtener el resto, que nos indicará las horas que han sobrado.
Es aquí donde fallaba el código que has puesto de ejemplo. Para las horas no se hace mod 24 directamente sobre las hora totales, si no sobre el resto obtenido al dividir entre 168

Recapitulación final:
Semanas = 200 / 168 = 1
Dias = 200 % 168 / 24 = 1
Horas = (200 % 168) % 24 = 8

Según esto, 200 horas equivalen a 1 semana, 1 día y 8 horas.
¿Es correcto?
Pues a ver...

1 semana = 168 horas
       1 dia =   24 horas
       resto =     8 horas
                  ----------
                   200 horas


Esto, escrito así rápido en Java podría ser:

Código: [Seleccionar]
public class CalculaSemanas {

public static void main(String[] args) {

Scanner teclado = new Scanner(System.in);

System.out.print("Horas totales: ");
int horasTotal = teclado.nextInt();

int semanas = horasTotal / 168;
int dias = horasTotal % 168 / 24;
int horas = (horasTotal % 168) % 24;

System.out.println("\n" + horasTotal + " horas equivalen a");
System.out.println("- Semanas: " + semanas);
System.out.println("- Dias: " + dias);
System.out.println("- Horas: " + horas);

teclado.close();
}

}

Y si probamos a ejecutarlo en pantalla nos da este resultado:
Citar
Horas totales: 200

200 horas equivalen a
- Semanas: 1
- Dias: 1
- Horas: 8

Y bueno, espero haberme explicado bien.

Como digo, esto es más matemáticas que programación. Hay que entender como obtener el resto de la división y qué se puede calcular con él.

Pregunta lo que necesites. Y si alguien sabe explicarlo mejor que yo, por favor, que lo haga y todos aprendemos más.

Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

CoduJ

  • Sin experiencia
  • *
  • Mensajes: 28
    • Ver Perfil
Re:Comprensión de un código
« Respuesta #2 en: 27 de Abril 2020, 02:05 »
Este es un tema más de matemáticas que de programación.
Por cierto, el código de ejemplo no es correcto, las horas no se están calculando bien porque hace directamente módulo entre 24 sobre las horas totales. Y no es correcto.

Pero vamos a verlo poco a poco.


Supón que HorasTotales = 200

Y queremos saber a cuantas semanas, días y horas equivalen esa cantidad de horas.

Si una semana tiene 168 horas, pues es evidente que si dividimos esas HorasTotales entre 168, nos dirá a cuantas semanas equivalen

200 / 168 = 1,19

Vale, con ese resultado sabemos que 200 horas equivale a 1 semana y un poco más.
Esa parte decimal, el 0,19, no es una semana completa, pero equivale a cierta cantidad de días y de horas.
Pero, ¿como transformamos ese 0.19 en días? ¿Dividimos entre 24 porque un día tiene 24 horas?

0,19 / 24 = 0.007916

Buff... estamos obteniendo valores decimales muy pequeños que no nos dicen gran cosa.

Es evidente que el razonamiento matemático que estamos siguiendo no es el bueno.

No podemos coger la parte decimal y seguir haciendo cálculos con ella.

Lo que tenemos que coger es el "resto", que como su propio nombre indica, es lo que "resta" sin computar tras haber hecho la división, es lo que realmente ha sobrado.

Para obtener el resto se usa el operador "módulo", que en muchos lenguajes (no todos) se representa con el símbolo %.
Ojo porque puede confundirnos y pensar que estamos calculando porcentajes. Pero no es así, en Java ese operador lo que nos da es el resto.

Entonces, recapitulemos.
Si hacemos una "división entera" de HorasTotales entre 168 nos dirá las "semanas enteras" equivalentes.
En el código que has puesto no se ve, pero la variable Semanas seguramente será de tipo int. Esto fuerza a que la división sea "entera", es decir, esa variable no va a recoger la parte decimal, solo la parte entera.

Así que:
Semanas = 200 / 168 = 1

Ya tenemos calculado el valor de Semanas.
Ahora queremos calcular el valor de Dias.
Como hemos dicho, necesitamos el resto resultante de dividir entre 168, el valor que nos daba las semanas.
Para ello usamos el operador módulo:

Dias = 200 % 168 = 32

Tenemos el valor 32, pero eso es lo que ha sobrado al transformar en semanas.
Eso que sobra, ahora hay que transformarlo en días

32 / 24 = 1,33333

Similar a como ocurría antes, tenemos 1 día entero y un poco más.
Ese poco más, el 0.3333, no da para un día, pero si equivaldrá a unas horas que hay que calcular.
Así que una vez más, habrá que obtener el resto, que nos indicará las horas que han sobrado.
Es aquí donde fallaba el código que has puesto de ejemplo. Para las horas no se hace mod 24 directamente sobre las hora totales, si no sobre el resto obtenido al dividir entre 168

Recapitulación final:
Semanas = 200 / 168 = 1
Dias = 200 % 168 / 24 = 1
Horas = (200 % 168) % 24 = 8

Según esto, 200 horas equivalen a 1 semana, 1 día y 8 horas.
¿Es correcto?
Pues a ver...

1 semana = 168 horas
       1 dia =   24 horas
       resto =     8 horas
                  ----------
                   200 horas


Esto, escrito así rápido en Java podría ser:

Código: [Seleccionar]
public class CalculaSemanas {

public static void main(String[] args) {

Scanner teclado = new Scanner(System.in);

System.out.print("Horas totales: ");
int horasTotal = teclado.nextInt();

int semanas = horasTotal / 168;
int dias = horasTotal % 168 / 24;
int horas = (horasTotal % 168) % 24;

System.out.println("\n" + horasTotal + " horas equivalen a");
System.out.println("- Semanas: " + semanas);
System.out.println("- Dias: " + dias);
System.out.println("- Horas: " + horas);

teclado.close();
}

}

Y si probamos a ejecutarlo en pantalla nos da este resultado:
Citar
Horas totales: 200

200 horas equivalen a
- Semanas: 1
- Dias: 1
- Horas: 8

Y bueno, espero haberme explicado bien.

Como digo, esto es más matemáticas que programación. Hay que entender como obtener el resto de la división y qué se puede calcular con él.

Pregunta lo que necesites. Y si alguien sabe explicarlo mejor que yo, por favor, que lo haga y todos aprendemos más.

Un saludo.
Vale, creo que comprendo.
Pero creo que lo que necesito es como funciona el "%", estoy un tanto confundido, sé que este operador solo obtiene el resto de una división, ¿pero solo toma el primer resto? De hecho, mientras veía ejercicios en Java, me tope con este (un tanto similar al anterior):
Código: [Seleccionar]
import java.util.Scanner;

public class Practica_7 {
   public static void main(String[] args) {
   int num;
   int unidades, decenas;
   Scanner Entrada = new Scanner(System.in);
// esta versión muesrta 11 como diez y uno.
// es una forma de hacerlo bastante burda.

// se puede poner algunos condicionales para los números especiales: 11,12,...
// y otro condicional para mostrar "y"
   System.out.print("Introduzca un número (0 a 99): ");
   num=Entrada.nextInt();
   unidades = num % 10;
   decenas = num / 10;
   switch(decenas){
      case 0:
         System.out.print("");
      break;
      case 1:
         System.out.print("diez");
      break;
      case 2:
         System.out.print("veinte");
      break;
      case 3:
         System.out.print("treinta");
      break;
      case 4:
         System.out.print("cuarenta");
      break;
      case 5:
         System.out.print("cincuenta");
      break;
      case 6:
         System.out.print("sesenta");
      break;
      case 7:
         System.out.print("setenta");
      break;
      case 8:
         System.out.print("ochenta");
      break;
      case 9:
         System.out.print("noventa");
      break;
   }
   System.out.print (" y ");
   switch(unidades){
   case 0:
      System.out.println("");
   break;
   case 1:
      System.out.println("uno");
   break;
   case 2:
      System.out.println("dos");
   break;
   case 3:
      System.out.println("tres");
   break;
   case 4:
      System.out.println("cuatro");
   break;
   case 5:
      System.out.println("cinco");
   break;
   case 6:
      System.out.println("seis");
   break;
   case 7:
      System.out.println("siete");
   break;
   case 8:
      System.out.println("ocho");
   break;
   case 9:
      System.out.println("nueva");
   break;
      }
   }
}
El primer y segundo problema lo "entiendo" (nótese comillas), al igual que el "%", pero me cuesta imaginar como lo podría aplicar a muchas otras cosas, lamento las molestias.

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Re:Comprensión de un código
« Respuesta #3 en: 27 de Abril 2020, 17:12 »
El operador módulo te da el resto final.
Por ejemplo, mira la división de esta imagen:




Si en el código hacemos un 243 % 5, el resultado que nos dará sera 3

Un ejemplo muy habitual en programación para practicar el operador módulo es un programa que reciba un número y diga si es par o impar.
La forma de saber si un número es par, es dividir entre 2 y comprobar si el resto es 0.
Es decir, si tenemos el número guardado en una variable llamada num, pues preguntaríamos esto:

Código: [Seleccionar]
if (num % 2 == 0)
    System.out.println("Es par");
else
    System.out.println("Es impar);

De este ejemplo, podemos deducir que también podemos usarlo para saber si un número es múltiplo de otro.
De nuevo, imagina que tenemos num1 y num2. Si al dividir num1 entre num2, el resto es cero, significa que num1 es múltiplo de num2.

Mayormente, el resto es útil en aplicaciones matemáticas como por ejemplo una técnica para dividir polinomios (Teorema del residuo/resto).


Pero hay también algún que otro uso curioso.

Por ejemplo en España, los DNI/NIF para identificar a cada ciudadano consta de una cadena con un número de 8 cifras y una letra.
Esa letra no es al azar, depende del resto de ese número al dividir entre 23.

En el curso de Java se propone resolver este ejercicio en Java.
Esta más pensado para aprender a  usar arrays, pero bueno, puedes intentarlo.


NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

CoduJ

  • Sin experiencia
  • *
  • Mensajes: 28
    • Ver Perfil
Re:Comprensión de un código
« Respuesta #4 en: 28 de Abril 2020, 00:35 »
El operador módulo te da el resto final.
Por ejemplo, mira la división de esta imagen:




Si en el código hacemos un 243 % 5, el resultado que nos dará sera 3

Un ejemplo muy habitual en programación para practicar el operador módulo es un programa que reciba un número y diga si es par o impar.
La forma de saber si un número es par, es dividir entre 2 y comprobar si el resto es 0.
Es decir, si tenemos el número guardado en una variable llamada num, pues preguntaríamos esto:

Código: [Seleccionar]
if (num % 2 == 0)
    System.out.println("Es par");
else
    System.out.println("Es impar);

De este ejemplo, podemos deducir que también podemos usarlo para saber si un número es múltiplo de otro.
De nuevo, imagina que tenemos num1 y num2. Si al dividir num1 entre num2, el resto es cero, significa que num1 es múltiplo de num2.

Mayormente, el resto es útil en aplicaciones matemáticas como por ejemplo una técnica para dividir polinomios (Teorema del residuo/resto).


Pero hay también algún que otro uso curioso.

Por ejemplo en España, los DNI/NIF para identificar a cada ciudadano consta de una cadena con un número de 8 cifras y una letra.
Esa letra no es al azar, depende del resto de ese número al dividir entre 23.

En el curso de Java se propone resolver este ejercicio en Java.
Esta más pensado para aprender a  usar arrays, pero bueno, puedes intentarlo.
Ah vale, ¡muchas gracias otra vez Kabuto!.

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".