Products Consultancy

Create a process bar


Thursday, June 16, 2011

The most OmniTRANS classes show a progress bar while they are running. When you create your own job, you might be interesting in the progress of this job. The OtGauge class allows you to create a progress bar and to assign the gauge progress in terms of a percentage.


First we have to define the Class by:

writeln "Progress:"
gauge = OtGauge.new


Now, we have to create a job which takes a long time and supplies some identification such that we know when to update the progress bar. We create a for-statement that runs 1800 times and sleeps each run for 0.003 seconds.

for i in 1..1800  
    sleep(0.003)
end

Within the for-loop, we have to set the actual progress. The OtGauge.progress property allows you to assign the gauge progress in terms of a percentage:

gauge.progress = value

The easiest way to set the value is to calculate the exact percentage of the progress.

value = (100.0/1800.0)*i

 

Floats vs. integers


Make sure that you use floats when performing mathematical calculations

  • 100.0 is a float. Float numbers may include a decimal point.
  • 100 is a integer. Integer numbers are natural numbers (..., −2, −1, 0, 1, 2, ...).
    When transforming a float to an integer, all numbers behind the komma will be removed (e.g. a float value of 1.96 will be transformed to an integer value of 1)

 

When dividing a integer by an integer, the results is also an integer.

In this example, this will result in the value of 0 (100/1800 = 0.055 = 0).

 

Combining the seperate code blocks results in the following job:

writeln "Progress:"  
gauge = OtGauge.new  

for i in 1...1800    
	value = (100.0/1800.0)*i  
	gauge.progress = value  
	sleep(0.003)
end  

The code above works fine and you can use this code within your jobs. There is one problem within this code; the progress bar is been updated 1800 times, although only about 100 times are visibly useful. This won't make your job slower, because OmniTRANS will recognize that it doesn't make sense to update the progress bar such often.

 

However, we want to make sure that the gauge.progress property is only triggered when the output of the calculation results in a natural number (0,1,2,3,etc.).

 

This can be done by determining if the percentage value is a natural number. When subtracting the "rounded" value, transformed to an integer, from the raw value, an result of 0 indicates that the value is a natural number. In every other case, the value has digits behind the comma and isn't a natural number. By creating an if-statement which monitors this criteria, the job will be much more clean. This results in the job below.

writeln "Progress:"  
gauge = OtGauge.new  

for i in 1..1800
	value = (100/1800.0)*i

	if (value - value.to_i) == 0
		gauge.progress = value
	end

	sleep(0.003)
end

 

For the real expert, you can make the job above a little bit more efficient by using the Ruby modulo property. This property is used like:

x.modulo(y)

which actually means:

x-y*(x/y).floor

When the answer of this formula is equal to 0, x can be divided by y and result in a natural number.

 

This results in our final job:

writeln "Progress:"  
gauge = OtGauge.new  

for i in 1..1800
    if i.modulo(18) == 0
        gauge.progress = (100/1800.0)*i  
    end
    sleep(0.003)
end