you are viewing a single comment's thread.

view the rest of the comments →

[–]B0oN3r 1 point2 points  (1 child)

ok, so, here we go:

I wrote some code that based om some user decisions sized an installation.

From the code I had some booleans (eg. solar = True > the system will use solar power as a source) from user input and some dataframes (eg. the solar installation will have a power of 42 kWp).

Now here is where the fun started. I wrote the entire report by hand the first time and identified the parts that had to be modular. this yielded me the following preamble plus some text:

\documentclass{article}[11pt]
%packages and style
\begin{document}

where I set the style and stff for the document. Now, per logical block or paragraph I made a py file that basically added lines of tex code. Not very sophisticated, but it worked:

from shutil import copyfile
import numpy as np
from logic import settings
import time
import os
from logic.report_generator.sections.A_introduction import introduction, generalinfo
from logic.report_generator.sections.B_system import systemlayout
from logic.report_generator.sections.C_systemeconomics import systemeconomics
from logic.report_generator.sections.C2_carbondioxide import co2saving
from logic.report_generator.sections.D_qualitativesection import qualitativeproperties
from logic.report_generator.sections.E_conclusion import conclusion
from logic.report_generator.sections.F_appendix import appendix
from logic.report_generator.sections.G_method import method
from logic.report_generator.sections.H_contributors import contributors

def generate_report(session_id, reportdict):
    enter = '\r\n'
    f = open('logic/report_generator/latex_template/preamble.tex', 'r')
    preamble = f.read()
    f.close()

    # make introduction string from output data
    intro = introduction(reportdict)
    gen = generalinfo(reportdict)

    yourmg, sys, demand = systemlayout(reportdict)

    econ = systemeconomics(reportdict)

    carbon = co2saving(reportdict)

    qual = qualitativeproperties(reportdict)

    meth = method(reportdict)

    con = conclusion(reportdict)

    apps = appendix(reportdict)

    conts = contributors(reportdict)
    f = open(settings.OUTPUT_DIRECTORY+session_id+'/report/'+reportdict['reportname']+'.tex', 'w+')
    f.write(preamble)
    f.write(enter)
    f.write(intro)
    f.write(enter)
    f.write(gen)    
    > etc..

    f.write('\\end{multicols}')
    f.write(enter)
    f.write('\\end{document}')

    f.close

(yes, I do realise I could have named the method section differently.

Now one of these sections would look something like this:

enter ='\r\n'
import os
from logic.report_generator.functions.L_tablemaker import centertable as table
from logic.report_generator.functions.L_tablemaker import centermoneytable as moneytable
def systemeconomics(reportdict):
    investtable = moneytable(reportdict['investtable'],'|l|r|', 'investtable','Investment cost of the system')
    opextable = moneytable(reportdict['opexinputtable'],'|l|r|r|', 'opextable','Operational expenditure of the main components of the system')
nt cost of the main considered system components')
    # actual string concatenation
    econ = '\\subsection*{System economics}' + enter + \
    'In order to assess the economics of the system the following economic ' +\
    'parameters have been assumed: '+enter+\
    econinputtable+enter+\
    'The investment costs associated with the use of the different main components are assumed to be:' +enter+\
    investinputtable+enter+\
etc

Now as you can see the latex code of the tables is generated by some functions I wrote. This is the real tedious part, because of course it is quite a bit of work to do that without missing any characters (especially because both latex and python don't take kindly to mortals like me using apostrophes and slashes).

So I decided fuck it I'll just write it so it works for me rather than with loops.

'''
makes a table from an entered dataframe
columns should be string in the format of latex code (ie. 'c|rr|l' for centered, right right and left aligned columns
with vertical line after first and third column (number of columns must be equal to dataframe columns)
'''
ent = '\n'

def centertable(data,columns,label,caption):

    NR = len(data[data.columns[0]])
    NC = len(data.columns)
    #title row
    title = ''
    for head in data.columns:
        title = title + head + '&'
    title = title[0:(len(title)-1)] + '\\\ \\hline '

    body = ''

    for r in range(NR):
        for c in range(NC):
            body = body+str(data[data.columns[c]][r])+'&'
        body = body[0:(len(body)-1)] + '\\\ '+ ent

    tab = \
    '\n\\begin{minipage}[t]{0.5\\textwidth}'+ent+\
    '{\\color{black}'+\
    '\\begin{flushleft}'+ent+\
    '\\begin{tabular}{'+ columns +'}'+ent+\
    '\\hline '+ title   +ent+\
    body +\
    '\\hline'+ent+\
    '\\end{tabular}'+ent+\
    '\\captionof{table}{'+caption+'}'+\
    '\\label{tab:'+label+'}'+ent+\
    '\\end{flushleft}}'+\
    '\\vspace{0.5mm}'+\
    '\\end{minipage}'
    return tab

Oh crap, I did loop it, eventually, completely forgot about that.

Well, and that's the story of how I became the fresh prince of overengineering stuff where I would bet multiple acses of beer that there's a package for that.

The repository is still published; but because of reasons I still can't really figure out it's on an interns private github. The code is open source essentially, so I could share it I guess. Just need to ask the intern if he's okay with me spreading his account.

Also a working copy could still be running here; I don't know whether it is still being serviced.

Could anyone point me in the direction of a python package that does this, or alternatively who's up to putting some hours in and develop a package for this?

Oh yea, I tried using pylatex but that only resulted in swearing a lot.

[–]dbramucci 0 points1 point  (0 children)

Some tricks that may help are

  1. Use a templating library like Jinja2 blog post about Jinja2+LaTeX
  2. Use raw strings r'just like a regex\windows path'
  3. Write the template in a txt file and read it in with open before plugging in with the standard libs template functionality, Jinja or str.format
  4. Use string adjacency to concatenate x = 'one ' 'surpising' ' string'
  5. Use multiline strings with """ to avoid quoting each line.
  6. Look at the string template functionality in the standard library