I'm creating a lexer which creates tokens and outputs them as a JSON list. The tokens are namedtuples.
More specifically, Token = namedtuple('Token', ['kind', 'lexeme'])
I create my tokens and print them using json.dumps(tokens, separators=(',', ':'))).
The output looks like this:
[
[
"INT",
"123"
],
[
"ID"
"b32"
],
]
I am looking to add a 'kind' and 'lexeme' label so that it looks like:
[
[
"kind" : "INT",
"lexeme" : "123"
],
[
"kind" : "ID"
"lexeme" : "b32"
],
]
Any ideas on how to do this?
Convert the namedtuple to dict before running json.dumps().
json.dumps([t._asdict() for t in tokens], separators=(',', ':'))
This should generate:
[
{
"kind" : "INT",
"lexeme" : "123"
},
{
"kind" : "ID",
"lexeme" : "b32"
}
]
Try it online!
Related
I am working with a JSON file similar to the one below:
{ "Response" : {
"TimeUnit" : [ 1576126800000 ],
"metaData" : {
"errors" : [ ],
"notices" : [ "query served by:1"]
},
"stats" : {
"data" : [ {
"identifier" : {
"names" : [ "apiproxy", "response_status_code", "target_response_code", "target_ip" ],
"values" : [ "IO", "502", "502", "7.1.143.6" ]
},
"metric" : [ {
"env" : "dev",
"name" : "sum(message_count)",
"values" : [ 0.0]
} ]
} ]
} } }
My object is to display a mapping of the identifier and values like :
apiproxy=IO
response_status_code=502
target_response_code=502
target_ip=7.1.143.6
I have been able to parse both names and values with
.[].stats.data[] | (.identifier.names[]) and .[].stats.data[] | (.identifier.values[])
but I need help with the jq way to map the values.
The whole thing can be done in jq using the -r command-line option:
.[].stats.data[]
| [.identifier.names, .identifier.values]
| transpose[]
| "\(.[0])=\(.[1])"
i have test case to compare against the source kept in Kafka message.
I noticed the structured is not same.
no missing field, but the structure is not arranged in the same sequence.
how do i make the result converted same as the source structure?
code to retrieve the message, then decode the base64 format and prettyprint the result.
def responseList = new JsonSlurper().parseText(consumeMessage.getResponseText())
println('response text: \n' + JsonOutput.prettyPrint(JsonOutput.toJson(responseList)))
def decoded = new JsonSlurper().parseText(new String(responseList[0].value.decodeBase64()))
println('response decoded text: \n' + JsonOutput.prettyPrint(JsonOutput.toJson(decoded)))
below is the result printed at console
2019-11-20 16:36:44.934 DEBUG oingDRToAllocationVerification-DynamicID - 10: decoded = JsonSlurper().parseText(new java.lang.String(responseList[0].value.decodeBase64()))
2019-11-20 16:36:44.945 DEBUG oingDRToAllocationVerification-DynamicID - 11: println("response decoded text:
" + JsonOutput.prettyPrint(JsonOutput.toJson(decoded)))
response decoded text:
{
"contexts": [
{
"activityId": "c2884e63-d30d-48a3-965c-0b33202885c2",
"incomingTimestamp": "2019-11-20T08:36:29.0829958Z",
"sourceName": "DispenseOrderService",
"timestamp": "2019-11-20T08:36:29.0829958+00:00",
"userId": "unknown"
}
],
"dispenseOrder": [
{
"dispenseRequestType": "DISPENSEORDER",
"id": "6320112019043628",
"items": [
{
"administrationInstructions": "drug intake information test 123",
"dispenseAsWritten": false,
"id": "cda92ec7-3191-4b7b-a972-7f4545146db4",
"itemId": "Augmentn",
"quantity": 100
},
{
"administrationInstructions": "drug intake information test 234",
"dispenseAsWritten": false,
"id": "19e00776-b08d-47c8-930b-76ddc01f0ff4",
"itemId": "Clopidogrl",
"quantity": 200
},
{
"administrationInstructions": "drug intake information test 456",
"dispenseAsWritten": true,
"id": "0a5b0f4a-366d-4fa7-a0b8-2e8c83f4af13",
"itemId": "Adenosine",
"quantity": 300
}
],
"locationId": "Pharmacy Jewel East",
"piiIdentifiers": {
"doctorId": "b502f046-fb1e-4fcf-8135-a7a13cfb47f6",
"patientId": "fe49b461-8eeb-46d5-b995-a31cdaaa35f3",
"pharmacistId": "b502f046-fb1e-4fcf-8135-a7a13cfb47f6"
},
"priority": 4,
"state": "NEW",
"type": "Test ingest type"
}
],
"messageClass": "DispenseRequestV1",
"messageId": "83e94dac-dfb6-49d7-8ca0-219d155fecce",
"notifications": [
],
"operation": "Add",
"timestamp": "2019-11-20T08:36:29.0952632+00:00"
}
below is the source. the result after conversion is not same as source. as in the structure is not arranged accordingly.
{
"operation" : "Add",
"dispenseOrder" : [ {
"id" : "6320112019043628",
"locationId" : "Pharmacy Jewel East",
"piiIdentifiers" : {
"patientId" : "fe49b461-8eeb-46d5-b995-a31cdaaa35f3",
"doctorId" : "b502f046-fb1e-4fcf-8135-a7a13cfb47f6",
"pharmacistId" : "b502f046-fb1e-4fcf-8135-a7a13cfb47f6"
},
"priority" : 4,
"state" : "NEW",
"type" : "Test ingest type",
"dispenseRequestType" : "DISPENSEORDER",
"items" : [ {
"id" : "cda92ec7-3191-4b7b-a972-7f4545146db4",
"itemId" : "Augmentn",
"quantity" : 100,
"dispenseAsWritten" : false,
"administrationInstructions" : "drug intake information test 123"
}, {
"id" : "19e00776-b08d-47c8-930b-76ddc01f0ff4",
"itemId" : "Clopidogrl",
"quantity" : 200,
"dispenseAsWritten" : false,
"administrationInstructions" : "drug intake information test 234"
}, {
"id" : "0a5b0f4a-366d-4fa7-a0b8-2e8c83f4af13",
"itemId" : "Adenosine",
"quantity" : 300,
"dispenseAsWritten" : true,
"administrationInstructions" : "drug intake information test 456"
} ]
} ],
"messageId" : "83e94dac-dfb6-49d7-8ca0-219d155fecce",
"timestamp" : "2019-11-20T08:36:29.0952632+00:00",
"messageClass" : "DispenseRequestV1",
"contexts" : [ {
"userId" : "unknown",
"timestamp" : "2019-11-20T08:36:29.0829958+00:00",
"activityId" : "c2884e63-d30d-48a3-965c-0b33202885c2",
"incomingTimestamp" : "2019-11-20T08:36:29.0829958Z",
"sourceName" : "DispenseOrderService"
} ],
"notifications" : [ ]
}
As json.org says:
An object is an unordered set of name/value pairs.
So, different JSON methods/libraries might order them in a different way. You shouldn't rely on order of name/value pairs when working with JSON.
(If order is very important to you, you might try using suggested solution from this post.)
I've been working with Firebase, and in a part of my JSON tree, I had a bunch of consecutive numbers as keys.
Here's an abbreviated portion of that part of the tree:
"matches" : {
"1" : {
"0931-Red" : [
"John Smith"
],
"2022-Blue" : [
"Paul Adams"
]
},
"2" : {
"1489-Red" : [
"Matthew Brown"
],
"1565-Blue" : [
"Ian Fowler"
]
},
"3" : {
"1652-Red" : [
""
],
"2626-Blue" : [
""
]
}
}
When I downloaded it from Firebase and used this:
if let r = ref {
r.child(accessKey).child("matches").observeSingleEvent(of: .value, with: { (snapshot) in
if let groups = snapshot.value as? NSDictionary {
The conversion to NSDictionary failed.
However, when I edited "matches" to look like this:
"matches" : {
"1" : {
"0931-Red" : [
"John Smith"
],
"2022-Blue" : [
"Paul Adams"
]
},
"2" : {
"1489-Red" : [
"Matthew Brown"
],
"1565-Blue" : [
"Ian Fowler"
]
},
"4" : {
"1652-Red" : [
""
],
"2626-Blue" : [
""
]
}
}
It worked.
I was able to convert the data to an NSDictionary.
This also worked by changing the first "1" to "01" and appending a string to the beginning of each number like "match-1", "match-2", etc.
Even though my code works, the error is still bothering me because I don't know why it was wrong in the first place.
Why didn't it work with consecutive numbers as keys in the first place?
Thanks in advance!
I have the following sample data in MongoDB:
{
"_id" : ObjectId("54833e93ade1a1521a2a2fe8"),
"fname" : "yumi",
"mname" : "sakura",
"lname" : "kirisaki",
"consultations" : [
{
"medications" : [
"paracetamol",
"ibuprofen",
"carbocisteine"
],
"diagnosis" : [
"sore throat",
"fever",
"cough"
],
"date" : ISODate("2014-12-01T16:00:00Z")
},
{
"medications" : [
"paracetamol",
"carbocisteine",
"afrin"
],
"diagnosis" : [
"cough",
"colds",
"fever"
],
"date" : ISODate("2014-12-11T16:00:00Z")
}
]
}
{
"_id" : ObjectId("54833e93ade1a1521a2a2fe9"),
"fname" : "james",
"mname" : "legaspi",
"lname" : "reyes",
"consultations" : [
{
"medications" : [
"zanamivir",
"ibuprofen",
"paracetamol"
],
"diagnosis" : [
"influenza",
"body aches",
"headache"
],
"date" : ISODate("2014-10-22T16:00:00Z")
},
{
"medications" : [
"carbocisteine",
"albuterol",
"ibuprofen"
],
"diagnosis" : [
"asthma",
"cough",
"headache"
],
"date" : ISODate("2014-11-13T16:00:00Z")
}
]
}
I am trying to query patients with zanamivir AND ibuprofen AND cough:
db.patient.find({
$and:
[
{"consultations.medications":["zanamivir", "ibuprofen"]},
{"consultations.diagnosis":"cough"}
]
}).pretty()
So, in the short sample data, I was hoping james would be returned since he is the only one with zanamivir medication.
Nothing is happening when I enter the above query in cmd. It just goes to the next line (no syntax errors, etc.)
How must I go about the query?
You need the use the $all operator.
db.patient.find({
"consultations.medications": { "$all" : [ "zanamivir", "ibuprofen" ]},
"consultations.diagnosis": "cough"
})
Pretty simple, it's just your first part of the query.
db.patient.find({
$and:[
{"consultations.medications":["zanamivir", "ibuprofen"]},
{"consultations.diagnosis":"cough"}]})
Asking Mongodb to find consultations.medications against ["zanamivir", "ibuprofen"] is asking it to find someone whose medications are equal to ['zanamivir', 'ibuprofen'].
If you want to find people who have had zanamivir and ibuprofen medicated you need to tweak the query to this:
db.patient.find({
$and:[
{"consultations.medications":"zanamivir"},
{"consultations.medications":"ibuprofen"},
{"consultations.diagnosis":"cough"}]})
Enjoy!
On the Actor/Movie demo graph, cypher returns column names in a separate array.
MATCH (n:Person) RETURN n.name as Name, n.born as Born ORDER BY n.born LIMIT 5
results:
{ "columns" : [ "Name", "Born" ], "data" : [ [ "Max von Sydow", 1929 ], [ "Gene Hackman", 1930 ], [ "Richard Harris", 1930 ], [ "Clint Eastwood", 1930 ], [ "Mike Nichols", 1931 ] ]}
Is it possible to get each node properties tagged instead?
{ "nodes" : [ ["Name": "Max von Sydow", "Born": 1929 ], ...] }
If I return the node instead of selected properties, I get way too many properties.
MATCH (n:Person) RETURN n LIMIT 5
results:
{ "columns" : [ "n" ], "data" : [ [ { "outgoing_relationships" : "http://localhost:7474/db/data/node/58/relationships/out", "labels" : "http://localhost:7474/db/data/node/58/labels", "data" : { "born" : 1929, "name" : "Max von Sydow" }, "all_typed_relationships" : "http://localhost:7474/db/data/node/58/relationships/all/{-list|&|types}", "traverse" : "http://localhost:7474/db/data/node/58/traverse/{returnType}", "self" : "http://localhost:7474/db/data/node/58", "property" : "http://localhost:7474/db/data/node/58/properties/{key}", "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/58/relationships/out/{-list|&|types}", "properties" : "http://localhost:7474/db/data/node/58/properties", "incoming_relationships" : "http://localhost:7474/db/data/node/58/relationships/in", "extensions" : { }, "create_relationship" : "http://localhost:7474/db/data/node/58/relationships", "paged_traverse" : "http://localhost:7474/db/data/node/58/paged/traverse/{returnType}{?pageSize,leaseTime}", "all_relationships" : "http://localhost:7474/db/data/node/58/relationships/all", "incoming_typed_relationships" : "http://localhost:7474/db/data/node/58/relationships/in/{-list|&|types}" } ], ... ]}
You can use the new literal map syntax in Neo4j 2.0 and do something like:
MATCH (n:Person)
RETURN { Name: n.name , Born: n.born } as Person
ORDER BY n.born
LIMIT 5