----------------------------------------------------
-- LuaCalc Functions --
----------------------------------------------------
-- This file is part of luacalc (C) 2006
-- This is probably the easiest place to contribute code to,
-- if you have any ideas for functions, send in a patch or an email.
--
-- NB: all function paramaters are likely to be passed as strings.
-- implicit or explicit coercion may be necessary.
--
--
-- keeps track of all documented functions.
--
function_list = {}
-- GUI only function, appends function to the edit->functions menu (to be completed)
add_to_help = add_to_help or function(_,_) end
--
-- It is helpful for a function to be directly associated with its documentation.
-- This function takes a single table as it's argument, registers it as a luacalc function
-- and makes it callable by name. The table has a string member 'name',
-- a function member 'call' and a string member 'help', where 'call' is the function
-- to be evaluated and 'help' is it's documentation.
function luacalc_function(t)
assert(t.call and t.help and t.name)
_G[t.name]=t.call
function_list[t.name]=t
return t
end
-- Simple IF function
luacalc_function{
name = "IF",
call = function(test,succeed,fail)
-- intuitive approach:
-- if test then
-- return succeed
-- else
-- return fail
-- end
-- lua approach:
return test and succeed or fail
end,
help= "IF(cond, iftrue, <iffalse>): Evaluates cond, and returns iftrue if cond is true otherwise it returns iffalse "
}
luacalc_function{
name = "NOT",
call = function(val)
return not(val)
end,
help = "NOT(val) returns true if val is not true, false otherwise"
}
luacalc_function{
name="CONCATENATE",
call = function(...)
return table.concat(unpack(arg))
end,
help="CONCATENTE(...) returns all arguments joined together as a single string."
}
luacalc_function{
name="SUM",
call = function (arg)
local total = 0
for _, val in ipairs(arg) do
total = total+val
end
return total
end,
help=[[
SUM(...):
returns the sum of all arguments. Use the range operator or reference a whole column.
All values must be numeric. eg:
SUM(A) --sum of all values in column A
SUM(A2:F2) -- sum values in row 2 from A2 to B2
]]
}
luacalc_function{
name="AVERAGE",
call = function (arg)
return SUM(arg)/#arg
end,
help=[[
AVERAGE(...):
returns the average(mean) of all arguments. Use the range operator or reference a whole column.
All values must be numeric. eg:
AVERAGE(A) --average value in column A
]]
}
function ISEMPTY(val)
if (val=="" or not val) then return true else return false end
end
function TIME()
return os.date()
end
luacalc_function{
name = "RANDOM",
call = function(...)
return math.random(unpack(arg))
end,
help = [[
RANDOM([n], [m])
Calls the ansi C function: rand
both arguments are optional.
The value returned changes frequently as the function is recalled: try using rand instead.
]]
}
luacalc_function{
name = "RAND",
call = function(x, y)
x=x or ""
y=y or ""
rands = rands or setmetatable({}, {
__index = function(t, k)
t[k]=math.random()
end
})
return rands[x.."-"..y]
end,
help = [[
RAND($x, $y)
call with $x and $y as arguments, so that the random number is different in each cell, but is not recalculated.
]]
}
fibs = {1, 1}
setmetatable(fibs, {
__index=function(ta, k)
--local key = tonumber(k)
if k < 1 then
ta[k] = 0
else
ta[k] = ta[k-2]+ta[k-1]
end
return ta[k]
end
})
-- gives the nth fibonacci number
luacalc_function{
name = "FIB",
call = function(n)
return fibs[tonumber(n) or 1]
end,
help=[[FIB(n)
Returns the nth number in the fibonacci sequence where each number in the sequence is found by adding the previous two:
{1, 1, 2, 3, 5}
Results are cached for performance.
]]
}
luacalc_function{
name = "ABS",
call = function(n)
return math.abs(tonumber(n))
end,
help=[[ABS(num) Returns the absolute value of num]]
}
luacalc_function{
name="ACOS",
call=function(n)
return math.ACOS()
end,
help=[[ACOS(num) Returns the arc cosine of num (in radians).
.]]
}
luacalc_function{
name="CEIL",
call=function(n)
return math.ceil(n)
end,
help=[[CEIL(num) Returns the smallest integer larger than or equal to num.
]]
}
luacalc_function{
name="FLOOR",
call=function(n)
return math.floor(n)
end,
help=[[FLOOR(num) Returns the largest integer smaller than or equal to num.]]
}
luacalc_function{
name="ROUND",
call=function(n,offset)
return math.floor(n+(offset or .5))
end,
help=[[ROUND(num[,offset]) Returns the largest integer smaller than or equal to num+(offset or .5).]]
}
luacalc_function{
name="EXP",
call=function(...)
return math.exp(unpack(arg))
end,
help=[[EXP(num) Returns the value e^num]]
}
luacalc_function{
name="MAX",
call=function(n)
return math.max(unpack(n))
end,
help=[[MAX(arg) Returns the maximum value among its arguments.]]
}
luacalc_function{
name="MIN",
call=function(n)
return math.min(unpack(n))
end,
help=[[MIN(arg) Returns the minimum value among its arguments.]]
}
luacalc_function{
name = "VERSION",
call = function()
return luacalc.version
end,
help="Returns the current version of luacalc"
}
luacalc_function{
name = "WXROWS",
call = function()
return grid:GetNumberRows()
end,
help=[[WXROWS() returns amount of Rows (y) in current wxGrid]]
}
luacalc_function{
name = "WXCOLS",
call = function()
return grid:GetNumberCols()
end,
help=[[WXCOLS() returns amount of Cols (x) in current wxGrid]]
}
luacalc_function{
name = "LCROWS",
call = function()
return #luacalc.sheet or 1
end,
help=[[LCROWS() returns amount of Rows (y) in current LuaCalc]]
}
luacalc_function{
name = "LCCOLS",--x
call = function()
return #luacalc.sheet[1] or 1
end,
help=[[LCCOLS() returns amount of Cols (x) in current LuaCalc]]
}
luacalc_function{
name = "ANA_TAB",--x
call = function(tab,sep)
if sep==nil then sep=" - " end
local rep=""
for k,v in pairs(tab or {}) do
rep=rep..'["'..k..'"]='..tostring(v)..sep
end
return rep
--return #luacalc.sheet[1] or -1
end,
help=[[ANA_TAB(table,seperator) returns traversed table indexed k..'='..tostring(v)..seperator]]
}
luacalc_function{
name = "INIT_SET_TIMEZONE",--x
call = function(strnum)
if type(strnum)=="number" then
return num
elseif type(strnum)=="string" then
return wx.wxDateTime[strnum]
end
return 0--should be -1 meaning failure (this assumes we are on GMT0)
-- return #luacalc.sheet[1] or -1
end,
help=[[INIT_SET_TIMEZONE() sets and returns the current timezone (as a number or as a string:
// underscore stands for minus
GMT_12, GMT_11, GMT_10, GMT_9, GMT_8, GMT_7,
GMT_6, GMT_5, GMT_4, GMT_3, GMT_2, GMT_1,
GMT0,
GMT1, GMT2, GMT3, GMT4, GMT5, GMT6,
GMT7, GMT8, GMT9, GMT10, GMT11, GMT12, GMT13,
// Note that GMT12 and GMT_12 are not the same: there is a difference
// of exactly one day between them
// some symbolic names for TZ
// Europe
WET = GMT0, // Western Europe Time
WEST = GMT1, // Western Europe Summer Time
CET = GMT1, // Central Europe Time
CEST = GMT2, // Central Europe Summer Time
EET = GMT2, // Eastern Europe Time
EEST = GMT3, // Eastern Europe Summer Time
MSK = GMT3, // Moscow Time
MSD = GMT4, // Moscow Summer Time
// US and Canada
AST = GMT_4, // Atlantic Standard Time
ADT = GMT_3, // Atlantic Daylight Time
EST = GMT_5, // Eastern Standard Time
EDT = GMT_4, // Eastern Daylight Saving Time
CST = GMT_6, // Central Standard Time
CDT = GMT_5, // Central Daylight Saving Time
MST = GMT_7, // Mountain Standard Time
MDT = GMT_6, // Mountain Daylight Saving Time
PST = GMT_8, // Pacific Standard Time
PDT = GMT_7, // Pacific Daylight Saving Time
HST = GMT_10, // Hawaiian Standard Time
AKST = GMT_9, // Alaska Standard Time
AKDT = GMT_8, // Alaska Daylight Saving Time
// Australia
A_WST = GMT8, // Western Standard Time
A_CST = GMT13 + 1, // Central Standard Time (+9.5)
A_EST = GMT10, // Eastern Standard Time
A_ESST = GMT11, // Eastern Summer Time
// New Zealand
NZST = GMT12, // Standard Time
NZDT = GMT13, // Daylight Saving Time
// Universal Coordinated Time = the new and politically correct name
// for GMT
UTC = GMT0
]]
}
-- some functions for playing sudoku
luacalc_function{
name = "LEFT",
call = function(arg)
local t = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}
for _, tab in next, arg do
if type(tab)=="table" then
for _, v in next, tab do
--print(":"..v)
local num = tonumber(v)
if num then
t[num]=''
end
end
else
local num = tonumber(tab)
if num then
t[num]=''
end
end
end
return CONCATENATE(t)
end,
help="Returns a string containing the numbers from 1-9 not given as an argument.\nUseful for playing sudoku - can tell what numbers are available in a certain area."
}
luacalc_function{
name = "SAME",
call = function(a, b, c)
local aa = {}
string.foreach(a, function(_, letter) aa[letter] = true end)
local bb = {}
string.foreach(b, function(_, letter) bb[letter] = true end)
local cc = {}
string.foreach(c, function(_, letter) cc[letter] = true end)
local res = {}
for k, _ in pairs(aa) do
if bb[k] and cc[k] then
table.insert(res, k)
end
end
table.sort(res)
return CONCATENATE(res)
end,
help="Returns a string containing the numbers from 1-9 given in each string argument.\nUseful for playing sudoku - can tell what numbers are available in a row, col and box."
}
luacalc_function{
name = "SELECT",
call = function(x1, y1, x2, y2)
return luacalc.getselection{x1, y1, x2, y2}
end,
help=[[Returns the value(s) in a selection of cells indexed by numbers instead of A1 type syntax. Result is not necesarily displayable in a cell
and this function is designed to be used to pass arguments to other functions and be used with the $x and $y syntax.]]
}