I have defined a dataclass in which all variable are in snake_case. Whereas when I am returning my object I want to return everything in lowerCamerCase. But the problem is then nesting is very deep. Is there any way to automate this.
Although I have defined upper response object in camelCase what can I do for others.
#My json looks like
{
"highLevelObj1" : {
"low_level_obj1" : 1,
"low_level_obj2" : 2
},
"someRandomText" : {
"some_random_info1" : 1,
"some_random_info2" : 2
}
}
My expected output is
{
"highLevelObj1" : {
"lowLevelObj1" : 1,
"lowLevelObj2" : 2
},
"someRandomText" : {
"someRandomInfo1" : 1,
"someRandomInfo2" : 2
}
}
We can define a method to convert a snake_case string to a lowerCamelCase string
(source), then I think the easiest way would be to convert your json into a string convert it to camelCase then convert it back to a dictionary
import json
def to_camel_case(snake_str):
components = snake_str.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
my_dict = {
"highLevelObj1" : {
"low_level_obj1" : 1,
"low_level_obj2" : 2
},
"someRandomText" : {
"some_random_info1" : 1,
"some_random_info2" : 2
}
}
string_dict = json.dumps(my_dict)
string_dict_camel_case = to_camel_case(string_dict)
my_dict = json.loads(string_dict_camel_case)
Output :
{'highLevelObj1': {'lowLevelObj1': 1, 'LowLevelObj2': 2},
'Somerandomtext': {'SomeRandomInfo1': 1, 'SomeRandomInfo2': 2}}
Related
I want to retrieve the single value "count "from pymongo DB but it is not working. The image below shows how the data entry is setup.
Here is the call to my Database class to use the db.find_one().
CODE HERE:
filters = {"email": session.get('email')}
returns = {f'words.{today_s}.{self.length - 3}.count': 1}
count_value = Database.find_one_return_one("users", filters, returns)
print({f'words.{today_s}.{self.length - 3}.count':1})
print(count_value)
#staticmethod
def find_one_return_one(collection: str, query: Dict, data: Dict) -> Dict:
return Database.DATABASE[collection].find_one(query, data)
This returns an empty list of dictionaries from the correct data? I want the count value returned.
This is the projection query: {words.20220302.0.count : 1}
This is what is returned:
{'_id': ObjectId('621ee5065d08c44070140df0'), 'words': {'20220302': [{}, {}, {}, {}, {}, {}, {}]}}
What is wrong or is there a better quicker way to retrieve the count value?
The following query projection can be used to get the desired result. Note this worked with MongoDB v5.
A sample document; similar to the one in the question post:
{ _id: 1, words: { fld: [ { a: 1, b: 2 }, { a: 9, b: 100 } ] } }
The expected result is: { "_id" : 1, "words" : { "fld" : { "a" : 9 } } }
The query:
INDEX = 1 # this is the index of the array element
query = { }
projection = {
'words.fld': {
'$arrayElemAt': [
{ '$map': { 'input': '$words.fld', 'in': { 'a': '$$this.a' } } },
INDEX
]
}
}
result = collection.find_one(query, projection)
print(result)
I am creating a JSON file of a nested dictionary. My code is currently as follows:
myfamily = {
"child1" : {
"name" : "Emil"
},
"child2" : {
"name" : "Tobias"
},
"child3" : {
"name" : "Linus"
}
}
names = []
for i in myfamily.values():
print(type(i))
print(i)
s = json.dumps(i)
names.append(s)
df_family = pd.DataFrame()
df_family['Child'] = myfamily.keys()
df_family['Name'] = values
text = df_family.to_json(orient='records')
print(text)
This leads to the following output:
[{"Child":"child1","Name":"{\"2022\": 50, \"2023\": 50, \"2024\": 0}"},{"Child":"child2","Name":"{\"2022\": 50, \"2023\": 50, \"2024\": 50}"},{"Child":"child3","Name":"{\"2022\": 0, \"2023\": 100, \"2024\": 0}"}]
So my question is, why are these slashes added and is this the correct way to create a JSON text format of a nested dictionary?
import json
myfamily = {
"child1" : {
"name" : "Emil"
},
"child2" : {
"name" : "Tobias"
},
"child3" : {
"name" : "Linus"
}
}
def nested_json(dict_t,fist_key="Child"):
list_t= []
for key,val in myfamily.items():
nested_key = next(iter( val.keys()))
list_t+= [{
fist_key:key,
nested_key:val[nested_key]
}]
return json.dumps(list_t)
nested_json(myfamily)
Trying to parse a Json structure in python and Adding a new value with key 'cat':
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 print 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
Below is a sample Json structure:
{
"_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,
}
}
},
..
If you want to store all values change
k['cat'] = s
to
if 'cat' in k.keys():
k['cat'] += s
else:
k['cat'] = s
If you want to store only the first one change
k['cat'] = s
to
if 'cat' not in k.keys():
k['cat'] = s
I have the following valid dictionary. I'm trying to add another group of terms under the "expansion_modules" group.
lan_router = {
'HOSTNAME1':{
'system_type': 'MDF',
'chassis':{
0:{
'model_num': 'EX4550',
'vc_role': 'MASTER',
'expansion_modules':{
1:{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
}
},
'built-in_modules':{
0:{
'pic_slot': 2,
'built-in_model': 'EX4550BI'
}
}
}
}
}
}
I want to add the following under "expansion_modules" without removing "1"...
2:{'pic_slot': 2, 'expan_model': 'EX4550SFP'}
The following code adds what I want, but removes the existing term...
print lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][1]['expan_model']
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'] = { 2: {} }
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {'pic_slot' : 1, 'expan_model' : 'EX45504XSFP'}
You do not need the line - lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'] = { 2: {} } , it is replacing the dictionary inside expansion_modules , just remove this and execute rest.
Code -
print lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][1]['expan_model']
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {'pic_slot' : 1, 'expan_model' : 'EX45504XSFP'}
Access it like this:
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {}
Anand's answer is correct as it answers your question.
I would add that often dictionaries with [0, 1, ...] as keys should be just lists. Instead of:
'expansion_modules':{
1:{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
},
2:{ ... }
}
perhaps you should have:
'expansion_modules':[
{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
},
{ ... }
]
I have a mongo collection, i want get total value of 'number_of_ad_clicks' by given sitename, timestamp and variant id. Because we have large data so it would be better use map/reduce. Could any guys give me any suggestion?
Here is my collection json format
{ "_id" : ObjectId( "4e3c280ecacbd1333b00f5ff" ),
"timestamp" : "20110805",
"variants" : { "94" : { "number_of_ad_clicks" : 41,
"number_of_search_keywords" : 9,
"total_duration" : 0,
"os" : { "os_2" : 2,
"os_1" : 1,
"os_0" : 0 },
"countries" : { "ge" : 6,
"ca" : 1,
"fr" : 8,
"uk" : 4,
"us" : 6 },
"screen_resolutions" : { "(320, 240)" : 1,
"(640, 480)" : 5,
"(1024, 960)" : 5,
"(1280, 768)" : 5 },
"widgets" : { "widget_1" : 1,
"widget_0" : 0 },
"languages" : { "ua_uk" : 8,
"ca_en" : 2,
"ca_fr" : 2,
"us_en" : 5 },
"search_keywords" : { "search_keyword_8" : 8,
"search_keyword_5" : 5,
"search_keyword_4" : 4,
"search_keyword_7" : 7,
"search_keyword_6" : 6,
"search_keyword_1" : 1,
"search_keyword_3" : 3,
"search_keyword_2" : 2 },
"number_of_pageviews" : 18,
"browsers" : { "browser_4" : 4,
"browser_0" : 0,
"browser_1" : 1,
"browser_2" : 2,
"browser_3" : 3 },
"keywords" : { "keyword_5" : 5,
"keyword_4" : 4,
"keyword_1" : 1,
"keyword_0" : 0,
"keyword_3" : 3,
"keyword_2" : 2 },
"number_of_keyword_clicks" : 83,
"number_of_visits" : 96 } },
"site_name" : "fonter.com",
"number_of_variants" : 1 }
Here is my try. but failed.
He is my try.
m = function() {
emit(this.query, {variants: this.variants});
}
r = function(key , vals) {
var clicks = 0 ;
for(var i = 0; i < vals.length(); i++){
clicks = vals[i]['number_of_ad_clicks'];
}
return clicks;
}
res = db.variant_daily_collection.mapReduce(m, r, {out : "myoutput", "query":{"site_name": 'fonter.com', 'timestamp': '20110805'}})
db.myoutput.find()
could somebody any suggestion?
Thank you very much, i try you solution but nothing return.
I invoke the mapreduce in the following, is there any thing wrong?
res = db.variant_daily_collection.mapReduce(map, reduce, {out : "myoutput", "query":{"site_name": 'facee.com', 'timestamp': '20110809', 'variant_id': '305'}})
db.myoutput.find()
The emit function emits both a key and a value.
If you are used to SQL think of key as your GROUP BY and value as your SUM(), AVG(), etc..
In your case you want to "group by": site_name, timestamp and variant id. It looks like you may have more than one variant, so you will need to loop through the variants, like this:
map = function() {
for(var i in variants){
var key = {};
key.timestamp = this.timestamp;
key.site_name = this.site_name;
key.variant_id = i; // that's the "94" string.
var value = {};
value.clicks = this.variants[i].number_of_ad_clicks;
emit(key, value);
}
}
The reduce function will get an array of values each one like this { clicks: 41 }. The function needs to return one object that looks the same.
So if you get values = [ {clicks:21}, {clicks:10}, {clicks:5} ] you must output {clicks:36}.
So you do something like this:
reduce = function(key , vals) {
var returnValue = { clicks: 0 }; // initializing to zero
for(var i = 0; i < vals.length(); i++){
returnValue.clicks += vals[i].clicks;
}
return returnValue;
}
Note that the value from map has the same shape as the return from reduce.