Publicidad Google grande + Astroradio
URE foro pequeñas
Programación ágil
 
Notificaciones
Limpiar todo

Programación ágil

EA2J
 EA2J
Mensajes: 3764
#368631  - 28 octubre, 2021 17:51 

Este es un foro de software y el tema va de programación pura y dura. No sé el nivel de interés pero estoy seguro que entre los coegas hay programadores principiantes, avanzados y profesionales, para estos colegas les hago partícipe de una experiencia.

El fin de programar software es crear código para que una máquina resuelva o ayude a realizar tareas, entre estas tareas se encuentras muchas que realizamos los radioaficionados. Ahora bien, cuando se realizan programas de código abierto o se trata de trabajo colectivo no basta con que el código funcione, además el código debe ser limpio, legible, reproducible y auto definido. A este patrón se le llama programación ágil. 

Hay mucho código por Internet con aplicaciones para los radioaficionados, una parte del este código simplemente no funciona o no es reproducible, una gran parte es reproducible pero es un galimatías que no lo entiende ni el que lo escribió.

Este post viene a cuento con una revisión que acabo de hacer de una función que calcula automáticamente el lapso de tiempo entre la hora UTC y la local en función de la fecha. Sabemos que el horario se cambia en los meses de marzo y octubre, concretamente el último domingo de cada mes a las tres de la mañana.

La declaración de números enteros se con notación del tama. Emn lugar de utilizar usigned int, se utiliza uint8_t (8bit) y uint16_t (16bit) 

El código está escrito en C++ 

La primera versión que hice:

uint16_t calc_time_offset(DateTime dt_utc) {
  byte last_day_before_last_monday = 24;  
  byte hour_of_change = 2;
  int winter_offset = 3600; //1 hour = 3600sec
  int summer_offset = 3600 * 2; //2 hour 
  month_name number_month = dt_utc.month();
  dow_name dow_number = dt_utc.dayOfTheWeek();

  if (number_month > march && number_month < october) {
    return summer_offset;
  }

  if (number_month > october || number_month < march) {
    return winter_offset;
 }

  if (number_month == march) {
    if (dt_utc.day() < last_day_before_last_monday) {
      return winter_offset;
    } else {
      if (dow_number == sunday) {
       if (dt_utc.hour() < hour_of_change) {
         return winter_offset;
       } else {
          return summer_offset; 
    }
  } else {
    if (last_day_before_last_monday - dt_utc.day() + dow_number >= 0) {
      return winter_offset;
  } else {
    return summer_offset;
  }
}
}
}

if (number_month = october) {
if (dt_utc.day() < last_day_before_last_monday) {
return summer_offset;
} else {
if (dow_number == sunday) {
if (dt_utc.hour() < hour_of_change) {
return summer_offset;
} else {
return winter_offset;
}
} else {
if (last_day_before_last_monday - dt_utc.day() + dow_number >= 0) {
return summer_offset;
} else {
return winter_offset;
}
}
}
}
}

Comentarios. Las variables con valor fijo se describen en una lis enum que crea una clase de variable int de valor correlativo, por esta razón es más fácil aplicar los valores de variables en ugar de los valores ordinales.

Pasamos a la función un objeto de la clase DataTime,  (dtUtc) creado por la librería que controla el RTC, los métodos que utilizamos son rtc.month(), rtc.day(), rtc.hour() y rtc.dayOfTheWeek(), que contienen el mes (int), día /int), hora (int) día de la semana (int), tabién utilizaremos un método rtc.unixtime() que contiene los segundos transcurridos desde una fecha fija. A este método se le añade el lapso de tiempo del horario de verano (300 segundos) o invierno (7200 segundos). Los datos del tiempo correcponden al horario UTC.

El cálculo del lapso horario se basa en que marzo y octubre tienen ambos 31 días y el mínimo día que puede ser domingo es el 25.

La decisión de la hora del camnbio se resuelkve con una expresión ternaria que reduci código y mejora la comprensión. Ambas funciones trabajan correctactamente, pero la segunda es mucho más clara y reproducible.

Con este formato se evitan una serie de condiciones IF anidadas que hacen compleja la comprensión del código y acorta

 

La misma función revisada:

enum months {ene=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};

enum dow {sun, mon, tue, wed, thu, fre, sat};

 

int calc_time_offset (DateTime dtUtc) {

  months month = dtUtc.month ();

  uint8_t day = dtUtc.day ();

  uint8_t = dt.hour ();

  dow dayOfWeek = dtUtc.dayOfTheWeek ();

  uint16_t summerOffset = 3600;

  uint16_t winterOffset = 7200;

  uint8_t hourOfChange = 3;

 

  switch case {

    case mar:

       if (day <= 24) 

         return winterOffset;

       if (dayOfWeek == sun) {

          return (hour >= hourOfChange) ? summerOffset : winterOffset;

       } else {

          return winterOffset;

       }

 

    case oct:   

     if (day <= 24) 

         return winterOffset;

       if (dayOfWeek == sun) {

          return (hour >= hourOfChange) ? summerOffset : winterOffset;

       } else {

          return winterOffset;

       }

 

    default:

      if (month > mar && month < oct)

        return summerOffset;

     if (month < mar || month > oct)

        return winterOffset;

}

La cultura del esfuerzo se cultiva desde la motivación, no mediante el castigo como algunos quisieran.
http://www.enioea2hw.wordpress.com
73, Enio

ResponderCitar
Inició el tema

QDURE - https://qsl.ure.es


Imprime y confirma tus QSL en tan solo tres click.

Nunca fue tan fácil y cómodo
el confirmar tus contactos.

TIENDA ONLINE URE


Publicaciones, mapas, polos, camisetas, gorras, tazas, forros polares y mucho más...

WEBCLUSTER EA4URE


Conoce el nuevo WebCluster de URE, ahora con nuevos filtros e información y compatible con GDURE