Start second while loop only after first is finished - lua

I'm trying to write a function that puts the remaining seconds into a human readable format. The problem I'm having(I think) is that my second while loop is trying to do it's job before the first is finished. I'll end up with "1 hour, 271 minutes and 37 seconds. In my latest attempt, I tried to use minNeeded but that doesn't work either because it's checking for it's existence prior to the first loop being finished. How can I manage this?
function prettyTime(secs)
local hr = 0
local hrDisplay = ''
local min = 0
local minDislplay = ''
local minNeeded = 0
if(secs >= 3600) then
while secs >= 3600 do
secs = secs - 3600
hr = hr + 1
if secs < 3600 then
secsRemaining = secs
minNeeded = 1
end
end
else
minNeeded = 1
end
while true do
if(minNeeded == 1){
while secsRemaining >= 60 do
secsRemaining = secsRemaining - 60
min = min + 1
end
end
end
if hr > 1 then
hrDisplay = hr .. ' hours, '
elseif hr == 1 then
hrDisplay = '1 hour, '
end
if min > 1 then
minDisplay = min .. ' minutes and '
elseif min == 1 then
minDisplay = '1 minute and '
else
minDisplay = ''
end
return hrDisplay .. minDisplay .. secs .. ' seconds'
end

your Code has few bugs, if(minNeeded == 1){ is syntax error, while true do will never break.
Here is the simple converter,
function prettyTime(sec)
local sec = tonumber(sec)
if sec <= 0 then
return "00.00.00";
else
h = tonumber(string.format("%02.f", math.floor(sec/3600)))
m = tonumber(string.format("%02.f", math.floor(sec/60 - (h*60))))
s = tonumber(string.format("%02.f", math.floor(sec - h*3600 - m*60)))
-- return h.."."..m.."."..s
end
local res = ''
if h == 1 then
res = res ..h .. ' hour, '
elseif h > 1 then
res = res ..h .. ' hours, '
end
if m <= 1 then
res = res ..m .. ' minute, '
elseif m > 1 then
res = res ..m .. ' minute, '
end
if s <= 1 then
res = res ..s .. ' second, '
elseif s > 1 then
res = res ..s .. ' seconds '
end
return res
end
print(prettyTime(3670)) -- 1 hour, 1 minute, 10 seconds

Related

Lua script sometimes doesn't save values in the file

I made a Timer script for Minecraft that should display the time spent in the game. You can pause resume and reset the time. My next step was to make it able to save the time in a file called timesave.txt but sometimes it isn't saving the time and its just empty... If it saves the time it reads and uses it to restore the old time.
This is the code:
name = "Timer"
description = "Just a normal Timer."
positionX = 0
positionY = 0
sizeX = 24
sizeY = 10
scale = 1
START_STOP_KEY = 0x55 --or 'U'
RESET_KEY = 0x4A --or 'J'
--
--[[
Timer Module Script by SebyGHG original script by Onix64(Stopwatch)
if you wish to change the key you can take the key code from here
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
]] -------------script-code-------------
timesaved = 0
stopTime = 0
startTime = 0
f = io.input("timesave.txt")
resultstop = f :read("*line")
resultstart = f :read("*line")
f :close()
startTime = resultstop
stopTime = resultstart
timesaved = resultstart - resultstop
state = 2
function keyboard(key, isDown)
if (isDown == true) then
if (key == RESET_KEY) then
f = io.input("timesave.txt")
resultstart = f :read("*line")
resultstop = f :read("*line")
f :close()
startTime = resultstop
stopTime = resultstart
timesaved = resultstart - resultstop
state = 0
elseif (key == START_STOP_KEY) then
if (state == 0) then
state = 1
startTime = os.time() - timesaved
io.output("timesave.txt")
timesave= (io.open("timesave.txt","w"))
io.write(startTime,'\n',stopTime)
io.close(timesave)
elseif (state == 1) then
state = 2
stopTime = os.time()
elseif (state == 2) then
state = 1
startTime =startTime + os.time() - stopTime
end
end
end
end
TimerText = "00:00"
TextColor = {r = 30, g = 255, b = 30, a = 255}
function doubleDigit(number)
if (number < 10) then
return "0" .. math.floor(number)
else
return math.floor(number)
end
end
function timeText(time)
local result = ""
local days = 0
while (time > 86399) do
days = days + 1
time = time - 86400
end
local hours = 0
while (time > 3599) do
hours = hours + 1
time = time - 3600
end
local minutes = 0
while (time > 59) do
minutes = minutes + 1
time = time - 60
end
if (days == 0) then
if (hours == 0) then
return doubleDigit(minutes) .. ":" .. doubleDigit(time)
else
return math.floor(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time)
end
else
return math.floor(days) ..
" : " .. doubleDigit(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time)
end
end
function update()
if (state == 0) then
TextColor = {r = 255, g = 0, b = 0, a = 255}
TimerText = "00:00"
elseif (state == 1) then
TimerText = timeText(os.time() - startTime)
TextColor = {r = 0, g = 255, b = 255, a = 255}
elseif (state == 2) then
TimerText = timeText(stopTime - startTime)
TextColor = {r = 255, g = 255, b = 0, a = 255}
end
end
function render()
local font = gui.font()
local tw = font.width(TimerText)
gfx.color(0, 0, 0, 0)
gfx.rect(0, 0, tw + 4, 10)
gfx.color(TextColor.r, TextColor.g, TextColor.b, TextColor.a)
gfx.text(2, 1, TimerText)
end
Add io.flush() or timesave:flush() after your write operation to save the written data to the file.
See https://www.lua.org/manual/5.3/manual.html#pdf-file:flush

My timer script for minecraft is not working

I have a problem with my Minecraft timer script I tried to add a function that saves the time values from worlds in a document. The timer worked completely fine before i added this function...
Code:
name = "Timer"
description = "Just a normal Timer."
positionX = 0
positionY = 0
sizeX = 24
sizeY = 10
scale = 1
START_STOP_KEY = 0x55 --or 'U'
RESET_KEY = 0x4A --or 'J'
--
--[[
if you wish to change the key you can take the key code from here
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
]] -------------script-code-------------
previoustime = 0
state = 0
startTime = 0
stopTime = 0
ImportedLib = importLib("readfile.lua")
function keyboard(key, isDown)
if (isDown == true) then
if (key == RESET_KEY) then
state = 0
elseif (key == START_STOP_KEY) then
if (state == 0) then
state = 1
startTime = os.time()
elseif (state == 1) then
state = 2
previoustime = os.time()
stopTime = os.time()
elseif (state == 2) then
state = 1
startTime = startTime + os.time() - stopTime
end
end
end
end
TimerText = "00:00"
TextColor = {r = 30, g = 255, b = 30, a = 255}
function doubleDigit(number)
if (number < 10) then
return "0" .. math.floor(number)
else
return math.floor(number)
end
end
function timeText(time)
local result = ""
local days = 0
while (time > 86399) do
days = days + 1
time = time - 86400
end
local hours = 0
while (time > 3599) do
hours = hours + 1
time = time - 86400
end
local minutes = 0
while (time > 59) do
minutes = minutes + 1
time = time - 60
end
if (days == 0) then
if (hours == 0) then
return doubleDigit(minutes) .. ":" .. doubleDigit(time)
else
return math.floor(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time)
end
else
return math.floor(days) ..
" : " .. doubleDigit(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time)
end
end
function update()
if (state == 0) then
TextColor = {r = 255, g = 0, b = 0, a = 255}
TimerText = "00:00"
elseif (state == 1) then
TimerText = timeText(os.time() - startTime)
TextColor = {r = 0, g = 255, b = 255, a = 255}
elseif (state == 2) then
TimerText = timeText(stopTime - startTime)
TextColor = {r = 255, g = 255, b = 0, a = 255}
end
end
function render()
local font = gui.font()
local tw = font.width(TimerText)
gfx.color(0, 0, 0, 0)
gfx.rect(0, 0, tw + 4, 10)
gfx.color(TextColor.r, TextColor.g, TextColor.b, TextColor.a)
gfx.text(2, 1, TimerText)
end
This is the function i want to add
if (state == 1) then
local worldName = server.worldName()
io.open(local worldName".txt", "w")
io.output(file)
io.write(time)
io.close(file)
end
if (state == 0) then
local worldName = server.worldName()
io.open(local worldName".txt", "r")
io.output(file)
time = (file:read())
io.close(file)
end
It appears that you want to concatenate (join) two strings io.open(local worldName".txt", "r"). You should use the concat operator (double dot) for that:
local s1 = "Hello "
local s2 = "World!!!"
local s3 = s1..s2
print(s3)
This program will print the string "Hello world!!" (without the quotes).
Also, the you are only supposed to use the local keyword when declaring a variable.
So:
if (state == 1) then
local worldName = server.worldName()
io.open(worldName..".txt", "w")
io.output(file)
io.write(time)
io.close(file)
end
if (state == 0) then
local worldName = server.worldName()
io.open(worldName..".txt", "r")
io.output(file)
time = (file:read())
io.close(file)
end
This code is the correct version of what you wanted to write. I removed the incorrect uses of the local keyword and added the concat operator.

I am making a timer script in lua but if i stop it the time freezes and jumps forward when i resume it (Minecraft)

When I stop the timer and start it again, it jumps forward depending on how much time has passed when it was paused.
Link for a video of the problem: https://drive.google.com/file/d/1Xohbzbx4oyVfbRnSMLc_7u1gf7AWMJVy/view?usp=sharing
Code:
name = "Stopwatch"
description = "Count time for whatever reason..."
positionX = 0
positionY = 0
sizeX = 24
sizeY = 10
scale = 1
START_STOP_KEY = 0x55 --or 'U'
RESET_KEY = 0x4A --or 'I'
--[[
Stopwatch Module Script
if you wish to change the key you can take the key code from here
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
]]--
-------------script-code-------------
previoustime = 0
state = 0
startTime = 0
stopTime = 0
function keyboard(key, isDown)
if (isDown == true) then
if (key == RESET_KEY) then
state = 0
end
end
end
function keyboard(key, isDown)
if (isDown == true) then
if (key == START_STOP_KEY) then
if (state == 0) then
state = 1
startTime = os.time()
elseif (state == 1) then
state = 2
previoustime = os.time()
stopTime = os.time()
elseif (state == 2) then
state = 1
time = previoustime
end
end
end
end
TimerText = "00:00"
TextColor = {r=30,g=255,b=30,a=255}
function doubleDigit(number)
if (number < 10) then
return "0" .. math.floor(number)
else
return math.floor(number)
end
end
function timeText(time)
local result = ""
local days = 0
while (time > 86399) do
days = days + 1
time = time - 86400
end
local hours = 0
while (time > 3599) do
hours = hours + 1
time = time - 86400
end
local minutes = 0
while (time > 59) do
minutes = minutes + 1
time = time - 60
end
if (days == 0) then
if (hours == 0) then
return doubleDigit(minutes) .. ":" .. doubleDigit(time)
else
return math.floor(hours) .. " : " .. doubleDigit(minutes) .. ":" ..doubleDigit(time)
end
else
return math.floor(days) .. " : " .. doubleDigit(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time)
end
end
function update()
if (state == 0) then
TextColor = {r=30,g=255,b=30,a=255}
TimerText = "00:00"
elseif (state == 1) then
TimerText = timeText(os.time() - startTime)
TextColor = {r=30,g=255,b=30,a=255}
elseif (state == 2) then
TimerText = timeText(stopTime - startTime)
TextColor = {r=30,g=30,b=255,a=255}
end
end
function render()
local font = gui.font()
local tw = font.width(TimerText)
gfx.color(0,0,0,120)
gfx.rect(0, 0, tw + 4, 10)
gfx.color(TextColor.r, TextColor.g, TextColor.b, TextColor.a)
gfx.text(2, 1, TimerText)
end
Thanks for helping!

RoR: Method to return a statement in a json format?

I'm looking for a method that will return this statement in a JSON format.
def statement
total = 0
bonus points = 0
result = 'Car rental for #{#name.to_s}\n'
for r in #rentals
this_amount = 0
case r.car.style
when Car::SUV
this_amount += r.days_rented * 30
when Car::HATCHBACK
this_amount += 15
if r.days_rented > 3
this_amount += (r.days_rented - 3) * 15
end
when Car::SALOON
this_amount += 20
if r.days_rented > 2
this_amount += (r.days_rented - 2) * 15
end
else
end
if this_amount < 0
bonus_points -= 10
end
bonus_points = bonus_points + 1
if r.car.style == Car::SUV && r.days_rented > 1
bonus_points = bonus_points + 1
end
result += r.car.title.to_s + "," + this_amount.to_s + "\n"
total += this_amount
end
result += "Amount owed is " + "#{total.to_s}" + "\n"
result +="Earned bonus points: " + bonus_points.to_s
result
end
What method would I need to add to my class to return this statement in a JSON format? Thank you.
Simplest way to do that
return {:result => result}
at the end of your method.
But if you are using controller to show data to user, I would prefer using .to_json in my controller method

How to time interval between event in lua

I am writing a simple script in lua. If the LED is on, it will increment the counter by 1. If the led is off for more than 1 seconds, it reset the counter.
So how exactly do we time event like that in lua ?
This is what i have and been testing multiple ways so far.
function ReadADC1()
local adc_voltage_value = 0
adc_voltage_value = tonumber(adc.readadc()) * 2 -- 0.10 --get dec number out of this -- need to know where package adc come from
--convert to voltage
adc_voltage_value = adc_voltage_value *0.000537109375 --get V
adc_voltage_value = math.floor(adc_voltage_value *1000 +0.5) --since number is base off resolution
--print (adc_voltage_value)
return adc_voltage_value
end
-- end of readADC1() TESTED
function interval()
local counter1 =0
ledValue = ReadADC1()
if (ledValue >= OnThreshHold) then
ledStatus = 1
t1=os.time()
else
ledStatus = 0
t2 = os.time()
end
--counter1 =0
for i=1,20 do
if (ledStatus == 1) then -- if led is off for more than 1 second, reset counter = 0
counter1 = counter1 + 1
elseif ((ledStatus ==0 and ((os.difftime(os.time(),t2)/100000) > 1000))) then -- increment counter when led is on
counter1 = 0
end
end
print (counter1)
end
I know for sure the logic for interval is wrong since os.time return a huge number (i assume it in psecond instead of second).
Any suggest or solution is welcome. I tried vmstarttimer and vmstoptimmer before this but not sure how it work.
EDIT:
function counter()
local ledValue = ReadADC1()
local t1 = os.clock()
while true do
local t2 = os.clock()
local dt = t2 - t1
t1 = t2
if ((ledValue < OnThreshHold) and (dt < 1)) then -- if led is off for less than 1 second
ledCounter = ledCounter + 1
elseif ((ledValue < OnThreshHold) and (dt > 1)) then-- if led is off for more than 1 second
ledCounter = 0;
else
ledCounter = ledCounter
end
print (ledCounter)
end
end
Ultimately, it will be return ledCounter instead of print counter since I will plug the value of counter to another function that will print a message correspond to the number of counter
You could use os.clock which returns your programs runtime since start in seconds.
Returns an approximation of the amount in seconds of CPU time used by the program.
Source
This function could be used in this way.
local t1 = os.clock() -- begin
local t2 = os.clock() -- end
local dt = t2 - t1 -- calulate delta time
-- or looped
local t1 = os.clock() -- begin
while true do
local t2 = os.clock() -- end
local dt = t2 - t1 -- calulate delta time
t1 = t2 -- reset t1
-- use dt ...
end
-- or wait for time elapsed
-- runs until 1 second passed
local t1 = os.clock()
while (os.clock() - t1) < 1 do
-- do stuff while dt is smaller than 1
-- could even reset timer (t1) to current to
-- repeat waiting
-- t1 = os.clock() | ...
end
-- logic for your example
function counter()
local time = os.clock()
local lastLedOn = false
local counter = 0
while true do
if os.clock() - time > 1.0 then
break
end
if getLedValue() == on then -- replace
time = os.clock()
if not lastLedOn then
lastLedOn = true
counter = counter + 1
-- print(counter) | or here if you want to print repeatedly
end
end
end
print(counter)
end -- was unable to test it

Resources