* k, v -- can't see the forest for the trees

Writing and using plugins for Version 5 and above.
Post Reply
User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

k, v -- can't see the forest for the trees

Post by Ron Melby » 16 Apr 2021 23:03

I have a table with 1 ... n entries, or an array it doesnt matter.

when I do
function read_tbl_entries(tbl)
for k, v in pairs(tbl) do
rtx =wtrent(tbl[k])
end
end
am I sending in a parm in which I can retrieve the key as well as the value(s)?

lucky me, I got my importinent-ist data back from my disk crash, but I am brain dead, little stuff all over the place to collect yet.....
I been thinking for 3 days on it. its gotta be that simple, right?
FH V.6.2.7 Win 10 64 bit

User avatar
tatewise
Megastar
Posts: 21534
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: k, v -- can't see the forest for the trees

Post by tatewise » 17 Apr 2021 09:19

Yes, rtx = wtrent( tbl[k] ) is sending the value v because tbl[k] is the value v
So rtx = wtrent( v ) is exactly the same.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

Re: k, v -- can't see the forest for the trees

Post by Ron Melby » 17 Apr 2021 12:17

Yeah, thats what I saw, but not what I want

I need the keyable table entry, for example

[1] = {a, b, c, table, table, table}

I need the key as well. the entire entry.

rtx = wtrent( tbl[#tbl] )
is fundamentally the same though, just getting v
FH V.6.2.7 Win 10 64 bit

User avatar
tatewise
Megastar
Posts: 21534
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: k, v -- can't see the forest for the trees

Post by tatewise » 17 Apr 2021 12:28

If every entry in tbl is itself a table then tbl[k] and v are one of these tables such as {a, b, c, table, table, table}

So for that particular k instance effectively rtx = wtrent( {a, b, c, table, table, table} ) is being performed.

If function wtrent( ) changes its parameter values then the contents of tbl[k] should also get changed because all tables are passed by reference.

If that is not what you want then you will have to pass the table and k separately.
rtx = wtrent( tbl, k )

Perhaps you need to explain what wtrent( ) is doing with its parameter.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

Re: k, v -- can't see the forest for the trees

Post by Ron Melby » 17 Apr 2021 17:13

I spent an hour answering you in detail. the site decides (murky, no warning, and without reason or intellect) that for reasons only known to those who do not care, that even though I am typing in this block, to log me out, and lose all my typing. happens often in long posts. ridiculous.

so I will try short

[1] = 0
[2] = {0, 0, 0} or {x=0,y=0,z=0}
[3] = {{abc}, var, var, {[1]{{{[miketate]{{{{{abc}}}}}}} you get the idea, tables within tables, variables and so on...

this code fails on [3]

Code: Select all

  local cmt = ''

  local function writeIndent(_outf, level)
    _outf:write(string.rep(' ', level))
  end

  local function writeln(_outf, item, level)    
    -- build writer functions for each item type
    cmt = ''
    _wrtobj[type(item)](_outf, item, level)
  end

  _wrtobj = 
  -- Format tbl entries for lua portable savrst
  {
    ['boolean'] = function(_outf, item, level)
      if item then
        _outf:write('true')
      else
        _outf:write('false')
      end
    end, -- fn boolean

    ['string'] = function(_outf, item, level)
      -- format Lua compliant string
      item = string.format('%q', item)
      -- fix loose apostrophes
      -- item = string.gsub(item, string.char(26), '\' .. string.char(26) .. \'')
      --  replace oversaturated escape sequences
      --  item = string.gsub(item, '\\\n', '\\n')
      --  item = string.gsub(item, '\r', '\\r')

      _outf:write(item) --(string.format('%q', item))
    end, -- fn string

    ['thread'] = function(_outf, item, level)
      local _, _ = pcall(string.dump, item)
      _outf:write('nil')
      cmt = [[ -- thread]]
    end, -- fn thread

    ['table'] = function (_outf, item, level)
      _outf:write('{\n')

      for k, v in pairs(item) do
        writeIndent(_outf, level + 1)

        _outf:write('[')
        writeln(_outf, k, level + 1) 
        _outf:write('] = ')

        writeln(_outf, v, level + 1)

        local nl = (',' .. (cmt or '') .. '\n')
        _outf:write(nl)
        cmt = ''
      end
      writeIndent(_outf, level)
      _outf:write('}')
    end, -- fn table

    ['userdata'] = function(_outf, item, level)
      local _, _ = pcall(string.dump, item)
      _outf:write('nil')
      cmt =  [[ -- userdata]]
    end, -- userdata generally fhPTR

    ['function'] = function(_outf, item, level)
      -- Only 'normal' functions, not upvalues or Cfunctions
      local dbg_info = debug.getinfo(item, 'uS')
      if dbg_info.nups > 0 then
        _outf:write('nil')
        cmt = [[ -- functions with upvalues not supported]]
      elseif dbg_info.what ~= 'Lua' then
        _outf:write('nil')
        cmt = [[ -- non-Lua function not supported]]
      else
        local r, s = pcall(string.dump, item)
        if r then
          _outf:write(string.format('loadstring(%q)', s))
          cmt = ''
        else
          _outf:write('nil')
          cmt = [[ -- cannot dump function]]
        end
      end
    end, -- fn function

    ['number'] = function(_outf, item, level)
      _outf:write(tostring(item))
    end, -- number

    ['nil'] = function(_outf, item, level)
      _outf:write('nil')
    end, -- fn nil
  }

  -- *ENTRYPOINT( fully qualified file to save to, table to save)  
  local _outf, _err
  local _ovrout = io.stdout
  if type(_pth) == 'string' then
    -- hold a previous override to stdout
    _outf, _err = io.open(_pth, 'w')
    if not _outf then
      return error(_err)
    end
    -- override
    io.stdout  = _outf
  end

  -- CRT TBL FILE
  _outf:write('return \n')
  writeln(_outf, _tbl, 0)
  _outf:write('\n')
  _outf:flush()
  _outf:close()
  io.stdout = _ovrout
end  -- savTBL
I am trying to make it tight as possible, so I dont have to duplicate the table as the other saves do, and run out of memry (even when I collected garbage every record on the others) doubling a huge file to save it doesnt leave much room in the program space to process it. I could probably save my big files over days...but--- why have a computer.

this is much less than my first writing to you.
FH V.6.2.7 Win 10 64 bit

User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

Re: k, v -- can't see the forest for the trees

Post by Ron Melby » 17 Apr 2021 17:16

I cannot keep enough information in my head at one time to see where it fails in debug.

here is the logical type of record (annotated) I am failing on, of course it is presented to me by lua in no logical sequence.

-- _famOBJ table
[fID] =
{
EPI = {(E)xtended (P)rogramming (I)nterface},
HDR = {Header},
HUSB = {Husband <INDI>, recursive <INDI>(s)},
WIFE = {Wife <INDI>, recursive <INDI>(s)},
CHIL = {Child <INDI>(s), recursive <INDI>(s)},
}


[number] =
{
[EPI] =
(
[1]
{
ID = number,
rt = 'FAM',
usig = number
},

[2] .. [n]
{
ID = number,
rt = '<INDI>',
usig = number
},
},

[HDR] =
(
_fix = number,
fID = number,
FAM = string,
MDAT = string,
DDAT = string,

fanc =
[0] .. [n]
{
<INDI>
},

HUSB =
(
0..1 <INDI>
),

WIFE =
{
0..1 <INDI>
},

CHIL = {
[0(4)] .. [n] <INDI>
},
}

<INDI> =
(
ORD = number,
PTG = number,
iID = number,
fID = number,
NAME = string,
SEX = string,
ERA = string,
BIRTH = string,
DEATH = string,

famc =
{
[0] .. [n]
fID = number,
fpa = string,
fby = string,
},

fams =
(
[0] .. [n]
fID = number,
MDAT = string,
DDAT = string,
),

fanc =
{
[0] .. [n] <INDI>
},

fdsc =
{
[0] .. [n] <INDI>
},

},
FH V.6.2.7 Win 10 64 bit

User avatar
tatewise
Megastar
Posts: 21534
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: k, v -- can't see the forest for the trees

Post by tatewise » 17 Apr 2021 17:27

If you don't use Preview or Save Draft then you will get times out as appearing to be inactive.
What some users do is compose the reply in a text editor and then copy & paste into the reply box.

I'm sorry but I have no idea what your code is doing so I cannot help.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

Re: k, v -- can't see the forest for the trees

Post by Ron Melby » 17 Apr 2021 17:45

as I stated at the outset, saving a table to a file.

its pretty simple code, what don't you understand?

get an outfile get a table
at level 0 the entire table is sent in
so the first type it sees is table
it cuts up the table entry,
is the value a function, boolean, string, number and so on?
write each value based on type
its recursive calls the function by type as it gets them.
when you are done, end.

the trouble comes in those tables within tables getting the { and } in the right spots, when it doesnt come in order.


there should be a warning on this site on every page, don't write meaningful and detailed explanations of your questions here... And if the 'program' knows its going to time out, it could certainly write you a screen telling you to save as draft, and so on, rather than surprise you and bit bucket your work with whatever random timer it chooses.
FH V.6.2.7 Win 10 64 bit

User avatar
tatewise
Megastar
Posts: 21534
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: k, v -- can't see the forest for the trees

Post by tatewise » 18 Apr 2021 11:30

as I stated at the outset, saving a table to a file.
No, you didn't. This is the first time you have mentioned saving to a file and recursive calls. Go read what you posted.

The order of table entries should not matter. Only numerical index arrays have any concept of ordering.

for k, v in pairs(...) do should always traverse the next level of table entries.

So without a more specific example of the problem, it is impossible to help.
The example must be concise and well explained as to what is working and what is the problem.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
Ron Melby
Megastar
Posts: 705
Joined: 15 Nov 2016 15:40
Family Historian: V6.2

Re: k, v -- can't see the forest for the trees

Post by Ron Melby » 03 May 2021 13:08

miketate, you are right. I apologize. I had it all in the lost post, but not in the redone post.

let me try and make my original post on this more compact.

given general forms of 'tables' for this discussion I would like to refer to them in these terms, if you see some general type that is not represented, please advise:

1. [DIC] = 'Dictionary'
2. [ARRAY} = {0,0,0,0}
3. [RECORD] = ( [ID] = 95, [rt] = 'INDI', [usig] = 737715 }

4. [COMPLEX] .. i.e.

[number] =
{
[EPI] = ( [1] = {ID = number, rt = 'FAM', usig = number}, [2] .. [n] = {ID = number, rt = 'INDI', usig = number}, },
[HDR] = ( [fix] = number, [fID] = number, [FAM] = string, [MDAT] = string, [DDAT] = string, [fanc] = ( [0] .. [n] = r:{<INDI>}, },
[HUSB] = ( [2] = <INDI> or ''},
[WIFE] = ( [3] = <INDI> or ''},
[CHIL] = { [4] .. [n] = r:<INDI> or ''},
}

where <INDI> is a single structure and r:<INDI> may repeat the structure.
<INDI> =
(
ORD = number,
PTG = number,
iID = number,
fID = number,
NAME = string,
SEX = string,
ERA = string,
BIRTH = string,
DEATH = string,

famc =
{
[0] .. [n]
fID = number,
fpa = string,
fby = string,
},

fams =
(
[0] .. [n]
fID = number,
MDAT = string,
DDAT = string,
),

fanc =
{
[0] .. [n] r:<INDI>
},

fdsc =
{
[0] .. [n] r:<INDI>
},

},

below you find my save function save TABLE (savTBL)
(*NB: indentation and spacing (__lvl) does not work correctly, however it will save complex tables correctly so that they can be savrst-ed by loadfile (but a problem with fh debug in separate post.)
my **PROBLEM** is trying to figure out when I am at the end of a single entry, regardless of simplicity or complexity of that entry. the business end of the save is in 'table' anonymous function of wrt_type. Does anyone have a clever way of knowing it?
additionally, if anyone can find any way to simplify and squeeze performance or memory reduction out of it, please advise.


function savTBL(_pth, _tbl)
local __cmt = ''
-- local __depth = 0

local function wrt_indent(_outf, __lvl)
-- build space indent for table nesting
_outf:write(string.rep(' ', __lvl))
end

local function wrt_ctl(_outf, __item, __lvl)
-- build space indent for table nesting
_outf:write(string.rep(' ', __lvl), __item)
end

local function wrt_obj(_outf, __item, __lvl)
-- build writer function for each __item type
__cmt = ''
wrt_type[type(__item)](_outf, __item, __lvl)
end

wrt_type =
{
['table'] = function(_outf, __item, __lvl)
-- Format tbl entries for lua portable savrst
-- TODO indentation needs to carryover
for key, val in pairs(__item) do

-- write key
if key then
wrt_indent(_outf, (__lvl + 1))
-- wrt_ctl(_outf, '[', (__lvl + 1))
_outf:write('[')
wrt_obj(_outf, key, (__lvl + 1))
-- wrt_ctl(_outf, '] = ', (__lvl))
_outf:write('] = ')
end

if type(val) == 'table' then
if next(val) then
wrt_ctl(_outf, '\n{\n', (__lvl + 1))
-- _outf:write('\n{\n')
else
wrt_ctl(_outf, '{', (__lvl))
-- _outf:write('{')
end
end

-- write element
wrt_obj(_outf, val, (__lvl + 1))
_outf:write(string.format(', %s\n', (__cmt or '')))
end -- key, val

-- end of array or table
-- wrt_ctl(_outf, ')', (__lvl - 1))
wrt_indent(_outf, (__lvl - 1))
_outf:write('}')
_outf:flush()
end, -- fn table

['boolean'] = function(_outf, __item, __lvl)
-- __lvl unused
if __item then
_outf:write('true')
else
_outf:write('false')
end
end, -- fn boolean

['string'] = function(_outf, __item, __lvl)
-- __lvl unused
-- fix loose apostrophes and replace oversaturated escape sequences
-- __item = __item:gsub(string.char(26), '\' .. string.char(26) .. \''):gsub('\\\n', '\\n'):gsub('\r', '\\r')
-- format Lua compliant string
__item = string.format('%q', __item)
_outf:write(__item)
end, -- fn string

['thread'] = function(_outf, __item, __lvl)
-- __lvl unused
local _, _ = pcall(string.dump, __item)
_outf:write('nil')
__cmt = [[ -- thread]]
end, -- fn thread

['userdata'] = function(_outf, __item, __lvl)
-- __lvl unused
local _, _ = pcall(string.dump, __item)
_outf:write('nil')
__cmt = [[ -- userdata]]
end, -- userdata generally fhPTR

['function'] = function(_outf, __item, __lvl)
-- __lvl unused
-- Only 'normal' functions, not upvalues or Cfunctions
local dbg_info = debug.getinfo(__item, 'uS')
if dbg_info.nups > 0 then
_outf:write('nil')
__cmt = [[ -- function(upvalues)]]
elseif dbg_info.what ~= 'Lua' then
_outf:write('nil')
__cmt = [[ -- function not supported]]
else
local rc, s = pcall(string.dump, __item)
if rc then
_outf:write(string.format('loadstring(%q)', s))
__cmt = ''
else
_outf:write('nil')
__cmt = [[ -- function not dumped]]
end
end
end, -- fn function

['number'] = function(_outf, __item, __lvl)
-- __lvl unused
_outf:write(__item)
end, -- number

['nil'] = function(_outf, __item, __lvl)
-- __lvl unused
-- __item unused
_outf:write('nil')
end, -- fn nil
}

-- *ENTRY MAIN()
local _outf, _err
local _ovrout = io.stdout
if type(_pth) == 'string' then
-- hold a previous override to stdout
_outf, _err = io.open(_pth, 'w')
if not _outf then
return error(_err)
end
-- override
io.stdout = _outf
end

-- CRT TBL FILE
_outf:write('return\n{\n')
wrt_obj(_outf, _tbl, 0)
_outf:write('\n')
_outf:flush()
_outf:close()
io.stdout = _ovrout
end -- savTBL
FH V.6.2.7 Win 10 64 bit

Post Reply