Updating value of a nested dictionary in Python - dictionary

I have a nested dictionary
users={'user502':{'firstname':'James' , 'lastname':'Jones'}}
User can search for first or last name and be able to update to something else. I wrote the following code:
name_change=input('Enter name to change: ')
for key,value in users.items():
for k,v in value.items():
if name_change==v:
#print('name found in', value.get(name_change))
#print('name found in', value.get(k))
print('name found in', k)
updated_name=input('What would be the new name: ')
users.update(k=updated_name)
break
else:
print('name not found')
I am getting RuntimeError: dictionary changed size during iteration error. I did some research on update and also looked at this stackoverflow discussion Update value in nested dictionary - Python
I am not able to figure out how to point the code to pick first name or last name based on whatever user enters. Some hints would be helpful.
Thanks in advance.
**From other discussion it seems like in Python 3 it does not work because of '3.x because keys returns an iterator instead of a list.'
I tried to do a pop first and then update
updated_name=input('What would be the new name: ')
# users[k][v]=updated_name
x= value.get(k)
users.pop(x)
users[x]=updated_name
However now I get KeyError: 'James'

This code is doing what I wanted. May be my question was not clear sorry about that
print('Actual-', users)
name_change=input('Enter name to change: ')
for key,value in users.items():
for k,v in value.items():
if name_change==v:
#print('name found in', value.get(name_change))
#print('name found in', value.get(k))
print('name found in', k)
updated_name=input('What would be the new name: ')
value[k]=updated_name
break
else:
print('name not found')
print("modified name:", users)
Output:
Actual- {'user502': {'lastname': 'Jones', 'firstname': 'James'}}
Enter name to change: Jones
name found in lastname
What would be the new name: January
modified name: {'user502': {'lastname': 'January', 'firstname': 'James'}}

Related

How do I access a calculated field in Rails?

In my first attempt to develop something in Ruby on Rails :) ... I have a list of names stored in fields "first_name" and "last_name". In my Person model, I have defined something like this:
def sort_name
sort_name = last_name + ',' + first_name
end
Now I want to show all persons shown in a list, sorted by sort_name, but (in my controller) something like
#persons = Person.order(:sort_name)
doesn't work (Unknown column 'sort_name' in 'order clause'). How do reference to the calculated field sort_name in my controller?
I am sure this is a "oh my god I am so stupid moment" but happy for any advise!
If the model Person has the fields name, first_lastname and second_lastname, you can do the next:
Person.order(:name, :first_lastname, :second_lastname)
By default is ordering in ascending way. Also you can put if you want ascending or descending way for each field:
Person.order(name: :asc, first_lastname: :desc, second_lastname: :asc)
Additional if you want add a column with the complete name, you can use select, using postgresql the code would be:
people = Person.order(
name: :asc, first_lastname: :desc, second_lastname: :asc
).select(
"*, concat(name,' ', first_lastname, ' ',second_lastname) as sort_name"
)
people[0].sort_name
# the sort_name can be for example "Adán Saucedo Salas"

DynamoDb , unable to update the item dynamically using expressions

I am trying to update Dynamo Table using expression, I am trying to generate keys dynamically. The issue looks like if they key has space in it, expressions don't evaluate properly.
Following in my update implementation:
update_expression = 'SET {}'.format(','.join(f'#{p}=:{p}' for p in row_as_dict))
expression_attribute_values = {f':{p}': v for p, v in row_as_dict.items()}
expression_attribute_names = {f'#{p}': p for p in row_as_dict}
if result_set.get('Item') and result_set.get('Item').get(primary_key):
TABLE.update_item(
Key={
primary_key: row_as_dict[primary_key],
sort_key: row_as_dict[sort_key]
},
UpdateExpression=update_expression,
ExpressionAttributeValues=expression_attribute_values,
ExpressionAttributeNames=expression_attribute_names
)
if i print the values for update_expression and expression_attribute_values and expression_attribute_names i get following output.
update_expression
SET #Ref No=:Ref No,#FT/Hot=:FT/Hot,#Irfan watch List=:Irfan watch List,#F.Soahil watchList=:F.Soahil watchList,#HR Responible=:HR Responible,#Pipeline(Adv/Ref)=:Pipeline
(Adv/Ref),#Source=:Source,#Date Submitted=:Date Submitted,#Name=:Name,#Candidate Location=:Candidate Location,#Tech =:Tech ,#Current Company=:Current Company,#Exp=:Exp,#Position being considered for=:Position being considered for,#Proj. / Gen Hiring=:Proj. / Gen Hiring,#Comments / Latest Status / Next Step=:Comments / Latest Status / Next Step,#Status=:Status,#hiring status=:hiring status,#Link to Lever=:Link to Lever,#LinkedIn Link / Resume=:LinkedIn Link / Resume,#Interview Feedback Google Doc=:Interview Feedback Google Doc,#Email=:Email
expression_attribute_values
{':Ref No': '1', ':FT/Hot': 'NaN', ':Irfan watch List': 'NaN', ':F.Soahil watchList': 'NaN', ':HR Responible': 'Khurram', ':Pipeline\r\n(Adv/Ref)': 'Referred', ':Source': 'Usman Khan', ':Date Submitted': '17-Dec', ':Name': 'Asif Mahmood Mughal Zain', ':Candidate Location': 'ISL', ':Tech ': 'Spark. Hadoop\r\nSQL, Big Data', ':Current Company': 'Zain Telecom', ':Exp': '18+', ':Position being considered for': 'Senior SA', ':Proj. / Gen Hiring': 'General', ':Comments / Latest Status / Next Step': 'Muhammaf Naseer Recommneded\r\nAdeel Ashraf Recommended\r\nFaheem Khan Recommended\r\n\r\nAccepted offer.will join on 6 jan', ':Status': 'Joined', ':hiring status': 'Hired', ':Link to Lever': 'Link to Lever', ':LinkedIn Link / Resume': 'Asif Mehmood Mughal', ':Interview Feedback Google Doc': 'Link to Feedback', ':Email': 'some_email1#test.com'}
expression_attribute_names
{'#Ref No': 'Ref No', '#FT/Hot': 'FT/Hot', '#Irfan watch List': 'Irfan watch List', '#F.Soahil watchList': 'F.Soahil watchList', '#HR Responible': 'HR Responible', '#Pipeline\r\n(Adv/Ref)': 'Pipeline\r\n(Adv/Ref)', '#Source': 'Source', '#Date Submitted': 'Date Submitted', '#Name': 'Name', '#Candidate Location': 'Candidate Location', '#Tech ': 'Tech ', '#Current Company': 'Current Company', '#Exp': 'Exp', '#Position being considered for': 'Position being considered for', '#Proj. / Gen Hiring': 'Proj. / Gen Hiring', '#Comments / Latest Status / Next Step': 'Comments / Latest Status / Next Step', '#Status': 'Status', '#hiring status': 'hiring status', '#Link to Lever': 'Link to Lever', '#LinkedIn Link / Resume': 'LinkedIn Link / Resume', '#Interview Feedback Google Doc': 'Interview Feedback Google Doc', '#Email': 'Email'}
The Error generated is
An error occurred (ValidationException) when calling the UpdateItem operation: ExpressionAttributeValues contains invalid key: Syntax error; key: ":hiring status"
You can't have spaces in your attribute keys/values in the expression. So :hiring status needs to be something like :hiring_status.
Go Dynamof!
You might be very interested in dynamof. Its a library purposed to do exactly what your trying to do. At the very least you can take a peak and check out how it handles dynamically creating all the expressions.
I suggest you take a look at the args module.
It has the functions that do what your trying to do. The args module gets some help from another module (the request builder) in dynamof that is responsible for some preprocessing of the entire action's arguments so the args module's functions get an easy to use and parse RequestTree object.
Answer...
I would just use dynamof - but I'm biased. If you want to write it yourself, heres a little example on how its been done straight from dynamof.
def UpdateExpression(request: RequestTree):
def expression(attr):
if attr.func is not None:
return attr.func.expression(attr)
return f'{attr.alias} = {attr.key}'
key_expressions = [expression(key) for key in request.attributes.values]
key_expression = ', '.join(key_expressions)
return f'SET {key_expression}'
NOTE: The attr.alias is whats used to handle the special name cases - like spaces. Its set in the request builder module mentioned above.
disclaimer: I wrote dynamof

Query is unable to match parts after "/" or parts within "()" in the data

I have a search request written as
import sqlite3
conn = sqlite3.connect('locker_data.db')
c = conn.cursor()
def search1(teacher):
test = 'SELECT Name FROM locker_data WHERE Name or Email LIKE "%{0}%"'.format(teacher)
data1 = c.execute(test)
return data1
def display1(data1):
Display1 = []
for Name in data1:
temp1 = str(Name[0])
Display1.append("Name: {0}".format(temp1))
return Display1
def locker_searcher(teacher):
data = display1(search1(teacher))
return data
This allows me to search for the row containing "Mr FishyPower (Mr Swag)" or "Mr FishyPower / Mr Swag" with a search input of "FishyPower". However, when I try searching with an input of "Swag", I am then unable to find the same row.
In the search below, it should have given me the same search results.
The database is just a simple 1x1 sqlite3 database containing 'FishyPower / Mr Swag'
Search Error on 'Swag'
Edit: I technically did solve it by limiting the columns being searched to only 'Name' but I intended the code search both the 'Name' and 'Email' columns and output the results as long as the search in within either or both columns.
Edit2: SELECT Name FROM locker_data WHERE Email LIKE "%{0}%" or Name LIKE "%{0}%" was the right way to go.
I'm gonna guess that Mr. FishyPower's email address is something like mrFishyPower#something.com. The query is only comparing Email to teacher. If it was
WHERE Name LIKE "%{0}%"
OR Email LIKE "%{0}%"'
you would (probably) get the result you want.

Iterating over an Array in Meteor

I have the following Test collection where each document looks like:
firstName: "Jeff",
lastname: "Harper",
scores:[ {'period':'week one', 'score':90},
{'period':'week two', 'score':85},
{'period':'week three','score':92},
{'period':'week four', 'score':87}
I would like to iterate through the scores array and console.log the score. As a trial, I have tried:
Test.find()forEach(function(doc){ console.log( doc.firstName ) } );
This works fine to print out the first name. If I would want to print the first score in the array object, i.e., I try the statement:
Test.find()forEach(function(doc){ console.log( doc.scores[0].score ) } );
which doesn't work. How do I gain access to the elements in the array of objects?
Thanks everyone for your input. Christian Fritz identified my problem. Now, I limit my search to only documents that have the object array. Both the forEach method and the fetch() method work now. However, Ethaan, I had to include an inner for-loop inside the primary for-loop to gain access to each internal score. Thanks for your help and your editing and the picture of the beautiful asian princess.

How to save a record that has_many other records in EmberJs

Please can you help me.
I have a model A:
A = DS.Model.extend
title: DS.attr('string')
bs: DS.hasMany('b', {async: true})
`export default A'
and model B:
B = DS.Model.extend
title: DS.attr('string')
as: DS.hasMany('a', {async: true})
'export default B'
I can not seem to save A with some Bs.
I tried different things I could have found on SO or around the internet.
But the best thing I accomplished was to get A saved without Bs.
someB = here exists loaded from server
a = #store.createRecord 'a', {
title: 'sth'
}
a.save().then((a) ->
a.get('bs').then((bs) ->
bs.pushObject(someB)
a.save()
)
# i tried with a.save() here as well
)
So A get saved, but when I want to save A with bs, so that on my server goes PUT/PATCH on a with {bs: [someID]}
I have succeeded to make it work, but it is hackish so if someone knows better solution please help.
a.save().then((a)=>
a.get('bs').then((bs)=>
bs.pushObjects(someBs)
a.save()
).then((a)=>
a.save()
)
)
As you can see there is one save to many but this is the only way it worked. First save of a sends to server bs: nil, the second one sends bs: [someBID, someOtherBID, ...]

Resources