Parser of berki style problems and generator of latex file
Samo Penic
2018-10-28 78d798a9561138e58a3a16309d949e88701d7aa6
Added templates, fixed sci formatter and some other bug fixes. Some code was refactored.
6 files modified
5 files added
214 ■■■■■ changed files
GenerateTests.py 19 ●●●●● patch | view | raw | blame | history
tools/BerkiParse.py 6 ●●●● patch | view | raw | blame | history
tools/Exceptions.py 3 ●●●●● patch | view | raw | blame | history
tools/Problem.py 29 ●●●● patch | view | raw | blame | history
tools/Template.py 36 ●●●●● patch | view | raw | blame | history
tools/Variable.py 17 ●●●●● patch | view | raw | blame | history
tools/tests/formatter_test.py 65 ●●●● patch | view | raw | blame | history
tools/textemplates/headtemplate.tpl 23 ●●●●● patch | view | raw | blame | history
tools/textemplates/newpaperwithSIDtemplate.tpl 4 ●●●● patch | view | raw | blame | history
tools/textemplates/newpolatemplate.tpl 5 ●●●●● patch | view | raw | blame | history
tools/textemplates/problemtemplate.tpl 7 ●●●●● patch | view | raw | blame | history
GenerateTests.py
@@ -1,6 +1,7 @@
from tools.BerkiParse import BerkiParse
from tools.Problem import ProblemSource, Problem
import pprint
from tools.Template import TemplateEngine
if __name__ == "__main__":
    from glob import glob
@@ -16,18 +17,10 @@
    parser=BerkiParse(naloge[0][1])
    parser.parseSections()
    n = ProblemSource(parser=parser)
#    print(n.parsedVariables)
#    print(n.parsedSolutions)
#    for i in range(0,5):
#        print(next(n.variableGenerator['d']))
    """
    for i in range(0,5):
        n=Problem(parser=parser)
        for var in n.varDict.values():
            print( var )
    """
    t = TemplateEngine("tools/textemplates")
    for i in range(0,5):
        p= Problem(n)
        print(p.problem)
        pprint.pprint(p.problem)
    print(t.put_problem_into_template(p.problem))
tools/BerkiParse.py
@@ -84,11 +84,11 @@
                elif sp[0].strip() == "napacna":
                    retval["wrong"].append(sp[1].strip("\n\t"))
                elif sp[0].strip() == "izpis":
                    retval["type"]=sp[1].strip("\n\t'")
                    retval["type"] = sp[1].strip("\n\t'")
                elif sp[0].strip() == "enota":
                    retval["unit"]= sp[1].strip("\n\t")
                    retval["unit"] = sp[1].strip("\n\t")
                elif sp[0].strip() == "TeX":
                    retval["glyph"]=sp[1].strip("\n\t")
                    retval["glyph"] = sp[1].strip("\n\t")
            parsedSolutions.append(retval)
        return parsedSolutions
tools/Exceptions.py
@@ -1,3 +1,6 @@
class WrongParameters(Exception):
    pass
class TemplatePathError(Exception):
    pass
tools/Problem.py
@@ -5,12 +5,12 @@
class Problem:
    def __init__(self, source=None):
        self.source=source
        self.source = source
        self.source.generateVariables()
        self.source.generateSolutions()
        self.problem=self.source.generateProblem()
        self.problem = self.source.generateProblem()
    def toTexFormatterDict(self):
    def toTexFormatterDict(self, template=None):
        pass
@@ -26,7 +26,7 @@
            self.introduction, self.subproblems, self.parsedVariables, self.parsedSolutions, self.variableGenerator = (
                parser.get_parsed_sections()
            )
            #self.generateVariables()
            # self.generateVariables()
    def generateVariables(self):
        for key in self.parsedVariables:
@@ -59,8 +59,8 @@
                    else:
                        __result = eval(self.substitute_octave(__corrsplit))
                __ps["wrong"].append(Variable(__result, formatting=__s["type"]))
            __ps['glyph']=__s['glyph']
            __ps['unit']=__s['unit']
            __ps["glyph"] = __s["glyph"]
            __ps["unit"] = __s["unit"]
            __retsol.append(__ps)
        return __retsol
@@ -86,11 +86,12 @@
        for p in self.subproblems:
            sp.append(self.substitute_variables(p))
        sol = self.generateSolutions()
        soltex = []
        for s in sol:
            entry = {
                "correct": [("${}={}\mathrm{{{}}}$").format(s['glyph'], i.format_as_tex(), s['unit']) for i in s["correct"]],
                "wrong": [("${}={}\mathrm{{{}}}$").format(s['glyph'], i.format_as_tex(), s['unit']) for i in s["wrong"]],
            }
            soltex.append(entry)
        return intro, sp, soltex
        # soltex = []
        # for s in sol:
        #    entry = {
        #        "correct": [("${}={}\mathrm{{{}}}$").format(s['glyph'], i.format_as_tex(), s['unit']) for i in s["correct"]],
        #        "wrong": [("${}={}\mathrm{{{}}}$").format(s['glyph'], i.format_as_tex(), s['unit']) for i in s["wrong"]],
        #    }
        #    soltex.append(entry)
        # return intro, sp, soltex
        return {"introduction": intro, "subproblems": sp, "solutions": sol}
tools/Template.py
New file
@@ -0,0 +1,36 @@
from string import Template
import os
from . import Exceptions
class TemplateEngine:
    def __init__(self, path=None):
        if path is None:
            raise(Exceptions.TemplatePathError("No path to templates"))
        self.template_filenames = {
            "head": os.path.join(path, "headtemplate.tpl"),
            "paper": os.path.join(path, "newpolatemplate.tpl"),
            "paper_sid": os.path.join(path, "newpaperwithSIDtemplate.tpl"),
            "problem": os.path.join(path, "problemtemplate.tpl"),
        }
        self.template = {}
        for key, value in self.template_filenames.items():
            self.template[key] = self.loadtemplate(value)
    def loadtemplate(self, filename):
        with open(filename) as fd:
            template = fd.read()
        return template
    def put_problem_into_template(self, problem_dict):
        retstr=""
        retstr+=Template(self.template['problem']).substitute({'problem_number': 0,
                                                               'text': problem_dict['introduction'],
                                                               'ans1': str(problem_dict['solutions'][0]['correct'][0]),
                                                               'ans2': str(problem_dict['solutions'][0]['wrong'][0]),
                                                               'ans3': str(problem_dict['solutions'][0]['wrong'][1]),
                                                               'ans4': str(problem_dict['solutions'][0]['wrong'][2])
                                                               })
        return retstr
tools/Variable.py
@@ -41,6 +41,9 @@
    def __str__(self):
        return str(self.format_as_tex())
    def __repr__(self):
        return self.__str__()
class FormatterFactory:
    @staticmethod
@@ -80,18 +83,20 @@
        exp = self.fexp(num)
        man = self.fman(num)
        return ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}").format(
            man, int(exp)
        )
        if exp == 0:
            return ("{:." + str(self.precision - 1) + "f}").format(man)
        else:
            return ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}").format(
                man, int(exp)
            )
    def getValue(self, num):
        exp = self.fexp(num)
        man = self.fman(num)
        man = ("{:." + str(self.precision - 1) + "f}e{}").format(
            man, int(exp))
        man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp))
        return float(man)
class EngFloatFormatter(FormatterFactory):
    def __init__(self, formatparameters):
        if len(formatparameters) != 1:
tools/tests/formatter_test.py
@@ -28,33 +28,32 @@
            0,
        ]
        sci2_solutions = [
            "1.2 \cdot 10^{0}",
            "1.2 \cdot 10^{0}",
            "3.0 \cdot 10^{0}",
            "3.5 \cdot 10^{0}",
            "1.2",
            "1.2",
            "3.0",
            "3.5",
            "5.0 \cdot 10^{-2}",
            "-1.2 \cdot 10^{0}",
            "-3.0 \cdot 10^{0}",
            "-1.2",
            "-3.0",
            "1.1 \cdot 10^{-6}",
            "-1.1 \cdot 10^{6}",
            "9.8 \cdot 10^{255}",
            "0.0 \cdot 10^{0}",
            "0.0",
        ]
        sci3_solutions = [
            "1.24 \cdot 10^{0}",
            "1.20 \cdot 10^{0}",
            "3.00 \cdot 10^{0}",
            "3.50 \cdot 10^{0}",
            "1.24",
            "1.20",
            "3.00",
            "3.50",
            "5.00 \cdot 10^{-2}",
            "-1.23 \cdot 10^{0}",
            "-3.00 \cdot 10^{0}",
            "-1.23",
            "-3.00",
            "1.12 \cdot 10^{-6}",
            "-1.12 \cdot 10^{6}",
            "9.81 \cdot 10^{255}",
            "0.00 \cdot 10^{0}",
            "0.00",
        ]
        sci2 = Variable.FormatterFactory().get_formatter("sci 2")
        for case, result in zip(testcases, sci2_solutions):
            self.assertEqual(result, sci2.toFormat(case))
@@ -78,34 +77,34 @@
            0,
        ]
        sci2_solutions = [
            "1.2 \cdot 10^{0}",
            "1.2 \cdot 10^{0}",
            "3.0 \cdot 10^{0}",
            "3.5 \cdot 10^{0}",
            "1.2",
            "1.2",
            "3.0",
            "3.5",
            "5.0 \cdot 10^{-2}",
            "-1.2 \cdot 10^{0}",
            "-3.0 \cdot 10^{0}",
            "-1.2",
            "-3.0",
            "1.1 \cdot 10^{-6}",
            "-1.1 \cdot 10^{6}",
            "9.8 \cdot 10^{255}",
            "0.0 \cdot 10^{0}",
            "0.0",
        ]
        sci3_solutions = [
            "1.24 \cdot 10^{0}",
            "1.20 \cdot 10^{0}",
            "3.00 \cdot 10^{0}",
            "3.50 \cdot 10^{0}",
            "1.24",
            "1.20",
            "3.00",
            "3.50",
            "5.00 \cdot 10^{-2}",
            "-1.23 \cdot 10^{0}",
            "-3.00 \cdot 10^{0}",
            "-1.23",
            "-3.00",
            "1.12 \cdot 10^{-6}",
            "-1.12 \cdot 10^{6}",
            "9.81 \cdot 10^{255}",
            "0.00 \cdot 10^{0}",
            "0.00",
        ]
        sci2_rounded=[
        sci2_rounded = [
            1.2,
            1.2,
            3.0,
@@ -116,7 +115,7 @@
            1.1e-6,
            -1.1e6,
            9.8e255,
            0
            0,
        ]
        for case, result in zip(testcases, sci2_solutions):
            self.assertEqual(result, Variable.Variable(case, "sci 2").format_as_tex())
@@ -125,4 +124,6 @@
            self.assertEqual(result, Variable.Variable(case, "sci 3").format_as_tex())
        for case, result in zip(testcases, sci2_rounded):
            self.assertEqual(result, Variable.Variable(case, 'sci 2').get_formatted_value())
            self.assertEqual(
                result, Variable.Variable(case, "sci 2").get_formatted_value()
            )
tools/textemplates/headtemplate.tpl
New file
@@ -0,0 +1,23 @@
\documentclass[10pt,a4paper]{article}
%define global variables for the whole problem set
\usepackage{sizif}
\def \facultyid {$faculty_id}
\def \facultyname {$faculty_name}
\def \examid {$exam_id}
\def \examtitle {$exam_title}
\def \examdate {$date}
\def \footertext {$last_line}
\setcounter{problemsetid}{$start_number} %the first exam will have id of problemsetid+1 !!!
\def \sidprefill{\sid{$sid_prefill}}
%somesettings
\def \multilinesep {1mm}
\def \texttoanswerskip{2mm}
\def \answertotextskip{5mm}
\def \productname{SIZiF}
\def \productversion{0}
\pagestyle{otherswithname}
\begin{document}
tools/textemplates/newpaperwithSIDtemplate.tpl
New file
@@ -0,0 +1,4 @@
\pagestyle{otherswithsid}
\thispagestyle{firstpagewithsid}
tools/textemplates/newpolatemplate.tpl
New file
@@ -0,0 +1,5 @@
\def \studentid {$student_id}
\def \studentname {$student_name}
\pagestyle{otherswithname}
\thispagestyle{firstpagewithname}
tools/textemplates/problemtemplate.tpl
New file
@@ -0,0 +1,7 @@
%this is a template for text
\problemtext{$problem_number}{$text}
\vskip\texttoanswerskip
%this is a template for answers in-line
\answersinline{$ans1}{$ans2}{$ans3}{$ans4}
\vskip\answertotextskip