Parser of berki style problems and generator of latex file
Samo Penic
2018-10-26 ef19a925aa1356ee1e50f5b9919657a475b8fc05
Solver added, variables are formatted properly. The exceptions are not caught.
5 files modified
190 ■■■■ changed files
GenerateTests.py 11 ●●●●● patch | view | raw | blame | history
tools/BerkiParse.py 10 ●●●● patch | view | raw | blame | history
tools/Formatter.py 7 ●●●● patch | view | raw | blame | history
tools/Problem.py 57 ●●●●● patch | view | raw | blame | history
tools/tests/formatter_test.py 105 ●●●●● patch | view | raw | blame | history
GenerateTests.py
@@ -19,9 +19,12 @@
    print(n.parsedVariables)
    print(n.parsedSolutions)
    for i in range(0,5):
        print(next(n.variableGenerator['d']))
#    for i in range(0,5):
#        print(next(n.variableGenerator['d']))
    """
    for i in range(0,5):
        n=Problem(parser=parser)
        print(n.varDict)
        for var in n.varDict.values():
            print( var )
    """
    print(n.generate_tex())
tools/BerkiParse.py
@@ -80,9 +80,15 @@
            for r in s.split("\n"):
                sp = r.split(":")
                if sp[0].strip("\n\t'") == "formula":
                    retval["correct"].append(sp[1].strip("\n\t'"))
                    retval["correct"].append(sp[1].strip("\n\t"))
                elif sp[0].strip() == "napacna":
                    retval["wrong"].append(sp[1].strip("\n\t'"))
                    retval["wrong"].append(sp[1].strip("\n\t"))
                elif sp[0].strip() == "izpis":
                    retval["type"]=sp[1].strip("\n\t'")
                elif sp[0].strip() == "enota":
                    retval["unit"]= sp[1].strip("\n\t")
                elif sp[0].strip() == "TeX":
                    retval["glyph"]=sp[1].strip("\n\t")
            parsedSolutions.append(retval)
        return parsedSolutions
tools/Formatter.py
@@ -38,6 +38,9 @@
    def get_formatted_value(self):
        return self.formatted_value if self.type != STRING else self.value
    def __str__(self):
        return str(self.format_as_tex())
class FormatterFactory:
    @staticmethod
@@ -78,7 +81,7 @@
        exp = self.fexp(num)
        man = self.fman(num)
        return ("${:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}$").format(
        return ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}").format(
            man, int(exp)
        )
@@ -102,4 +105,4 @@
            raise ValueError
        # TODO: Change formatting string
        return ("${:." + str(self.precision) + "f}$").format(num)
        return ("{:." + str(self.precision) + "f}").format(num)
tools/Problem.py
@@ -1,4 +1,7 @@
from .BerkiParse import BerkiParse
from .Formatter import Variable
import re
from math import *
class Problem:
@@ -17,7 +20,7 @@
    def generateVariables(self):
        for key in self.parsedVariables:
            self.varDict[key] = next(self.variableGenerator[key])
            self.varDict[key] = Variable(next(self.variableGenerator[key]), self.parsedVariables[key]['type'])
    def generateSolutions(self):
        pass
@@ -27,3 +30,55 @@
            return True
        else:
            return False
    def substitute_variables(self, text):
        for key,var in self.varDict.items():
            text=re.sub ("\/\*\/"+key+"\/\*\/", var.format_as_tex(), text)
        return text
    def substitute_octave(self,text):
            text = re.sub("\^", "**", text)
            text = re.sub(";", "\n", text)
            return text
    def solve(self):
        #a dirty one but it has to be like this ;)
        __retsol = []
        #define variables
        for __varname,__var in self.varDict.items():
            exec(__varname+"="+str(__var.get_formatted_value()))
        for __s in self.parsedSolutions:
            __ps = {}
            __ps['correct'] = []
            __ps['wrong'] = []
            #for __s in self.parsedSolutions:
            for __corr in __s['correct']:
                for __corrsplit in __corr.split(';'):
                    if(__corrsplit.find("=")>=0):
                        exec(self.substitute_octave(__corrsplit))
                    else:
                        __result=eval(self.substitute_octave(__corrsplit))
                __ps['correct'].append(Variable(__result, formatting=__s['type']))
            for __corr in __s['wrong']:
                for __corrsplit in __corr.split(';'):
                    if(__corrsplit.find("=")>=0):
                        exec(self.substitute_octave(__corrsplit))
                    else:
                        __result=eval(self.substitute_octave(__corrsplit))
                __ps['wrong'].append(Variable(__result, formatting=__s['type']))
            __retsol.append(__ps)
        return __retsol
    def generate_tex(self, shuffle=True):
        intro=self.substitute_variables(self.introduction)
        sp=[]
        for p in self.subproblems:
            sp.append(self.substitute_variables(p))
        sol=self.solve()
        soltex=[]
        for s in sol:
            entry={'correct': [i.format_as_tex() for i in s['correct']], 'wrong': [i.format_as_tex() for i in s['wrong']]}
            soltex.append(entry)
        return (intro, sp, soltex)
tools/tests/formatter_test.py
@@ -28,32 +28,33 @@
            0,
        ]
        sci2_solutions = [
            "$1.2 \cdot 10^{0}$",
            "$1.2 \cdot 10^{0}$",
            "$3.0 \cdot 10^{0}$",
            "$3.5 \cdot 10^{0}$",
            "$5.0 \cdot 10^{-2}$",
            "$-1.2 \cdot 10^{0}$",
            "$-3.0 \cdot 10^{0}$",
            "$1.1 \cdot 10^{-6}$",
            "$-1.1 \cdot 10^{6}$",
            "$9.8 \cdot 10^{255}$",
            "$0.0 \cdot 10^{0}$",
            "1.2 \cdot 10^{0}",
            "1.2 \cdot 10^{0}",
            "3.0 \cdot 10^{0}",
            "3.5 \cdot 10^{0}",
            "5.0 \cdot 10^{-2}",
            "-1.2 \cdot 10^{0}",
            "-3.0 \cdot 10^{0}",
            "1.1 \cdot 10^{-6}",
            "-1.1 \cdot 10^{6}",
            "9.8 \cdot 10^{255}",
            "0.0 \cdot 10^{0}",
        ]
        sci3_solutions = [
            "$1.24 \cdot 10^{0}$",
            "$1.20 \cdot 10^{0}$",
            "$3.00 \cdot 10^{0}$",
            "$3.50 \cdot 10^{0}$",
            "$5.00 \cdot 10^{-2}$",
            "$-1.23 \cdot 10^{0}$",
            "$-3.00 \cdot 10^{0}$",
            "$1.12 \cdot 10^{-6}$",
            "$-1.12 \cdot 10^{6}$",
            "$9.81 \cdot 10^{255}$",
            "$0.00 \cdot 10^{0}$",
            "1.24 \cdot 10^{0}",
            "1.20 \cdot 10^{0}",
            "3.00 \cdot 10^{0}",
            "3.50 \cdot 10^{0}",
            "5.00 \cdot 10^{-2}",
            "-1.23 \cdot 10^{0}",
            "-3.00 \cdot 10^{0}",
            "1.12 \cdot 10^{-6}",
            "-1.12 \cdot 10^{6}",
            "9.81 \cdot 10^{255}",
            "0.00 \cdot 10^{0}",
        ]
        sci2 = Formatter.FormatterFactory().get_formatter("sci 2")
        for case, result in zip(testcases, sci2_solutions):
            self.assertEqual(result, sci2.toFormat(case))
@@ -77,35 +78,51 @@
            0,
        ]
        sci2_solutions = [
            "$1.2 \cdot 10^{0}$",
            "$1.2 \cdot 10^{0}$",
            "$3.0 \cdot 10^{0}$",
            "$3.5 \cdot 10^{0}$",
            "$5.0 \cdot 10^{-2}$",
            "$-1.2 \cdot 10^{0}$",
            "$-3.0 \cdot 10^{0}$",
            "$1.1 \cdot 10^{-6}$",
            "$-1.1 \cdot 10^{6}$",
            "$9.8 \cdot 10^{255}$",
            "$0.0 \cdot 10^{0}$",
            "1.2 \cdot 10^{0}",
            "1.2 \cdot 10^{0}",
            "3.0 \cdot 10^{0}",
            "3.5 \cdot 10^{0}",
            "5.0 \cdot 10^{-2}",
            "-1.2 \cdot 10^{0}",
            "-3.0 \cdot 10^{0}",
            "1.1 \cdot 10^{-6}",
            "-1.1 \cdot 10^{6}",
            "9.8 \cdot 10^{255}",
            "0.0 \cdot 10^{0}",
        ]
        sci3_solutions = [
            "$1.24 \cdot 10^{0}$",
            "$1.20 \cdot 10^{0}$",
            "$3.00 \cdot 10^{0}$",
            "$3.50 \cdot 10^{0}$",
            "$5.00 \cdot 10^{-2}$",
            "$-1.23 \cdot 10^{0}$",
            "$-3.00 \cdot 10^{0}$",
            "$1.12 \cdot 10^{-6}$",
            "$-1.12 \cdot 10^{6}$",
            "$9.81 \cdot 10^{255}$",
            "$0.00 \cdot 10^{0}$",
            "1.24 \cdot 10^{0}",
            "1.20 \cdot 10^{0}",
            "3.00 \cdot 10^{0}",
            "3.50 \cdot 10^{0}",
            "5.00 \cdot 10^{-2}",
            "-1.23 \cdot 10^{0}",
            "-3.00 \cdot 10^{0}",
            "1.12 \cdot 10^{-6}",
            "-1.12 \cdot 10^{6}",
            "9.81 \cdot 10^{255}",
            "0.00 \cdot 10^{0}",
        ]
        sci2_rounded=[
            1.2,
            1.2,
            3.0,
            3.5,
            0.05,
            -1.2,
            -3.0,
            1.1e-6,
            -1.1e6,
            9.8e255,
            0
        ]
        for case, result in zip(testcases, sci2_solutions):
            self.assertEqual(result, Formatter.Variable(case, "sci 2").format_as_tex())
        for case, result in zip(testcases, sci3_solutions):
            self.assertEqual(result, Formatter.Variable(case, "sci 3").format_as_tex())
        for case, result in zip(testcases, sci2_rounded):
            self.assertEqual(result, Formatter.Variable(case, 'sci 2').get_formatted_value())