I´m just starting learning python and therefore like to create a html table based on filenames. Imaging following files
apple.good.2.svg
apple.good.1.svg
banana.1.ugly.svg
banana.bad.2.svg
kiwi.good.svg
The kind of object is always the first part (before the first dot) the quality property is somewhere in the name.
My resulting table should look like this:
Object Name | good | bad | ugly
-------------------------------------------------------------------------
apple | apple.good.1.svg |
| apple.good.2.svg |
-------------------------------------------------------------------------
banana | | banana.bad.2.svg | banana.1.ugly.svg
-------------------------------------------------------------------------
kiwi | kiwi.good.svg
-------------------------------------------------------------------------
This is what I did so far
#!/usr/bin/python
import glob
from collections import defaultdict
fileNames = defaultdict(list)
# fill sorted list of tables based on svg filenames
svgFiles = sorted(glob.glob('*.svg'))
for s in svgFiles:
fileNames[s.split('.', 1)[0]].append(s)
# write to html
html = '<html><table border="1"><tr><th>A</th><th>' + '</th><th>'.join(dict(fileNames).keys()) + '</th></tr>'
for row in zip(*dict(fileNames).values()):
html += '<tr><td>Object Name</td><td>' + '</td><td>'.join(row) + '</td></tr>'
html += '</table></html>'
file_ = open('result.html', 'w')
file_.write(html)
file_.close()
I managed to read the files sorted in a dict:
{'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
But fail by generating the html table.
How can I build the html table as shown above? Where Objects are written to the first first column of a row and the filename in columns depending on their quality property?
An HTML table is created with an opening <table> tag and a closing </table> tag. Inside these tags, data is organized into rows and columns by using opening and closing table row <tr> tags and opening and closing table data <td> tags. Table row <tr> tags are used to create a row of data.
You have to iterate all combinations of fruits from your dictionaries and states, and then create one line (instead of one column) for each fruit. Then just iterate all the files matching that fruit and filter those that contain the current state and join those in one cell.
d = {'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
html = """<html><table border="1">
<tr><th>Object</th><th>Good</th><th>Bad</th><th>Ugly</th></tr>"""
for fruit in d:
html += "<tr><td>{}</td>".format(fruit)
for state in "good", "bad", "ugly":
html += "<td>{}</td>".format('<br>'.join(f for f in d[fruit] if ".{}.".format(state) in f))
html += "</tr>"
html += "</table></html>"
Result:
Update: If you have state expressions that are part of other states, like bad
and medium_bad
, then just using in
won't work. Instead, you can use a regular expression to get the best match.
>>> fruit = "banana_bad.svg", "banana_medium_bad.svg"
>>> [re.search(r"[._](good|bad|medium_bad|ugly)[._]", f).group(1) for f in fruit]
['bad', 'medium_bad']
You could use this code then:
d = {'kiwi': ['kiwi.good.svg', 'kiwi_medium_bad.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
states = ['good', 'bad', 'medium_bad', 'ugly']
html = """<html><table border="1">
<tr><th>Object</th><th>{}</th></tr>""".format("</th><th>".join(states))
for fruit in d:
html += "<tr><td>{}</td>".format(fruit)
by_state = {f: re.search(r"[._]({})[._]".format('|'.join(states)), f).group(1) for f in d[fruit]}
for state in states:
html += "<td>{}</td>".format('<br>'.join(f for f in d[fruit] if by_state[f] == state))
html += "</tr>"
html += "</table></html>"
Alternatively, you could also restructure your dictionary to have another "layer" of states, i.e. {"kiwi": {"good": ["kiwi.goog.svg"]}, ...}
If you want to wrap the filenames within image tags, you can put another format
within the join
:
html += "<td>{}</td>".format('<br>'.join('<img src="{}">'.format(f) for f in d[fruit] if by_state[f] == state))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With