## Share your favourite helper functions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
spir
Citizen
Posts: 76
Joined: Wed Oct 17, 2012 1:12 pm

### Re: Share your favourite helper functions

Robin wrote:
Inny wrote:So, implementing round(x) as floor(x+0.5) is wrong.
Not necessarily. There are a lot of different rules for tie-breaking, and one is not necessarily "right" or "wrong".
Thank you to bring the subject on the table, Robin. Can one point to a doc where is explained the reason for the "round-to-even" rule? I read several times that it's supposed to produce equal counts of numbers up and down, but never expalined why. For me, intuitively, common, school-math round to next (x.5 --> x+1, -x.5 --> -x-1) is obviously right. My intuition is probably wrong here though, I won't contradict great brains of mathematicians, but I want to understand why I'm wrong.

Denis
... la vita e estrany ...
spir
Citizen
Posts: 76
Joined: Wed Oct 17, 2012 1:12 pm

### Re: Share your favourite helper functions

Robin wrote:
spir wrote:EDIT2: But my dream tool func is rather:

Code: Select all

   local x = 1
note(x)      --> "x : 1"
--> not just "1"

Option: add in parens the func name and line number of the "note" statement:

Code: Select all

f = function (x)
local x = 1
note(x)      --> "x : 1 (f, 333)"
end

Those two aren't really possible in Lua (unless you hack together a preprocessor or manage to incorporate MetaLua or something).
Yes, you are right, Robin. Thus the word "dream"... (but this may need a new check with tools in the debug lib allowing to get local names, I guess; haven't studied yet, though).
... la vita e estrany ...
spir
Citizen
Posts: 76
Joined: Wed Oct 17, 2012 1:12 pm

### Re: Share your favourite helper functions

spir wrote:
Robin wrote:
Inny wrote:So, implementing round(x) as floor(x+0.5) is wrong.
Not necessarily. There are a lot of different rules for tie-breaking, and one is not necessarily "right" or "wrong".
Thank you to bring the subject on the table, Robin. Can one point to a doc where is explained the reason for the "round-to-even" rule? I read several times that it's supposed to produce equal counts of numbers up and down, but never expalined why. For me, intuitively, common, school-math round to next (x.5 --> x+1, -x.5 --> -x-1) is obviously right. My intuition is probably wrong here though, I won't contradict great brains of mathematicians, but I want to understand why I'm wrong.

Denis
I answer myself about simplicity: the wikipedia article now has nice formulas, which led me to:

Code: Select all

--[[  Round to next integer and round to given precision.
Using "round half to infinite" or "round half away from zero".
A formula for round0 is : sign(n) * floor(abs(n) + 0.5)
]]
math.round0 = function (n)       -- to next int (1.5 --> 2, -1.5 --> -2)
if n >= 0 then return math.floor(n + 0.5)
else return - math.floor(-n + 0.5) end
end
math.round = function (n, p)     -- to given power-of-ten precision
local factor = 10^p
local mult = n * factor
local mult_round0 = math.round0(mult)
return mult_round0 / factor
end

denis
... la vita e estrany ...
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

### Re: true escaped quoted string?

spir wrote:I don't get what you mean here: I'm producing an escaped string (thus backslahes are all escaped in the replacement patterns).
You had elseif c == '\"'. I changed it to elseif c == '"'. That's all.
spir wrote:(other things)
Do you know Python? It has two functions for converting things to strings: str, which is like Lua's tostring, and repr, which is like your tostring. To only have str is good, to have both is better, but to only have repr is madness, because now you have a problem when you want to display things to the user.

To prevent "\"\\\"nested\\\"\"" quoting stacking up, you need to write a function real_tostring:

Code: Select all

function real_tostring(t)
if type(t) == "string" then
return t
end
end
and then you need to change all functions that look like this:

Code: Select all

function someFunc(someArg)
someArg = tostring(someArg)
-- ...
to

Code: Select all

function someFunc(someArg)
someArg = real_tostring(someArg)
-- ...
The real problem comes when someone else has to maintain your code, and they find al these calls to real_tostring in your code. They'll assume tostring(foo) == foo holds if foo is a string (because it usually does), and reason:
"real_tostring is the same as"

Code: Select all

function real_tostring(t)
if type(t) == "string" then
end
end
"which is the same as"

Code: Select all

function real_tostring(t)
end
"which means real_tostring is just a waste of stack space. I'll remove the functions and change all the calls to real_tostring to tostring."

And that's a problem.

So: I think your function string.quoted is really useful, and if you write a function that writes out tables, be sure to use string.quoted on string keys and values, but you shouldn't change the behaviour of standard library functions (especially not one as basic as tostring).
Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

### Re: Share your favourite helper functions

spir wrote:
Robin wrote:
spir wrote:EDIT2: But my dream tool func is rather:

Code: Select all

   local x = 1
note(x)      --> "x : 1"
--> not just "1"

Option: add in parens the func name and line number of the "note" statement:

Code: Select all

f = function (x)
local x = 1
note(x)      --> "x : 1 (f, 333)"
end

Those two aren't really possible in Lua (unless you hack together a preprocessor or manage to incorporate MetaLua or something).
Yes, you are right, Robin. Thus the word "dream"... (but this may need a new check with tools in the debug lib allowing to get local names, I guess; haven't studied yet, though).
Sure they are possible:

Code: Select all

local function note(var,scope)
local printedstartlocal = false
local printedstartenviroment = false
if ((not scope) or (scope == "local")) then
local i = 0
while (true) do
i = 1 + i
local name,value = debug.getlocal(2,i)
if (name ~= nil) then
if (name:sub(1,1) ~= "(") then
if (value == var) then
if (not printedstartlocal) then
printedstartlocal = true
print("Local variables:")
end
print(name.." : "..tostring(value))
end
end
else
break
end
end
end
if ((not scope) or (scope == "enviroment")) then
local env = getfenv()
for name,value in pairs(env) do
if (value == var) then
if (not printedstartenviroment) then
if (printedstartlocal) then print("") end
printedstartenviroment = true
print("Enviroment variables:")
end
print(name.." : "..tostring(value))
end
end
end
end

y = 123
local function test(x)
local x = 123
local z = 123
local q = 1
note(x)
end
test()
spir
Citizen
Posts: 76
Joined: Wed Oct 17, 2012 1:12 pm

### Re: true escaped quoted string?

Robin wrote: So: I think your function string.quoted is really useful, and if you write a function that writes out tables, be sure to use string.quoted on string keys and values, but you shouldn't change the behaviour of standard library functions (especially not one as basic as tostring).
Yo, I understand your point of view better, now. And you are certainly right, in the general case. (Maybe I code too much on my own, or rather actually echanging with a few people who mostly share my obsession of practicle debugging tools. Anyway.)

Your solution of explicitely using string.quoted is good and works anyway. The only point is it (systematically) complicates a bit the coding of tostring functions or more generally "output writing" functions, in every single case. I mean when we write such a func for a given element, for a general "type" like array-, set-, . object-like tables, or for a custom type, then we always need to consider string items especially. Not a big deal, but I find myself idiot when faced with such stupid, repetitively mechanic tasks (that's precisley what machines are good for, thus I wish the machine to do it for me).

Anyway, you are indeed very on the point of sharing code.

Denis
... la vita e estrany ...
Nsmurf
Party member
Posts: 191
Joined: Fri Jul 27, 2012 1:58 am
Location: West coast.

### Re: Share your favourite helper functions

I recently made a blog post about loading levels from images. It takes a file path and a array as input, and returns a level that is compatible with YellowAfterLife’s Platformer engine, although you could export it into almost any format. It's also a nice example of how to use love.image, for those of you who are as confused about it as I was .
OBEY!!!
My Blog
UE0gbWUgd2l0aCB0aGUgd29yZCAnSE1TRycgYXMgdGhlIHN1YmplY3Q=
verilog
Citizen
Posts: 97
Joined: Thu Nov 03, 2011 3:15 am
Contact:

### Re: Share your favourite helper functions

Nice code snippet, Nsmurf, thanks for sharing. Also, nice blog post on collision detection, I found it quite helpful.
Nsmurf
Party member
Posts: 191
Joined: Fri Jul 27, 2012 1:58 am
Location: West coast.

### Re: Share your favourite helper functions

verilog wrote:Nice code snippet, Nsmurf, thanks for sharing. Also, nice blog post on collision detection, I found it quite helpful.
Thanks, I'm glad to hear that people like my blog!
OBEY!!!
My Blog
UE0gbWUgd2l0aCB0aGUgd29yZCAnSE1TRycgYXMgdGhlIHN1YmplY3Q=
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

### Re: Share your favourite helper functions

Nsmurf wrote:I recently made a blog post about loading levels from images. It takes a file path and a array as input, and returns a level that is compatible with YellowAfterLife’s Platformer engine, although you could export it into almost any format. It's also a nice example of how to use love.image, for those of you who are as confused about it as I was .
Nice! Finally, something easier to load my levels
Currently designing themes for WordPress.

Sometimes lurks around the forum.

### Who is online

Users browsing this forum: No registered users and 12 guests