How to set a deeply nested JSON value? - python

For the JSON below, I want to add/update an item to "bonuses". Is there a way I can directly put a the variable {"name": "ham", "bonus": 12} ?
{
"abilities": {
"FGI": {
"score": 10,
"mod": 1,
"bonuses": [
{
"name": "spam",
"bonus": 1
},
{
"name": "eggs",
"bonus": 1
}
]
}
}
}
NOTE: I should clarify that the "JSON" is a Python Object built from a JSON String.

abilities.FGI.bonuses.push({"name": "ham", "bonus": 12});
EDIT or:
abilities["FGI"]["bonuses"].push(..);

That'll be a fun one! There isn't really an easy (built-in) way to do it. In markusf's answer, he mentions pushing at item on the end, but that's only half of your problem. If you want to make sure there's not already a "ham" item in there, you'll have to loop through it using a function like this:
function array_has_item_already(array, key, look_for_key_value) {
for( var i = 0; i < array.length; i++) {
if( typeof array[i][key] != 'undefined' && array[i][key] == look_for_key_value )
return array[i];
}
return false;
}
you'd call it like this, and it would return false if it didn't find the item:
array_has_item_already(abilities.FGI.bonuses, "name", "ham");
I'll leave it to you to push the function out to make it update or push or whatever. Have fun!
UPDATE
I just realized that you're looking for something in python. Welp, you can completely disregard my answer, or translate it, as it's in js. HA.

Related

Use python to rewrite if-else statements like javascript object literals

Here is an example of if-else statement in javascript.
function getTranslation(rhyme) {
if (rhyme.toLowerCase() === "apples and pears") {
return "Stairs";
} else if (rhyme.toLowerCase() === "hampstead heath") {
return "Teeth";
} else if (rhyme.toLowerCase() === "loaf of bread") {
return "Head";
} else if (rhyme.toLowerCase() === "pork pies") {
return "Lies";
} else if (rhyme.toLowerCase() === "whistle and flute") {
return "Suit";
}
return "Rhyme not found";
}
A more elegant way is to rewrite the if-else implementation using object.
function getTranslationMap(rhyme) {
const rhymes = {
"apples and pears": "Stairs",
"hampstead heath": "Teeth",
"loaf of bread": "Head",
"pork pies": "Lies",
"whistle and flute": "Suit",
};
return rhymes[rhyme.toLowerCase()] ?? "Rhyme not found";
}
Can python be used to write similar elegant code like javascript object literals?
I am using python 3.8
Javascript code segment is from link below;
https://betterprogramming.pub/dont-use-if-else-and-switch-in-javascript-use-object-literals-c54578566ba0
Python equivalent:
def get_translation_map(rhyme):
rhymes = {
"apples and pears": "Stairs",
"hampstead heath": "Teeth",
"loaf of bread": "Head",
"pork pies": "Lies",
"whistle and flute": "Suit"
}
return rhymes.get(rhyme.lower(), "Rhyme not found")
Another useful variation if you don't know the content of the dict and want to ensure a value is always returned:
v = adict.get('whatever') or 'default'
Would get a default value even if a there was a key with a None value in the dict

How would you translate this Pine Script nested loop into Python?

I'm new to Pine Script and I've been struggling to understand the logic behind the if/else Pine Script's operators. I can understand all the simple examples that I could find online, but when it comes to the particular code I want to translate into Python, it becomes more difficult. Here is the nested loop I'm struggling to understand:
hi:=hi[1]?high[1]>=stop[1]?false:true:low[1]<=stop[1]?true:false
stop:=hi?max1:min1
stop:=hi?hi[1]==false?stop:stop>stop[1]?stop[1]:stop:hi[1]?stop:stop<stop[1]?stop[1]:stop
As I've mentioned before my goal is to translate this snippet of code into Python. Thank you guys for help!
P.S. this is Pine Script v4
You can convert any ternary (?:) construction to an if-then-else on this website
The [1] does not denote an array, but is a history referencing operator.
With that, you can access values on previous bars.
First example
hi:=hi[1]?high[1]>=stop[1]?false:true:low[1]<=stop[1]?true:false
becomes
hi :=
if (hi[1]) {
if (high[1] >=stop[1]) {
false
} else {
true
}
} else {
if (low[1] <=stop[1]) {
true
} else {
false
}
}
Second example
stop:=hi?max1:min1
becomes
stop:=
if (hi) {
max1
} else {
min1
}
Third example
stop:=hi?hi[1]==false?stop:stop>stop[1]?stop[1]:stop:hi[1]?stop:stop<stop[1]?stop[1]:stop
becomes
stop :=
if (hi) {
if (hi[1]==false) {
stop
} else {
if (stop>stop[1]) {
stop[1]
} else {
stop
}
}
} else {
if (hi[1]) {
stop
} else {
if (stop<stop[1]) {
stop[1]
} else {
stop
}
}
}

Update nested Python list key using pop

I have a json file called pool.json which contains this:
{
"pools": {
"$poolId": {
"nodes": {
"$nodeId": {
"bcm": {
"address": {
"ip": "10.10.10.10"
},
"password": "ADMIN",
"username": "ADMIN"
}
}
}
}
}
}
This is my Python code:
pool_id = ['123456']
json_pool = json.loads(read_json_file('pool.json'))
for i in pool_id:
json_pool['pools'][i] = json_pool.pop(['pools']['$poolId'])
print('json_pool: %s' % json_pool)
I'm trying to update $poolId with the value in pool_id(I know I've only got one pool_id. I just want to get this piece working before I do anything else). Ive been trying to do this with pop but am having no success when it's nested as in this case. I can get it working when I want to change a top level key. What am I doing wrong?
I think you want to execute json_pool['pools'].pop('$poolId') instead of json_pool.pop(['pools']['$poolId']).

How to get values of keys for changing Json

I am using python2.7
I have a json i pull that is always changing when i request it.
I need to pull out Animal_Target_DisplayName under Term7 Under Relation6 in my dict.
The problem is sometimes the object Relation6 is in another part of the Json, it could be leveled deeper or in another order.
I am trying to create code that can just export the values of the key Animal_Target_DisplayName but nothing is working. It wont even loop down the nested dict.
Now this can work if i just pull it out using something like ['view']['Term0'][0]['Relation6'] but remember the JSON is never returned in the same structure.
Code i am using to get the values of the key Animal_Target_DisplayName but it doesnt seem to loop through my dict and find all the values with that key.
array = []
for d in dict.values():
row = d['Animal_Target_DisplayName']
array.append(row)
JSON Below:
dict = {
"view":{
"Term0":[
{
"Id":"b0987b91-af12-4fe3-a56f-152ac7a4d84d",
"DisplayName":"Dog",
"FullName":"Dog",
"AssetType1":[
{
"AssetType_Id":"00000000-0000-0000-0000-000000031131",
}
]
},
{
"Id":"ee74a59d-fb74-4052-97ba-9752154f015d",
"DisplayName":"Dog2",
"FullName":"Dog",
"AssetType1":[
{
"AssetType_Id":"00000000-0000-0000-0000-000000031131",
}
]
},
{
"Id":"eb548eae-da6f-41e8-80ea-7e9984f56af6",
"DisplayName":"Dog3",
"FullName":"Dog3",
"AssetType1":[
{
"AssetType_Id":"00000000-0000-0000-0000-000000031131",
}
]
},
{
"Id":"cfac6dd4-0efa-4417-a2bf-0333204f8a42",
"DisplayName":"Animal Set",
"FullName":"Animal Set",
"AssetType1":[
{
"AssetType_Id":"00000000-0000-0000-0001-000400000001",
}
],
"StringAttribute2":[
{
"StringAttribute_00000000-0000-0000-0000-000000003114_Id":"00a701a8-be4c-4b76-a6e5-3b0a4085bcc8",
"StringAttribute_00000000-0000-0000-0000-000000003114_Value":"Desc"
}
],
"StringAttribute3":[
{
"StringAttribute_00000000-0000-0000-0000-000000000262_Id":"a81adfb4-7528-4673-8c95-953888f3b43a",
"StringAttribute_00000000-0000-0000-0000-000000000262_Value":"meow"
}
],
"BooleanAttribute4":[
{
"BooleanAttribute_00000000-0000-0000-0001-000500000001_Id":"932c5f97-c03f-4a1a-a0c5-a518f5edef5e",
"BooleanAttribute_00000000-0000-0000-0001-000500000001_Value":"true"
}
],
"SingleValueListAttribute5":[
{
"SingleValueListAttribute_00000000-0000-0000-0001-000500000031_Id":"ef51dedd-6f25-4408-99a6-5a6cfa13e198",
"SingleValueListAttribute_00000000-0000-0000-0001-000500000031_Value":"Blah"
}
],
"Relation6":[
{
"Animal_Id":"2715ca09-3ced-4b74-a418-cef4a95dddf1",
"Term7":[
{
"Animal_Target_Id":"88fd0090-4ea8-4ae6-b7f0-1b13e5cf3d74",
"Animal_Target_DisplayName":"Animaltheater",
"Animal_Target_FullName":"Animaltheater"
}
]
},
{
"Animal_Id":"6068fe78-fc8e-4542-9aee-7b4b68760dcd",
"Term7":[
{
"Animal_Target_Id":"4e87a614-2a8b-46c0-90f3-8a0cf9bda66c",
"Animal_Target_DisplayName":"Animaltitle",
"Animal_Target_FullName":"Animaltitle"
}
]
},
{
"Animal_Id":"754ec0e6-19b6-4b6b-8ba1-573393268257",
"Term7":[
{
"Animal_Target_Id":"a8986ed5-3ec8-44f3-954c-71cacb280ace",
"Animal_Target_DisplayName":"Animalcustomer",
"Animal_Target_FullName":"Animalcustomer"
}
]
},
{
"Animal_Id":"86b3ffd1-4d54-4a98-b25b-369060651bd6",
"Term7":[
{
"Animal_Target_Id":"89d02067-ebe8-4b87-9a1f-a6a0bdd40ec4",
"Animal_Target_DisplayName":"Animalfact_transaction",
"Animal_Target_FullName":"Animalfact_transaction"
}
]
},
{
"Animal_Id":"ea2e1b76-f8bc-46d9-8ebc-44ffdd60f213",
"Term7":[
{
"Animal_Target_Id":"e398cd32-1e73-46bd-8b8f-d039986d6de0",
"Animal_Target_DisplayName":"Animalfact_transaction",
"Animal_Target_FullName":"Animalfact_transaction"
}
]
}
],
"Relation10":[
{
"TargetRelation_b8b178ff-e957-47db-a4e7-6e5b789d6f03_Id":"aff80bd0-a282-4cf5-bdcc-2bad35ddec1d",
"Term11":[
{
"AnimalId":"3ac22167-eb91-469a-9d94-315aa301f55a",
"AnimalDisplayName":"Animal",
"AnimalFullName":"Animal"
}
]
}
],
"Tag12":[
{
"Tag_Id":"75968ea6-4c9f-43c9-80f7-dfc41b24ec8f",
"Tag_Name":"AnimalAnimaltitle"
},
{
"Tag_Id":"b1adbc00-aeef-415b-82b6-a3159145c60d",
"Tag_Name":"Animal2"
},
{
"Tag_Id":"5f78e4dc-2b37-41e0-a0d3-cec773af2397",
"Tag_Name":"AnimalDisplayName"
}
]
}
]
}
}
The output i am trying to get is a list of all the values from key Animal_Target_DisplayName like this ['Animaltheater','Animaltitle', 'Animalcustomer', 'Animalfact_transaction', 'Animalfact_transaction'] but we need to remember the nested structure of this json always changes but the keys for it are always the same.
I guess your only option is running through the entire dict and get the values of Animal_Target_DisplayName key, I propose the following recursive solution:
def run_json(dict_):
animal_target_sons = []
if type(dict_) is list:
for element in dict_:
animal_target_sons.append(run_json(element))
elif type(dict_) is dict:
for key in dict_:
if key=="Animal_Target_DisplayName":
animal_target_sons.append([dict_[key]])
else:
animal_target_sons.append(run_json(dict_[key]))
return [x for sublist in animal_target_sons for x in sublist]
run_json(dict_)
Then calling run_json returns a list with what you want. By the way, I recommend you to rename your json from dict to, for example dict_, since dict is a reserved word of Python for the dictionary type.
Since you're getting JSON, why not make use of the json module? That will do the parsing for you and allow you to use dictionary functions+features to get the information you need.
#!/usr/bin/python2.7
from __future__ import print_function
import json
# _somehow_ get your JSON in as a string. I'm calling it "jstr" for this
# example.
# Use the module to parse it
jdict = json.loads(jstr)
# our dict has keys...
# view -> Term0 -> keys-we're-interested-in
templist = jdict["view"]["Term0"]
results = {}
for _el in range(len(templist)):
if templist[_el]["FullName"] == "Animal Set":
# this is the one we're interested in - and it's another list
moretemp = templist[_el]["Relation6"]
for _k in range(len(moretemp)):
term7 = moretemp[_k]["Term7"][0]
displayName = term7["Animal_Target_DisplayName"]
fullName = term7["Animal_Target_FullName"]
results[fullName] = displayName
print("{0}".format(results))
Then you can dump the results dict plain, or with pretty-printing:
>>> print(json.dumps(results, indent=4))
{
"Animaltitle2": "Animaltitle2",
"Animalcustomer3": "Animalcustomer3",
"Animalfact_transaction4": "Animalfact_transaction4",
"Animaltheater1": "Animaltheater1"
}

How to use mapreduce in mongodb?

I have the following code in python:
from pymongo import Connection
import bson
c = Connection()
db = c.twitter
ids = db.users_from_united_states.distinct("user.id")
for i in ids:
count = db.users_from_united_states.find({"user.id":i}).count()
for u in db.users_from_united_states.find({"user.id":i, "tweets_text": {"$size": count}}).limit(1):
db.my_usa_fitness_network.insert(u)
I need to get all the users and find the register of each user where the number of tweets_text is equal to the number of times that it appears in the collection (meaning that this document contains ALL the tweets that the same user posted).
Then, I need to save it in another collection, or just group it on the same collection.
When I run this code it gives me a number of documents that is less than the ids number
I saw something about mapReduce but I just can't figure out how to use it in my case.
I tried to run another code directly on mongodb but it hasn't worked at all:
var ids = db.users_from_united_states.distinct("user.id")
for (i=0; i< ids.length; i++){
var count = db.users_from_united_states.find({"user.id":ids[i]}).count()
db.users_from_united_states.find({"user.id":ids[i], "tweets_text": {$size: count}).limit(1).forEach(function(doc){db.my_usa_fitness_network.insert(doc)})
}
Can you help me please? I have a huge project and I need help. Thank you.
[
{
"$group": {
"_id": "$user.id",
"my_fitness_data": {
"$push": "$text"
}
}
},
{
"$project": {
"UserId": "$_id",
"TweetsCount": {
"$size": "$my_fitness_data"
},
"Tweets": "$my_fitness_data"
}
}
]

Categories