Manipulate JSON Object Data After Iterating via For Each - json

Might be a dumb question or a small typo. I'm iterating through a JSON object I loaded in and my goal is to MTL some text deep inside. I'm iterating through a list of objects for a specified code, then I translate the text on a correct match. So Iterate through objects > Match Code > Translate Text
The problem is when I try to alter the object by replacing the text with the translated version, that data isn't changed in the returned data object.
def findMatch(data):
# Search Events
for event in data['events']:
if (event is not None):
pages = event['pages']
for page in pages:
lists = page['list']
for list in lists:
if(list['code'] == 401):
for parameter in list['parameters']:
parameter = checkLine(parameter)
return data
checkLine(parameter) will return a string of the text translated.
I'm guessing parameter isn't connected to the data object which is why it's not working but unsure how exactly it should be written out.
Also any suggestions on how to make this faster/more efficient are welcome.

for i, parameter in enumerate(list['parameters']):
list['parameters'][i] = checkLine(parameter)
Does the trick.

Related

Extract a specified data object that resides inside a PDF form field to an external file

I am looking for a script to extract a data object nested inside a data object to a new data object. Aside from being able to easily clone the object by creating a new one, while I can also extract one of several objects nested inside an object that includes all its related properties and values, the name associated with the property and values is missing. Hence, I require a script to create a new object containing any one of several names including its related properties and values extracted from the existing object provided below.
{"J Doe Company":{"lastUpdate":"01/05/2023","website":"jdoecompany.com","userID":"jdoe1985#gmail.com","password":"igfndhsi1985","primaryCC":"Discover","secondaryCC":"Capital One","primaryBank":"Chase","secondaryBank":"","sq1":"Year Graduated HS","sa1":"1985","sq2":"","sa2":"","notes1":"Sample password record","notes2":""},"Bob The Builder":{"lastUpdate":"01/05/2023","website":"bobthebuilder.com","userID":"bobthebuilder#gmail.com","password":"bbob1985","primaryCC":"Amazon Visa","secondaryCC":"Mastercard","primaryBank":"Wells Fargo","secondaryBank":"","sq1":"First Girlfriend's Name","sa1":"Kaye","sq2":"","sa2":"","notes1":"Sample password record","notes2":""},"SpongeBob Square Pants":{"lastUpdate":"01/07/2023","website":"spongebobsquarepants.com","userID":"spongebob#gmail.com","password":"spongebob1999","primaryCC":"None/Not Applicable","secondaryCC":"","primaryBank":"None/Not Applicable","secondaryBank":"","sq1":"Year show debuted on TV","sa1":"1999","sq2":"","sa2":"","notes1":"Animated TV show for kids","notes2":""}}
You can run cpdf -output-json in.pdf -o put.json and process the result. The format is described in the cpdf manual.
Upon further trial and error after learning more about how to create and edit an object literal, the script required to add an object along with its key-value properties is as follows:
dsFld =getField("dataSrc");// dataSRC is a hidden field containing a JS object converted to a JSON string
oVendors = JSON.parse(dsFld.value); // oVendors is a JS object
oVendors[event.value]=oVendorsPropValues;//oVendorsPropValues = {key-value pairs}
dsFld.value = JSON.stringify(oVendors);// convert the JS obj back to a JSON string

Using Flow to return a SharePoint list to Powerapps

I've used this Flow to return the count of any Sharepoint list to Powerapps.
https://masteroffice365.com/get-sharepoint-library-or-list-total-items-from-power-apps/
How would I modify it to return the contents of a list to Powerapps, so that I can use Powerapps to put it into a collection?
Would this mean I don't have to worry about Delegation if the list has more than 2000 items?
This is what I've tried so far.
There is a variable TotalItemsCount which I have changed to ListItems. Instead of using an Integer I set ListItems to an array.
In the Get Library list contents I use this for the URI.
concat( '_api/web/lists/GetbyTitle(''', first( body('Filter_Library_List_Being_Queried') )?['displayName'], ''')/Items' )
I'm not sure what to put in as the last step given that I want it to be able to return the contents of any list. I think this rules out a parse json step as that requires a definite schema.
I've added an ApplyToEach
I'm getting this error message when it runs.
ExpressionEvaluationFailed. The execution of template action
'Apply_to_each' failed: the result of the evaluation of 'foreach'
expression '#body('Get_Library_List_Contents')' is of type 'Object'.
The result must be a valid array.
I don't think you can return an array back to PowerApps. You would have to return the response as a JSON string, then have your PowerApp do the logic to convert the JSON string into a collection.
Likely your PowerApp would have to include something like this to convert the JSON string that's returned from the flow:
ClearCollect(
*collectionName*,
MatchAll(
*JSON_String*,
*"\{""date"":""(?<date>[^""]*)"",""message"":""(?<message>[^""]*)"",""user"":""(?<user>[^""]*)""\}"*
));
Flow returning response body to PowerApp
If I understand you correctly, you want to retrieve 14000 records from the Sharepoint list, and not just the total count.
Would this mean I don't have to worry about Delegation if the list has more than 2000 items?
Yes, when you use a cloud flow rather than directly accessing Sharepoint list from Powerapps, you basically avoid delegation of 2k records.
Now coming back to you main topic of retrieving Records, you would have to Test and run your flow and check what does the below http return. I believe it returns a JSON Array.
concat( '_api/web/lists/GetbyTitle(''', first( body('Filter_Library_List_Being_Queried') )?['displayName'], ''')/Items' )
You would have to apply a for each or clean your JSON output to return String Array or JSON Array as output of your all 14K Records.
In addition if you are using Sharepoint online why not use connector for flow mentioned here

Use a period in a field name in a Matlab struct

I'm using webwrite to post to an api. One of the field names in the json object I'm trying to setup for posting is odata.metadata. I'm making a struct that looks like this for the json object:
json = struct('odata.metadata', metadata, 'odata.type', type, 'Name', name,);
But I get an error
Error using struct
Invalid field name "odata.metadata"
Here's the json object I'm trying to use in Matlab. All strings for simplicity:
{
"odata.metadata": "https://website.com#Element",
"odata.type": "Blah.Blah.This.That",
"Name": "My Object"
}
Is there a way to submit this json object or is it a lost cause?
Field names are not allowed to have dots in them. The reason why is because this will be confused with accessing another nested structure within the structure itself.
For example, doing json.odata.metadata would be interpreted as json being a struct with a member whose field name is odata where odata has another member whose field name is metadata. This would not be interpreted as a member with the combined field name as odata.metadata. You're going to have to rename the field to something else or change the convention of your field name slightly.
Usually, the convention is to replace dots with underscores. An automated way to take care of this if you're not willing to manually rename the field names yourself is to use a function called matlab.lang.makeValidName that takes in a string and converts it into a valid field name. This function was introduced in R2014a. For older versions, it's called genvarname.
For example:
>> matlab.lang.makeValidName('odata.metadata')
ans =
odata_metadata
As such, either replace all dots with _ to ensure no ambiguities or use matlab.lang.makeValidName or genvarname to take care of this for you.
I would suggest using a a containers.Map instead of a struct to store your data, and then creating your JSON string by iterating over the Map filednames and appending them along with the data to your JSON.
Here's a quick demonstration of what I mean:
%// Prepare the Map and the Data:
metadata = 'https://website.com#Element';
type = 'Blah.Blah.This.That';
name = 'My Object';
example_map = containers.Map({'odata.metadata','odata.type','Name'},...
{metadata,type,name});
%// Convert to JSON:
JSONstr = '{'; %// Initialization
map_keys = keys(example_map);
map_vals = values(example_map);
for ind1 = 1:example_map.Count
JSONstr = [JSONstr '"' map_keys{ind1} '":"' map_vals{ind1} '",'];
end
JSONstr =[JSONstr(1:end-1) '}']; %// Finalization (get rid of the last ',' and close)
Which results in a valid JSON string.
Obviously if your values aren't strings you'll need to convert them using num2str etc.
Another alternative you might want to consider is the JSONlab FEX submission. I saw that its savejson.m is able to accept cell arrays - which can hold any string you like.
Other alternatives may include any of the numerous Java or python JSON libraries which you can call from MATLAB.
I probably shouldn't add this as an answer - but you can have '.' in a struct fieldname...
Before I go further - I do not advocate this and it will almost certainly cause bugs and a lot of trouble down the road... #rayryeng method is a better approach
If your struct is created by a mex function which creates a field that contains a "." -> then you will get what your after.
To create your own test see the Mathworks example and modify accordingly.
(I wont put the full code here to discourage the practice).
If you update the char example and compile to test_mex you get:
>> obj = test_mex
obj =
Doublestuff: [1x100 double]
odata.metadata: 'This is my char'
Note: You can only access your custom field in Matlab using dynamic fieldnames:
obj.('odata.metadata')
You need to use a mex capability to update it...

I can't write/encode JSON files properly. Code produces different results

I am having problems with the JSON file in my Corona game. Basically, the game gives you trophies (cards) when you reach certain points. The card information is then written into a JSON file. When you start the game, it checks if the file "playerCards.json" already exists, and if not, it creates such file with the following structure:
{"common":[],"uncommon":[],"rare":[]}
Later in the game, the player finally receives one card. The (simplified) code below runs:
local category = "common"
local rdm = math.random(1,20)
array = loadFile("playerCards.json")
array[category][rdm] = collection[category][rdm]
writeFile("playerCards.json", array)
Collection is a preloaded Lua table structured like this: {"common" = {"001", "002", "003",..., "020"}}. For the sake of the question, I've restricted the cards to a certain category (common). Let's suppose the player won card number 3, so the code should run like this:
array["common"][3] = collection["common"][3]
And the resulting table array would be:
array = {"common" = {nil, nil, "003"}}
When I use the function writeFile("playerCards.json", array) I am encoding the table above into the file playerCards.json. For now, this code works perfectly, and the resulting JSON file is as follows:
{"common":[null,null,"003"],"uncommon":[],"rare":[]}
The problem comes when the player gets a card above 9, for example, 15. When written, the JSON file becomes this:
{"common":{"3":"003","15":"015"},"uncommon":[],"rare":[]}
How can the same code produce such different results? Can you help me solve this problem? If you need it, here is the code for the load and write functions:
local loadFile = function(name)
local data = nil
local path = system.pathForFile(name, system.DocumentsDirectory)
handle = io.open(path, "r")
if handle then
data = json.decode(handle:read("*a"))
io.close(handle)
end
return data
end
local writeFile = function(name, data)
local path = system.pathForFile(name, system.DocumentsDirectory)
local handle = io.open(path, "w+")
if handle then
handle:write(json.encode(data))
io.close(handle)
end
end
The problem is that Lua does not distinguish between list and mapping objects (tables are used for both) while JSON does.
This creates ambiguity when serializing to JSON; the serializer has to determine whether a Lua table should serialize to an array or an object. Most serializers do this by checking if the keys of the table are roughly sequential integers, and only serializing to an array if so. If your array is too 'sparse', as in your second example, then the serializer thinks its a map with numerical keys instead.
I don't know about Corona, but some Lua JSON libraries I have seen include a method to mark tables explicitly as arrays. Alternatively, you can fill empty slots of the array with a placeholder value like false instead of nil.

printing JSON values in Python

I've search a ton of articles here and elsewhere via the Googles, plus read a few related docs over at docs.python.org and still stuck.
I am getting a response from an API like below:
{"status":"active","perms":1,"data":{"40332895":{"user_values":{"delta":-203,"value":53.32,"order":42509}}}}
I have no problem printing the 'status' or 'data'. However, all I can grab is the name of the *user_values*, not the date inside them.
Been at it for way to long and was hoping someone could point me in the right direction. Fairly new to Python and if I need to change how I am doing this because it is bad practices or there is an easier way to get the results I am looking for, please let me know.
Code:
import json
import urllib2
url = urllib2.urlopen('http://URLofAPI.com')
json_url = json.load(url)
api_result = json_url
for doc in api_result['data']['40332895']['user_values']:
print doc
outputs:
delta
value
order
what I really want to get is the value of them (i.e.: '-203', '53.32', '42509').
I am basically trying to save that data into a list\dict (individually or separately), then print it with other data. I have tried all sorts of things and cannot manage it. I am sure it's probably something super easy that I missing, but it's driving me nuts. :)
Also, I was really expecting the below to give me '42509', but I get an error:
for doc in api_result['data']['40332895']['user_values']['order']
Thanks in advance!
You're asking for the keys of the user_values dictionary, and getting them. Try this:
uv = api_result['data']['40332895']['user_values']
for doc in uv:
print uv[doc]
In your example api_result['data']['40332895']['user_values'] is a dictionary.
If you iterate over a dictionary you will get the keys. This is the case in your original example and in mgkrebbs answer.
However if you iterate over the .iteritems() (or .items()) of the dictionary you get the (key, value) pairs in a tuple:
uv = api_result['data']['40332895']['user_values']
for key,value in uv.iteritems():
print key, value
If you only need the values, you iterate over .itervalues()
uv = api_result['data']['40332895']['user_values']
for value in uv.itervalues():
print value
Or if you only need the values as a list:
my_list = api_result['data']['40332895']['user_values'].values()
The difference between .itervalues() and .values() is that the former gives you an iterable (an object which returns one value at a time, but does not create the structure in memory), while the latter gives you a list.