Parser of berki style problems and generator of latex file
Samo Penic
2018-10-28 993a25c9284de2f3e9014320bd24cf6d5fc68ec3
Many fixes... Works with string variables and eng. dec and sci still missing!
7 files modified
147 ■■■■■ changed files
GenerateTests.py 39 ●●●●● patch | view | raw | blame | history
testcases/8b_dispneja.txt 12 ●●●●● patch | view | raw | blame | history
tools/Exceptions.py 2 ●●●●● patch | view | raw | blame | history
tools/Problem.py 7 ●●●●● patch | view | raw | blame | history
tools/Template.py 24 ●●●●● patch | view | raw | blame | history
tools/Variable.py 57 ●●●● patch | view | raw | blame | history
tools/textemplates/sizif.sty 6 ●●●● patch | view | raw | blame | history
GenerateTests.py
@@ -7,32 +7,41 @@
    from glob import glob
    # THIS IS TO BE READ FROM THE DATABASE
    filelist = glob("testcases/dvovod3.txt")
    filelist = glob("testcases/*")
    naloge = []
    for i, f in enumerate(filelist):
        with open(f) as fd:
            cont = fd.read()
        naloge.append((i, cont))
    source=[]
    for nal in naloge:
        par=BerkiParse(nal[1])
        par.parseSections()
        source.append(ProblemSource(parser=par))
    parser = BerkiParse(naloge[0][1])
    parser.parseSections()
    n = ProblemSource(parser=parser)
    #parser = BerkiParse(naloge[1][1])
    #parser.parseSections()
    #n = ProblemSource(parser=parser)
    t = TemplateEngine("tools/textemplates")
    for i in range(0, 5):
        p = Problem(n)
        pprint.pprint(p.problem)
    problems=[]
    for src in source:
        problems.append(Problem(src))
    #   pprint.pprint(p.problem)
    print(
        t.head(
    text=""
    text+=t.head(
            exam_title="Naslov izpita",
            date="27.10.2018",
            faculty_name="Fakulteta test",
            sid_prefill="11x0xxxx",
        )
    )
    print(t.start_paper())
    for i in range(0, 5):
        p = Problem(n)
        print(t.put_problem_into_template(p.problem))
    print(t.tail())
    text+=t.start_paper()
    for p in problems:
        text+=t.put_problem_into_template(p.problem)
    text+=t.tail()
    print(text)
    with open('preverjanje.tex','w') as problem_fd:
        problem_fd.write(text)
testcases/8b_dispneja.txt
@@ -1,10 +1,6 @@
#StartUvod
#EndUvod
#StartPodnaloga
Dispneja je:
#EndPodnaloga
#EndUvod
#StartRezultat
TeX:        
@@ -16,10 +12,4 @@
napacna:    'bradipnea'
#EndRezultat
--- Od tukaj za tekstne naloge nepomebno ---
#StartSkalar
ime:    c
izpis:    decimal 2
nacin:    FixedVals 3 4
#EndSkalar
tools/Exceptions.py
@@ -4,3 +4,5 @@
class TemplatePathError(Exception):
    pass
class NoResult(Exception):
    pass
tools/Problem.py
@@ -1,5 +1,6 @@
from .Variable import Variable
import re
from . import Exceptions
from math import *
@@ -47,17 +48,23 @@
            __ps["wrong"] = []
            for __corr in __s["correct"]:
                for __corrsplit in __corr.split(";"):
                    __result=None
                    if __corrsplit.find("=") >= 0:
                        exec(self.substitute_octave(__corrsplit))
                    else:
                        __result = eval(self.substitute_octave(__corrsplit))
                if (__result is  None):
                    raise Exceptions.NoResult("Result cannot be calculated. Be sure to specify last term without = sign!")
                __ps["correct"].append(Variable(__result, formatting=__s["type"]))
            for __corr in __s["wrong"]:
                for __corrsplit in __corr.split(";"):
                    __result = None
                    if __corrsplit.find("=") >= 0:
                        exec(self.substitute_octave(__corrsplit))
                    else:
                        __result = eval(self.substitute_octave(__corrsplit))
                if(__result is None):
                    raise Exceptions.NoResult("Result cannot be calculated. Be sure to specify last term without = sign!")
                __ps["wrong"].append(Variable(__result, formatting=__s["type"]))
            __ps["glyph"] = __s["glyph"]
            __ps["unit"] = __s["unit"]
tools/Template.py
@@ -34,25 +34,33 @@
                {"problem_number": 0, "text": problem_dict["introduction"]}
            )
            for sp, sol in zip(problem_dict["subproblems"], problem_dict["solutions"]):
                if sol["correct"][0].formatting == 'str':
                    formatstr = "{}{}{}"
                else:
                    formatstr = "${}={}\,\mathrm{{{}}}$"
                retstr += Template(self.template["subproblem"]).substitute(
                    {
                        "text": sp,
                        "ans1": ("${}={}\,\mathrm{{{}}}").format(sol['glyph'],sol["correct"][0], sol['unit']),
                        "ans2": ("${}={}\,\mathrm{{{}}}").format(sol['glyph'],sol["wrong"][0], sol['unit']),
                        "ans3": ("${}={}\,\mathrm{{{}}}").format(sol['glyph'],sol["wrong"][1], sol['unit']),
                        "ans4": ("${}={}\,\mathrm{{{}}}").format(sol['glyph'],sol["wrong"][2], sol['unit']),
                        "ans1": ("${}={}\,\mathrm{{{}}}$").format(sol['glyph'],sol["correct"][0], sol['unit']),
                        "ans2": ("${}={}\,\mathrm{{{}}}$").format(sol['glyph'],sol["wrong"][0], sol['unit']),
                        "ans3": ("${}={}\,\mathrm{{{}}}$").format(sol['glyph'],sol["wrong"][1], sol['unit']),
                        "ans4": ("${}={}\,\mathrm{{{}}}$").format(sol['glyph'],sol["wrong"][2], sol['unit']),
                    }
                )
            retstr += Template(self.template["subproblem_end"]).substitute()
        else:
            if problem_dict["solutions"][0]["correct"][0].formatting == 'str':
                formatstr = "{}{}{}"
            else:
                formatstr = "${}={}\,\mathrm{{{}}}$"
            retstr += Template(self.template["problem"]).substitute(
                {
                    "problem_number": 0,
                    "text": problem_dict["introduction"],
                    "ans1": ("${}={}\,\mathrm{{{}}}").format(problem_dict["solutions"]["glyph"],problem_dict["solutions"][0]["correct"][0], problem_dict["solutions"]["unit"]),
                    "ans2": str(problem_dict["solutions"][0]["wrong"][0]),
                    "ans3": str(problem_dict["solutions"][0]["wrong"][1]),
                    "ans4": str(problem_dict["solutions"][0]["wrong"][2]),
                    "ans1": formatstr.format(problem_dict["solutions"][0]["glyph"],problem_dict["solutions"][0]["correct"][0], problem_dict["solutions"][0]["unit"]),
                    "ans2": formatstr.format(problem_dict["solutions"][0]["glyph"],problem_dict["solutions"][0]["wrong"][0], problem_dict["solutions"][0]["unit"]),
                    "ans3": formatstr.format(problem_dict["solutions"][0]["glyph"],problem_dict["solutions"][0]["wrong"][1], problem_dict["solutions"][0]["unit"]),
                    "ans4": formatstr.format(problem_dict["solutions"][0]["glyph"],problem_dict["solutions"][0]["wrong"][2], problem_dict["solutions"][0]["unit"]),
                }
            )
        return retstr
tools/Variable.py
@@ -7,36 +7,37 @@
class Variable:
    def __init__(self, value=None, formatting=None):
        self.formatted_value = None
        try:
            self.value = float(value)
            self.type = FLOAT
        except (ValueError, TypeError):
            self.type = STRING
        self.formatted_value = None
            self.value=value
            self.formatted_value=value
        if formatting is not None:
            self.format_float(formatting)
        self.formatting = formatting
        # self.formatter=FormatterFactory(formatting)
    def format_float(self, formatting=None):
        if self.type != STRING:
            if formatting is None:
                formatting = self.formatting
            formatter = FormatterFactory.get_formatter(formatting)
            self.formatted_value = formatter.getValue(self.value)
        if formatting is None:
            formatting = self.formatting
        formatter = FormatterFactory.get_formatter(formatting)
        self.formatted_value = formatter.getValue(self.value)
    def format_as_tex(self, formatting=None):
        if self.type != STRING:
            if formatting is None:
                formatting = self.formatting
        #if self.type != STRING:
        if formatting is None:
            formatting = self.formatting
            formatter = FormatterFactory.get_formatter(formatting)
            return formatter.toFormat(self.value)
        else:
            return self.value
        formatter = FormatterFactory.get_formatter(formatting)
        return formatter.toFormat(self.value)
        #else:
        #    return self.value
    def get_formatted_value(self):
        return self.formatted_value if self.type != STRING else self.value
        return self.formatted_value
        #if self.type != STRING else self.value
    def __str__(self):
        return str(self.format_as_tex())
@@ -54,7 +55,12 @@
        if type == "sci":
            return SciFloatFormatter(arglist)
        elif type =="str":
            return StringFormatter()
        elif type =="eng":
            return EngFloatFormatter(arglist)
        elif type =="dec":
            return DecFloatFormatter(arglist)
        else:
            return None
@@ -65,6 +71,17 @@
    @staticmethod
    def fman(f):
        return f / 10 ** FormatterFactory.fexp(f)
class StringFormatter(FormatterFactory):
    def __init__(self):
        pass
    def toFormat(self, string):
        return string
    def getValue(self, string):
        return string
class SciFloatFormatter(FormatterFactory):
@@ -97,7 +114,13 @@
        return float(man)
class EngFloatFormatter(FormatterFactory):
class DecFloatFormatter(SciFloatFormatter):
    pass
class EngFloatFormatter(SciFloatFormatter):
    pass
class EngFloatFormatter1(FormatterFactory):
    def __init__(self, formatparameters):
        if len(formatparameters) != 1:
            raise Exceptions.WrongParameters("Eng format accept only one argument")
tools/textemplates/sizif.sty
@@ -196,9 +196,9 @@
\newcommand{\answersinline}[4]{\noindent%
\parbox[t][][t]{180mm}{
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{A}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #1\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{B}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #1\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{C}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #1\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{D}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #1\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{B}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #2\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{C}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #3\end{flushleft}}}\end{minipage}}%
\makebox[48mm][l]{\textcircled{\scriptsize{\rm{D}}}\hskip2pt\begin{minipage}[t][][t]{42mm}{{\small\begin{flushleft} #4\end{flushleft}}}\end{minipage}}%
\marker{$\blacksquare$}
}
}