AutoHotkey Community

It is currently May 27th, 2012, 1:32 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: April 11th, 2009, 5:50 pm 
Offline

Joined: November 4th, 2008, 9:23 am
Posts: 1045
Functions: ETA and helper functions

Description
  • ETA returns a formatted time for the estimated finish time of a loop, file download, etc.
  • Supports tracking multiple ETAs simultaneously
  • Supports pausing (and resuming) an ETA timer


Download
ETA.zip

Requirements
None



Functions
ETA_Start(ByRef PreviousTime, ByRef TimeTaken, ByRef TimerIndex = 0)
Initializes values to be used by ETA.

Parameters
PreviousTime - variable to store the previous time (the "Timer" variable)
TimeTaken - variable to store how long the timer has been running so far
TimerIndex - variable to store the timer index (initializes it to 0)



ETA(CurrentValue, TotalValue, ByRef PreviousTime, ByRef TimeTaken)
Returns the estimated finish time given the specified current value, total value, previous time, and time taken; updates PreviousTime and TimeTaken accordingly.

ReturnValue
A formatted string represing the estimated finish time.

Format
If ETA is less than a minute:
0:ss

If ETA is less than an hour (but more than a minute):
m:ss

Else:
h:mm:ss

Remarks
CurrentValue and TotalValue must be positive numbers - either can be a decimal.

Supports percentages by specifing 100 for TotalValue and the percentage for CurrentValue.

Can be used to show the ETA for a file download. Specify the file size (in bytes) for TotalValue and the size (in bytes) already downloaded for CurrentValue.



ETA_Stop(ByRef PreviousTime, ByRef TimeTaken)
1) Stops the specified timer
2) Updates TimeTaken (if the timer was previously running, and not paused)
3) Sets PreviousTime to -2, to signify the timer is stopped (see example 2 below, for use)
4) Returns TimeTaken (in seconds)

Note: Although this function is not required to be called, it can be used to store the time taken (in seconds) for the timer into a variable. Additionally, this function sets PreviousTime to -2, to signify the timer is stopped - this allows an easy check to see if the timer is stopped (see example 2 below).

Note: Do not call this function if you intend to start the timer back up - instead, call ETA_Pause.



ETA_Pause(ByRef PreviousTime, ByRef TimeTaken)
1) Pauses the specified timer. Does nothing if the timer was already paused (or stopped).
2) Updates TimeTaken
3) Sets PreviousTime to -1, to signify the timer is paused (see example 2 below, for use)



ETA_Resume(ByRef PreviousTime)
Resumes the specified Timer. Does nothing if the timer wasn't paused.



Code
Code:
;for all functions, PreviousTime is the "timer" - the previous time is stored

/*
calculates ETA
(supports "pausing")

returns the formatted ETA
*/
ETA(CurrentValue, TotalValue, ByRef PreviousTime, ByRef TimeTaken)
{
    /*
    values MUST start at 0 and have a constant step
    (CurrentValue or TotalValue can be a decimal value)


    e.g.

    A_Index (in a loop),
    percentages (TotalValue = 100),
    file download (use bytes for values),
    etc.
    */

    /*
    Derivation of formula

    ETA = TimeRequired - TimeTaken

    TimeTaken / CurrentValue = TimeRequired / TotalValue
    TimeRequired = TimeTaken / CurrentValue * TotalValue
    TimeRequired - TimeTaken = TimeTaken / CurrentValue * TotalValue - TimeTaken
    ETA = TimeTaken * (TotalValue / CurrentValue - 1)
    */

    if (PreviousTime >= 0)
    {
        ;timer is not "paused" and not stopped
       
        TimeTaken += A_TickCount - PreviousTime
        PreviousTime := A_TickCount
    }

    ;divide by 1000 to convert from milliseconds to seconds
    ETA := round(TimeTaken * (TotalValue - CurrentValue) / CurrentValue / 1000)

    ;ETA is less than a minute
    if (ETA < 60)
        return "0:" . (ETA < 10 ? "0" : "") . ETA

    seconds := mod(ETA, 60)
    ETA //= 60


    ;ETA is less than an hour
    if (ETA < 60)
        return ETA ":" . (seconds < 10 ? "0" : "") . seconds

    minutes := mod(ETA, 60)
    ETA //= 60


    ;else, ETA is greater than an hour
    return ETA ":" . (minutes < 10 ? "0" : "") . minutes
        . ":" . (seconds < 10 ? "0" : "") . seconds
}

;initializes a Timer
;pass variables to use for each the
;   previous time, time taken, and timer index (optional)
ETA_Start(ByRef PreviousTime, ByRef TimeTaken, ByRef TimerIndex = 0)
{
    PreviousTime := A_TickCount
    TimeTaken := 0
    TimerIndex := 0
}

;"stops" an ETA timer
;(use ETA_Pause if you plan to continue the timer later)
;updates TimeTaken, and returns this value (in seconds)
;sets PreviousTime to -2, to signify the time is done
ETA_Stop(ByRef PreviousTime, ByRef TimeTaken)
{
    ;only if timer is "ticking"
    if (PreviousTime >= 0)
        TimeTaken += A_TickCount - PreviousTime
       
    PreviousTime := -2
   
    return round(TimeTaken / 1000)
}

;"pauses" an ETA timer
ETA_Pause(ByRef PreviousTime, ByRef TimeTaken)
{
    ;already paused (or stopped)
    if (PreviousTime < 0)
        return

    TimeTaken += A_TickCount - PreviousTime
    PreviousTime := -1
}

;"resumes" a "paused" ETA timer
ETA_Resume(ByRef PreviousTime)
{
    ;you don't need to pass TimeTaken, because the time taken doesn't increase
    ;(since the timer was paused)

    ;wasn't paused
    if (PreviousTime != -1)
        return

    PreviousTime := A_TickCount
}


Example 1
Code:
#SingleInstance Force
#NoEnv

;initialize an ETA timer
ETA_Start(Timer1, Timer1Time)

;loops for about 15 seconds
LoopCount := 150

Loop, %LoopCount%
{
    Sleep, 100
    ToolTip, % ETA(A_Index, LoopCount, Timer1, Timer1Time)
}


Example 2
Code:
#SingleInstance Force
#NoEnv

;each loop loops for about 5 seconds (4 loops = 20 seconds)
LoopCount := 50


;initialize an ETA timer
ETA_Start(Timer1, Timer1Time, Index1)

;Store the total count
TotalValue1 := 4 * LoopCount


;initialize an ETA timer
ETA_Start(Timer2, Timer2Time, Index2)

;Store the total count
TotalValue2 := 2 * LoopCount


Loop, %LoopCount%
{
    Sleep, 100
   
    ;store pause state
    isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
    isPaused2 := (Timer2 = -1) ? " (Paused)" : ""
   
    ;stores done state
    isDone1 := (Timer1 = -2) ? " (Done)" : ""
    isDone2 := (Timer2 = -2) ? " (Done)" : ""

    ;increase indexes
    Index1++
    Index2++
       
    ToolTip, % "Loop #1`n`n"
        . "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
        . isDone1 . isPaused1
        . "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
        . isDone2 . isPaused2
}

;pause Timer2
ETA_Pause(Timer2, Timer2Time)

Loop, %LoopCount%
{
    Sleep, 100

    ;store pause state
    isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
    isPaused2 := (Timer2 = -1) ? " (Paused)" : ""

    ;stores done state
    isDone1 := (Timer1 = -2) ? " (Done)" : ""
    isDone2 := (Timer2 = -2) ? " (Done)" : ""

    ;increase indexes
    Index1++
    ;don't increase Index2 (Timer2 is paused)

    ToolTip, % "Loop #2`n`n"
        . "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
        . isDone1 . isPaused1
        . "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
        . isDone2 . isPaused2
}

;resume Timer2
ETA_Resume(Timer2)

Loop, %LoopCount%
{
    Sleep, 100

    ;store pause state
    isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
    isPaused2 := (Timer2 = -1) ? " (Paused)" : ""

    ;stores done state
    isDone1 := (Timer1 = -2) ? " (Done)" : ""
    isDone2 := (Timer2 = -2) ? " (Done)" : ""

    ;increase indexes
    Index1++
    Index2++

    ToolTip, % "Loop #3`n`n"
        . "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
        . isDone1 . isPaused1
        . "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
        . isDone2 . isPaused2
}

/*
Timer2 is done

calling ETA_Stop is not required;
   it can be used to store the "total time required" into a variable.
*/
TotalTime2 := ETA_Stop(Timer2, Timer2Time)

Loop, %LoopCount%
{
    Sleep, 100

    ;store pause state
    isPaused1 := (Timer1 = -1) ? " (Paused)" : ""
    isPaused2 := (Timer2 = -1) ? " (Paused)" : ""

    ;stores done state
    isDone1 := (Timer1 = -2) ? " (Done)" : ""
    isDone2 := (Timer2 = -2) ? " (Done)" : ""

    ;increase indexes
    Index1++
    ;don't increase Index2 (Timer2 is already finished)
   
    ToolTip, % "Loop #4`n`n"
        . "Timer1: " ETA(Index1, TotalValue1, Timer1, Timer1Time) . "`n"
        . isDone1 . isPaused1
        . "Timer2: " ETA(Index2, TotalValue2, Timer2, Timer2Time)
        . isDone2 . isPaused2
}

;Timer1 is done
TotalTime1 := ETA_Stop(Timer1, Timer1Time)

ToolTip

MsgBox, % "Timer1 took " TotalTime1 " seconds.`n"
    . "Timer2 took " TotalTime2 " seconds."




How to use
Extract the zip's contents to a library folder for automatic inclusion - StdLib compliant.

A copy of the above examples can be found in the "Func Examples" folder.

Download ETA function

_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bon and 14 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group