It is currently October 18th, 2024, 5:19 am

Lua for conditional operators with strings as result. [Help]

Discuss the use of Lua in Script measures.
RicardoTM
Posts: 376
Joined: December 28th, 2022, 9:30 pm
Location: México

Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

So I wrote this simple lua function since I thought it could be useful on some especial cases, but I can't get it to work for unknown reasons, since it works fine on the lua console.

Code: Select all

function conditional(cond, true_str, false_str)
    if cond then
        return true_str
    else
        return false_str
    end
end
It should let you input a conditional and output a string based on the result.

So this:

Code: Select all

print(conditional(10 > 18, 'Yes', 'No'))
Prints: No

Here you can check that's true: https://onecompiler.com/lua/42vdzfkm4

The problem is that rainmeter will always return true (yes) no matter what.

Example skin:

#@#Script.lua

Code: Select all

function conditional(cond, true_str, false_str)
	if cond then
        return true_str
    else
        return false_str
    end
end
Test.ini

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1
DynamicVariables=1

[Condition]
Measure=String
String=[&Script:conditional(10 > 18,'Yes','No')]
UpdateDivider=-1
DynamicVariables=1

[MeterResult]
Meter=String
FontFace=Consolas
FontColor=225,255,255,255
SolidColor=9,25,25,255
Padding=5,5,5,5
FontSize=18
AntiAlias=1
MeasureName=Condition
Text="Condition result: %1"
DynamicVariables=1
The result should be no, but it's yes.. Somehow.

I'm guessing the problem is a syntax one, so please enlighten me with your knowledge :) .

I already tried '10 > 18', ''10 > 18'', "10 > 18", (10 > 18), '(10 > 18)' without luck. There's also no errors on the log.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2747
Joined: March 23rd, 2015, 5:26 pm

Re: Lua for conditional operators with strings as result. [Help]

Post by SilverAzide »

RicardoTM wrote: Yesterday, 9:36 pm
There are multiple problems here, so welcome to the Rainmeter/Lua mashup world.

First, from the Rainmeter side, the Rainmeter parser doesn't always know when to parse a string and when not to. In this case, you will find that if you remove the spaces from the conditional expression, it will work. So this...

Code: Select all

String=[&Script:conditional((10>18),'Yes','No')]
...will work.

BUT WAIT! Before you try it, you need to fix your Lua code. The problem is you've missed this tidbit from the Lua manual (section 2.2, Booleans)
Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.
So change your code to:

Code: Select all

    if cond == 0 then
        return false_str
    else
        return true_str
    end
(Note that I've flipped your expression around to my preferred style.) If you add the following debug code to your function...

Code: Select all

    print("cond = " .. cond .. " and is of type " .. type(cond))
... you'll see that your original code was passing 10. ( :confused: )
Gadgets Wiki GitHub More Gadgets...
RicardoTM
Posts: 376
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

SilverAzide wrote: Yesterday, 10:50 pm
Thank you so much Silver, it now works perfectly fine.

Here's the corrected example skin for anyone who wants to try it, I added variables as well.

#@#Script.lua

Code: Select all

function conditional(cond, true_str, false_str)
    if cond == 0 then
        return false_str
    else
        return true_str
    end
end
Test.ini

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]

Condition=10>18
True=[#Condition] is True
TrueColor=0,255,0
False=[#Condition] is False
FalseColor=255,0,0

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1
DynamicVariables=1

[Condition]
Measure=String
String=[&Script:conditional(([#Condition]),'[#True]','[#False]')]
UpdateDivider=-1
DynamicVariables=1

[MeterResult]
Meter=String
FontFace=Consolas
FontColor=[&Script:conditional(([#Condition]),'[#TrueColor]','[#FalseColor]')]
SolidColor=9,25,25,255
Padding=5,5,5,5
FontSize=18
AntiAlias=1
MeasureName=Condition
Text="Condition result: %1"
DynamicVariables=1
Thank you so much! The debug code idea is also pretty good, I'll use it more while doing stuff on lua.
User avatar
nek
Posts: 121
Joined: November 3rd, 2019, 12:00 am

Re: Lua for conditional operators with strings as result. [Help]

Post by nek »

You can use loadstring() in the Lua function. See also Brian's post

Code: Select all

function conditional(cond_str, true_str, false_str)
 
  local r = loadstring('return '..cond_str)()
  -- print(type(r), r)
  return r and true_str or false_str

end

--
-- Lua Note: for type boolean, nil and false count as false;
--           everything else is true (including 0 and "").
--
See also Dont assert() with Inline Lua by jsmorley


From 10 > 18 to '10 > 18' in the Test.ini (original post)

Code: Select all

[Condition]
Measure=String
; String=[&Script:conditional(10 > 18,'Yes','No')]
String=[&Script:conditional('10 > 18','Yes','No')]
UpdateDivider=-1
DynamicVariables=1


Rainmeter & Lua | https://docs.rainmeter.net/manual/lua-scripting/
Lua Online | https://onecompiler.com/lua/
Lua Tutorial | https://www.tutorialspoint.com/lua/
lua-users Tutorial | http://lua-users.org/wiki/TutorialDirectory
lua-users Sample Code | http://lua-users.org/wiki/SampleCode
Lua 5.1 Reference Manual | https://lua.org/manual/5.1/manual.html
Stack Overflow | https://stackoverflow.com/questions/tagged/lua?tab=Frequent
RicardoTM
Posts: 376
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

nek wrote: Today, 12:03 am
Hey Nek, thank you for your contribution.

Only drawback I've seen is, when using math, for example '10 + 8 = 18', it won't work. It needs the lua way: '10 + 8 == 18'

It does work fine as well though, for anyone wanting to try it, here's the example code using it:

#@#Script.lua

Code: Select all

function conditional(cond_str, true_str, false_str)
  local r = loadstring('return '..cond_str)()
  return r and true_str or false_str
end
Test.ini

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]

Condition=(10 + 8)*2 == 36
True=[#Condition] is True
TrueColor=0,255,0
False=[#Condition] is False
FalseColor=255,0,0

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1
DynamicVariables=1

[Condition]
Measure=String
String=[&Script:conditional('[#Condition]','[#True]','[#False]')]
UpdateDivider=-1
DynamicVariables=1

[MeterResult]
Meter=String
FontFace=Consolas
FontColor=[&Script:conditional('[#Condition]','[#TrueColor]','[#FalseColor]')]
SolidColor=9,25,25,255
Padding=5,5,5,5
FontSize=18
AntiAlias=1
MeasureName=Condition
Text="Condition result: %1"
DynamicVariables=1
Thank you both!
Crest
Posts: 154
Joined: August 16th, 2013, 12:47 pm

Re: Lua for conditional operators with strings as result. [Help]

Post by Crest »

I use SKIN:ParseFormula(SKIN:ReplaceVariables(str)) for this in the Lua side so I can pass INI-based variables and whathaveyou as a string argument as-is.

The above example when first wrapped in the standard formula parentheses works fine then as it's using Rainmeter's formula handling, eg:

Code: Select all

String=[&Script:conditional('((10 + 8)*2 = 18)','Yes','No')]

Code: Select all

if SKIN:ParseFormula(SKIN:ReplaceVariables(cond)) == 1 then
    return true_str
You can also use Clamp(), Round(), etc.

(A reason why this is useful is since you reuse the same function for non-formula string equivalence checks, too, by toggling formula parsing—edit: with modifications to the arguments and logic, obviously)
RicardoTM
Posts: 376
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

Crest wrote: Today, 1:57 am
Hey Crest, thank you for your contribution as well, however, I don't understand how to implement it to test it. :???:

If it's supposed to go like this:

Code: Select all

function conditional(cond, true_str, false_str)
if SKIN:ParseFormula(SKIN:ReplaceVariables(cond)) == 1 then
    return true_str
end
It didn't work.
Crest
Posts: 154
Joined: August 16th, 2013, 12:47 pm

Re: Lua for conditional operators with strings as result. [Help]

Post by Crest »

RicardoTM wrote: Today, 4:19 am Hey Crest, thank you for your contribution as well, however, I don't understand how to implement it to test it. :???:

If it's supposed to go like this:

It didn't work.
Sorry, to clarify, I was only posting the beginning of the lines to show the if statement. The full function would be:

Code: Select all

function conditional(cond, true_str, false_str)
    if SKIN:ParseFormula(SKIN:ReplaceVariables(cond)) == 1 then
        return true_str
    else
        return false_str
    end
end

And also ensure that the input formula is wrapped in outer parentheses, like the typical Rainmeter formula syntax. Or you could alternatively concatenate a pair of them if the input lacks it from within the function using SKIN:ParseFormula(SKIN:ReplaceVariables("("..cond..")"))