extracting CSV data that needs to be re-read frequently? - variables

Most of the time when I read in CSV data I use local variables:
(defun do-something ()
...
(let ((thing (read-csv #P"~/Desktop/file.csv")))
.... do stuff with thing))
This works. However, some of my functions are becoming quite large and messy. So I tried putting the function to read in data in a special variable:
(defparameter *file* (read-csv #P"~/Desktop/file.csv"))
But when I use the *file* variable, it doesn't update with the new file.csv.
Is there a way to force refresh or maybe a better way of extracting CSV data in real time?

As a variable, *file* is initialized from the result of read-csv function. So unless you setf *file* again from read-csv it will not update.
If the path doesn't change you could wrap read-csv into another function like:
(defun retrieve-csv-data ()
(read-csv #P"~/Desktop/file.csv"))
And use that where ever you need the csv data.

Related

loading values from `require(file)` into local variables

Sorry if this is an FAQ but if some lib.lua returns a table of local functions e.g.
return {readCsv=readCsv, sumList=sumList, printHelp=printHelp}
and file2.lua imports it using
local lib=require("lib")
is there some programmatic way to automate the loading of the lib values into the local space? So i DON'T have to keep doing e.g.
local readCsv,sumList,printHelp=lib.readCsv,lib.sumList,lib.printHelp
I know its standard practice in LUA and it properly does not annoy many people. But it happens so often that I was wondering if there was a standard shortcut.
(Note: Just to be clear, I know how to make them globals by loading them into _ENV but that is exactly what I do not want.)
In Lua, local variables are statically declared constructs. They're known at compile-time and cannot (generally) be allocated at runtime. Even the number of locals that an individual function holds is known at compile-time, even if the values held in them are not known until the function object is created.
As such, there is no dynamic mechanism to dump the contents of a table into a runtime-defined number of local variables.
The closest you could do is to parse the Lua script text manually to find all of the require statements, do those require yourself, and parse the tables to generate a sequence of local declarations that you will insert into the appropriate place in your Lua script text. You would then compile that script and use it.
But this is a huge amount of work just to get rid of lib.. It's just not worth it.
Since, it's just a regular table that is being returned by require, you can "unpack" that table to turn it into a list of values:
-- return values as both array and hash
return {readCsv, sumList, printHelp,
readCsv=readCsv, sumList=sumList, printHelp=printHelp}
-- then do
local readCsv,sumList,printHelp = (table.unpack or unpack)(require "lib")
The order of returned/assigned values will obviously matter.
If somebody still wants to use a "regular" syntax with local lib = require "lib", it will continue to work.
Based on the above, I came up with a function that simplifies importing. Now I sort of agree with #NicolBolas that is all a little "cancer of the semi-colon" but heh, its short and optional (only a few lines of code, does not mess with usual LUA module conventions)
get"file" requires the file and unpacks results in alphabetical order. Kind of analogous to the Python command
from file import *
get"file thing1 thing2.." requires the file and unpacks only thing1 thing2. Kind of analogous to the Python command
from file import thing1,thing2
e.g. heres a file that returns some code:
-- file = cc.lua
function fun1() print(1) end
function fun2() print(2) end
function fun3() print(3) end
function fun4() print(4) end
function fun5() print(5) end
return {fun3=fun3, fun1=fun1, fun2=fun2, funs5=fun5, fun4=fun4}
Here's one example of usage (unpack all). Note that the sub-module (cc.lua) can return its things in any order at all and this code will unpack them in alpha order:
-- file = gettest1.lua
local get=require"get"
local fun1,fun2,fun3,fun4,fun5=get"cc"
fun5()
And here's the other usage where we can unpack somethings, in any order we want:
-- file = gettest2.lua
local get=require"get"
local fun3,fun1=get"cc fun3 fun1"
fun1()
And here's the code for the get.lua file that holds the get function
-- file = get.lua
local function get(spec)
local gets, keys,out={},{},{}
for get in string.gmatch(spec, "([^ ]+)") do gets[#gets+1]= get end
local results = require(table.remove(gets,1))
if #gets>0
then keys= gets
else for key,_ in pairs(results) do keys[#keys+1] = key end
table.sort(keys)
end
for _,key in ipairs(keys) do out[#out+1] = results[key] end
return table.unpack(out)
end
return get
Improvements? Suggestions? Comments?

AS400 RPGLE/free dynamic variables in operations

I'm fairly certain after years of searching that this is not possible, but I'll ask anyway.
The question is whether it's possible to use a dynamic variable in an operation when you don't know the field name. For example, I have a data structure that contains a few hundred fields. The operator selects one of those fields and the program needs to know what data resides in the field from the data structure passed. So we'll say that there are 100 fields, and field50 is what the operator chose to operate on. The program would be passed in the field name (i.e. field50) in the FLDNAM variable. The program would read something like this the normal way:
/free
if field50 = 'XXX'
// do something
endif;
/end-free
The problem is that I would have to code this 100 times for every operation. For example:
/free
if fldnam = 'field1';
// do something
elseif fldnam = 'field2';
// do something
..
elseif fldnam = 'field50';
// do something
endif;
Is there any possible way of performing an operation on a field not yet known? (i.e. IF FLDNAM(pointer data) = 'XXX' then do something)
If the data structure is externally-described and you know what file it comes from, you could use the QUSLFLD API to find out the offset, length, and type of the field in the data structure, and then use substring to get the data and then use other calculations to get the value, depending on the data type.
Simple answer, no.
RPG's simply not designed for that. Few languages are.
You may want to look at scripting languages. Perl for instance, can evaluate on the fly. REXX, which comes installed on the IBM i, has an INTERPRET keyword.
REXX Reference manual

reverse function: from output to input

there is a simple function that from a configuration file, with its value, return a byte array and then the following functions write it on Data Memory on a PLC.
Here is my question: i need to read firt of all these data Memory, get its values, and check if is there any different value with my configuration file's values.
Then from this byte array, write the corrispondentig values on the configuration file; in other word i need a reverse function that from output returns the input.
I think it is a very usefull function.
Maybe using reflection??
Thanks for any help
Matteo M.

How to append hash tables in velocity template?

I tried to append two hash tables in velocity.
#foreach($dun1 in $dotcontent.pull("+structureName:Checnas +(conhost:fe1d98e8-9699-4f3f-abf5-a6c0afc8ab47 conhost:SYSTEM_HOST)",10,"modDate desc"))
#set($foo={
$!{dun1.mname}:$!{dun1.subname}
})
#end
In the above for each loop I am pulling content from structure "Checnas".
But at the end we can get only the last value in the content.To solve that we need to append for every iteration.I need syntax for appending hash tables.
Please help me to solve this.
Your code currently is over writing $foo each time and hence you are just getting the last value. You can use lists in velocity to achieve this.
This might work:
#set($listOfMnames=[])
#set($listOfSubNames=[])
#foreach($dun1 in $dotcontent.pull("+structureName:Checnas +(conhost:fe1d98e8-9699-4f3f-abf5-a6c0afc8ab47 conhost:SYSTEM_HOST)",10,"modDate desc"))
#set($foo=$listOfMnames.add($!{dun1.mname}))
#set($foo=$listOfSubNames.add($!{dun1.subname}))
#end
This way, you will end up with two lists 'listOfMnames' and 'listOfSubNames', both fully populated. You can later iterate through them to print/utilise their values.
This link will be helpful and tell you the purpose of using $foo which is not being used and just being assigned.
Alternatively, you can also use velocity maps with proper key/val pairs but be sure to declare it before the loop begins.

one variable for all the sql output

myRs=myStmt.executeQuery("select i_col,col_name from tab_col")
i=0
while (myRs.next()):
list= myRs.getString("I_COL")+','+myRs.getString("COL_NAME")
i have a jython code to run a sql statement i want to store all the row of the sql into a single variable. I used to list to store the value but its always storing only the single line , so is there is way to append all the rows and keep adding to single variable.
Thanks so much for your help.
With that code you overwrite the "list" variable in every iteration of the while loop (= is an assignment), try something like this (I used rs rather than list to avoid a name clash with the builtin function list()):
myRs=myStmt.executeQuery("select i_col,col_name from tab_col")
rs=[]
i=0
while (myRs.next()):
rs.append(myRs.getString("I_COL")+','+myRs.getString("COL_NAME"))