1

I am using ConTeXt to mark my pupils in a semi-automated way. My comments and grades are stored in dataset variable, as in the MWE below. I am trying to sum automatically points using a Lua function inspired by Lua wiki. Unfortunately, I do not know how to pass a whole table defined with \setdataset to a Lua macro.

\startluacode
   userdata = userdata or {}
   -- http://lua-users.org/wiki/SimpleStats
   function userdata.somme(n)
   local sum=0
   -- loop sur key=value d’une table
   for k,v in pairs(t) do
      -- si c’est un nombre, on ajoute à la somme
      if type(v) == 'number' then
         sum=sum+v
      end
   end
   return sum
end
\stopluacode

%how to declare a whole list?
\def\Total#1{userdata.somme(#1)}

\setdataset [Exercice] [Astérix]
   [introduction={Nice try},
    PointsIntro={1},
    conclusion={where is it?},
    PointsConclusion={0},
    Bonus={did you take your magic potion?},
    PointsBonus={},
   ]

\setdataset [Exercice] [Obélix]
   [introduction={too big},
    PointsIntro={1},
    conclusion={don't hurt me!},
    PointsConclusion={0},
    Bonus={you didn't need any magic potion},
    PointsBonus={1},
   ]

\starttext

\Total{Astérix}

\Total{Obélix}
\stoptext

\datasetvariable returns only one variable, not a whole table, and I am a bit lost with the data structure from the *tuc file. How can I declare my Total function to pass all Asterix keys and values (that is Astérix's table) as a variable?

I expect \Total{Astérix} to return 1 and \Total{Obélix} to return 2.

I suspect it might be easier to do the whole thing in Lua, but I am not yet able to do it.

6
  • 2
    You can get the all entries as a Lua table with job.datasets.getdata("Exercice","Astérix") and a single entry as a string with job.datasets.getdata("Exercice","Astérix","PointsIntro"). Dec 3, 2019 at 18:52
  • That sounds great, by I get an error if I tune my macro like this \def\Total#1{\ctxlua{userdata.somme(job.datasets.getdata("Exercice",#1))}}. Any idea why?
    – sztruks
    Dec 3, 2019 at 19:21
  • 1
    You have to pass the name of the entry as string ("#1") and the names of the variables in your Lua function don't match (userdata.somme(n) vs. pairs(t)). Another problem is your number check which doesn't work because everything (even the score values) is stored as a string. Dec 3, 2019 at 19:38
  • Thanks a lot for the debugging. How can I store the score value as number? Without the braces? Sadly I was convinced there were numbers…
    – sztruks
    Dec 3, 2019 at 19:48
  • 1
    You can't change the way how values are stored but you can convert the stored to a number with the tonumber function. You can also drop the check when you grab only the values from the PointsIntro and PointsBonus fields. Dec 3, 2019 at 19:55

1 Answer 1

0

All my attempts to use dataset failed. Thanks to @Wolfgang Schuster, I understood this is a format issue, that playing with tonumberdidn't solve. A working — and shorter — solution, is to store those tables directly in lua. For the records and those who are lua newbies, as I am, strings are within quotemarks, numbers aren't.

\startluacode
   userdata = userdata or {}
   -- http://lua-users.org/wiki/SimpleStats
   function userdata.somme(t)
   local sum=0
   -- loop on table key=value
   for k,v in pairs(t) do
      -- if it is a number, then sumed
      if type(v) == 'number' then
         sum=sum+v
      end
   end
   return sum
end

Astérix = {
    introduction="Nice try",
    PointsIntro=2,
    conclusion="where is it?",
    PointsConclusion=0,
    Bonus="did you take your magic potion?",
    PointsBonus=0,
}

Obélix = {
    introduction="too big",
    PointsIntro=1,
    conclusion="don't hurt me!",
    PointsConclusion=2,
    Bonus="you didn't need any magic potion",
    PointsBonus=0,
}
\stopluacode


\starttext

Astérix: \ctxlua{context(userdata.somme(Astérix))}

Obélix: \ctxlua{context(userdata.somme(Obélix))}
\stoptext

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .