how do i extract a value from a lua array? - arrays

I'm debugging someone else's application and I've run across a data structure that, when dumped to a file, looks like this:
["value"] = {}
["value"]["0.ouname"] = {}
["value"]["0.ouname"]["label"] = "Test value"
["value"]["0.ouname"]["seq"] = 90
["value"]["0.ouname"]["type"] = "text"
["value"]["0.ouname"]["value"] = ""
["value"]["1.ouname"] = {}
["value"]["localityName"]["value"] = "California"
I need to be able to extract the seq number "90" from it but I'm at a loss as to how.
I am able to get at the "California" value by doing the following:
print(myvar.value.localityName.value)
However, I can't seem to get the sequence number
So far, I've tried the following:
print(myvar.value.0.ouname.seq)
print(myvar.value.["0.ouname"].seq)
print(myvar.value."0.ouname".seq)
But I haven't been successful!
If you have any suggestions, I'd appreciate it.

In Lua, a.b is syntactic sugar for a["b"]. Of course, you can use it only when it's possible, and the resulting expression won't mean something else (as in your example).
Thus, you have to use
print(myvar.value["0.ouname"].seq)
You could also drop all dots and use only [], as such:
print(myvar["value"]["0.ouname"]["seq"])
Which is exactly the same format that has been written to file.

print(myvar.value['0.ouname'].seq)

Related

ArduinoJSON; test if property exists in JSON / Conversion

I have code running on a microcontroller, and I am parsing the control command it will receive.
The command is JSON, and looks approximately like this...
{[PARAMTER_1]:[VALUE_1], [...] , [PARAMTER_N]:[VALUE_N]}
So it could be...
{"opMode"=1, "StringA" = "Hello"}
or it could be
{"brightness"=5, "StringB"="Goodbye"}
How can I test to see if a parameter is included?
For example, if I process with this code:
String command = <JSON COMMAND>
char conString[200];
command.toCharArray(conString, sizeof(conString));
StaticJsonBuffer<1000> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(conString);
How can I test the resultant root["PARAMTER"] outputs to see if they existed? The problem is that if I just do something like...
resultString = root["StringA"];
resultInt = root["opMode"];
If those exist but are "" and 0, they will return the same values as if they were not included in the JSON in the first place.
Do I have to use something like command.indexOf("opMode") on the raw JSON string to make sure it's there? (In this example, that would work. But with more complicated JSON, that seems to be a lot of work to make sure a response is valid/existing)

Chef - Ruby - How to extract values from a nested array/list

I'm using this json content (I'm open to suggestions on better formatting here):
{"forwardingZones": [{"name": "corp.mycompany.com","dnsServers": ["192.168.0.1","192.168.0.2"]}]}
Note: we may add more items to this list as we scale out, both more IPs and more names, hence the "join(',')" in the end of the code below.
And I'm trying to loop through it to get this result:
corp.mycompany.com=192.168.0.1;192.168.0.2
Using this code:
forward_zones = node['DNS']['forward_zones'].each do |forwarded_zone|
forwarded_zone_name = forwarded_zone['name']
forwarded_zone_dns_servers = forwarded_zone['dns_servers'].join(';')
"#{forwarded_zone_name}=#{forwarded_zone_dns_servers}"
end.join(',')
This is the result that I get:
{"dnsServers"=>["192.168.0.1", "192.168.0.2"], "name"=>"corp.mycompany.com"}
What am i doing wrong...?
x.each returns x. You want x.map.

Accessing data from a structure returned by C function in Python using ctypes

I know the subject has already been treated, but I've failed to find anything that works for me, so I guess my problem is slightly different from the others.
What I do, basically, is that I use a C function wrapped into a python code using ctypes.
My goal is to compute some quantities in the C function, store them into a single structure, and return the structure in Python where I could read all the different data in the structure.
So :
To define my structure in python, I use :
class BITE(ctypes.Structure):
_fields_ = [
("lum", ctypes.c_int),
("suce", ctypes.c_int)
]
I compile like that :
sub.call(["gcc","-shared","-Wl,-install_name,ex.so","-o","ex.so","-fPIC","ex.c"])
lum = ctypes.CDLL('ex.so')
lum = lum.lum
I declare the arguments and result types like this :
lum.restype = ctypes.POINTER(BITE)
lum.argtypes = [ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.c_float,ctypes.c_float,ctypes.c_float,ctypes.c_float,ctypes.c_float]
Then, I call the C function "lum" in the python code
out = lum(all the different variables needed)
The problem begins here. I have my structure, but impossible to read the data stored in each fields.
A partial solution I found is to do :
out = out[0]
But then, when doing
print(out.suce)
I have a segmentation fault 11. DOn't know why. I tried to understand how to used create_string_buffer, but I didn't really understand how it works and what it supposed to do. Moreover, I tried to using as a black box, and still, nothing works.
I also tried some other solutions mentionned in other threads such as using out.contents or something like that, but it has no .contents attributes. Nor out.suce.value, which is also something I saw somewhere during my desperate research.
Of course, I checked in the C code that the structure exists and that each field of the structure exists, and has the right data in it.
Thanks.
Suppose you have a C-structure like this :
typedef struct _servParams
{
unsigned short m_uServPort;
char m_pInetAddr[MAX_LENGTH_OF_IP_ADDRESS];
} ServerParams_t;
To use it within ctypes you should create a wrapper like this :
class ServerParams_t(Structure):
_fields_ = [ ("m_uServPort", c_ushort),
("m_pInetAddr", (c_char * 16)) ]
Later on inside your python you can use the following snippet :
servParams = ServerParams_t()
servParams.m_uServPort = c_ushort(int(port))
servParams.m_pInetAddr = ip.encode()
If you need to pass it by value, simply pass servParams variable to you api. If you need to pass a pointer use byref(servParams).

Locating a dynamic string in a text file

Problem:
Hello, I have been struggling recently in my programming endeavours. I have managed to receive the output below from Google Speech to Text, but I cannot figure out how draw data from this block.
Excerpt 1:
[VoiceMain]: Successfully initialized
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello","confidence":0.46152416},{"transcript":"how low"},{"transcript":"how lo"},{"transcript":"how long"},{"transcript":"Polo"}],"final":true}],"result_index":0}
[VoiceMain]: Successfully initialized
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello"},{"transcript":"how long"},{"transcript":"how low"},{"transcript":"howlong"}],"final":true}],"result_index":0}
Objective:
My goal is to extract the string "hello" (without the quotation marks) from the first transcript of each block and set it equal to a variable. The problem arises when I do not know what the phrase will be. Instead of "hello", the phrase may be a string of any length. Even if it is a different string, I would still like to set it to the same variable to which the phrase "hello" would have been set to.
Furthermore, I would like to extract the number after the word "confidence". In this case, it is 0.46152416. Data type does not matter for the confidence variable. The confidence variable appears to be more difficult to extract from the blocks because it may or may not be present. If it is not present, it must be ignored. If it is present however, it must be detected and stored as a variable.
Also please note that this text block is stored within a file named "CurlOutput.txt".
All help or advice related to solving this problem is greatly appreciated.
You could do this with regex, but then I am assuming you will want to use this as a dict later in your code. So here is a python approach to building this result as a dictionary.
import json
with open('CurlOutput.txt') as f:
lines = f.read().splitlines()
flag = '{"result":[]} '
for line in lines: # Loop through each lin in file
if flag in line: # check if this is a line with data on it
results = json.loads(line.replace(flag, ''))['result'] # Load data as a dict
# If you just want to change first index of alternative
# results[0]['alternative'][0]['transcript'] = 'myNewString'
# If you want to check all alternative for confidence and transcript
for result in results[0]['alternative']: # Loop over each alternative
transcript = result['transcript']
confidence = None
if 'confidence' in result:
confidence = result['confidence']
# now do whatever you want with confidence and transcript.

setting object properties value for object array in matlab

I have created an array of objects and I would like assign a property value in a vector operation without using a for loop. Unfortunately I get an error.
A simplified example of the problem.
classdef clsMyClass < handle
properties
dblMyProperty1
end
methods
function obj = clsMyClass()
end
end
end
And when running
vecMyArray = clsMyClass.empty(100,0);
vecMyArray(100) = clsMyClass;
vecMyArray.dblMyProperty1 = 1:100;
We get the following error:
??? Incorrect number of right hand side elements in dot name
assignment. Missing [] around left hand side is a likely cause.
Any help would be appreciated.
I see what you're trying to do now. Use disperse from the MATLAB File Exchange:
>> [vecMyArray.dblMyProperty1] = disperse(1:100);
>> vecMyArray(1).dblMyProperty1
ans =
1
>> vecMyArray(10).dblMyProperty1
ans =
10
You can use the deal function for exactly this purpose:
[vecMyArray.dblMyProperty1] = deal(1:100);
See: http://www.mathworks.com/company/newsletters/articles/whats-the-big-deal.html
Edit: No you can't, actually; that'll set them to all be the vector 1:100.
I think you'll find your answer here in "Struct array errors." Even though this is a class, similar rules apply.
Unfortunately missing [] is not the cause, since adding them causes more errors. The cause is that you cannot assign the same value to all fields of the same name at once, you must do it one at a time, as in the following code:
So you'll need:
for ii=1:100
vecMyArray(ii).dblMyProperty1 = ii;
end
I know it's not satisfying, but I think it at least helps us to definitively understand this error.

Resources