Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

domingo, 5 de abril de 2020

JavaFX. Inecuación de Gott. Calcular fechas del pasado.

Continuando con un post anterior relacionado con la inecuación de Gott, se procede a realizar la misma aplicación pero esta vez utilizando las librerías de JavaFX en las que aparecen nuevos componentes como por ejemplo los "DataPicker" que son utilizados para facilitar selección de fechas.

Se comentó en el post anterior que la "Inecuación de Gott" intentaba calcular el tiempo "de vida" de un evento histórico elegido al azar partiendo de un solo dato que era la fecha del inicio del evento.
En resumidas cuentas la fórmula predice la fecha del fin de un suceso que aún sigue en activo y que finalizará en un futuro aparentemente indeterminado.


Inecuación de Gott:



Ahora la idea NO es calcular cosas que van a suceder en el futuro, sino fechas del pasado, que por otra parte son fáciles de comprobar si los resultados obtenidos corresponden con la realidad consultando en la Wikipedia del hecho histórico en cuestión. Ejemplo:

Un ejemplo claro de un hecho histórico son las caídas de las Torres Gemelas de Nueva York. Todo el mundo se acuerda del año y día de la desaparición de las torres (11S de 2001), pero seguramente la mayoría no sabe la fecha de su inauguración. Imaginemos que no tenemos acceso a internet ni a hemerotecas para consultar año de su inauguración. Sólo disponemos de la fecha actual (04/04/2020) y fecha del fin de las Torres (11/09/2001).

Aplicando la fórmula con una fiabilidad del 50%:
Resultado obtenido: Fecha de inauguración de las Torres Gemelas entre 1946 y 1992
Realidad (consultando Wikipedia): "...Torres Gemelas, inauguradas el 4 de abril de 1973..."
Conclusión: Resultado satisfactorio ya que se encuentra dentro del rango fechas obtenido.

 

Inecuación de Gott aplicada al cálculo de fecha inauguración de las Torres Gemelas:





Ejemplo 2 -> Muro de Berlin (f = 50%):

Hecho histórico: Muro de Berlin
fecha actual: 04/04/2020
fecha caída del muro: 09/11/1989
fecha inauguración: ? (no lo sabemos)

Aplicando la fórmula con una fiabilidad del 50%:
Resultado obtenido: Fecha de inauguración entre 1898 y 1979
Realidad (consultando Wikipedia): "...formó parte de la frontera interalemana desde el 13 de agosto de 1961..."
Conclusión: Resultado satisfactorio ya que se encuentra dentro del rango de fechas obtenido.



Inecuación de Gott aplicada al cálculo de fecha inauguración del Muro de Berlín:

 


Cabe destacar que la "fiabilidad" es inversamente proporcional al grado de precisión. Es decir si queremos ganar en precisión (reducir el rango de fechas en el resultado) debemos bajar la fiabilidad.
Es algo parecido al principio de incertidumbre de Heisenberg que establece que a mayor certeza de la posición de una partícula, menor conocimiento de su momento o cantidad de movimiento y viceversa.


Ejemplo 3 -> Muro de Berlín (f = 1%):

Ahora aplicando a la fórmula una fiabilidad de sólo un 1% (más exactitud pero menos probabilidad):
Resultado obtenido: Fecha de comienzo entre 1958 y 1960
Realidad: Inaugurado en 1961
Conclusión: Como vemos da un resultado casi exacto pero esta fuera del rango obtenido (+exacto -fiable)


Notas varias:
 

Se recomienda dejar una fiabilidad del 50% para que haya un equilibrio entre grado de fiabilidad y grado de precisión.
Se observa que para obtener las fechas del pasado hay que poner en "Fecha_actual" la fecha de finalización. Y en "Fecha de inicio" la fecha actual (inversión de datos de entrada para pasar del futuro al pasado).



Código Java 1 (NewFXMain.java):

package inecuaciongottfx;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class NewFXMain extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("FXML.fxml"));
        Scene scene = new Scene(root);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();
    }

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

}


Código Java 2 (FXMLController.java):

package inecuaciongottfx;

import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.input.MouseEvent;

public class FXMLController implements Initializable {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    double f, fa, tmin, tmax;

    @FXML
    private DatePicker Fecha_Actual;
    @FXML
    private DatePicker Fecha_Inicio;
    @FXML
    private Label Tiempo_Transcurrido;
    @FXML
    private Label Fiabilidad;
    @FXML
    private Slider Slider_Fiabilidad;
    @FXML
    private Label Fecha_Minima;
    @FXML
    private Label Fecha_Maxima;
    @FXML
    private Label lb_fechas;
    @FXML
    private Button Calcular;
    @FXML
    private Button Limpiar;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        limpiar();
        Calcular.setOnMouseClicked((MouseEvent me) -> {
            calcular();
        });
        Limpiar.setOnMouseClicked((MouseEvent me) -> {
            limpiar();
        });
        // control arrastrar -clicar Slider
        Slider_Fiabilidad.setOnMouseClicked((MouseEvent me) -> {
            Fiabilidad.setText(Math.round(Slider_Fiabilidad.getValue()) + " %");
            calcular();
        });
        Slider_Fiabilidad.setOnMouseDragged((MouseEvent me) -> {
            Fiabilidad.setText(Math.round(Slider_Fiabilidad.getValue()) + " %");
            calcular();
        });
    }

    private void limpiar() {
        Fecha_Inicio.setValue(LocalDate.now());
        Fecha_Actual.setValue(LocalDate.now());
        Tiempo_Transcurrido.setText("0");
        Slider_Fiabilidad.setValue(50d);
        Fiabilidad.setText(Slider_Fiabilidad.getValue() + " %");
        Fecha_Minima.setText("00/00/0000");
        Fecha_Maxima.setText("00/00/0000");
        lb_fechas.setText("Resultado:");
    }

    private void calcular() {

        try {
            fa = ((dateFormat.parse(Fecha_Actual.getValue().toString()).getTime() - dateFormat.parse(Fecha_Inicio.getValue().toString()).getTime()) / 86400000);
        } catch (ParseException ex) {
        }

        f = Slider_Fiabilidad.getValue() / 100d;

        Tiempo_Transcurrido.setText("" + (int) Math.round(fa));

        tmin = fa * (Math.abs((f - 1) / (f + 1)));
        tmax = fa * (Math.abs((f + 1) / (f - 1)));

        Fecha_Minima.setText(sumarRestarDiasFecha(Fecha_Actual.getValue(), (int) Math.round(tmin)));
        Fecha_Maxima.setText(sumarRestarDiasFecha(Fecha_Actual.getValue(), (int) Math.round(tmax)));

        lb_fechas.setText("Resultado: Duración entre " + Math.round(tmin) + " y " + Math.round(tmax) + " días.");

    }

    public String sumarRestarDiasFecha(LocalDate ld, int dias) {

        // convertir Localdate a Date
        Instant instant = Instant.from(ld.atStartOfDay(ZoneId.systemDefault()));
        Date date = Date.from(instant);

        // sumar dias a la fecha
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, dias);

        // convertir Date a Localdate
        instant = calendar.getTime().toInstant();
        ld = instant.atZone(ZoneId.systemDefault()).toLocalDate();

        // formato dd-mm-yyy
        String[] aux = ld.toString().split("-");
        return aux[2] + "/" + aux[1] + "/" + aux[0];

    }

}


Código FMXL.fxml (generado con Scene Builder):

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.effect.Glow?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" prefHeight="580.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inecuaciongottfx.FXMLController">
   <children>
      <Label alignment="CENTER" contentDisplay="TEXT_ONLY" layoutX="70.0" layoutY="14.0" text="Inecuación de Gott. ¿cuánto tiempo dura algo?" textAlignment="CENTER" textFill="#077034" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="16.0">
         <font>
            <Font name="Tw Cen MT Condensed Bold" size="29.0" />
         </font>
         <opaqueInsets>
            <Insets />
         </opaqueInsets>
         <padding>
            <Insets bottom="10.0" />
         </padding>
         <effect>
            <Glow />
         </effect>
      </Label>
      <Pane layoutX="56.0" layoutY="92.0" prefHeight="364.0" prefWidth="494.0" translateY="5.0" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0">
         <children>
            <Label alignment="CENTER" contentDisplay="TEXT_ONLY" text="Entrada de datos:" textAlignment="CENTER" textFill="#067235" underline="true">
               <font>
                  <Font name="Verdana Bold" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </Label>
            <GridPane layoutY="29.0" prefHeight="122.0" prefWidth="493.0">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="195.4000244140625" minWidth="10.0" prefWidth="186.60003662109375" />
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.199951171875" minWidth="10.0" prefWidth="143.39996337890625" />
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="75.0" prefWidth="75.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <Label depthTest="ENABLE" text="Fecha inicio:">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fecha actual:" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Tiempo transcurrido:" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fiabilidad (%):" GridPane.rowIndex="3">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <DatePicker fx:id="Fecha_Inicio" promptText="1/1/2000" GridPane.columnIndex="1" />
                  <DatePicker fx:id="Fecha_Actual" promptText="1/1/2000" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                  <Label fx:id="Tiempo_Transcurrido" alignment="CENTER" contentDisplay="CENTER" prefHeight="18.0" prefWidth="163.0" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Slider fx:id="Slider_Fiabilidad" blockIncrement="1.0" snapToTicks="true" value="50.0" GridPane.columnIndex="1" GridPane.rowIndex="3" />
                  <Label fx:id="Fiabilidad" text="50 %" GridPane.columnIndex="2" GridPane.rowIndex="3">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label contentDisplay="CENTER" text="días" textAlignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets left="10.0" right="10.0" />
                     </padding>
                  </Label>
               </children>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </GridPane>
            <Label alignment="CENTER" contentDisplay="TEXT_ONLY" layoutY="191.0" text="Intervalo de duración del evento:" textAlignment="CENTER" textFill="#067235" translateY="-20.0" underline="true">
               <font>
                  <Font name="Verdana Bold" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </Label>
            <GridPane layoutY="219.0" prefHeight="143.0" prefWidth="493.0" translateY="-15.0">
               <columnConstraints>
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="195.4000244140625" minWidth="10.0" prefWidth="186.60003662109375" />
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.199951171875" minWidth="10.0" prefWidth="143.39996337890625" />
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
               </columnConstraints>
               <rowConstraints>
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
               </rowConstraints>
               <children>
                  <Label text="Fecha mínima:" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fecha máxima:" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label fx:id="Fecha_Minima" alignment="CENTER" prefWidth="163.0" text="00/00/0000" GridPane.columnIndex="1" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Label fx:id="Fecha_Maxima" alignment="CENTER" prefWidth="163.0" text="00/00/0000" GridPane.columnIndex="1" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Label fx:id="lb_fechas" prefHeight="18.0" prefWidth="501.0" text="Resultado: " GridPane.columnSpan="3" GridPane.rowIndex="4">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <GridPane.margin>
                        <Insets left="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Separator prefWidth="200.0" GridPane.columnSpan="3" GridPane.rowIndex="3" />
                  <Separator prefWidth="200.0" GridPane.columnSpan="3" />
               </children>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </GridPane>
         </children>
      </Pane>
      <HBox layoutX="389.0" layoutY="383.0" prefHeight="28.0" prefWidth="161.0" translateX="-10.0" translateY="100.0" AnchorPane.bottomAnchor="150.0">
         <children>
            <Button fx:id="Calcular" mnemonicParsing="false" text="Calcular" textAlignment="CENTER">
               <font>
                  <Font name="Verdana" size="14.0" />
               </font>
            </Button>
            <Button fx:id="Limpiar" alignment="CENTER_RIGHT" contentDisplay="RIGHT" mnemonicParsing="false" text="Limpiar" textAlignment="CENTER">
               <font>
                  <Font name="Verdana" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
               <HBox.margin>
                  <Insets left="10.0" />
               </HBox.margin>
            </Button>
         </children>
      </HBox>
   </children>
</AnchorPane>


No hay comentarios:

Publicar un comentario

Con la tecnología de Blogger.