# Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

# Determine if Day of the Week is during the weekend

#### Joe Caverly

Here's a function that I am using to determine if the Day of the Week is during the weekend;
Code:
``function weekend=`%@if[%@eval[%1 mod 6] = 1,1,0]```

If I want to see if the current day of the week is on the weekend, I can do;
Code:
``echo %@weekend[%_dowi]``

which returns 1 if it is the weekend, or 0 if it is not.

Joe

Code:
``function weekend=`%@if[%@eval[%1 mod 6] = 1,1,0]```

Elegant!

Here's a function that I am using to determine if the Day of the Week is during the weekend;
Code:
``function weekend=`%@if[%@eval[%1 mod 6] = 1,1,0]```

Shouldn't that be
Code:
``function weekend=`%@if[%@eval[%1 mod 6] == 0,1,0]```
As you have it, Monday is the only weekend day!
Code:
``````v:\> function weekend=`%@if[%@eval[%1 mod 6] = 1,1,0]`

v:\> do i=0 to 6 ( echo %@weekend[%i] )
0
1
0
0
0
0
0``````

And, I didn't know you could use '=' as a relational operator.

On my system,
Code:
``````TCC  16.00.43  Windows Vista [Version 6.0.6002]
TCC Build 43  Windows Vista Build 6002  Service Pack 2``````

Sunday = 1, Monday = 2, .... Saturday = 7
Code:
``````do i=1 to 7 (echo %@weekend[%i] )
1
0
0
0
0
0
1``````

According to the TCC help, this is the same as _dowi.

As for EQ, hmmm... = works in this and other functions that I have.

Do I have something set in a TCC .INI file that might be allowing me to use = instead of EQ? If I am reading the TCC help correctly, under Conditional Expressions, the equal sign should not work.

Joe

Oops! I didn't even think of that and assumed Sunday was 0.

Yeah, the documented ones are 'EQ' and '=='. But '=' seems to work even with plain old IF.

Here's how I figure it out...

Am I at work? Yes, so it's not the weekend.

Edit: But seriously, cool function.

Yeah, the documented ones are 'EQ' and '=='. But '=' seems to work even with plain old IF.

I just launched 4DOS 8.00 (in DOSBox), and
Code:
``echo %@if[%@eval[7 mod 6] = 1,1,0]``

also works. So, if I have been using = wrong, I've been using it wrong for a long time.

Rex, any explanation?

Joe

Weekend
Code:
``function wke=`%@index[1 7,%_dowi,0]```
returns 1 if Saturday or Sunday

Here's another.

Code:
``````v:\> function weekend `%@eval[1-(721 mod %1)]`

v:\> do x=1 to 7 (echos %@weekend[%x])
1000001``````

Here's another.

Code:
``````v:\> function weekend `%@eval[1-(721 mod %1)]`

v:\> do x=1 to 7 (echos %@weekend[%x])
1000001``````
I spent Saturday afternoon tweaking a BTM to measure the speed of various functions that answer this question. Of the ones mentioned so far, @Kachupp's `function wke=`%@index[1 7,%1,0]`` (rephrased for variable input) is easily the fastest, about 20% faster than my recent one (which can be changed to `function weekend `%@eval[1-(301 mod %1)]``).

After a lot of messing around I realized that I wasn't going tp do very well using @EVAL. I could not rival the speed of @WKE even with the simplest function that used @EVAL. Even `function weekend `%@eval[1]`` (which doesn't give the right answer) doesn't come close.

I finally came up with `function weekend `%@instr[%1,1,01000001]`` which equals the speed of @WKE. I doubt it's going to get any faster.

Interesting how do you measure speed? %@timer[] ? or do you have a smart .exe of plugin to pass it to?

Interesting how do you measure speed? %@timer[] ? or do you have a smart .exe of plugin to pass it to?
Right now I'm using @TIMER. I have used my plugins _PERFCOUNT/_PERFFREQ (Windows performance counter) with very similar results. I'm also using my plugin NOOP if it's available; it just makes all the times a little smaller. Here's the subroutine that times various UDFs; the performance counter stuff is commented out.

Code:
``````:timer_routine [name]
set func=%%@%name
timer /q on
::set t0=%_perfcount
iff isplugin noop then
do i=1 to 10000 ( noop %[func][%@random[1,7]] )
else
(do i=1 to 10000 ( echo %[func][%@random[1,7]] )) > nul
endiff
::set t1=%_perfcount
::echo %@eval[(%t1-%t0)/%_perffreq=3]
echo %@timer[1,s] s
return``````

Here's a typical result. The function definitions which appear are actually read from the BTM.

Code:
``````v:\> dowtest.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]`           2.299 s
function kachupp `%@index[17,%1,0]`                 2.300 s
function fatica2 `%@eval[1-(301 MOD %1)]`           2.688 s
function fatica3 `%@eval[abs(%1-4)\3]`              2.788 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       3.008 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  3.051 s``````

Here's another. It doesn't beat the @INDEX one or the @INSTR one but it's faster than the rest.

Code:
``function fatica5 `%@regex[[17],%1]`                 2.304 s``

I removed the overhead of iff/else/endiff just plain %@timer the results are very different. All in the mid 1.460 range obviously the overhead made a difference

I removed the overhead of iff/else/endiff just plain %@timer the results are very different. All in the mid 1.460 range obviously the overhead made a difference
It also made a difference in which order the functions was called in your timer_routien, in TCC Console (fastest) WT tcc console slower times.

I've done all mine in WT. I just tried a console and got pretty much the same numbers. Later I'll take out the IFF... and see what it does.

My computer is 3.5 GHz (12 cores). What's yours? Are you using NOOP or ECHO>NUL?

I think the instance of TCC matters too. If you have multiple cores, they're probably not all equally fast.

mine is a older high end Xeon 8 core 3.4ghz, It still goes well

I removed the overhead of iff/else/endiff just plain %@timer the results are very different. All in the mid 1.460 range obviously the overhead made a difference
Hmmm! I took out the IFF and I'm still getting numbers like before (2.2 - 3.0) with either NOOP or (DO ...) > NUL. I was getting numbers like 1.5 when there was a bug in my BTM. Did you test to see if it's doing the right thing?

I even took out the GOSUB and I'm still getting numbers like before. Here's the whole (current) BTM and it's output.

Code:
``````v:\> type dowtest.btm
setlocal
:: Note that the main DO loop relies on the positions of the next 7 lines!
function fatica4 `%@instr[%1,1,01000001]`
function kachupp `%@index[17,%1,0]`
function fatica2 `%@eval[1-(301 MOD %1)]`
function fatica3 `%@eval[abs(%1-4)\3]`
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`
function fatica5 `%@regex[[17],%1]`

on break (timer /q off & quit)

echo ^r^nTiming 10,000 iterations, each with a random (1-7) weekday ...^r^n

do line_no=2 to 8
setdos /x-47
set line=%@line[%0,%line_no]
echos %@format[-50,%line]^s^s
set f=%@word[1,%line]
setdos /x+47
set func=%%@%f
timer /q on
(do i=1 to 10000 (echos %[func][%@random[1,7]])) > NUL
echo %@timer[1,s] s
enddo
timer /q off

v:\> dowtest.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]`           2.332 s
function kachupp `%@index[17,%1,0]`                 2.334 s
function fatica2 `%@eval[1-(301 MOD %1)]`           2.677 s
function fatica3 `%@eval[abs(%1-4)\3]`              2.776 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       2.975 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  3.044 s
function fatica5 `%@regex[[17],%1]`                 2.347 s``````

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]` 1.485 s
function kachupp `%@index[17,%1,0]` 1.484 s
function fatica2 `%@eval[1-(301 MOD %1)]` 1.889 s
function fatica3 `%@eval[abs(%1-4)\3]` 1.958 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]` 2.155 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]` 2.248 s
function fatica5 `%@regex[[17],%1]` 1.523 s

The first version didn't give 010101 text picture so I guess it was only counting iteration times not working as intended. However this version does display a 010101 text picture so it is working as intended.

The clock speed of mine is misleading sticker says 3.4Ghz but it is clocked a little higher
@3.6 it can reach @3.8 but becomes annoyingly fan noisy so I lock it in the middle.

BTW how did you format your paste to screen. My paste to screen is iggle d piggle d

Aha! Compared to each other, your results are much like mine. But yours are so much faster. That seems odd considering that out computers are pretty close to the same speed. Got any ideas?

I manually type [ c o d e ] and [ / c o d e ] (without the spaces) before and after what I want formatted as code. I find it easier, but you can do the same thing with the toolbar ... click the righthand vertical three dots then "</>" to get to the code inserter. The lefthand vertical three dots then ">_" lets you make selected text `inline code`.

I re-did DOWTEST.BTM again ... got rid of the subroutine and put the function definitions in DOWTEST.BTM:FUNCTIONS.BTM (an NTFS "alternate data stream) which I CALL from the main BTM. It made things much nicer. Here's both BTMs and the output.

Code:
``````v:\> type dowtest.btm:functions.btm
function fatica4 `%@instr[%1,1,01000001]`
function kachupp `%@index[17,%1,0]`
function fatica2 `%@eval[1-(301 MOD %1)]`
function fatica3 `%@eval[abs(%1-4)\3]`
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`
function fatica5 `%@regex[[17],%1]`

v:\> type dowtest.btm
setlocal

call %0:functions.btm

on break (timer /q off & quit)

echo ^r^nTiming 10,000 iterations, each with a random (1-7) weekday ...^r^n

do line_no=0 to %@lines[%0:functions.btm]

setdos /x-47
set line=%@line[%0:functions.btm,%line_no]
echos %@format[-50,%line]^s^s
set func=%%@%@word[1,%line]
setdos /x+47

timer /q on
(do i=1 to 10000 (echos %func[%@random[1,7]])) > NUL
::do i=1 to 10000 (noop %func[%@random[1,7]])
echo %@timer[1,s] s

enddo
timer /q off

v:\> dowtest.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]`           2.471 s
function kachupp `%@index[17,%1,0]`                 2.460 s
function fatica2 `%@eval[1-(301 MOD %1)]`           2.830 s
function fatica3 `%@eval[abs(%1-4)\3]`              2.959 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       3.223 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  3.256 s
function fatica5 `%@regex[[17],%1]`                 2.493 s``````

Clean Leaner script but runs a tad slower .. forget about WT its a full half second slower on this end

Clean Leaner script but runs a tad slower .. forget about WT its a full half second slower on this end
I see no difference between WT and a console. And I can't imagine how it could make a difference. There must be things going on here that I just don't understand.

Hmmm! Running TCC elevated, I get times more like yours.

Code:
``````v:\> dowtest.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]`           1.621 s
function kachupp `%@index[17,%1,0]`                 1.621 s
function fatica2 `%@eval[1-(301 MOD %1)]`           1.912 s
function fatica3 `%@eval[abs(%1-4)\3]`              1.981 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       2.149 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  2.214 s
function fatica5 `%@regex[[17],%1]`                 1.658 s``````

Ahha I'll try the elevated WT run.

Yep the timings match

Two version first versions functions in the script

j:\dba>d2test.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]` 1.428 s
function kachupp `%@index[17,%1,0]` 1.433 s
function fatica2 `%@eval[1-(301 MOD %1)]` 1.838 s
function fatica3 `%@eval[abs(%1-4)\3]` 1.902 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]` 2.100 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]` 2.174 s
function fatica5 `%@regex[[17],%1]` 1.475 s

Mon 14/03/22 19:00
j:\dba>d3test.btm

Stream version

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]` 1.530 s
function kachupp `%@index[17,%1,0]` 1.532 s
function fatica2 `%@eval[1-(301 MOD %1)]` 2.101 s
function fatica3 `%@eval[abs(%1-4)\3]` 2.226 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]` 2.440 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]` 2.529 s
function fatica5 `%@regex[[17],%1]` 1.577 s

All in WT

The last one was a console ... likewise in an elevated WT. I didn't think elevated processes automatically got a higher priority.

Code:
``````v:\> dowtest.btm

Timing 10,000 iterations, each with a random (1-7) weekday ...

function fatica4 `%@instr[%1,1,01000001]`           1.651 s
function kachupp `%@index[17,%1,0]`                 1.653 s
function fatica2 `%@eval[1-(301 MOD %1)]`           1.944 s
function fatica3 `%@eval[abs(%1-4)\3]`              1.982 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       2.177 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  2.238 s
function fatica5 `%@regex[[17],%1]`                 1.709 s``````

This is all very interesting; I'm trying to get some interest in BTM analytical code engine that's able to perform tests if invoked on the fly. "Bit like code optimiser for c++ etc".
Similar to the IDE but without its slowness when your debugging multiple called scripts at once.

I was thinking jpavel's hashmap might be useful in storing and retrieving methods/functions