Creating Python dictionaries based on a condition - python

I am trying to create dictionaries that will be order requests for a portfolio of funds. The dictionaries will be exported as JSON files, just to give a bit of context. This is what the dictionaries look like.
{
"accountID":"02e57c7d-d071-4c63-b491-1194a9939ea5.1452548617456",
"accountNo":"DWTE000005",
"userID":"02e57c7d-d071-4c63-b491-1194a9939ea5",
"accountType":2,
"ordType":"1",
"side":"B",
"instrumentID":"06926627-e950-48f3-9c53-b679f61120ec",
"orderQty":1.4312,
"comment":""
}
The condition that the dictionaries will be created upon are if the target weightings are above 0, as follows.
targetportfolio = {
'VXUS' : 0.2,
'GOVT' : 0,
'IVW' : 0.2,
'EEM' : 0.2,
'JNK' : 0,
'VDE' : 0.15,
'LQD' : 0,
'IJR' : 0.1,
'BIL' : 0,
'AAXJ' : 0.15
}
Where each fund (for example VXUS) will have an order generated if the amount in the target portfolio dict is greater than 0. I was thinking of something along the lines of the code below, but I am quite confused. Any ideas?
def ordergen(portfolio):
for i in portfolio:
{
"accountID" : "02e57c7d-d071-4c63-b491-1194a9939ea5.1452548617456",
"accountNo" : "DWTE000005",
"userID" : "02e57c7d-d071-4c63-b491-1194a9939ea5",
"accountType" : 2,
"ordType" : "1",
"side" : "B",
"instrumentID" :fundID[i],
"orderQty" : ,
"comment":""
}

targetPortfolio = {
'VXUS' : 0.2,
'GOVT' : 0,
'IVW' : 0.2,
'EEM' : 0.2,
'JNK' : 0,
'VDE' : 0.15,
'LQD' : 0,
'IJR' : 0.1,
'BIL' : 0,
'AAXJ' : 0.15
}
orders = []
for k in targetPortfolio.keys():
if targetPortfolio[k] > 0:
orders.append({
"accountID" : "02e57c7d-d071-4c63-b491-1194a9939ea5.1452548617456",
"accountNo" : "DWTE000005",
"userID" : "02e57c7d-d071-4c63-b491-1194a9939ea5",
"accountType" : 2,
"ordType" : "1",
"side" : "B",
"instrumentID" : "",
"orderQty" : "",
"comment":""
})
print(orders)
.keys() is your friend. You can now use 'k' to fill in your order details under the condition that their weight is above 0.

Related

How to completely traverse a complex dictionary of unknown depth in python?

I'm trying to find full path to every key in my json
{ "Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder":{
"CoopRoomDifficultySetups": [
{
"RoomDifficulties": [
{
"Id" : 510,
"IsEnabled" : 1,
"AvailableRegions" : [ ],
"Weight" : 1,
"MinLevel" : 60,
"MaxLevel" : 69,
"MinFriendsLevel" : 50,
"MaxFriendsLevel" : 99,
"MinPunishLevel" : 0,
"MaxPunishLevel" : 0,
"MinHardCP" : "0",
"MinCP" : "0",
"MaxCP" : "0",
"MaxHardCP" : "0",
"LowPowerBonus" : 0.5,
"LowPowerCp" : "0",
"LowPowerLevel" : 90,
"Maps" : [ {
"MapId" : 4,
"NpcPreset" : "NPCPresetMap5Coop3",
"TypesLimit" : 1000,
"TierSpawnProbabilities" : [ {
"Tier" : 0,
"SpawnProbability" : 0.6
}, {
"Tier" : 1,
"SpawnProbability" : 0.75
}, {
"Tier" : 2,
"SpawnProbability" : 0.52
}, {
"Tier" : 3,
"SpawnProbability" : 0.6
} ],
"ChampionProbabilityTier2" : 0.1,
"ChampionProbabilityTier3" : 0.08,
"PlayersWhenMaxProbabilityTier2" : 3,
"PlayersWhenMaxProbabilityTier3" : 6,
"NpcLevelMultiplier" : 1.15,
"MapWeight" : 1,
"PointsNpcMultiplier" : 0.85,
"XpNpcMultiplier" : 0.85,
"ScoreNpcMultiplier" : 0.85,
"NpcMinLevel" : 63,
"NpcMaxLevel" : 77
} ],
"TimeOfDayMode_Parsable" : 0
}]},[{"foo":"foo"}]]}}
And with that being said I've found a function on stackoverflow to do it, however it doesn't return the exact path that I need to walk through manually to access the values, for example: to access "Id":
json['Assets']['Coop'][0]['Room'][0]['Id'] and then it returns 510
however this function returns the following path:
json['Assets']['Coop']['Room']['Id']
So it looks as if it doesn't read lists like I'd like it to. What's more I've already tried deepmerge library as a solution since my main goal is to read all the values from the json above and then compare it with another json, and when it finds "Id" : 510, then all the values below should be changed
def walktree(tree, at=lambda node: not isinstance(node, dict), prefix=(),
flattennode=lambda node:isinstance(node, (list, tuple, set))):
"""
Traverse a tree, and return a iterator of the paths from the root nodes to the leaf nodes.
tree: like '{'a':{'b':1,'c':2}}'
at: a bool function or a int indicates levels num to go down. walktree(tree, at=1) equivalent to tree.items()
flattennode: a bool function to decide whether to iterate at node value
"""
if isinstance(at, int):
isleaf_ = at == 0
isleaf = lambda v: isleaf_
at = at - 1
else:
isleaf = at
if isleaf(tree):
if not flattennode(tree):
yield (*prefix, tree)
else:
for v in tree:
yield from walktree(v, at, prefix, flattennode=flattennode)
else:
for k,v in tree.items():
yield from walktree(v, at, (*prefix, k), flattennode=flattennode)
Here is a generator which meets your requirements:
def dict_generator(dictionary, previous=None):
previous = previous[:] if previous else []
if isinstance(dictionary, dict):
for key, value in dictionary.items():
if isinstance(value, dict):
for d in dict_generator(value, previous + [key]):
yield d
elif isinstance(value, list) or isinstance(value, tuple):
for k,v in enumerate(value):
for d in dict_generator(v, previous + [key] + [[k]]):
yield d
else:
yield previous + [key, value]
else:
yield previous + [dictionary]
mydict ={'foo': {'foo1': [1,2,3], 'foo2': 1}}
print(list(dict_generator(mydict)))
Will produce output like this:
[['foo', 'foo1', [0], 1], ['foo', 'foo1', [1], 2], ['foo', 'foo1', [2], 3], ['foo', 'foo2', 1]]
Preparation:
jsonpath-ng can parse even such a nested json object very easily. It can be installed by the following command:
pip install --upgrade jsonpath-ng
Code:
import jsonpath_ng as jp
# Create the sample json
data = {"Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder":{ "CoopRoomDifficultySetups": [ { "RoomDifficulties": [ { "Id" : 510, "IsEnabled" : 1, "AvailableRegions" : [ ], "Weight" : 1, "MinLevel" : 60, "MaxLevel" : 69, "MinFriendsLevel" : 50, "MaxFriendsLevel" : 99, "MinPunishLevel" : 0, "MaxPunishLevel" : 0, "MinHardCP" : "0", "MinCP" : "0", "MaxCP" : "0", "MaxHardCP" : "0", "LowPowerBonus" : 0.5, "LowPowerCp" : "0", "LowPowerLevel" : 90, "Maps" : [ { "MapId" : 4, "NpcPreset" : "NPCPresetMap5Coop3", "TypesLimit" : 1000, "TierSpawnProbabilities" : [ { "Tier" : 0, "SpawnProbability" : 0.6 }, { "Tier" : 1, "SpawnProbability" : 0.75 }, { "Tier" : 2, "SpawnProbability" : 0.52 }, { "Tier" : 3, "SpawnProbability" : 0.6 } ], "ChampionProbabilityTier2" : 0.1, "ChampionProbabilityTier3" : 0.08, "PlayersWhenMaxProbabilityTier2" : 3, "PlayersWhenMaxProbabilityTier3" : 6, "NpcLevelMultiplier" : 1.15, "MapWeight" : 1, "PointsNpcMultiplier" : 0.85, "XpNpcMultiplier" : 0.85, "ScoreNpcMultiplier" : 0.85, "NpcMinLevel" : 63, "NpcMaxLevel" : 77 } ], "TimeOfDayMode_Parsable" : 0 }]},[{"foo":"foo"}]]}}
# Define a dictionary
d = {}
# Define an expression to parse the json object
expr = jp.parse('$..*')
for m in expr.find(data):
# Show a json path
print(str(m.full_path))
# Update the dictionary
d[str(m.full_path)] = m.value
# Show an example value in the dictionary
key = 'Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].NpcMaxLevel'
print(d[key])
Output:
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Id
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].IsEnabled
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].AvailableRegions
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Weight
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MinLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MaxLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MinFriendsLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MaxFriendsLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MinPunishLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MaxPunishLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MinHardCP
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MinCP
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MaxCP
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].MaxHardCP
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].LowPowerBonus
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].LowPowerCp
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].LowPowerLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].TimeOfDayMode_Parsable
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].MapId
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].NpcPreset
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TypesLimit
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].ChampionProbabilityTier2
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].ChampionProbabilityTier3
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].PlayersWhenMaxProbabilityTier2
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].PlayersWhenMaxProbabilityTier3
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].NpcLevelMultiplier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].MapWeight
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].PointsNpcMultiplier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].XpNpcMultiplier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].ScoreNpcMultiplier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].NpcMinLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].NpcMaxLevel
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[0].Tier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[0].SpawnProbability
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[1].Tier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[1].SpawnProbability
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[2].Tier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[2].SpawnProbability
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[3].Tier
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[0].RoomDifficulties.[0].Maps.[0].TierSpawnProbabilities.[3].SpawnProbability
Assets/CustomGameData/Resources/Configs/RoomDifficulty/RoomDifficultySetupHolder.CoopRoomDifficultySetups.[1].[0].foo
and
77
What almost helped me completely is that piece of code
https://stackoverflow.com/a/59186999/18018783
def dict_generator(indict, pre=None):
pre = pre[:] if pre else []
if isinstance(indict, dict):
for key, value in indict.items():
if isinstance(value, dict):
for d in dict_generator(value, pre + [key]):
yield d
elif isinstance(value, list) or isinstance(value, tuple):
for k,v in enumerate(value):
for d in dict_generator(v, pre + [key] + [k]):
yield d
else:
yield pre + [key, value]
else:
yield indict
However still there is one exception when it doesn't work as I wish for example when this structure is given
{
"foo":{
"foo1": [1,2,3],
"foo2": 1
}
}
the output of dict_generator will be
[1, 2, 3, ['foo', 'foo2', 1]]
so it doesn't give me a path to the key that has a list as an value since my desired output should look that way:
[['foo', 'foo1', [0], 1], ['foo', 'foo2', [1], 2], ['foo', 'foo2, [2], 3], ['foo', 'foo2', 1]]]

Auto increment pymongo

I am trying to auto increment a field in my mongo collection. The field is an 'id' field and it contains the 'id' of each document. For example. 1, 2, 3 etc.
What I want to happen is insert a new document and take the 'id' from the last document and add 1 to it so that the new document is lastID + 1.
The way I have written the code makes it so that it gets the last document and adds 1 to the last document and then updates it. So if the last id is 5, then the new document will have 5 and the document that I was incrementing on now has the new 'id' of 6.
I am not sure how to get round this so any help would be appreciated.
Code
last_id = pokemons.find_one({}, sort=[( 'id', -1)])
last_pokemon = pokemons.find_one_and_update({'id' : last_id['id']}, {'$inc': {'id': 1}}, sort=[( 'id', -1)])
new_pokemon = {
"name" : name, "avg_spawns" : avg_spawns, "candy" : candy, "img" : img_link, "weaknesses" : [], "type" : [], "candy_count" : candy_count,
"egg" : egg, "height" : height, "multipliers" : [], "next_evolution" : [], "prev_evolution" : [],
"spawn_chance" : spawn_chance, "spawn_time" : spawn_time, "weight" : weight, "id" : last_pokemon['id'], "num" : last_pokemon['id'],
}
pokemons.insert_one(new_pokemon)
The variables in new_pokemon don't matter as I am just having issues with the last_pokemon part
The find_one command in MongoDB command doesn't support sort functionality. You have to make use of normal find command with limit parameter set to 1.
last_id = pokemons.find({}, {"id": 1}, sort=[('id', -1)]).limit(1).next() # Will error if there are no documents in collection due to the usage of `next()`
last_id["id"] += 1
new_pokemon = {
"name" : name, "avg_spawns" : avg_spawns, "candy" : candy, "img" : img_link, "weaknesses" : [], "type" : [], "candy_count" : candy_count,
"egg" : egg, "height" : height, "multipliers" : [], "next_evolution" : [], "prev_evolution" : [],
"spawn_chance" : spawn_chance, "spawn_time" : spawn_time, "weight" : weight, "id" : last_id['id'], "num" : last_id['id'],
}
pokemons.insert_one(new_pokemon)

Update_one or insert_many to update records in mongodb?

I'm new to MongoDB and already inserted a table to my collection. Now I have new data (added new rows and updated values) but I don't know update_one or update_many which one should be used to update the records in the collection.
The data in my database
from pymongo import MongoClient, UpdateOne
import pandas as pd
{
"_id" : ObjectId("6143b5b78d248ba8ed0c3d88"),
"Sector" : "A",
"RKK_T" : 0.15,
"RKK_M" : 0.2,
"lastModified" : ISODate("2021-09-16T22:23:45.411Z")
},
{
"_id" : ObjectId("6143b5b78d248ba8ed0c3d89"),
"Sector" : "B",
"RKK_T" : 0.22,
"RKK_M" : 0.3,
"lastModified" : ISODate("2021-09-16T22:23:45.411Z")
}
And this is my new data that I want to push it to the database
data = [{
"_id" : "6143b5b78d248ba8ed0c3d88",
"Sector" : "A",
"RKK_T" : 0.15,
"RKK_M" : 0.25,
"lastModified" :datetime.utcnow()
},
{
"_id" : "6143b5b78d248ba8ed0c3d89",
"Sector" : "B",
"RKK_T" : 0.22,
"RKK_M" : 0.3,
"lastModified" : datetime.utcnow()
},
{
"_id" : "6143b5b78d248ba8ed0c3d90",
"Sector" : "C",
"RKK_T" : 0.25,
"RKK_M" : 0.32,
'RKK_K' : 0.4,
"lastModified" : datetime.utcnow()
}
]
df = pd.DataFrame(data, columns=['_id', 'Sector', 'RKK_T', 'RKK_M', 'lastmodified'])
df
_id Sector RKK_T RKK_M lastmodified
0 6143b5b78d248ba8ed0c3d88 A 0.15 0.25 NaN
1 6143b5b78d248ba8ed0c3d89 B 0.22 0.30 NaN
2 6143b5b78d248ba8ed0c3d90 C 0.25 0.32 NaN
So I think I need to filter by each Sector and update values of RKK_T and RKK_M columns.
So based on my research I think one way to update the collection with new data is
for i in range(len(data)):
print(i)
for key, values in data[i].items():
# print(key, values)
collection.update_one({'Sector': 'Sector'},
{'$set': {key.keys()[i]: values.values()[i]}, "$currentDate": {"lastModified": True}},
upsert=True)
but got this error
AttributeError: 'str' object has no attribute 'keys'
I really need a help for kick start:)
Thanks in advance!
pymongo update_one(), upsert=True without using $ operators
PyMongo & Pandas - Update multiple records in MongoDB collection from dataframe by matching id
How do I update a Mongo document after inserting it?
use bulkWrite
create for like this
a = []
b = {}
for d in data :
b = {'updateOne':{
"filter": {'Sector':d['Sector']},
"update":{'$set':{
"RKK_T":d["RKK_T"],
"RKK_M" : d["RKK_M"],
'RKK_K' :d["RKK_K"],
"lastModified" :d["lastModified"]
}}
}}
a.append(b)
db.collection.bulk_write(a)
it will be like this
db.collection.bulk_Write( [
{ updateOne :
{
"filter": {Sector:"A"},
"update":{$set:{"RKK_T" : 0.25,
"RKK_M" : 0.32,
'RKK_K' : 0.4,
"lastModified" : datetime.utcnow()}}
},
{ updateOne :
{
"filter": {Sector:"B"},
"update":{$set:{"RKK_T" : 0.25,
"RKK_M" : 0.32,
'RKK_K' : 0.4,
"lastModified" : datetime.utcnow()}}
},
{ updateOne :
{
"filter": {Sector:"A"},
"update":{$set:{"RKK_T" : 0.25,
"RKK_M" : 0.32,
'RKK_K' : 0.4,
"lastModified" : datetime.utcnow()}}
}
]
)

Issues with turning json data into an variable in python

I have been working on an educational project a small part of it requires me to convert a single line of json data into an variable in python 3 which I recieve from domoticz (an external open source software) however due to my skill level with json I have expierenced some issues and I am not exactly sure what im doing wrong. I did get the 200 response everytime so I assume from what I understood that means the connection isnt the issue but rather the python code. (I censored the addressed but they are correct.)
The code im using:
import time
import re
import requests
from ctypes import c_int, c_char_p, byref, sizeof, c_uint16, c_int32, c_byte
from ctypes import c_void_p
from datetime import datetime
import os
import urllib.request
import json
import logging
import sys
from requests.exceptions import HTTPError
logger = logging.getLogger(__name__)
domoticzserver='ip'
switchid='3'
device='5'
tempbed=str(4)
def domoticzrequest (url):
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
return response.read()
import urllib.request, json
with urllib.request.urlopen("http://domoticzip/json.htm?type=devices&rid=4") as url:
data = json.loads(url.read().decode())
print(data)
The json I get back which i can see by typing clicking the url in python:
{
"ActTime" : 1606722346,
"AstrTwilightEnd" : "18:37",
"AstrTwilightStart" : "06:23",
"CivTwilightEnd" : "17:14",
"CivTwilightStart" : "07:47",
"DayLength" : "08:08",
"NautTwilightEnd" : "17:56",
"NautTwilightStart" : "07:04",
"ServerTime" : "2020-11-30 08:45:46",
"SunAtSouth" : "12:30",
"Sunrise" : "08:26",
"Sunset" : "16:34",
"app_version" : "2020.2",
"result" :
[
{
"AddjMulti" : 1.0,
"AddjMulti2" : 1.0,
"AddjValue" : 0.0,
"AddjValue2" : 0.0,
"BatteryLevel" : 255,
"CustomImage" : 0,
"Data" : "Normal",
"Description" : "",
"Favorite" : 0,
"HardwareID" : 1,
"HardwareName" : "Domoticz Internal",
"HardwareType" : "Domoticz Internal interface",
"HardwareTypeVal" : 67,
"HaveDimmer" : false,
"HaveGroupCmd" : false,
"HaveTimeout" : false,
"ID" : "148702",
"LastUpdate" : "2020-10-19 15:10:02",
"MaxDimLevel" : 0,
"Name" : "Domoticz Security Panel",
"Notifications" : "false",
"PlanID" : "0",
"PlanIDs" :
[
0
],
"Protected" : false,
"ShowNotifications" : true,
"SignalLevel" : "-",
"Status" : "Normal",
"StrParam1" : "",
"StrParam2" : "",
"SubType" : "Security Panel",
"SwitchType" : "Security",
"SwitchTypeVal" : 0,
"Timers" : "false",
"Type" : "Security",
"TypeImg" : "security",
"Unit" : 0,
"Used" : 0,
"XOffset" : "0",
"YOffset" : "0",
"idx" : "2"
},
{
"AddjMulti" : 1.0,
"AddjMulti2" : 1.0,
"AddjValue" : 0.0,
"AddjValue2" : 0.0,
"BatteryLevel" : 255,
"CustomImage" : 0,
"Data" : "-5.0 C",
"Description" : "",
"Favorite" : 1,
"HardwareID" : 2,
"HardwareName" : "Test sensor",
"HardwareType" : "Dummy (Does nothing, use for virtual switches only)",
"HardwareTypeVal" : 15,
"HaveTimeout" : true,
"ID" : "14053",
"LastUpdate" : "2020-11-09 09:03:34",
"Name" : "Temperatuur Kachel",
"Notifications" : "false",
"PlanID" : "0",
"PlanIDs" :
[
0
],
"Protected" : false,
"ShowNotifications" : true,
"SignalLevel" : "-",
"SubType" : "LaCrosse TX3",
"Temp" : -5.0,
"Timers" : "false",
"Type" : "Temp",
"TypeImg" : "temperature",
"Unit" : 1,
"Used" : 1,
"XOffset" : "0",
"YOffset" : "0",
"idx" : "3",
"trend" : 0
},
{
"AddjMulti" : 1.0,
"AddjMulti2" : 1.0,
"AddjValue" : 0.0,
"AddjValue2" : 0.0,
"BatteryLevel" : 255,
"CustomImage" : 0,
"Data" : "17.5",
"Description" : "",
"Favorite" : 1,
"HardwareID" : 3,
"HardwareName" : "Test switch",
"HardwareType" : "Dummy (Does nothing, use for virtual switches only)",
"HardwareTypeVal" : 15,
"HaveTimeout" : true,
"ID" : "0014054",
"LastUpdate" : "2020-11-06 11:51:09",
"Name" : "Temperatuur gewenst",
"Notifications" : "false",
"PlanID" : "0",
"PlanIDs" :
[
0
],
"Protected" : false,
"SetPoint" : "17.5",
"ShowNotifications" : true,
"SignalLevel" : "-",
"SubType" : "SetPoint",
"Timers" : "false",
"Type" : "Thermostat",
"TypeImg" : "override_mini",
"Unit" : 1,
"Used" : 1,
"XOffset" : "0",
"YOffset" : "0",
"idx" : "4"
}
],
"status" : "OK",
"title" : "Devices"
}
Basicly I want SetPoint(in the last tab of text also right above this) which is in this instance 17.5 as a variable in python and I will make the python code loop so it will grab that json url everytime to update the status of setpoint. But im having issues only grabbing the 17.5 to make it into a variable. I end up getting the entire json like this code is doing. or I will end up getting everything past and including the setpoint if I change some stuff. Does anyone know what im doing wrong and possibly where I should be looking for an solution? I am a bit unexpierenced with the json part of python and I have no clue where to get started as the code's I found and have tried seem to not work or give me errors.
Thank you very much for your time!
json.loads returns a python dictionary so maybe sth like this would do:
result = json['result']
set_point = 0.0
for res in result:
if 'SetPoint' in res:
set_point = res['SetPoint']
You are getting your data stored in data ={"key": argument} as a dictionary.
If you want to access a certain value you have to call for it. in Your case:
SetPoint = float(data["result"][-1]["SetPoint"])
To break it down:
data["result"] # gives you a list which elements are dictionaries.
the [-1] # calls for the last element in you list which contains the SetPoint
["SetPoint"] # then calls for the SetPoint Value which is a String "17.5"
float(...) converts the string to a float value

Error while adding key/value to Python Dict in nested loop

I have a Json Structure as Follows:
{
"_id" : ObjectId("asdasda156121s"),
"Hp" : {
"bermud" : [
{
"abc" : {
"gfh" : 1,
"fgh" : 0.0,
"xyz" : [
{
"kjl" : "0",
"bnv" : 0,
}
],
"xvc" : "bv",
"hgth" : "INnn",
"sdf" : 0,
}
}
},
{
"abc" : {
"gfh" : 1,
"fgh" : 0.0,
"xyz" : [
{
"kjl" : "0",
"bnv" : 0,
}
],
"xvc" : "bv",
"hgth" : "INnn",
"sdf" : 0,
}
}
},
..
I am trying to parse this json and add a new value with key ['cat'] inside the object 'xyz',below is my py code.
data = []
for x in a:
for y in x['Hp'].values():
for z in y:
for k in z['abc']['xyz']:
for m in data:
det = m['response']
// Some processing with det whose output is stored in s
k['cat'] = s
print x
However when x is printed only the last value is being appended onto the whole dictionary, wheras there are different values for s. Its obvious that the 'cat' key is being overwritten everytime the loop rounds,but can't find a way to make it right.What mistake am I making?

Categories