domingo, 12 de junio de 2016

Nomina++

Este programa genera una lista de las fechas de un dia de la semana dentro de un periodo y escoge algunas al azar. En este caso quiero 44, fechas que caigan en jueves escogidos dentro del periodo de las ultimas 76 semanas.

En el se puede ver el uso de una función generadora que esta llenando un vector, despues vemos como se aplican algoritmos sobre el vector para eliminar los dias que no queremos, se aleatorizan, se eliminan de nuevo unos cuantos dejando solo los que queremos, se reordenan, se les da el formato deseado y finalmente se imprimen en pantalla.

Para compilar usa un compilador C++11

  1 /****************************
  2  Programa para calcular
  3  las fechas de una nomina
  4  Version: 2.0
  5  Licencia: GPL v3
  6  Autor: Jose Gabriel Espinoza Reyes
  7  ****************************/
  8  
  9  #define USE_STD_PUT_TIME 0
 10  
 11  #include <iostream>
 12  #include <vector>
 13  #include <algorithm>
 14  #include <chrono>
 15  #include <iterator>
 16  #if USE_STD_PUT_TIME == 1
 17      #include <iomanip>
 18  #endif
 19  
 20  
 21  namespace virtuosonic {
 22  
 23  using namespace std;
 24  using namespace std::chrono;
 25  /** configuracion */
 26  const unsigned kCantidadSemanas = 44;///cantidad que se desea de salida
 27  const unsigned kSemanasAntiguedad =76;/// semana mas vieja a calcular
 28  const int kDiaDeCorte = 4;//jueves
 29  const unsigned kSegDia = 86400; //segundo q tiene un dia
 30  
 31  /**
 32   * generador que produce std::chrono::system_clock::time_point
 33   * retrasando la fecha un dia por cada llamada a la funcion
 34  */
 35  class dias_pasados_gen
 36  {
 37      public:
 38          dias_pasados_gen() {_timepoint = system_clock::now();}
 39          system_clock::time_point operator () ()
 40          {
 41              system_clock::time_point tmp = _timepoint;
 42              _timepoint -= hours(24);
 43              return tmp;
 44          }
 45      private:
 46          system_clock::time_point _timepoint;
 47  };
 48  
 49  bool es_corte_de_nomina(system_clock::time_point tp)
 50  {
 51      time_t c_tp = system_clock::to_time_t(tp);
 52      tm* tm_dia = localtime(&c_tp);
 53      if (tm_dia->tm_wday == kDiaDeCorte)return false;
 54      //else ;)
 55      return true;
 56  }
 57  
 58  #if USE_STD_PUT_TIME == 0
 59  /**
 60   * implementacion incorrecta de put_time, pero funcional,
 61   * ya que gcc todavia no lo implementa
 62   */
 63  char* put_time(tm* t,const char* fmt)
 64  {
 65      char* lstr = new char[100];
 66      strftime(lstr,100,fmt,t);
 67      return lstr;
 68  }
 69  #endif
 70  
 71  /**
 72   * calcula el periodo de tiempo de una semana de nomina
 73   * sabiendo solo el dia de corte
 74   */
 75  class semana_de_nomina
 76  {
 77      public:
 78          semana_de_nomina(const system_clock::time_point& tp) {_tp = tp;}
 79          semana_de_nomina() {}
 80          semana_de_nomina(const semana_de_nomina& sn) {_tp = sn._tp;}
 81          semana_de_nomina& operator= (const semana_de_nomina& sn) {_tp = sn._tp;return *this;}
 82          semana_de_nomina& operator= (const system_clock::time_point& tp) {_tp = tp;return *this;}
 83          friend ostream& operator<<(ostream& os,const semana_de_nomina& sn)
 84          {
 85              time_t tmp = system_clock::to_time_t(sn._tp - hours(24*6));
 86              os << put_time(localtime(&tmp),"%d/%m/%Y") << "-";
 87              tmp = system_clock::to_time_t(sn._tp);
 88              os << put_time(localtime(&tmp),"%d/%m/%Y");
 89              return os;
 90          }
 91      private:
 92         system_clock::time_point _tp;
 93  };
 94  
 95  }//namespace virtuosonic
 96  
 97  int main()
 98  {
 99      //inicializar
100      using namespace virtuosonic;
101      vector<system_clock::time_point> diaspago(kSemanasAntiguedad*7);
102      //cargar dias de corte
103      dias_pasados_gen generador;
104      generate(diaspago.begin(),diaspago.end(),generador);
105      diaspago.erase(remove_if(diaspago.begin(),diaspago.end(),es_corte_de_nomina),diaspago.end());
106      //filtar y ordenar
107      random_shuffle(diaspago.begin(),diaspago.end());
108      diaspago.erase(diaspago.begin(),diaspago.begin()+kSemanasAntiguedad-kCantidadSemanas);
109      sort(diaspago.begin(),diaspago.end());
110      //generar semanas
111      vector<semana_de_nomina> semanas(diaspago.size());
112      copy(diaspago.begin(),diaspago.end(),semanas.begin());
113      //imprimir
114      copy(semanas.begin(),semanas.end(),ostream_iterator<semana_de_nomina>(cout,"\n"));
115      return 0;
116  }

No hay comentarios:

Publicar un comentario