histogram with underlying type of minutes

A class that dumps a histogram of time events in a bar graph like way to an output stream.

see histogram for a more general class.

Download timehistogram.zip

Synopsis:

timehistogram.h
timehistogram.cpp
timehistogram_test.cpp


timehistogram.h

Synopsis
#pragma once

#include <ostream>
using std::ostream;

class TimeHistogram
  {
  public:
    TimeHistogram();
    ~TimeHistogram();

    void bump(long txntime);
    void print(std::ostream& os);

  private:
    class Private;
    Private& impl;
  } ;

timehistogram.cpp

Synopsis
#include "TimeHistogram.h"
#include <crtdbg.h>

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

const long cMaxStars = 50;
class Slot
  {
  public:
    Slot()
      {
      init(0, 0);
      }
    void init(long start, long end)
      {
      tStart = start;
      tEnd = end;
      count = 0;
      }
    bool Contains(long txntime)
      {
      if (txntime < tStart || txntime > tEnd) return false;
      count++;
      return true;
      }
    void printStars(long max, ostream& os)
      {
      if (IsEmpty()) return;
      print(os);
      os << string(CalcNumStars(max), '*') << endl;
      }
    long getGreater(long max)
      {
      return (count > max) ? count : max;
      }
  private:
    void print(ostream& os)
      {
      os << setw(4) << tStart 
        << " - " 
        << setw(4) << tEnd
        << setw(6) << count
        << " : ";
      }
    int CalcNumStars(long max)
      {
      return (count * cMaxStars) / max;
      }
    bool IsEmpty()
      {
      return count == 0;
      }
  private:
    long tStart;
    long tEnd;
    long count;
  };

const long cMinTime  = 0;
const long cMaxTime  = 1439; //24*60 - 1
const long cDuration = 30;
const int  cMaxSlots = ((cMaxTime - cMinTime) / cDuration) + 1;
class Slots
  {
  public:
    void init(long duration, long start, long end)
      {
      mMax = -1;
      int i;
      for (i = 0; i < cMaxSlots; ++i)
        {
        if ((start + duration) >= end) break;
        mSlots[i].init(start, start + duration);
        start += duration;
        }
      mSlots[i].init(cMinTime, cMaxTime);
      }
    void bump(long txntime)
      {
      for (int i = 0; i < cMaxSlots; ++i)
        {
        if (mSlots[i].Contains(txntime)) 
          {
          mMax = mSlots[i].getGreater(mMax);
          break;
          }
        }
      }
    void print(ostream& os)
      {
      for (int i = 0; i < cMaxSlots; ++i)
        mSlots[i].printStars(mMax, os);
      }
  private:
    Slot mSlots[cMaxSlots];
    long mMax;
  } ;

class TimeHistogram::Private
  {
  public:
    Slots slots;
  } ;

TimeHistogram::TimeHistogram()
: impl(* new Private())
  {
  impl.slots.init(cDuration, cMinTime, cMaxTime);
  }
TimeHistogram::~TimeHistogram()
  {
  delete &impl;
  }
void TimeHistogram::bump(long txntime)
  {
  impl.slots.bump(txntime);
  }
void TimeHistogram::print(ostream& os)
  {
  impl.slots.print(os);
  }

timehistogram_test.cpp

Synopsis
#include <strstream>

//#define NODEBUGNEW
#include "utx.h"

#include "timehistogram.h"
using namespace std;

TEST(empty)
  {
  TimeHistogram th;
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), "");
  }

TEST(oneentry)
  {
  TimeHistogram th;
  th.bump(0);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), "   0 -   30     1 : **************************************************\n");
  }

TEST(twoentry_same)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(0);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), "   0 -   30     2 : **************************************************\n");
  }

TEST(twoentry_samehalfhour)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(1);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), "   0 -   30     2 : **************************************************\n");
  }

TEST(twoentry_oneeach)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(31);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), 
    "   0 -   30     1 : **************************************************\n"
    "  30 -   60     1 : **************************************************\n"
    );
  }

TEST(twoentry_oneeach_2)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(61);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), 
    "   0 -   30     1 : **************************************************\n"
    "  60 -   90     1 : **************************************************\n"
    );
  }

TEST(twoentry_oneeach_3)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(24*60 - 1);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), 
    "   0 -   30     1 : **************************************************\n"
    "   0 - 1439     1 : **************************************************\n"
    );
  }

TEST(twoentry_oneeach_4)
  {
  TimeHistogram th;
  th.bump(0);
  th.bump(23*60);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(), 
    "   0 -   30     1 : **************************************************\n"
    "1350 - 1380     1 : **************************************************\n"
    );
  }


TEST(manyentry)
  {
  TimeHistogram th;
  for(int i=0; i < 10; ++i)
    th.bump(0);
  th.bump(23*60);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(),
    "   0 -   30    10 : **************************************************\n"
    "1350 - 1380     1 : *****\n"
    );
  }

TEST(manyentry_half)
  {
  TimeHistogram th;
  for(int i=0; i < 10; ++i)
    th.bump(0);
  for(int i=0; i < 5; ++i)
    th.bump(23*60);
  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(),
    "   0 -   30    10 : **************************************************\n"
    "1350 - 1380     5 : *************************\n"
    );
  }

TEST(manyentry_oneineach)
  {
  TimeHistogram th;
  th.bump(1);
  int i;
  for(i = 30; i < 1409; i += 30)
    {
    th.bump(i);
    th.bump(i + 1);
    }
  th.bump(i);

  strstream s;
  th.print(s);
  s << ends;
  utxassert(s.str(),
    "   0 -   30     2 : **************************************************\n"
    "  30 -   60     2 : **************************************************\n"
    "  60 -   90     2 : **************************************************\n"
    "  90 -  120     2 : **************************************************\n"
    " 120 -  150     2 : **************************************************\n"
    " 150 -  180     2 : **************************************************\n"
    " 180 -  210     2 : **************************************************\n"
    " 210 -  240     2 : **************************************************\n"
    " 240 -  270     2 : **************************************************\n"
    " 270 -  300     2 : **************************************************\n"
    " 300 -  330     2 : **************************************************\n"
    " 330 -  360     2 : **************************************************\n"
    " 360 -  390     2 : **************************************************\n"
    " 390 -  420     2 : **************************************************\n"
    " 420 -  450     2 : **************************************************\n"
    " 450 -  480     2 : **************************************************\n"
    " 480 -  510     2 : **************************************************\n"
    " 510 -  540     2 : **************************************************\n"
    " 540 -  570     2 : **************************************************\n"
    " 570 -  600     2 : **************************************************\n"
    " 600 -  630     2 : **************************************************\n"
    " 630 -  660     2 : **************************************************\n"
    " 660 -  690     2 : **************************************************\n"
    " 690 -  720     2 : **************************************************\n"
    " 720 -  750     2 : **************************************************\n"
    " 750 -  780     2 : **************************************************\n"
    " 780 -  810     2 : **************************************************\n"
    " 810 -  840     2 : **************************************************\n"
    " 840 -  870     2 : **************************************************\n"
    " 870 -  900     2 : **************************************************\n"
    " 900 -  930     2 : **************************************************\n"
    " 930 -  960     2 : **************************************************\n"
    " 960 -  990     2 : **************************************************\n"
    " 990 - 1020     2 : **************************************************\n"
    "1020 - 1050     2 : **************************************************\n"
    "1050 - 1080     2 : **************************************************\n"
    "1080 - 1110     2 : **************************************************\n"
    "1110 - 1140     2 : **************************************************\n"
    "1140 - 1170     2 : **************************************************\n"
    "1170 - 1200     2 : **************************************************\n"

    "1200 - 1230     2 : **************************************************\n"
    "1230 - 1260     2 : **************************************************\n"
    "1260 - 1290     2 : **************************************************\n"
    "1290 - 1320     2 : **************************************************\n"
    "1320 - 1350     2 : **************************************************\n"
    "1350 - 1380     2 : **************************************************\n"
    "1380 - 1410     2 : **************************************************\n"
    );
  }






Contact me about content on this page using john_web-at-arrizza-dot-com
For Web Master or site problems contact: webadmin-at-arrizza-dot-com
Copyright John Arrizza (c) 2001,2002,2003,2004,2005,2006,2007