def load_csv(header, contents, sep=",", thousands=False, align=True): from jcvi.formats.base import is_number from jcvi.utils.cbook import thousands as th allcontents = [header] + contents if header else contents cols = len(contents[0]) for content in allcontents: assert len(content) == cols # Stringify the contents for i, content in enumerate(allcontents): if thousands: content = [int(x) if is_number(x, cast=int) else x \ for x in content] content = [th(x) if (is_number(x, cast=int) and x >= 1000) else x \ for x in content] allcontents[i] = [str(x) for x in content] colwidths = [max(len(x[i]) for x in allcontents) for i in xrange(cols)] sep += " " formatted_contents = [] for content in allcontents: rjusted = [x.rjust(cw) for x, cw in zip(content, colwidths)] \ if align else content formatted = sep.join(rjusted) formatted_contents.append(formatted) return formatted_contents
def write_csv(header, contents, sep=",", filename="stdout", thousands=False, tee=False): """ Write csv that are aligned with the column headers. >>> header = ["x_value", "y_value"] >>> contents = [(1, 100), (2, 200)] >>> write_csv(header, contents) x_value, y_value 1, 100 2, 200 """ from jcvi.formats.base import must_open, is_number from jcvi.utils.cbook import thousands as th fw = must_open(filename, "w") allcontents = [header] + contents if header else contents cols = len(contents[0]) for content in allcontents: assert len(content) == cols # Stringify the contents for i, content in enumerate(allcontents): if thousands: content = [int(x) if is_number(x, cast=int) else x for x in content] content = [th(x) if (is_number(x, cast=int) and x >= 1000) else x for x in content] allcontents[i] = [str(x) for x in content] colwidths = [max(len(x[i]) for x in allcontents) for i in xrange(cols)] sep += " " for content in allcontents: rjusted = [x.rjust(cw) for x, cw in zip(content, colwidths)] formatted = sep.join(rjusted) print >> fw, formatted if tee and filename != "stdout": print formatted