Dynamically create dependent column based other column values in dash - python-3.x

Guys i have this table in dash the following columns are drop down columns Reason Code, Staging and Overwrite. Based on their values i want to create values under Final Staging column dynamically in dash
https://i.stack.imgur.com/MDCMb.png
Here is my code
app.layout = html.Div([
dash_table.DataTable(
id='table-dropdown',
data=staging.to_dict('records'),
columns=[
{'id': 'customer_id', 'name': 'Customer ID'},
{'id': 'booking_date', 'name': 'Booking Date'},
{'id': 'oustanding_balance_(currency)',
'name': 'Outstanding Balance(currency)'},
{'id': 'booking_date', 'name': 'Booking Date'},
{'id': 'past_due_days', 'name': 'Past Due Days'},
{'id': 'segment', 'name': 'Segment'},
{'id': 'contract_rate_%', 'name': 'Contract Rate(%)'},
{'id': 'fee/commission_rate_%', 'name': 'Fee/Commission Rate(%)'},
{'id': 'collateral_(force_sale_value_(currency)',
'name': 'Collateral(currency)'},
{'id': 'collateral_(type)', 'name': 'Collateral(Type)'},
{'id': 'maturity_date', 'name': 'Maturity Date'},
{'id': 'repayment_years', 'name': 'Repayment(Years)'},
{'id': 'quantitative_assessment', 'name': 'Quantitative Assessment'},
{'id': 'reason_code',
'name': 'Reason Code', 'presentation': 'dropdown'},
{'id': 'staging',
'name': 'Staging', 'presentation': 'dropdown'},
{'id': 'overwrite',
'name': 'Overwrite', 'presentation': 'dropdown'},
{'id': 'final_staging', 'name': 'Final Staging'},
],
editable=True,
dropdown={
'reason_code': {
'options': [
{'label': i, 'value': i}
for i in staging['reason_code'].unique()
]
},
'staging': {
'options': [
{'label': i, 'value': i}
for i in staging['staging'].unique()
]
},
'overwrite': {
'options': [
{'label': i, 'value': i}
for i in staging['overwrite'].unique()
]
}
}
),
html.Div(id='table-dropdown-container')
])

Related

Filtering list of dicts based on a key value in python

I have a list of dictionaries in python which looks like below
list = [{'entityType': 'source', 'databaseName': 'activities', 'type': 'POSTGRES', 'children': [{'id': '3c144414-0c73-41df-9f0e-4dd7cb5af46e',
'path': ['Activities (DEV)', 'public'],
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False},
{'entityType': 'source', 'databaseName': 'pd-prod-dev', 'type': 'POSTGRES', 'children':
[{'id': '75d84ead-a9fe-4949-bc21-d4deb34e1ae1',
'path': ['pg-prd (DEV-RR)', 'pghero'],
'tag': 'PWGqdrkcD08=',
'type': 'CONTAINER',
'containerType': 'FOLDER'},
{'id': 'facc2c20-7561-430f-ac35-547b5bc7a92f',
'path': ['pg-prd (DEV-RR)', 'public'],
'tag': 'gcUL0NTOc+4=',
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False},
{'entityType': 'source', 'databaseName': 'pd-prod-prd', 'type': 'POSTGRES', 'children':
[{'id': '75d84ead-a9fe-4949-bc21-d4deb34e1ae1',
'path': ['pg-prd (PRD-RR)', 'pghero'],
'tag': 'PWGqdrkcD08=',
'type': 'CONTAINER',
'containerType': 'FOLDER'},
{'id': 'facc2c20-7561-430f-ac35-547b5bc7a92f',
'path': ['pg-prd (PRD-RR)', 'public'],
'tag': 'gcUL0NTOc+4=',
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False}]
This is just a sample. The actual list has a list of 30 dictionaries. What I am trying to do is filter out the dictionaries where the nested children dictionary has only ' public' schema in it. So my expected output would be
public_list = [{'entityType': 'source', 'databaseName': 'activities', 'type': 'POSTGRES', 'children': [{'id': '3c144414-0c73-41df-9f0e-4dd7cb5af46e',
'path': ['Activities (DEV)', 'public'],
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False},
{'entityType': 'source', 'databaseName': 'pd-prod-dev', 'type': 'POSTGRES', 'children':
[{'id': 'facc2c20-7561-430f-ac35-547b5bc7a92f',
'path': ['pg-prd (DEV-RR)', 'public'],
'tag': 'gcUL0NTOc+4=',
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False},
{'entityType': 'source', 'databaseName': 'pd-prod-prd', 'type': 'POSTGRES', 'children':
[{'id': 'facc2c20-7561-430f-ac35-547b5bc7a92f',
'path': ['pg-prd (PRD-RR)', 'public'],
'tag': 'gcUL0NTOc+4=',
'type': 'CONTAINER',
'containerType': 'FOLDER'}]'checkTableAuthorizer': False}]
I tried accessing the nested dict children by iterating but unable to filter out what condition to use
for d in list:
for k, v in d.items():
if k == 'children':
print(v)
I would love to apply this as a function since I'll be reusing it on a pandas column of list of dicts
You could create a function that gets the public data for children of each entry:
def get_public_data(data):
result = []
children = data.get("children")
if children:
for row in children:
path = row.get("path")
if path and "public" in path:
result.append(row)
return result
And then create a new list of entries where you just replace the children key:
public_list = []
for x in entities:
public_data = get_public_data(x)
if public_data:
public_list.append({**x, "children": public_data})
Combine these two and you'll get the function you need.
IIUC you want to collect the entries were all items have a public schema?
Assuming your 'children' keys are always valid and a tuple of 2 elements, you can use a simple comprehension:
[d for d in lst
if all(e['path'][1] == 'public' for e in d['children'])
]
NB. I called your input lst as list is a python builtin

Sum Values in List of Dictionaries

I have code that is returning a list of dicts, which looks like this:
[{'id': 3605917, 'qty': 66640, 'side': 'Buy', 'time': 1609395938896, 'symbol': 'BTCUSD', 'price': 28901.5}, {'id': 3605914, 'qty': 500, 'side': 'Buy', 'time': 1609395936891, 'symbol': 'BTCUSD', 'price': 28907.5}, {'id': 3605911, 'qty': 1, 'side': 'Buy', 'time': 1609395874764, 'symbol': 'BTCUSD', 'price': 28942}, {'id': 3605449, 'qty': 70000, 'side': 'Sell', 'time': 1609384815688, 'symbol': 'BTCUSD', 'price': 28956}, {'id': 3605440, 'qty': 40, 'side': 'Sell', 'time': 1609384671382, 'symbol': 'BTCUSD', 'price': 28940}]
Reading through some previous questions, I was able to get some code to allow me to sum the total quantity for each side, where stream is the list above.
from collections import defaultdict
b = defaultdict(int)
for q in stream:
b[q['side']] += q['qty']
print(b)
This returns something that looks like this. I truncated the list above, so the numbers below won't match the example list:
defaultdict(<class 'int'>, {'Buy': 8106603, 'Sell': 1482687})
I'd like to modify the code above to show both the sum of the quantity, but also the average price. Weighted average by qty would be ideal, but would also be ok with a simple average.
For printing sum of quantities, one-liners:
a = [{'id': 3605917, 'qty': 66640, 'side': 'Buy', 'time': 1609395938896, 'symbol': 'BTCUSD', 'price': 28901.5}, {'id': 3605914, 'qty': 500, 'side': 'Buy', 'time': 1609395936891, 'symbol': 'BTCUSD', 'price': 28907.5}, {'id': 3605911, 'qty': 1, 'side': 'Buy', 'time': 1609395874764, 'symbol': 'BTCUSD', 'price': 28942}, {'id': 3605449, 'qty': 70000, 'side': 'Sell', 'time': 1609384815688, 'symbol': 'BTCUSD', 'price': 28956}, {'id': 3605440, 'qty': 40, 'side': 'Sell', 'time': 1609384671382, 'symbol': 'BTCUSD', 'price': 28940}]
print('Buy', sum(i['qty'] for i in a if i['side'] == 'Buy'))
print('Sell', sum(i['qty'] for i in a if i['side'] == 'Sell'))
For average of prices:
print(sum(i['qty']*i['price'] for i in a if i['side'] == 'Buy')/len(list(i for i in a if i['side'] == 'Buy')))
print(sum(i['qty']*i['price'] for i in a if i['side'] == 'Sell')/len(list(i for i in a if i['side'] == 'Sell')))

Match key and value from two different dictionaries and merge them

I have this two dictionaries:
{'data': {'id': '001_101_001', 'name': 'chview', 'type': 'multiple', 'mapping': {}},
{'id': '001_102_001', 'name': 'view', 'type': 'binary', 'mapping': {'abc':'exp'}}
And:
{'queries':{'view': 'text', 'chview': 'text1'}}
The desired output should be:
{'new_data' : {'001_101_001': { 'query': 'text1', 'type': 'multiple', 'mapping': {}},
'001_102_001': { 'query1': 'text', 'type': 'binary', 'mapping': {'abc':'exp'}}
Because there are a lot of this dictionaries I need to match them by 'name', to have the coresponding id matched. Any ideas?
Your first dictionary has a problem, it is not hashable. It should be a list of dictionaries.
{"data" :[
{'id': '001_101_001', 'name': 'chview', 'type': 'multiple', 'mapping': {}},
{'id': '001_102_001', 'name': 'view', 'type': 'binary', 'mapping': {'abc':'exp'}}
]}
Complete code:
data = {"data" :[
{'id': '001_101_001', 'name': 'chview', 'type': 'multiple', 'mapping': {}},
{'id': '001_102_001', 'name': 'view', 'type': 'binary', 'mapping': {'abc':'exp'}}
]}
queries = {"queries" : {'view': 'text', 'chview': 'text1'}}
new_data = {}
for d in data["data"]:
item = {d["id"] : {
"query": queries["queries"][d["name"]],
"type": d["type"],
"mapping": d["mapping"]
}}
new_data.update(item)
print({"new_data": new_data})
OUTPUT:
{'new_data': {'001_101_001': {'query': 'text1', 'type': 'multiple', 'mapping': {}}, '001_102_001': {'query': 'text', 'type': 'binary', 'mapping': {'abc': 'exp'}}}}

TypeError: string indices must be integers - json

I want get value (abc.com/p/B3N) from this json :
{'id': 123456, 'parent_id': 0, 'number': '23856', 'order_key': 'abc', 'created_via': 'checkout', 'version': '3.6.4', 'status': 'processing', 'currency': 'USD', 'date_created': '2019-10-05T13:18:49', 'date_created_gmt': '2019-10-05T13:18:49', 'date_modified': '2019-10-05T13:19:20', 'date_modified_gmt': '2019-10-05T13:19:20', 'discount_total': '0.00', 'discount_tax': '0.00', 'shipping_total': '0.00', 'shipping_tax': '0.00', 'cart_tax': '0.00', 'total': '0.40', 'total_tax': '0.00', 'prices_include_tax': False, 'customer_id': 0, 'customer_ip_address': '111.101.111.111', 'customer_user_agent': 'Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-J337P) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/10.1 Chrome/71.0.3578.99 Mobile Safari/537.36', 'customer_note': '', 'billing': {'first_name': '', 'last_name': '', 'company': '', 'address_1': '', 'address_2': '', 'city': '', 'state': '', 'postcode': '', 'country': '', 'email': 'abc#gmail.com', 'phone': ''}, 'shipping': {'first_name': '', 'last_name': '', 'company': '', 'address_1': '', 'address_2': '', 'city': '', 'state': '', 'postcode': '', 'country': ''}, 'payment_method': 'paypal', 'payment_method_title': 'PayPal', 'transaction_id': '851R', 'date_paid': '2019-10-05T13:19:20', 'date_paid_gmt': '2019-10-05T13:19:20', 'date_completed': None, 'date_completed_gmt': None, 'cart_hash': '0675772a1e', 'meta_data': [{'id': 123456, 'key': 'is_vat_exempt', 'value': 'no'}, {'id': 123456, 'key': 'Payment type', 'value': 'instant'}, {'id': 274929, 'key': '_paypal_status', 'value': 'completed'}, {'id': 123456, 'key': 'PayPal Transaction Fee', 'value': '0.32'}], 'line_items': [{'id': 10927, 'name': 'Jeans', 'product_id': 1234, 'variation_id': 0, 'quantity': 1, 'tax_class': '', 'subtotal': '0.10', 'subtotal_tax': '0.00', 'total': '0.10', 'total_tax': '0.00', 'taxes': [], 'meta_data': [{'id': 100000, 'key': '', 'value': 'Views $0.00 × 500'}, {'id': 100001, 'key': '', 'value': 'Worldwide'}, {'id': 100002, 'key': '', 'value': 'abc.com/p/B3N'}, {'id': 100003, 'key': '', 'value': '17'}], 'sku': '', 'price': 0.1}], 'tax_lines': [], 'shipping_lines': [], 'fee_lines': [{'id': 10928, 'name': 'PayPal Fee (Free Fee for order over $5)', 'tax_class': '0', 'tax_status': 'taxable', 'amount': '0.3', 'total': '0.30', 'total_tax': '0.00', 'taxes': [], 'meta_data': [{'id': 122543, 'key': '_legacy_fee_key', 'value': 'paypal-fee'}]}], 'coupon_lines': [], 'refunds': [], '_links': {'self': [{'href': 'abc.com'}], 'collection': [{'href': 'abc.com'}]}}
this is my code
m = (wcapi.get(order + ordernumber).json())
n = json.dumps(m)
o = json.loads(n)
for i in o:
if i['id'] == '100002':
print(i['value'])
break
and i got this error :
if i['id'] == '100002':
TypeError: string indices must be integers
i have searched others topics but ... can't. thanks for help me!
When you do for i in o and o is a dictionary, the for loop iterates over the keys in o - which are strings in your case. Hence the error. i is a string.
To get the key you need to know the exact structure of o.
I'm gonna give you some examples:
o['id'] # 123456
o['billing']['email'] # "abc#gmai.com"
Now to get the value you want:
first_line_items_meta = o['line_items'][0]['metadata']
for item in first_line_items_meta:
if item['id'] == 100002:
print(item['value']) # "abc.com/p/B3N"

Convert a json file to a python dictionary of array

I'm a newbee in Python so excuse if my question looks, dummy.
I have a json file which look like this
[{'_id': '1', 'date': '2019-09-07', 'name': 'abi', 'value': 0, 'unit': '°C'},
{'_id': '2', 'date': '2019-09-08', 'name': 'allo', 'value': 3, 'unit': '°F'},
{'_id': '3', 'date': '2019-09-09', 'name': 'ali', 'value': 0, 'unit': '°C'}]
and I want to read this json file in order to convert it into a dictionary of array which looks like
[{'_id': [ '1', '2','3']},
{'date': [ '2019-09-07', '2019-09-08','2019-09-09']},
{'name': [ 'abi', 'allo','ali']},
{'value': [ '0', '3','0']},
{'unit': [ '°C', '°F','°C']},]
Thank you in advance
Use collections.defaultdict
Ex:
from collections import defaultdict
data = [{'_id': '1', 'date': '2019-09-07', 'name': 'abi', 'value': 0, 'unit': '°C'},
{'_id': '2', 'date': '2019-09-08', 'name': 'allo', 'value': 3, 'unit': '°F'},
{'_id': '3', 'date': '2019-09-09', 'name': 'ali', 'value': 0, 'unit': '°C'}]
result = defaultdict(list)
for i in data:
for k, v in i.items():
result[k].append(v)
print(result)
or .setdefault
Ex:
result = {}
for i in data:
for k, v in i.items():
result.setdefault(k, []).append(v)
print(result)
Output:
{'_id': ['1', '2', '3'],
'date': ['2019-09-07', '2019-09-08', '2019-09-09'],
'name': ['abi', 'allo', 'ali'],
'unit': ['°C', '°F', '°C'],
'value': [0, 3, 0]}

Resources