I'm trying to traverse an atom tree to get to a specific item value:
[
{"#":{"rel":"mentioned",
"ostatus:object-type":"http://activitystrea.ms/schema/1.0/collection",
"href":"http://activityschema.org/collection/public"}},
{"#":{"rel":"enclosure",
"type":"image/jpeg",
"length":"225009",
"href":"https://framapiaf.org/system/media_attachments/files/000/701/279/original/19ed3ec381293bd8.jpg"}},
{"#":{"rel":"enclosure",
"type":"image/jpeg",
"length":"180205",
"href":"https://framapiaf.org/system/media_attachments/files/000/701/280/original/101ec4084b0b1920.jpeg"}},
{"#":{"rel":"enclosure",
"type":"image/jpeg",
"length":"257325",
"href":"https://framapiaf.org/system/media_attachments/files/000/701/281/original/dff3d3dc2e8e1b89.jpg"}},
{"#":{"rel":"enclosure",
"type":"image/jpeg",
"length":"224565",
"href":"https://framapiaf.org/system/media_attachments/files/000/701/282/original/983f3ad336ebc721.jpg"}},
{"#":{"rel":"alternate",
"type":"text/html",
"href":"https://mastodon.art/#luka/99809176628976105"}}
]
(This is the output of JSON.stringify(item['activity:object'].link))
But I can't seem to get past those "#" keys ; How can I access the first #.type and #.href?
Related
I am trying to import a raster file that contains land-cover codes. Once the raster sets the patch variables to these land-cover codes, I want to link those codes to a separate .csv that has vegetation-specific parameters for each land-cover code. Thus each patch will be assigned the .csv variables based on its land-cover code. I'm completely stumped as to how to do this. More generally, how can I use a .csv as a cross-reference file? I don't have any code examples but here is an example of the kind of .csv I want to use:
Table example
So this .csv would assign the GR1 variables to multiple patches with land-cover code GR1
I agree with JenB for sure, especially if your values table is relatively short. However, if you have a lot of values, it might work to use the csv and table extensions together to make a dictionary where the 'land-cover code' acts as the key to retrieve the other data for your patch. So one path would be:
Read the csv
Take one of the columns as the key
Keep the remaining columns as a list of values
Combine these two lists into a list of lists
Make a dictionary out of those two lists
Have each patch query the dictionary for the values of interest
So with this example csv table:
lcover,fuel,type
GR1,15,a
GR2,65,b
GR3,105,a
And these extensions and variables:
extensions [ csv table ]
globals [ csvRaw keyValList dataList patchDataDict ]
patches-own [ land-cover fuel patchType]
We can run a code block to do all these steps (more explanation in comments):
to setup
ca
; Load the csv
set csvRaw but-first csv:from-file "landCoverMeta.csv"
print csvRaw
; Pull first value (land cover)
set keyValList map first csvRaw
print keyValList
; Pull data values
set dataList map but-first csvRaw
print dataList
; Combine these two lists into a list of lists
let tempList ( map [ [ a b ] -> list a b ] keyValList dataList )
; Make a dictionary with the land cover as the key
; and the other columns as the value (in a list)
set patchDataDict table:from-list tempList
ask patches [
; Randomly set patch 'land cover' for this example
set land-cover one-of [ "GR1" "GR2" "GR3" ]
; Query the dictionary for the fuel column (item 0 since
; we've used landcover as the key) and for the type (item 1)
set fuel item 0 table:get patchDataDict land-cover
set patchType item 1 table:get patchDataDict land-cover
]
; Do some stuff based on the retrieved values
ask patches [
set pcolor fuel
if patchType = "a" [
sprout 1
]
]
reset-ticks
end
This generates a toy landscape where each patch is assigned a fuel and patchType value according to a query based on the first column of that csv:
Hopefully that gets you started
I am using JSON APOC plugin to create nodes from a JSON with lists in it, and I am trying to create nodes whose label is listed as an element in the list:
{
"pdf":[
{
"docID": "docid1",
"docLink": "/examplelink.pdf",
"docType": "PDF"
}
],
"jpeg":[
{
"docID": "docid20",
"docLink": "/examplelink20.pdf",
"docType": "JPEG"
}
],
...,}
And I want to both iterate through the doctypes (pdf, jpeg) and set the label as the docType property in the list. Right now I have to do separate blocks for each doctype list (jpeg: [], pdf:[]):
WITH "file:////input.json" AS url
CALL apoc.load.json(url) YIELD value
UNWIND value.pdf as doc
MERGE (d:PDF {docID: doc.docID})
I'd like to loop through the doctype lists, creating the node for each doctype with the label as either the list name (pdf) or the node's docType name (PDF). Something like:
WITH "file:////input.json" AS url
CALL apoc.load.json(url) YIELD value
for each doctypelist in value
for each doc in doctype list
MERGE(d:doc.docType {docID: doc.docID})
Or
WITH "file:////input.json" AS url
CALL apoc.load.json(url) YIELD value
for each doctypelist in value
for each doc in doctype list
MERGE(d {docID: doc.docID})
ON CREATE SET d :doc.docType
Cypher currently does not support this. To set a label, you must hardcode it into the Cypher. You could do filters, or multiple matches to do this in a tedious way, but if you aren't allowed to install any plug-ins to your Neo4j db, I would recommend either just putting an index on the type, or use a node+relation instead of the label. (There are a lot of valid doc types, so if you have to support them all, pure Cypher will make it very painful.)
Using APOC however, there is a procedure specifically for this apoc.create.addLabels
CREATE (:Movie {title: 'A Few Good Men', genre: 'Drama'});
MATCH (n:Movie)
CALL apoc.create.addLabels( id(n), [ n.genre ] ) YIELD node
REMOVE node.genre
RETURN node;
I want to use the syntax to substitute "#N/A" instead of the calculated value 0, but "" is not displayed in the csv file in NetLogo 6.0.3 (This is displayed ⇒ #N/A. I want to calculate the average value by mixing "#N/A" with numerical data in Excel, but #N/A is displayed as calculation result. If "#N/A" is displayed as a csv file, it could be calculated with Excel. In NetLogo 6.0.1, this was possible. What should I do with NetLogo 6.0.3?
The "correct" way to do this is to handle it in excel by ignoring N/As in your average. That way, you preserve those values as N/As and so have to be conscious about how you deal with them. You can do this by calculating the average with something like =AVERAGE(IF(ISNUMBER(A2:A5), A2:A5)) and then entering with ctrl+shift+enter instead of just enter. That, of course, is kind of annoying.
To solve it on the netlogo side, report the value "\"#N/A\"" instead of "#N/A". That will preserve the quotes when you import into excel. Alternatively, you could output pretty much any other string other than "#N/A". For instance, reporting "not-a-number" would make it a string, or even just using an empty string. The quotes you see in excel are actually part of the string, not just indicators that the field is a string. In general, fields in CSV don't have a type. Excel just interprets what it can as a number. It treats the exact field of #N/A as special, so modifying it in any way (not just adding quotes around it) will prevent it from interpreting in that special way.
It's also worth noting that this was a bug in previous versions of NetLogo (I'm assuming you're using BehaviorSpace here; the CSV extension has always worked this way). There was no way to output a string without having a quote at the beginning and end of the string. That is, the string value itself would have quotes in it. This behavior is a consequence of fixing it. Now, you can output true #N/A values if you want to, which there was no way of doing before.
Maybe this will work for you. Assuming you have the csv extension enabled:
extensions [ csv ]
You can use a reporter that replaces 0 values in a list (or list of lists) with the string value "#NA" (or "N/A" if you want, but for me #NA is what works with Excel).
to-report replace-zeroes [ list_ ]
if list_ = [] [ report [] ]
let out map [ i ->
ifelse-value is-list? i
[ replace-zeroes i ]
[ ifelse-value ( i != 0 ) [ i ] [ "#NA" ] ]
] list_
report out
end
As a quick check:
to test
ca
; make fake list of lists for csv output
let fake n-values 3 [ i -> n-values 5 [ random 4 ] ]
; replace the 0 values with the NA values
let replaced replace-zeroes fake
; print both the base and 0-replaced lists
print fake
print replaced
; export to csv
csv:to-file "replaced_out.csv" replaced
reset-ticks
end
Observer output (random):
[[0 0 2 2 0] [3 0 0 3 0] [2 3 2 3 1]]
[[#NA #NA 2 2 #NA] [3 #NA #NA 3 #NA] [2 3 2 3 1]]
Excel output:
I've got JSON file that looks like this
{
"alliance":{
"name_part_1":[
"Ab",
"Aen",
"Zancl"
],
"name_part_2":[
"aca",
"acia",
"ythrae",
"ytos"
],
"name_part_3":[
"Alliance",
"Bond"
]
}
}
I want to store it in dynamoDB.
The thing is that I want a generator that would take random elements from fields like name_part_1, name_part_2 and others (number of name_parts_x is unlimited and overalls number of items in each parts might be several hundreds) and join them to create a complete word. Like
name_part_1[1] + name_part_2[10] + name_part[3]
My question is that what format I should use to do that effectively? Or NoSQL shouldn't be used for that? Should I refactor JSON for something like
{
"name": "alliance",
"parts": [ "name_part_1", "name_part_2", "name_part_3" ],
"values": [
{ "name_part_1" : [ "Ab ... ] }, { "name_part_2": [ "aca" ... ] }
]
}
This is a perfect use case for DynamoDB.
You can structure like this,
NameParts (Table)
namepart (partition key)
range (hash key)
namepart: name_part_1 range: 0 value: "Ab"
This way each name_part will have its own range and scalable. You can extend it to thousands or even millions.
You can do a batch getitem from the sdk of your choice and join those values.
REST API reference:
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html
Hope it helps.
You can just put the whole document as it is in DynamoDB and then use document path to access the elements you want.
Document Paths
In an expression, you use a document path to tell DynamoDB where to
find an attribute. For a top-level attribute, the document path is
simply the attribute name. For a nested attribute, you construct the
document path using dereference operators.
The following are some examples of document paths. (Refer to the item
shown in Specifying Item Attributes.)
A top-level scalar attribute: ProductDescription A top-level list
attribute. (This will return the entire list, not just some of the
elements.) RelatedItems The third element from the RelatedItems list.
(Remember that list elements are zero-based.) RelatedItems[2] The
front-view picture of the product. Pictures.FrontView All of the
five-star reviews. ProductReviews.FiveStar The first of the five-star
reviews. ProductReviews.FiveStar[0] Note The maximum depth for a
document path is 32. Therefore, the number of dereferences operators
in a path cannot exceed this limit.
Note that each document requires a unique Partition Key.
I have a JSON result I am trying to work with in AppleScript, but because the top level items are "unnamed" I can only access them by piping the item reference, which in this case is a number. As a result, I can't iterate through it, it has to be hard coded (scroll down to the last code sample to see what I mean)
For example, this is the JSON I'm looking at:
{
"1": {
"name": "Tri 1"
},
"2": {
"name": "Tri 2"
},
"3": {
"name": "Tri 3"
},
"4": {
"name": "Orb Dave"
},
"5": {
"name": "Orb Fah"
}
}
With the help of JSON Helper I get the JSON to a more usable format (for AppleScript).
{|3|:{|name|:"Tri 3"}, |1|:{|name|:"Tri 1"}, |4|:{|name|:"Orb Dave"}, |2|:{|name|:"Tri 2"}, |5|:{|name|:"Orb Fah"}}
I can then use this code to get a list of "lights" the objects in question:
set lights to (every item in theReturn) as list
repeat with n from 1 to count of lights
set light to item n of lights
log n & light
end repeat
From that, I get:
(*1, Tri 3*)
(*2, Tri 1*)
(*3, Orb Dave*)
(*4, Tri 2*)
(*5, Orb Fah*)
You may notice the result is not in the desired order. The index is the index within the list of lights. It's not the number that appears at the top of the object. If you look to the top two pre-formated areas, you'll see the items 1,2 and 3 are Tri 1, Tri 2, and Tri 3. It is correct that Tri 3 comes first, Tri 1 second, and an Orb is third.
What I need to do is find a way to be able to iterate through the JSON in any order (sorted or not) and be able to line up "1" with "Tri 1", "3" with "Tri 3" and "5" with "Orb Fah". But I can't find ANY way to interact with the returned JSON that lets me reference the third light and return it's name. The ONLY way I can seem to be able to do it is to hard code the light indexes, such that:
log |name| of |1| of theReturn
log |name| of |2| of theReturn
log |name| of |3| of theReturn
log |name| of |4| of theReturn
log |name| of |5| of theReturn
which gives me the correct light with the correct name:
(*Tri 1*)
(*Tri 2*)
(*Tri 3*)
(*Orb Dave*)
(*Orb Fah*)
I'm thinking the problem is arising because the light ID doesn't have a descriptor or sorts. That I can't change, but I need to iterate through them programatically. Hard coding them as above is not acceptable.
Any help would be appreciated
You are dealing with a list of records here, not a list of lists. Records are key/value pairs. They do not have indexes like a list. That makes it easy if you know the keys because you just ask for the one you want. And your records have records inside them so you have 2 layers of records. Therefore if you want the value of the |name| record corresponding to |3| record then ask for it as you've discovered...
set jsonRecord to {|3|:{|name|:"Tri 3"}, |1|:{|name|:"Tri 1"}, |4|:{|name|:"Orb Dave"}, |2|:{|name|:"Tri 2"}, |5|:{|name|:"Orb Fah"}}
set record3name to |name| of |3| of jsonRecord
The downside of records in applescript is that there is no command to find the record keys. Other programming languages give you the tools to find the keys (like objective-c) but applescript does not. You have to know them ahead of time and use them as I showed.
If you don't know the keys ahead of time then you can either use JSON Helper to give you the results in a different form or use a different programming language (python, ruby, etc) to extract the information from the records.
One other option you have is to just use the json text itself without using JSON Helper. For example, if you have the json as text then you can extract the information using standard applescript commands for text objects. Your json text has the information you want on the 3rd line, the 6th, 9th etc. You could use that to your advantage and do something like this...
set jsonText to "{
\"1\": {
\"name\": \"Tri 1\"
},
\"2\": {
\"name\": \"Tri 2\"
},
\"3\": {
\"name\": \"Tri 3\"
},
\"4\": {
\"name\": \"Orb Dave\"
},
\"5\": {
\"name\": \"Orb Fah\"
}
}"
set jsonList to paragraphs of jsonText
set namesList to {}
set AppleScript's text item delimiters to ": \""
repeat with i from 3 to count of jsonList by 3
set theseItems to text items of (item i of jsonList)
set end of namesList to text 1 through -2 of (item 2 of theseItems)
end repeat
set AppleScript's text item delimiters to ""
return namesList
For each index, loop through all the items in the list looking for the one whose name matches the index:
tell application "System Events"
-- Convert the JSON file to a property list using plutil.
do shell script "plutil -convert xml1 /Users/mxn/Desktop/tri.json -o /Users/mxn/Desktop/tri.plist"
-- Read in the plist
set theItems to every property list item of property list file "/Users/mxn/Desktop/tri.plist"
set theLights to {}
-- Iterate once per item in the plist.
repeat with i from 1 to count of theItems
set theName to i as text
-- Find the item whose name is the current index.
repeat with theItem in theItems
if theItem's name is theName then
-- We found it, so add it to the results.
set theValue to theItem's value
copy {i, theValue's |name|} to the end of theLights
-- Move on to the next index.
exit repeat
end if
end repeat
end repeat
return theLights
end tell
Result:
{{1, "Tri 1"}, {2, "Tri 2"}, {3, "Tri 3"}, {4, "Orb Dave"}, {5, "Orb Fah"}}
Ideally, instead of the nested loop, we’d be able to say something like this:
set theName to i as text
set theItem to (the first item in theItems whose name is theName)
But unfortunately that produces an error.
This solution also demonstrates an alternative to JSON Helper: you can convert the JSON file to a property list using the handy plutil command line tool and use System Events' built-in support for property lists.