csview: A tiny utility to view csv files Seeing a csv in table form is nicer then viewing it as row text, for example the csv from Calculate food company sales for the year (with headers added by me) looks much nicer in this table form than in plain-text:



&lt;table border="1"&gt;

&lt;tr&gt;
&lt;th&gt;    Kind&lt;/th&gt;
&lt;th&gt; Brand&lt;/th&gt;
&lt;th&gt; Sales in 2014&lt;/th&gt;
&lt;th&gt; Sales in 2015&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Cereal&lt;/td&gt;
&lt;td&gt;Magic Balls&lt;/td&gt;
&lt;td&gt;2200&lt;/td&gt;
&lt;td&gt;2344
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Cereal&lt;/td&gt;
&lt;td&gt;Kaptain Krunch&lt;/td&gt;
&lt;td&gt;3300&lt;/td&gt;
&lt;td&gt;3123
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Cereal&lt;/td&gt;
&lt;td&gt;Coco Bongo&lt;/td&gt;
&lt;td&gt;1800&lt;/td&gt;
&lt;td&gt;2100
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Cereal&lt;/td&gt;
&lt;td&gt;Sugar Munch&lt;/td&gt;
&lt;td&gt;4355&lt;/td&gt;
&lt;td&gt;6500
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Cereal&lt;/td&gt;
&lt;td&gt;Oats n Barley&lt;/td&gt;
&lt;td&gt;3299&lt;/td&gt;
&lt;td&gt;5400
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Sugar Candy&lt;/td&gt;
&lt;td&gt;Pop Rocks&lt;/td&gt;
&lt;td&gt;546&lt;/td&gt;
&lt;td&gt;982
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Sugar Candy&lt;/td&gt;
&lt;td&gt;Lollipop&lt;/td&gt;
&lt;td&gt;1233&lt;/td&gt;
&lt;td&gt;1544
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Sugar Candy&lt;/td&gt;
&lt;td&gt;Gingerbud&lt;/td&gt;
&lt;td&gt;2344&lt;/td&gt;
&lt;td&gt;2211
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Sugar Candy&lt;/td&gt;
&lt;td&gt;Respur&lt;/td&gt;
&lt;td&gt;1245&lt;/td&gt;
&lt;td&gt;2211
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Chocolate&lt;/td&gt;
&lt;td&gt;Coco Jam&lt;/td&gt;
&lt;td&gt;3322&lt;/td&gt;
&lt;td&gt;4300
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Chocolate&lt;/td&gt;
&lt;td&gt;Larkspur&lt;/td&gt;
&lt;td&gt;1600&lt;/td&gt;
&lt;td&gt;2200
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Chocolate&lt;/td&gt;
&lt;td&gt;Mighty Milk&lt;/td&gt;
&lt;td&gt;1234&lt;/td&gt;
&lt;td&gt;2235
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Chocolate&lt;/td&gt;
&lt;td&gt;Almond Berry&lt;/td&gt;
&lt;td&gt;998&lt;/td&gt;
&lt;td&gt;1233
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Condiments&lt;/td&gt;
&lt;td&gt;Peanut Butter&lt;/td&gt;
&lt;td&gt;3500&lt;/td&gt;
&lt;td&gt;3902
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Condiments&lt;/td&gt;
&lt;td&gt;Hot Sauce&lt;/td&gt;
&lt;td&gt;1234&lt;/td&gt;
&lt;td&gt;1560
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Condiments&lt;/td&gt;
&lt;td&gt;Jelly&lt;/td&gt;
&lt;td&gt;346&lt;/td&gt;
&lt;td&gt;544
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;    Condiments&lt;/td&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;2334&lt;/td&gt;
&lt;td&gt;5644&lt;/tr&gt;&lt;/table&gt;




To view a .csv file, I just translate it into HTML and call the browser on it.

The code is short because the task is simple, but I feel like it could be written better:

"""
This utility shows a csv file in table format
by translating it to html and calling the browser on the newly created file.

The html file is not deleted after being viewed
and has name `original_file.split('.')[0] + '.html'`

Example usage:
  python3 csview.py example.csv
"""
import webbrowser
import sys

def csv_to_html(csv):
    START = '''&lt;table border="1"&gt;\n\n'''
    END = '''&lt;/tr&gt;&lt;/table&gt;'''

    lines = [line for line in csv.split("\n") if line]

    html_lines = ["&lt;th&gt;" + lines[0].replace(',', '&lt;/th&gt;\n&lt;th&gt;') + '&lt;/th&gt;'] +\
                 ["&lt;td&gt;" + line.replace(',', '&lt;/td&gt;\n&lt;td&gt;') for line in lines[1:]]
    body = '&lt;tr&gt;\n' + '\n&lt;/tr&gt;\n\n&lt;tr&gt;\n'.join(html_lines)
    return START + body + END

if __name__ == "__main__":
    html_filename = sys.argv[1].split('.')[0] + '.html'
    with open(html_filename, "w+") as out_file:
        with open(sys.argv[1]) as in_file:
            out_file.write(csv_to_html(in_file.read()))
    webbrowser.open(html_filename)
Constants
They are better defined outside of functions; there is no need in reinitializing them each call.
Also they are not balanced, fixing it will avoid a weird body = '&lt;tr&gt;\n' + ....
Files management
Just in case the path of the input file contained a dot, I recommend you use rsplit('.', 1).
Also you should try to open the input file before the ouput one. Just in case an error happen during the access to the file, you won't create an empty output file.
And since you're dealing with CSV files, why not use the csv module? It will allow you to handle edge-case data (such as fields containing comas or newlines) easily.
Wrap stuff into tags
Since you're outputing HTML, it may be a better idea to build it as such: by wrapping stuff into tags.
You could define a PATTERN = &quot;&lt;{tag}&gt;{{}}&lt;/{tag}&gt;&quot;  and a formatter:
def formatter(tag):
    return PATTERN.format(tag=tag).format

map that formatter at will to wrap stuff into tags.
Proposed improvements
import webbrowser
import sys
import csv

PATTERN = &quot;&lt;{tag}&gt;{{}}&lt;/{tag}&gt;&quot;

def formatter(tag):
    return PATTERN.format(tag=tag).format

def csv_to_html(csv_file):
    reader = csv.reader(csv_file)

    header = formatter('tr')(
        '\n'.join(map(formatter('th'), next(reader)))
    )

    data = '\n'.join(
        map(formatter('tr'),
            '\n'.join(map(formatter('td'), row))
            for row in reader
        )
    )

    return formatter('table')('\n'.join((header, data)))

if __name__ == &quot;__main__&quot;:
    csv_filename = sys.argv[1]
    html_filename = csv_filename.rsplit('.', 1)[0] + '.html'
    with open(csv_filename) as in_file:
        with open(html_filename, &quot;w+&quot;) as out_file:
            out_file.write(csv_to_html(in_file))
    webbrowser.open(html_filename)