Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
New WEEKDAYS function.
Message
From
21/08/2003 08:50:11
 
 
To
20/08/2003 17:37:57
Mike Yearwood
Toronto, Ontario, Canada
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00821896
Message ID:
00822146
Views:
30
This is an excellent routine for "Workdays" and I would keep the shortened version in my function library but with explicit comments to fully explain the function. in addition I would also use a
 #if .f.
  Code Step && Comment
  Code Step && Comment
  Code Step && Comment
  Code Step && Comment
  Code Step && Comment
  Code Step && Comment
  Code Step && Comment
#endif
block so that any maintenance on this "TESTED AND PROVEN" function can be easily applied. It is my belief that known good functions SHOULD be optimized but not at the sake of enhancement. That is why MsFox gave us the * and the &&.

Just my 2cents worth.

Glenn
>Hey Tom.
>
>One thing I'm learning is, everything is in the eye of the beholder. Mark's "reasonable" is different from my reasonable and your reasonable too.
>
>My original code looked more like this until I shortened it.
>
>
ldTo = m.ldTo + IIF(m.lnDOWTo >= 2,7 - m.lnDOWTo,-1)
>  ldFrom = m.ldFrom - IIF(m.lnDOWFrom <= 6,m.lnDOWFrom - 1,0)
>  lnDays = INT((m.ldFrom - m.ldTo + 1) * 5 / 7)
>  lnDays = m.lnDays - IIF(m.lnDOWFrom >= 2 AND m.lnDOWFrom <= 6,m.lnDOWFrom - 2,0)
>  lnDays = m.lnDays - IIF(m.lnDOWTo >= 2 AND m.lnDOWTo <= 6,6 - m.lnDOWTo,0)
>RETURN m.lnDays
>
>As Glenn Domeracki put it, I was exploring minimalist alternatives. But while we're on the subject of readable ;)...
>
>The INT() isn't necessary! The adjusted To and From days should yield a number of 7 day weeks. Multiplied by 5 and divided by 7 will result in an integer value that is a multiple of 5!
>
>
ldTo = m.ldTo + IIF(m.lnDOWTo >= 2,7 - m.lnDOWTo,-1)
>ldFrom = m.ldFrom - IIF(m.lnDOWFrom <= 6,m.lnDOWFrom - 1,0)
>lnGrossDays = (m.ldTo - m.ldFrom + 1) * 5 / 7
>lnFromAdj = IIF(m.lnDOWFrom >= 2 AND m.lnDOWFrom <= 6,m.lnDOWFrom - 2,0)
>lnToAdj = IIF(m.lnDOWTo >= 2 AND m.lnDOWTo <= 6,6 - m.lnDOWTo,0)
>RETURN m.lnGrossDays - m.lnFromAdj - m.lnToAdj
>
>This way we can clearly see the steps I described at the start of this thread.
>
>Can we agree this is a cleaner version?
>
>Thanks!
>
>>Duh, thanks Sergey.
>>
>>
>>>Tom,
>>>
>>>The tags you wount to use are < pre > and < /pre >.
>>>
>>>>>You could time-test by running the code iteratively a few thousand times the way it is and with the code broken up into legible lines. However, practical use in an app probably would not necessitate sacrificing readability in order to retain some miniscule performance gain. IMHO, there should be a reasonable [practicle, again] balance between maintainability of code and performance. Now if his function was really going to be his numerous times like in a SQL query, then I would shift back toward performance gains.
>>>>
>>>>
>>>>Well here's one way to try testing it.
>>>>
>>>>Your mileage may vary but my averages on my 500mhz PIII were:
>>>>
>>>>5.4546 with the fast return as coded by Mike and
>>>>5.8230 with the separate calcs done as follows:
>>>>
>>>>@)$(&*((#&@*&*!))*#)#
>>>>
>>>>I am pooling my hair out to cut and paste the code here. I keep getting
>>>>"You cannot include a style attribute inside a tag. This is in regards to the Message Field." when I try to preview it.
>>>>
>>>>I get this whether I use the < per> < /per> tags or not ( without the spaces).
>>>>
>>>>
>>>>
>>
>>LOCAL lntotaltime,iloops,idates,idays,icycle
>>
>>FOR icycle=1 TO 2
>>	lntotaltime=0
>>
>>	?IIF(icycle=1,'Legible','Faster')+" Started time:"+TRANSFORM(TIME())
>>
>>	FOR iloops = 1 TO 10
>>		lnstarttime=SECONDS()
>>
>>		FOR idates = 1 TO 100000
>>			ldfrom=DATE()-(RAND()*50000)
>>			ldto=ldfrom+(RAND()*50000)
>>
>>			idays=weekdays(ldfrom,ldto,(icycle=1))
>>
>>		ENDFOR
>>		
>>		lnendtime=SECONDS()
>>		?SPACE(0)
>>		?"Loop "+TRANSFORM(iloops)+" Elapsed time in seconds:"+TRANSFORM(lnendtime-lnstarttime)
>>		lntotaltime=lntotaltime+(lnendtime-lnstarttime)
>>	ENDFOR
>>	?IIF(icycle=1,'Legible','Faster')+"Average per loop:"+TRANSFORM(lntotaltime/10)
>>
>>ENDFOR
>>
>>
>>FUNCTION weekdays
>>	LPARAMETERS tdFrom, tdTo, tllegible
>>
>>	IF VARTYPE(m.tdFrom)#"D" OR VARTYPE(m.tdTo)#"D"
>>		RETURN .F.
>>	ENDIF
>>
>>	LOCAL ldfrom, ldto, lnDOWFrom, lnDOWTo,lnstep1,lnstep2,lnstep3
>>	ldfrom = MIN(m.tdFrom,m.tdTo)
>>	ldto = MAX(m.tdFrom,m.tdTo)
>>
>>	lnDOWFrom = DOW(m.ldfrom,1)
>>	lnDOWTo = DOW(m.ldto,1)
>>
>>	IF tllegible
>>		lnstep1 = INT(((m.ldto + IIF(m.lnDOWTo >= 2,7 - m.lnDOWTo,-1));
>>			- (m.ldfrom - IIF(m.lnDOWFrom <= 6,m.lnDOWFrom - 1,0)) + 1) * 5 / 7)
>>		lnstep2 = IIF(m.lnDOWFrom >= 2 AND m.lnDOWFrom <= 6,m.lnDOWFrom - 2,0)	
>>		lnstep3 = IIF(m.lnDOWTo >= 2 AND m.lnDOWTo <= 6,6 - m.lnDOWTo,0)
>>
>>		RETURN lnstep1 - lnstep2 - lnstep3
>>	ELSE
>>		RETURN INT(((m.ldto + IIF(m.lnDOWTo >= 2,7 - m.lnDOWTo,-1));
>>			- (m.ldfrom - IIF(m.lnDOWFrom <= 6,m.lnDOWFrom - 1,0)) + 1) * 5 / 7) ;
>>			- IIF(m.lnDOWFrom >= 2 AND m.lnDOWFrom <= 6,m.lnDOWFrom - 2,0) ;
>>			- IIF(m.lnDOWTo >= 2 AND m.lnDOWTo <= 6,6 - m.lnDOWTo,0)
>>	ENDIF
>>
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform