Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Every OffLine hour of the day, last 15 months.

38 views
Skip to first unread message

Jeff-Relf.Me

unread,
Jan 19, 2017, 3:58:05 AM1/19/17
to
Here's a challenge for you ( Mr. DFS ).
Given this input ( when my monitor was off ):

http://Jeff-Relf.Me/SleepLog.TXT

Produce this output:

A table showing every HalfHour of the day OffLine, last 15 months:

http://Jeff-Relf.Me/SleepPat.HTM
http://Jeff-Relf.Me/SleepPat.PNG

Here's how _I did it:

void SleepPat() { LnP HardOut =
L" My 118 by 235 block of text is omitted here, for room. \n"
L" See 'HardOut' in X.CPP in 'http://Jeff-Relf.Me/X.ZIP' \n";
L" Help/Settings: 'http://Jeff-Relf.Me/X.HTM' \n";

// "TurnHr" is when the day begins, 3 am:

const int TurnHr = 3, DaySecs = 24*60*60, Rows = 48,
TopLns = 57, LnLen = 236, Cols = LnLen - 8, Hrs = 48 ;

int rv, _Row, Day, xAxisDrawn, Bot, Dur, DateLine,
Col, StartngRow, H, M ;

float fDur ; LnA LL ; LnP P, Tok, Date, _Out ;
i64 aDate, TopDate ; tm DayRec = {}, aRec; char _Month[8];
wchar Hex, ReHex, Ch, Ch2, sDay[8];

if ( Diff_Load = 1, !Load_File( LocDir, L"SleepLog.TXT" ) ) {
Sh( L"-- Couldn't READ \"%s\".", TheOpenFile ); return; }

DayRec.tm_isdst = -1, TopDate = xAxisDrawn = 0;

// "_B_Sh" is a OneMeg+ dynamic buffer I use, occationally.
_Out = _B_Sh, strCpy( _Out, HardOut );

// "fpLines" is the dynamic array of lines, from "Load_File()", above.
{ LoopPP( Ln, fpLines ) {

if ( LL = PP + 3, LL >= EE || !Eq( B + 19, L"offline:" ) )
// Get ( the line after ) the "offline:" line.
continue;

// Get the Month, Day, and Year OffLine info:
B = *LL, Date = B += 12 - B[-1], _Str( _Month, "%.3S", Date );
LoopJ(12) if ( *pInt( _Month ) == Mos[ J ] ) break ;

// _Only tm's Month, Day, and Year fields are set/used:
DayRec.tm_mon = J, DayRec.tm_mday = AtoI( Date + 4 );
DayRec.tm_year = AtoI( Date + 18 ) - 1900, aDate = mktime( &DayRec );

if ( !xAxisDrawn ) {
// "TopDate" ( i64 seconds since 1900 ) is the most recent date.
xAxisDrawn = 1, aRec = DayRec, TopDate = mktime( &aRec );
LoopBot(2) { LoopBacCol( Cols ) {
// Set the xAxis DayOfTheMonth labels:
mktime( &aRec ), Day = --aRec.tm_mday, Str( sDay, L"%d ", Day + 1 );
wmemmove( &Out( Rows + 1 + ( Day <= 27 ? Day%4 : 4 + Day - 28 ),
Col + 1 ), sDay, 2 );

if ( !Day ) // Set the Month Year labels:
P = &Out( Rows, ER( 0, Col - 3 ) ),
P += Str( P, L" %s %d", MonthNyms[ aRec.tm_mon ], aRec.tm_year + 1900 ),
*P = 32 ; } } }

// Get the Hours/Mintues OffLine info:
Date += 4, P = Date += *Date == 32 ; To32;
DateLen = P - Date, *P++ = 0, P++ ; To!32;
Tok = P ; LoopP( Ch != ':' ); *P++ = 0;
H = AtoI( Tok ); To!32; Tok = P ;
if ( isDigit( *Tok ) ) { To32; *P++ = 0; }
M = AtoI( Tok ); if ( *P == 'P' ) H += 12 ;

// "Cols" is the far right column, the most recent day.
// "Col" is "Cols - DaysAgo"; one column per day.
//
// Normally, Midnight signals a new day, a new Col.
//
// We correct for this by decrementing Col for 12am to 3am
// data, and Row is decremented 3 hours; i.e. cut 3 hours
// off the top of the table and paste it to the bottom,
// shifted a day left.

Col = Cols - ( TopDate - aDate )/DaySecs - ( H < TurnHr ),

// Bot is true when using the bottom table.

Bot = Col <= 0, Col += Bot*Cols ;

if ( Col <= 0 )
// Only two tables, !Bot and Bot; so we're done.
break ;

// "H - 3", the hour of the day, is -3 to 20.
// "Hrs" is 48, 2*24, one Row for each HalfHour.

StartngRow = Hrs + 2*( H - TurnHr ) + M/30, StartngRow %= Hrs;
fDur = AtoF( LL[-1] ), Dur = Round( fDur );

// Convert "Dur" ( Hours OffLine ) to a Hex digit.

Hex = NtoHex( Dur ), ReHex = 0 ;

{ LoopRow( Round( 2*fDur ) + 2 ) { _Row = StartngRow + Row ;

// The char at the Row, Col; Col increments on overflow.

wchar &Ch = Out( _Row%Rows, Col + ( _Row >= Rows ) );

if ( ( ReHex = isHex( Ch ) ) || Row >= eRow ) {

// "ReHex" joins adjacent runs, just for run.

ReHex = !ReHex ? 0 : NtoHex( HexToN( Ch ) + Dur - ( Row < eRow ) );
break; }

// Put the digit into the table.
Ch = Hex ; } }

if ( _Row = StartngRow - 1, ReHex ) LOOP {

// Join adjacent runs, give them a higher digit.
++_Row >= Rows && ( _Row = 0, Col++ );
wchar &Ch = Out( _Row, Col );
if ( !isHex( Ch ) ) break ; Ch = ReHex ; } } }

StartReport, Sh( L"%s\n%s\n%s", RptHdr, L"'C' (Hex) means my monitor"
L" was off for 12 hours, starting at the yAxis time, on the xAxis Date."
L" Days start at 3am.\n", _Out ); SaveShowReport( L"SleepPat.HTM" ); }

Globals:

typedef __int64 i64 ; typedef int *pInt ;
typedef wchar_t wchar ; typedef wchar *LnP ; typedef LnP *LnA ;

#define Eq !strCmp
#define strCpy wcscpy

#define MkInt( M ) *pInt( #M )

LnP MonthNyms[]= { L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun",
L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" };

const int Mos[]= { MkInt( Jan ), MkInt( Feb ), MkInt( Mar ),
MkInt( Apr ), MkInt( May ), MkInt( Jun ), MkInt( Jul ),
MkInt( Aug ), MkInt( Sep ), MkInt( Oct ), MkInt( Nov ), MkInt( Dec ) };

// Access " _Out ", a One Dimensional array,
// as if it were a couple of 2D tables, top and bottom.

#define Out( Row, Col ) _Out[ ( ( Row ) + Bot*TopLns )*LnLen + ( Col ) ]

// Special Named loops, for clarity:

#define LoopBot( N ) int eBot = N, Bot = -1 ; eBot-- ; while ( ++Bot <= eBot )
#define LoopBacCol( N ) int Col = N ; while ( --Col >= 0 )

// "LoopP()" loops P through a null terminated line.
// When "Bool" allows, it loops up to, and including, the null,
// setting Ch0, Ch, and Ch2 ( for Bool ), as it goes.

#define LoopP( Bool ) Ch = 1, Ch2 = 0, P-- ; \
while( ( Ch0 = Ch ) && ( Ch = *++P, Ch2 = !Ch ? 0 : P[1], Bool ) )

// "LoopPP()" loops PP through a (dynamic) array of lines,
// setting B and P (pointers) as it goes.

#define LoopPP( Tt, Xx ) Tt##P P = 0, B = 0 ; \
Tt##A BB = (Xx).BB, EE = (Xx).PP + 1, PP = BB - 1 ; \
if ( BB ) while( ++PP < EE ? ( B = P = *PP, 1 ) : 0 )

#define LoopJ( N ) int J = -1, eJ = ( N ) - 1 ; while ( ++J <= eJ )
#define LoopRow( N ) int Row = -1, eRow = ( N ) - 1 ; while ( ++Row <= eRow )

// Sh() is like printf(), but to my custom console/Shell.
int Sh( LnP S, ... )

// Marks off console lines, and saves them to a file:
StartReport
SaveShowReport( LnP S );

// Return the bigER one.
int ER( int X, int Y ) { return X > Y ? X : Y ; }

#define Raise_Ch towupper

inline int RaisC( LnP P ) { return *P = Raise_Ch( *P ); }

inline int HexToN( wchar C ) { if ( isDigit( C ) ) return C - '0' ;
if ( RaisC( & C ) >= 'A' && C <= 'F' ) return 10 + C - 'A' ; return -1 ; }

inline wchar NtoHex( int N ) { return N > 9 ? 'A' + N - 10 : '0' + N ; }

Jeff-Relf.Me

unread,
Jan 19, 2017, 11:21:05 PM1/19/17
to
You ( MrDFS ) replied to me:
> > Given this ( tracking when my monitor was off ):
> > http://Jeff-Relf.Me/SleepLog.TXT
> > Produce this:
> > A table showing every HalfHour of the day OffLine, last 15 months:
> > http://Jeff-Relf.Me/SleepPat.HTM http://Jeff-Relf.Me/SleepPat.PNG
>
> I might give it a shot, if you help me understand some things.
>
> The output is kind of interesting to look at, but I suggest you could
> also put your sleep log entries in a database and much more easily draw
> various plots and diagrams. You could log the data in SQLite, and
> probably plot it using R.

I can plot it whichever way I want; I'm better with C++ than SQL.
You can use SQL, Excel or Visual Basic, if you'd rather.

> Why do days begin at 3am?

Because that's how it is, _de _facto.
Noon is 3pm, the day ends at 3am; 9am to 9pm are mid_day.
People say, " See you at 2am tonight "; not: " 2am tomorrow ".

Chart it normally, where each day ( each column ) ends at 11:59pm,
then chop 3 hours ( 6 rows ) off the top,
and slap it on the bottom, shifted left one day ( one column ).

> 44.5 hour Day, 33% offline:
>
> 8.5 Jan 9 { 9:49 A, 2017 }: 9 VаΓȻ
> .0 Jan 9 { 1:21 A, 2017 }: 9 157 VаɝΞ
>
> 44.5 hour day?

Search for the line that ends with "offline:";
then plot the 8.5 ( hours ) from the line below.

_My day begins when I wake up, after sleeping 4 hours or more
( but not more than 16 hours; as my monitor might just be off ).
"X.EXE" updates "SleepLog.TXT" whenever I turn my monitor on or off.

From that, I can tell you how long _my day was.

> What kind of odd date format is:
> Jan 9 { 9:49 A, 2017 }: 9
> Is that 2017-01-09 09:49:09 ?

Yes.

> If so, why are you capturing seconds if they're never used?

"SleepPat.HTM" doesn't use it, but I do, personally.

> It looks like you're missing most but not all zeroes. Intentional?

I prefer "9" over "09", because it's more readable.
"Aug 29 { : P, 2016 }" ( in SleepLog.TXT ) is 12:00pm.

> Why are the 2 columns at left staggered?

The 8.5, in the far left column, is hours offline.
The .0 that begins the next line, staggered, is hours _on_line.

The offline hours are all in their own column;
same for the on_line hours, in the next column.

> What do the 7 and 157 at right represent?

The 157 on the far right is seconds online;
it's only there when it's a small number; otherwise, it's blank.

> What's with the 4 characters at the end of each line?

VаТω is seconds since 1970, in Base360 ( like Base64 ).

> To each his own, but it's like you go out of your way
> to make everything different and weird. To what end?

It's custom; I like custom " hot rods ".

Jeff-Relf.Me

unread,
Jan 19, 2017, 11:33:59 PM1/19/17
to
Speaking of "http://Jeff-Relf.Me/SleepLog.TXT", someone wrote:
> GIGO.

Without this data, I wouldn't know when I'm likely to be asleep.

I don't use alarm clocks, so it varies _a_lot;
at best, there's a trend I can follow; hence:

http://Jeff-Relf.Me/SleepPat.HTM
http://Jeff-Relf.Me/SleepPat.PNG

Jeff-Relf.Me

unread,
Jan 21, 2017, 7:44:19 AM1/21/17
to
I wrote:
> Given this ( tracking when my monitor was off ):
> http://Jeff-Relf.Me/SleepLog.TXT
> Produce this:
> A table showing every HalfHour of the day OffLine, last 15 months:
> http://Jeff-Relf.Me/SleepPat.HTM http://Jeff-Relf.Me/SleepPat.PNG
>
> Search for the line that ends with "offline:";
> then plot the 8.5 ( hours ) from the line below.

People woke me up; so I slept 4 hours today, twice, for a total of 8.
From 1:30pm to 5:30pm, 4 hours; and 11pm to 3am, another 4 hours.

Some of today's data: <<

9.3 hours awake, 65% offline.

4.0 Jan 21 { 2:57 A, 2017 }:41 Vиɭφ
1.0 Jan 20 { 10:57 P, 2017 }:44 VиȻω >>

The offline hours were 3 seconds short of a full 4 hours;
so it didn't get the "23.2 hour Day, 38% offline:" line.

So I decided to ignore the "23.2 hour Day, 38% offline:" lines;
instead, I plot _any line showing 4+ hours offline; to wit:

// B points to a "SleepLog.TXT" line.
// B[-1], a short, is the leading spaces.
// AtoF() is _wtof(). fDur, a float, is the hours offline.

B && *B && B[-1] <= 1 && B[5] == 32 && B[6] == 32
&& ( fDur = AtoF( B ), fDur >= 4 ) )

The line after ( B = *++PP ) is the start of the run.

Mr Flibble

unread,
Jan 21, 2017, 12:57:19 PM1/21/17
to
Mate, kindly fuck off.

/Flibble


0 new messages