Currently im trying to transform this python dict to a html unordered list:
{'dataStreamId': 'raw:com.google.nutrition:NutritionSource', 'dataStreamName': 'NutritionSource', 'type': 'raw', 'dataType': {'name': 'com.google.nutrition', 'field': [{'name': 'nutrients', 'format': 'map'}, {'name': 'meal_type', 'format': 'integer', 'optional': True}, {'name': 'food_item', 'format': 'string', 'optional': True}]}, 'application': {'version': '1', 'detailsUrl': 'http://example.com', 'name': 'My Example App'}, 'dataQualityStandard': []}
with this function:
def dict_to_html_ul(dd, level=4):
import simplejson
text = '<ul>'
for k, v in dd.items():
text = '<li><b>%s</b>: %s</li>' % (k, dict_to_html_ul(v, level 1) if isinstance(v, (dict)) else (simplejson.dumps(v) if isinstance(v, list) else v))
text = '</ul>'
return text
but I am getting this result:
<ul>
<li><b>dataStreamId</b>: raw:com.google.nutrition:NutritionSource</li>
<li><b>dataStreamName</b>: NutritionSource</li>
<li><b>type</b>: raw</li>
<li><b>dataType</b>: <ul>
<li><b>name</b>: com.google.nutrition</li>
<li><b>field</b>: [{"name": "nutrients", "format": "map"}, {"name": "meal_type", "format": "integer",
"optional": true}, {"name": "food_item", "format": "string", "optional": true}]</li>
</ul>
</li>
<li><b>application</b>: <ul>
<li><b>version</b>: 1</li>
<li><b>detailsUrl</b>: http://example.com</li>
<li><b>name</b>: My Example App</li>
</ul>
</li>
<li><b>dataQualityStandard</b>: []</li>
</ul>
And I am having issues trying to fix the result, basically I wanted to transform the rest of the result in the same way as the function was going.
I tried to transform the text with some string replacing after the function:
text = text.replace('[','').replace(']', '')
text= text.replace('{', '<br>' ' ' * level).replace('}', '')
text = text.replace(',', '<br>' ' ' * (level-1))
It came out with some extraspacing and I could not replace some parts like this:
"word": "word"
So I tried to make a "re.sub()" but did not have success.
Edit:
Expected output:
<ul>
<li><b>dataStreamId</b>: raw:com.google.nutrition:NutritionSource</li>
<li><b>dataStreamName</b>: NutritionSource</li>
<li><b>type</b>: raw</li>
<li><b>dataType</b>:
<ul>
<li><b>name</b>: com.google.nutrition</li>
<li><b>field</b>:
<ul>
<li><b>name</b>: nutrients</li>
<li><b>format</b>: map</li>
<br>
<li><b>name</b>: meal_type</li>
<li><b>format</b>: integer</li>
<li><b>optional</b>: true</li>
<br>
<li><b>name</b>: food_item</li>
<li><b>format</b>: string</li>
<li><b>optional</b>: true</li>
</ul>
</li>
</ul>
</li>
<li><b>application</b>: <ul>
<li><b>version</b>: 1</li>
<li><b>detailsUrl</b>: http://example.com</li>
<li><b>name</b>: My Example App</li>
</ul>
</li>
<li><b>dataQualityStandard</b>: []</li>
</ul>
Edit2: Thanks for the answer @AndrejKesely
I actually got the proper html in the first specific dict, but I have another dict that didnt actually work with this function: –
a = {'minStartTimeNs': '1573159699023000000', 'maxEndTimeNs': '1573159699023999000', 'dataSourceId': 'raw:com.google.nutrition:NutritionSource', 'point': [{'startTimeNanos': '1573159699023000000', 'endTimeNanos': '1573159699023999000', 'dataTypeName': 'com.google.nutrition', 'value': [{'mapVal': [{'key': 'fat.total', 'value': {'fpVal': 0.4}}, {'key': 'sodium', 'value': {'fpVal': 1}}, {'key': 'fat.saturated', 'value': {
'fpVal': 0.1}}, {'key': 'protein', 'value': {'fpVal': 1.3}}, {'key': 'carbs.total', 'value': {'fpVal': 27}}, {'key': 'cholesterol', 'value': {'fpVal': 0}}, {'key': 'calories', 'value': {'fpVal': 105}}, {'key': 'sugar', 'value': {'fpVal': 14}}, {'key': 'dietary_fiber', 'value': {'fpVal': 3.1}}, {'key': 'potassium', 'value': {'fpVal': 422}}]}, {'intVal': 4, 'mapVal': []}, {'stringVal': 'apple', 'mapVal': []}]}]}
I was expecting a function that could work for both
but the output with get_html() in the other dict outputs:
<ul>
<li><b>minStartTimeNs</b>: 1573159699023000000</li>
<li><b>maxEndTimeNs</b>: 1573159699023999000</li>
<li><b>dataSourceId</b>: raw:com.google.nutrition:NutritionSource</li>
<li><b>point</b>: <ul>
<li><b>startTimeNanos</b>: 1573159699023000000</li>
<li><b>endTimeNanos</b>: 1573159699023999000</li>
<li><b>dataTypeName</b>: com.google.nutrition</li>
<li><b>value</b>: [{'mapVal': [{'key': 'fat.total', 'value': {'fpVal': 0.4}}, {'key': 'sodium', 'value':
{'fpVal': 1}}, {'key': 'fat.saturated', 'value': {'fpVal': 0.1}}, {'key': 'protein', 'value': {'fpVal':
1.3}}, {'key': 'carbs.total', 'value': {'fpVal': 27}}, {'key': 'cholesterol', 'value': {'fpVal': 0}},
{'key': 'calories', 'value': {'fpVal': 105}}, {'key': 'sugar', 'value': {'fpVal': 14}}, {'key':
'dietary_fiber', 'value': {'fpVal': 3.1}}, {'key': 'potassium', 'value': {'fpVal': 422}}]}, {'intVal':
4, 'mapVal': []}, {'stringVal': 'apple', 'mapVal': []}]</li>
</ul>
</li>
</ul>
And I was expecting:
<ul>
<li><b>minStartTimeNs</b>: 1573159699023000000</li>
<li><b>maxEndTimeNs</b>: 1573159699023999000</li>
<li><b>dataSourceId</b>: raw:com.google.nutrition:NutritionSource</li>
<li><b>point</b>: <ul>
<li><b>startTimeNanos</b>: 1573159699023000000</li>
<li><b>endTimeNanos</b>: 1573159699023999000</li>
<li><b>dataTypeName</b>: com.google.nutrition</li>
<li><b>value</b>:
<ul>
<li><b>mapVal</b>:
<ul>
<li><b>key</b>: fat.total</li>
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 0.4</li>
</ul>
</li>
<br>
<li><b>key</b>: sodium</li>
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 1</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'fat.saturated',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 0.4</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'protein',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 5.4</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'carbs.total',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 6.4</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'cholesterol',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 4.5</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'calories',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 3.4</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'sugar',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 5.5</li>
</ul>
</li>
<br>
<li><b>key</b>:</li>'dietary_fiber',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 1</li>
</ul>
</li>
<br>
<li><b>key</b>:</li> 'potassium',
<li><b>value</b>:
<ul>
<li><b>fpVal</b>: 2</li>
</ul>
</li>
<br>
</ul>
<li><b>intVal</b>: 4</li>
<li><b>mapVal</b>: []</li>
<br>
<li><b>stringVal</b>: apple</li>
<li><b>mapVal</b>: []</li>
</li>
</ul>
</li>
</ul>
</li>
</ul>
CodePudding user response:
Try:
dct = {
"dataStreamId": "raw:com.google.nutrition:NutritionSource",
"dataStreamName": "NutritionSource",
"type": "raw",
"dataType": {
"name": "com.google.nutrition",
"field": [
{"name": "nutrients", "format": "map"},
{"name": "meal_type", "format": "integer", "optional": True},
{"name": "food_item", "format": "string", "optional": True},
],
},
"application": {
"version": "1",
"detailsUrl": "http://example.com",
"name": "My Example App",
},
"dataQualityStandard": [],
}
def get_html(o):
s = ""
if isinstance(o, dict):
s = "<ul>\n"
for k, v in o.items():
s = f"<li><b>{k}</b>: " get_html(v) "</li>\n"
s = "</ul>"
elif isinstance(o, list):
s = "<ul>\n"
if not o:
return str(o)
else:
out = []
for v in o:
ss = ""
for kk, vv in v.items():
ss = f"<li><b>{kk}</b>: {vv}</li>\n"
out.append(ss)
s = "<br>\n".join(out)
s = "</ul>"
else:
return str(o)
return s
print(get_html(dct))
Prints ("beautified" result):
<ul>
<li><b>dataStreamId</b>: raw:com.google.nutrition:NutritionSource</li>
<li><b>dataStreamName</b>: NutritionSource</li>
<li><b>type</b>: raw</li>
<li><b>dataType</b>:
<ul>
<li><b>name</b>: com.google.nutrition</li>
<li><b>field</b>:
<ul>
<li><b>name</b>: nutrients</li>
<li><b>format</b>: map</li>
<br>
<li><b>name</b>: meal_type</li>
<li><b>format</b>: integer</li>
<li><b>optional</b>: True</li>
<br>
<li><b>name</b>: food_item</li>
<li><b>format</b>: string</li>
<li><b>optional</b>: True</li>
</ul>
</li>
</ul>
</li>
<li><b>application</b>:
<ul>
<li><b>version</b>: 1</li>
<li><b>detailsUrl</b>: http://example.com</li>
<li><b>name</b>: My Example App</li>
</ul>
</li>
<li><b>dataQualityStandard</b>: []</li>
</ul>
CodePudding user response:
Got this function to work thanks to @AndrejKesely for basically crushing it
def get_html(o):
s = ""
if isinstance(o, dict):
s = "<ul>\n"
for k, v in o.items():
s = f"<li><b>{k}</b>: " get_html(v) "</li>\n"
s = "</ul>"
elif isinstance(o, list):
s = "<ul>\n"
if not o:
return str(o)
else:
out = []
for v in o:
ss = ""
for kk, vv in v.items():
ss = f"<li><b>{kk}</b>:" get_html(vv) " </li>\n"
out.append(ss)
s = "<br>\n".join(out)
s = "</ul>"
else:
return str(o)
return s
The only thing I changed in his function so it could work in any list/dict was make this:
for v in o:
ss = ""
for kk, vv in v.items():
ss = f"<li><b>{kk}</b>: {vv}</li>\n"
out.append(ss)
become iterative like this:
for v in o:
ss = ""
for kk, vv in v.items():
ss = f"<li><b>{kk}</b>:" get_html(vv) " </li>\n"
out.append(ss)