Vinod HC
Vinod HC

Reputation: 1627

Python dynamic dictionary + print html output

I am performing computation on complex query and getting below dictionary as final output and now want to print that dict in html format without hardcoding column names as it is dynamic.

If column is not there then add 0 in the report.

data = {'Author1': defaultdict(<class 'dict'>,
                        {'Microsoft': 248,
                         'Ubuntu': 24,
                         'IOS': 24,
                         'Solaris': 24,
                         'C': 248}),
 'Author2': defaultdict(<class 'dict'>,
                           {'Microsoft': 38,
                            'Ubuntu': 38,
                            'IOS': 38,
                            'Go': 38,
                            'C': 38}),
 'Author3': defaultdict(<class 'dict'>,
                    {'Microsoft': 2,
                     'IOS': 2,
                     'Go': 2,
                     'C': 2})}

Output

 Name       Microsoft  Ubuntu IOS Go Solaris C
Author1       248        24   24  0   24     248  
Author2        38        38    38 38   0      38
Author3        2         0     2  2    0      2

code:

html = '<table><tr><th>' + '</th><th>'.join(data.keys()) + '</th></tr>'

for row in zip(*data.values()):
    html += '<tr><td>' + '</td><td>'.join(row) + '</td></tr>'

html += '</table>'

print(html)

This code errors out bec of default dict inside a dictionary, which needs to be removed.

Upvotes: 0

Views: 1800

Answers (1)

Copperfield
Copperfield

Reputation: 8510

how about using pandas it does all the job for you

import pandas
df = pandas.DataFrame.from_dict(data)
html = """<!DOCTYPE html>
<html>
    <body>
{body}
    </body>
</html>
"""
with open("test.html","w") as file:
    file.write( html.format(body=df.to_html(na_rep="0")) )

this result in this table

enter image description here

use .T to transpose the table

with open("test2.html","w") as file:
    file.write( html.format(body=df.T.to_html(na_rep="0")) )

and result in

enter image description here


without pandas, them I would go like this

html = """<!DOCTYPE html>
<html>
    <body>
{body}
    </body>
</html>
"""

table="""
<table border="1" class="dataframe">
  <thead>
{thead}
  </thead>
  <tbody>
{tbody}
  </tbody>
</table>
"""

thead="""
<tr style="text-align: right;">
{th}
</tr>
"""
th="""<th>{}</th>\n"""
td="""<td>{}</td>\n"""
tr="""<tr>{}</tr>\n"""

def manual_table(data, colums):
    head = thead.format(th= "".join( map(th.format,["Name"]+colums)))
    pieces=[]
    for autor, value in data.items():
        temp = [autor]
        temp.extend( value.get(c,0) for c in colums )
        pieces.append(tr.format( "".join(td.format(x) for x in temp )) )
    body = "\n".join(pieces)
    return table.format(thead=head, tbody=body)

colums="Microsoft  Ubuntu IOS Go Solaris C".split()

with open("test3.html","w") as file:
    file.write( html.format(body=manual_table(data, colums)))

first I build some templates, so I get something that I can read at the end, then I go inside out filling those templates accordingly and in the order that I impose by the colums variable.

this result in

enter image description here


One of the problem with your code is that you don't fetch the values in the correct order, one partial solution for that is

colums="Microsoft  Ubuntu IOS Go Solaris C".split()
for row in data.values():
    table += '<tr><td>' + '</td><td>'.join(str(row.get(c,0)) for c in colums) + '</td></tr>'

if you don't want to hard code the column's names, but get them from the data, then you can do this

>>> {k for v in data.values() for k in v }
{'C', 'IOS', 'Solaris', 'Ubuntu', 'Microsoft', 'Go'}
>>> 

about your question in the comments, yes you can and is very easy with sum, like for example

>>> df
           Author1  Author2  Author3
C            248.0     38.0      2.0
Go             NaN     38.0      2.0
IOS           24.0     38.0      2.0
Microsoft    248.0     38.0      2.0
Solaris       24.0      NaN      NaN
Ubuntu        24.0     38.0      NaN
>>> df["Total"] = df.T.sum()
>>> df
           Author1  Author2  Author3  Total
C            248.0     38.0      2.0  288.0
Go             NaN     38.0      2.0   40.0
IOS           24.0     38.0      2.0   64.0
Microsoft    248.0     38.0      2.0  288.0
Solaris       24.0      NaN      NaN   24.0
Ubuntu        24.0     38.0      NaN   62.0

just play around with it until you get the desire result, and check the documentation so you know all the toys it have

Upvotes: 2

Related Questions