Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
New WEEKDAYS function.
Message
De
21/08/2003 08:45:46
 
 
À
20/08/2003 17:37:57
Mike Yearwood
Toronto, Ontario, Canada
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00821896
Message ID:
00822144
Vues:
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.


>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.
>
><pre>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
>>
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform