New dict filtered by item - python-3.x

Could you help me with this simple stuff, unfortunately I don't get it.
I have this a list with two another lists with lists of dicts (but it can be more lists).
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
My goal is to get a final list of merged dicts, derived by a rule ('merge all dicts that contain the 'INTF' field with the same number, in this case 77 or 0 , in other words to filter by interface number').
Like that
new_dict = [
{'DESCRIP': '', 'PROTOCOL': 'up', 'STATUS': 'up','INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up','MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'PROTOCOL': 'down', 'STATUS': 'admin down','INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]

Since we are looking to merge dicts based on a key, I think the best place to start will be to reshape our data to facilitate a key based lookup. While we are reshaping the data, let's also create a key that is just the number.
import re
a_reshaped = [
{re.search(r'\d+', x["INTF"]): x for x in y}
for y in a
]
print(a_reshaped )
This will give us:
[
{
'77': {'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
'0': {'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
},
{
'77': {'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
'0': {'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
}
]
At this point we can iterate over a_reshaped and merge the dicts based on the key. We can base this part on either setdefault() or collections.defaultdict(). I prefer the second myself.
import collections
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
Giving us:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
The complete solution based on collections.defaultdict() being:
import re
import collections
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
or based on setdefault() as:
import re
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = {}
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results.setdefault(key, {}), **value}
print(list(results.values()))
Both will give you:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]

Related

Making a list of dict from a list of lists with the list[0] as keys and other lists as values

could you tell me how can I get a list of dicts from that with the a[0] as keys for each dict and a[1:] as values accordingly.
a = [['PORT', 'NAME', 'STATUS', 'VLAN', 'DUPLEX', 'SPEED', 'TYPE', 'FC_MODE'], ['Gi1/0/1', 'S1-P1-01 Cisco_Roo', 'connected', '248', 'a-full', 'a-1000', '10/100/1000BaseTX', ''], ['Gi1/0/2', '', 'notconnect', '121', 'auto', 'auto', '10/100/1000BaseTX', ''], ['Gi1/0/3', '', 'notconnect', '121', 'auto', 'auto', '10/100/1000BaseTX', '']]
I wanna get
[{'PORT' : 'Gi1/0/1',
'NAME' : 'S1-P1-01 Cisco_Roo',
.
.
.
},
{'PORT' : 'Gi1/0/2',
'NAME' : '',
.
.
.
}]
The easiest is probably:
[dict(zip(a[0], x)) for x in a[1:]]
This walks through each element from 1 onwards, and combines it with the first element, converting to a dictionary.
Does this work?
a = [
['PORT', 'NAME', 'STATUS', 'VLAN', 'DUPLEX', 'SPEED', 'TYPE', 'FC_MODE'],
['Gi1/0/1', 'S1-P1-01 Cisco_Roo', 'connected', '248', 'a-full', 'a-1000', '10/100/1000BaseTX', ''],
['Gi1/0/2', '', 'notconnect', '121', 'auto', 'auto', '10/100/1000BaseTX', ''],
['Gi1/0/3', '', 'notconnect', '121', 'auto', 'auto', '10/100/1000BaseTX', '']
]
import pandas as pd
pd.DataFrame(a[1:],columns=a[0]).to_dict(orient="records")
Creates this output.
[{'PORT': 'Gi1/0/1',
'NAME': 'S1-P1-01 Cisco_Roo',
'STATUS': 'connected',
'VLAN': '248',
'DUPLEX': 'a-full',
'SPEED': 'a-1000',
'TYPE': '10/100/1000BaseTX',
'FC_MODE': ''},
{'PORT': 'Gi1/0/2',
'NAME': '',
'STATUS': 'notconnect',
'VLAN': '121',
'DUPLEX': 'auto',
'SPEED': 'auto',
'TYPE': '10/100/1000BaseTX',
'FC_MODE': ''},
{'PORT': 'Gi1/0/3',
'NAME': '',
'STATUS': 'notconnect',
'VLAN': '121',
'DUPLEX': 'auto',
'SPEED': 'auto',
'TYPE': '10/100/1000BaseTX',
'FC_MODE': ''}]

How to render Vega-lite viz in Google Colab

What is the recommended way of rendering a Vega-lite spec inside of Google Colab?
This post describes how to do this with Vega but not Vega-lite.
I've also tried this as suggested on Slack
chart = alt.Chart.from_dict(vl_spec_dict)
However, in Colab, I get a validation error using this valid spec converted a Python dict. The Python dict is given below.
Any suggestions would be much appreciated.
{'$schema': 'https://vega.github.io/schema/vega-lite/v4.8.1.json',
'background': 'white',
'config': {'axis': {'labelFontSize': 15,
'labelLimit': 1000,
'titleFontSize': 15},
'legend': {'labelFontSize': 15, 'symbolSize': 100, 'titleFontSize': 15},
'numberFormat': '.0f',
'scale': {'bandPaddingInner': 0.5, 'bandPaddingOuter': 0.5},
'style': {'bar': {'size': 20},
'guide-label': {'fontSize': 15},
'guide-title': {'fontSize': 15, 'value': 'asdf'}},
'title': {'fontSize': 20, 'offset': 20}},
'data': {'name': 'data-78d3ef908a3fe582b9e56995f5dff5f9'},
'datasets': {'data-78d3ef908a3fe582b9e56995f5dff5f9': [{'Year': '2011',
'counts': 1497,
'org': 'Board',
'percentage': 76},
{'Year': '2011', 'counts': 78023, 'org': 'Province', 'percentage': 65},
{'Year': '2012', 'counts': 1650, 'org': 'Board', 'percentage': 80},
{'Year': '2012', 'counts': 80429, 'org': 'Province', 'percentage': 66},
{'Year': '2013', 'counts': 1657, 'org': 'Board', 'percentage': 80},
{'Year': '2013', 'counts': 82928, 'org': 'Province', 'percentage': 68},
{'Year': '2014', 'counts': 1612, 'org': 'Board', 'percentage': 78},
{'Year': '2014', 'counts': 84985, 'org': 'Province', 'percentage': 70},
{'Year': '2015', 'counts': 1728, 'org': 'Board', 'percentage': 82},
{'Year': '2015', 'counts': None, 'org': 'Province', 'percentage': None},
{'Year': '2016', 'counts': 1844, 'org': 'Board', 'percentage': 84},
{'Year': '2016', 'counts': 85561, 'org': 'Province', 'percentage': 72},
{'Year': '2017', 'counts': 1984, 'org': 'Board', 'percentage': 85},
{'Year': '2017', 'counts': 93130, 'org': 'Province', 'percentage': 74},
{'Year': '2018', 'counts': 1950, 'org': 'Board', 'percentage': 84},
{'Year': '2018', 'counts': 93684, 'org': 'Province', 'percentage': 75}]},
'height': 300,
'layer': [{'encoding': {'color': {'field': 'org',
'title': None,
'type': 'nominal'},
'tooltip': [{'field': 'percentage',
'title': 'Percentage of Students',
'type': 'quantitative'},
{'field': 'counts',
'title': 'Number of Students',
'type': 'quantitative'},
{'field': 'org', 'title': 'level', 'type': 'nominal'}],
'x': {'axis': {'labelAngle': 55},
'field': 'Year',
'title': None,
'type': 'nominal'},
'y': {'field': 'percentage',
'scale': {'domain': [0, 100]},
'title': 'Percentage of Students',
'type': 'quantitative'}},
'mark': {'color': 'orange', 'point': True, 'type': 'line'}},
{'encoding': {'text': {'field': 'percentage', 'type': 'quantitative'},
'tooltip': [{'field': 'percentage',
'title': 'Percentage of Students',
'type': 'quantitative'},
{'field': 'counts',
'title': 'Number of Students',
'type': 'quantitative'},
{'field': 'org', 'title': 'level', 'type': 'nominal'}],
'x': {'field': 'Year', 'type': 'nominal'},
'y': {'field': 'percentage', 'type': 'quantitative'}},
'mark': {'size': 15, 'type': 'text'}}],
'title': 'Grade 3 Reading: Overall Achievement at or above the Provincial Standard',
'width': 300}
You can use the Altair HTMl renderer in Colab and then use the IPython display function to generate an out
import altair as alt
from IPython.display import display
spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"data": {
"values": [
{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43},
{"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53},
{"a": "G", "b": 19}, {"a": "H", "b": 87}, {"a": "I", "b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "nominal", "axis": {"labelAngle": 0}},
"y": {"field": "b", "type": "quantitative"}
}
}
display(alt.display.html_renderer(spec), raw=True)

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"

Getting error to normalize nested list in Python

I have a nested list with dictionary. The following is just first element of the list
{'id': 'abcde',
'authorization': None,
'operation_type': 'xx',
'method': 'card',
'transaction_type': 'asd',
'card': {'type': 'dd',
'brand': 'vv',
'address': {'line1': 'xxxxxxx',
'line2': '',
'line3': '',
'state': 'xx',
'city': 'xxx',
'postal_code': '12345',
'country_code': 'xx'},
'card_number': '123456XXXXXX7890',
'holder_name': 'name user,
'expiration_year': '20',
'expiration_month': '02',
'allows_charges': True,
'allows_payouts': True,
'bank_name': 'abc bank',
'bank_code': '000'},
'status': 'fgh',
'conciliated': True,
'creation_date': '2018-09-23T23:58:17-05:00',
'operation_date': '2018-09-23T23:58:17-05:00',
'description': 'asdmdefdsa',
'error_message': 'sdaskjflj',
'order_id': 'ashdgjasdfhk',
'amount': 418.0,
'customer': {'name': 'abc',
'last_name': 'xyz',
'email': 'abcdef#hotmail.com',
'phone_number': '12345678',
'address': None,
'creation_date': '2018-09-23T23:58:18-05:00',
'external_id': None,
'clabe': None},
'fee': {'amount': 0.56, 'tax': 0.91, 'currency': 'XXX'},
'currency': 'XXX'},
{'id': 'abcde',
'authorization': None,
'operation_type': 'xx',
'method': 'card',
'transaction_type': 'asd',
'card': {'type': 'dd',
'brand': 'vv',
'address': {'line1': 'xxxxxxx',
'line2': '',
'line3': '',
'state': 'xx',
'city': 'xxx',
'postal_code': '12345',
'country_code': 'xx'},
'card_number': '123456XXXXXX7890',
'holder_name': 'name user,
'expiration_year': '20',
'expiration_month': '02',
'allows_charges': True,
'allows_payouts': True,
'bank_name': 'abc bank',
'bank_code': '000'},
'status': 'fgh',
'conciliated': True,
'creation_date': '2018-09-23T23:58:17-05:00',
'operation_date': '2018-09-23T23:58:17-05:00',
'description': 'asdmdefdsa',
'error_message': 'sdaskjflj',
'order_id': 'ashdgjasdfhk',
'amount': 418.0,
'customer': {'name': 'abc',
'last_name': 'xyz',
'email': 'abcdef#hotmail.com',
'phone_number': '12345678',
'address': None,
'creation_date': '2018-09-23T23:58:18-05:00',
'external_id': None,
'clabe': None},
'fee': {'amount': 0.56, 'tax': 0.91, 'currency': 'XXX'},
'currency': 'XXX'}
I want to normalize the data to dataframe. I wrote the code as: json_normalize(d). But I am getting following error:
--------------------------------------------------------------------------- KeyError Traceback (most recent call
last) in ()
----> 1 df = json_normalize(data)
/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py in
json_normalize(data, record_path, meta, meta_prefix, record_prefix,
errors, sep)
201 # TODO: handle record value which are lists, at least error
202 # reasonably
--> 203 data = nested_to_record(data, sep=sep)
204 return DataFrame(data)
205 elif not isinstance(record_path, list):
/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py in
nested_to_record(ds, prefix, sep, level)
86 else:
87 v = new_d.pop(k)
---> 88 new_d.update(nested_to_record(v, newkey, sep, level + 1))
89 new_ds.append(new_d)
90
/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py in
nested_to_record(ds, prefix, sep, level)
82 new_d[newkey] = v
83 if v is None: # pop the key if the value is None
---> 84 new_d.pop(k)
85 continue
86 else:
KeyError: 'address'
I understood that because address in None, the code is giving me error. But I don't know how to fix it. Any help in this regard will be highly appreciated. Thanks in advance.
(Please note that the data is dummy data)
The dictionary is badly formatted. First of all, you have lines like the following:
'holder_name': 'name user,
where the value 'name user is not a valid string, since it's not enclosed by a single quote character on the right.
Second, in your code you have two elements of a list, that is, two dictionaries, each of them starting with {'id': ..., as opposed to a single element as claimed.
After fixing the values of 'holder_name in both dictionaries and making it a two-member list, you can proceed with using json_normalize and you would get an output like the following (with printed in stdout):
amount authorization card.address.city card.address.country_code ... operation_type order_id status transaction_type 0
418.0 None xxx xx ... xx ashdgjasdfhk fgh asd 1
418.0 None xxx xx ... xx ashdgjasdfhk fgh asd
[2 rows x 42 columns]
I tried to reproduce this error but I couldn't. After creating a python3 venv and installing pandas with pip I copied your code (python dictionary and not json - my mistake, thanks #AlessandroCosentino +1 from me) to an editor and found out that lines 16 and 56 are missing a single quote
'holder_name': 'name user,
and should be
'holder_name': 'name user',
from pandas.io.json import json_normalize
data = {'id': 'abcde',
'authorization': None,
'operation_type': 'xx',
'method': 'card',
'transaction_type': 'asd',
'card': {'type': 'dd',
'brand': 'vv',
'address': {'line1': 'xxxxxxx',
'line2': '',
'line3': '',
'state': 'xx',
'city': 'xxx',
'postal_code': '12345',
'country_code': 'xx'},
'card_number': '123456XXXXXX7890',
'holder_name': 'name user',
'expiration_year': '20',
'expiration_month': '02',
'allows_charges': True,
'allows_payouts': True,
'bank_name': 'abc bank',
'bank_code': '000'},
'status': 'fgh',
'conciliated': True,
'creation_date': '2018-09-23T23:58:17-05:00',
'operation_date': '2018-09-23T23:58:17-05:00',
'description': 'asdmdefdsa',
'error_message': 'sdaskjflj',
'order_id': 'ashdgjasdfhk',
'amount': 418.0,
'customer': {'name': 'abc',
'last_name': 'xyz',
'email': 'abcdef#hotmail.com',
'phone_number': '12345678',
'address': None,
'creation_date': '2018-09-23T23:58:18-05:00',
'external_id': None,
'clabe': None},
'fee': {'amount': 0.56, 'tax': 0.91, 'currency': 'XXX'},
'currency': 'XXX'},
{'id': 'abcde',
'authorization': None,
'operation_type': 'xx',
'method': 'card',
'transaction_type': 'asd',
'card': {'type': 'dd',
'brand': 'vv',
'address': {'line1': 'xxxxxxx',
'line2': '',
'line3': '',
'state': 'xx',
'city': 'xxx',
'postal_code': '12345',
'country_code': 'xx'},
'card_number': '123456XXXXXX7890',
'holder_name': 'name user',
'expiration_year': '20',
'expiration_month': '02',
'allows_charges': True,
'allows_payouts': True,
'bank_name': 'abc bank',
'bank_code': '000'},
'status': 'fgh',
'conciliated': True,
'creation_date': '2018-09-23T23:58:17-05:00',
'operation_date': '2018-09-23T23:58:17-05:00',
'description': 'asdmdefdsa',
'error_message': 'sdaskjflj',
'order_id': 'ashdgjasdfhk',
'amount': 418.0,
'customer': {'name': 'abc',
'last_name': 'xyz',
'email': 'abcdef#hotmail.com',
'phone_number': '12345678',
'address': None,
'creation_date': '2018-09-23T23:58:18-05:00',
'external_id': None,
'clabe': None},
'fee': {'amount': 0.56, 'tax': 0.91, 'currency': 'XXX'},
'currency': 'XXX'}
print(json_normalize(data))
the output is this
This could easily be avoided by using a smart editor - eg SublimeText - with python highlighting. What editor are you using?

Button alignment in Adaptive cards

I was wondering if there is a way to control alignment of buttons in Adaptive card in Bot Emulator.
I tried the same code in the emulator, and the Microsoft Visualizer, but they render differently. Here are the images: Emulator Visualizer
Here's the code I've used:
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
'$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
'version': '1.0',
'type': 'AdaptiveCard',
'body': [
{
'type': 'TextBlock',
'text': 'Meeting Title',
'weight': 'bolder'
},
{
'type': 'TextBlock',
'text': 'Location',
'separator': true,
'isSubtle': true,
'size': 'small'
},
{
'type': 'TextBlock',
'text': 'Location',
'spacing': 'none'
},
{
'type': 'TextBlock',
'text': 'Organizer',
'separator': true,
'isSubtle': true,
'size': 'small'
},
{
'type': 'TextBlock',
'text': 'Organizer Name',
'spacing': 'none'
},
{
'type': 'TextBlock',
'text': 'Start Time',
'separator': true,
'isSubtle': true,
'size': 'small'
},
{
'type': 'ColumnSet',
'spacing': 'none',
'columns': [
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': '05:00 PM',
'isSubtle': false,
'weight': 'bolder'
}
]
},
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': 'May 21'
}
]
},
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': '2017',
'isSubtle': true,
'weight': 'bolder'
}
]
}
]
},
{
'type': 'TextBlock',
'text': 'End Time',
'separator': true,
'isSubtle': true,
'size': 'small'
},
{
'type': 'ColumnSet',
'spacing': 'none',
'columns': [
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': '05:30 PM',
'isSubtle': false,
'weight': 'bolder'
}
]
},
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': 'May 21'
}
]
},
{
'type': 'Column',
'width': 'auto',
'items': [
{
'type': 'TextBlock',
'text': '2017',
'isSubtle': true,
'weight': 'bolder'
}
]
}
]
}
],
'actions': [
{
'type': 'Action.Submit',
'title': 'Accept',
'data':{
'accept': true
}
},
{
'type': 'Action.Submit',
'title': 'Decline',
'data':{
'accept': false
}
}
]
}
}
As seen, the buttons are aligned horizontally in the emulator, and next to each other in the visualizer. Is there a way to modify the height and width of the buttons, as well as the way they are aligned?
I was wondering if there is a way to control alignment of buttons in
Adaptive card in Bot Emulator.
Short answer is "No". You cannot modify the render of components in the Emulator.
Long answer is: Bot Framework Emulator is open-source, so you can try to modify and run locally your custom emulator. But I'm not sure that making a custom render on the emulator is very useful for real projects, as they will not run on the emulator.
Emulator sources are located here: https://github.com/Microsoft/BotFramework-Emulator
There is something called Hostconfig with Adaptive cards, try using that. Have shared the editor tool link.

Resources