Lua Cookbook

This page contains examples of common tasks performed in Lua under SIMION 8.0 or 8.1.

Loading/saving array from a text file

Method 1

-- test.dat:
return {
  3, 1, 4,
  1, 5, 9
}

-- test.lua:
local array = dofile("test.dat")
-- print contents
for i,v in ipairs(array) do
  print(i,v)
end

Result:

1       3
2       1
3       4
4       1
5       5
6       9

Above, test.dat is actually a Lua program itself that returns an array. The test.lua program runs the test.dat program to obtain the array it returns.

Method 2

-- test2.lua:
function read_file_numbers(filename)
  local array = {}
  local f = assert(io.open(filename))
  while true do
    local v = f:read("*number")
    if not v then break end
    table.insert(array, v)
  end
  f:close()
  return array
end

function write_file_numbers(filename, array)
  local f = assert(io.open(filename, 'w'))
  for _,v in ipairs(array) do
    f:write(v, ' ')
  end
  f:close()
end

-- Create array in memory
local t = {3,4,5,2,5,3e20,10,2,7,-0.3}

-- Write arry to file
write_file_numbers("test2.dat", t)

-- Read array back from file
local t2 = read_file_numbers("test2.dat")

-- check that array is unchanged
for i=1, #t do
  assert(t[i] == t2[i])
end
print("ok")

Benchmarking Time

os.time() returns the integer number of seconds since 1970. This can be used for benchmarking:

local t0 = os.time()
some_operation()
local dt = os.time() - t0

os.clock() can provide more accuracy (thousandths of a second precision), but beware that it represents CPU time, which is the amount of time that your process has been running on the CPU. If your process is temporarily paused by the OS to allow other processes to run on the CPU or to wait for something like disk I/O, then this value will not increment during that time.

Getting time-stamp string

This prints the current date and time as a string:

print(os.date("%Y%m%d-%H%M%S"))

Printing numbers with a given decimal precision

This example provides a function log that operates like print but prints with five decimal places of precision.

local function log(...)
  local t = {...}
  for k,v in ipairs(t) do
    t[k] = ("%0.5f"):format(v)
  end
  print(unpack(t))
end

log(math.pi, math.pi*2)

Merging files

This merges files, line by line. It’s useful if you have data from multiple runs that needs merged.

-- merges files
local filenames = {'output-1.csv', 'output-2.csv', 'output-2.csv'}
local outfilename = 'output-all.csv'

local outfile = assert(io.open(outfilename, 'w'))
for _, name in ipairs(filenames) do
  local file = assert(io.open(name))
  for line in file:lines() do
    outfile:write(line, '\n')
  end
  file:close()
end
outfile:close()