Attempting shuffling and proximity checks.
| | |
| | | import re |
| | | from . import Exceptions |
| | | from math import * |
| | | |
| | | from random import shuffle |
| | | |
| | | class Problem: |
| | | def __init__(self, source=None): |
| | | def __init__(self, source=None, shuffle=True, MaxShuffleAttempts=100, AnsDiff=0.05): |
| | | self.source = source |
| | | self.MaxShuffleAttempts=MaxShuffleAttempts |
| | | self.AnsDiff = AnsDiff |
| | | self.source.generateVariables() |
| | | self.source.generateSolutions() |
| | | self.problem = self.source.generateProblem() |
| | | if shuffle: |
| | | self.problem['solutions']=self.shuffleAnswers(self.problem['solutions']) |
| | | |
| | | def toTexFormatterDict(self, template=None): |
| | | pass |
| | | |
| | | |
| | | def shuffleAnswers(self,solList): |
| | | shuffList=[] |
| | | for cont in solList: |
| | | for i in range(0, self.MaxShuffleAttempts): |
| | | wrong=cont['wrong'] |
| | | shuffle(wrong) |
| | | ans=[*zip(cont['correct'],list('1'*len(cont['correct']))), *zip(wrong,list('0'*len(wrong)))] |
| | | ans=ans[0:4] |
| | | if self.checkAnsProximity(ans)==False: |
| | | break |
| | | shuffle(ans) |
| | | cont['shuffled']=ans |
| | | shuffList.append(cont) |
| | | return solList |
| | | |
| | | def checkAnsProximity(self, ans): |
| | | for idx1,val1 in ans: |
| | | for idx2, val2 in ans: |
| | | if(abs(val1.get_formatted_value()-val2.get_formatted_value())<self.AnsDiff): |
| | | return True |
| | | return False |
| | | |
| | | |
| | | class ProblemSource: |
| | |
| | | text = re.sub(";", "\n", text) |
| | | return text |
| | | |
| | | def generateProblem(self, shuffle=True): |
| | | def generateProblem(self): |
| | | intro = self.substitute_variables(self.introduction) |
| | | sp = [] |
| | | 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 |
| | | return {"introduction": intro, "subproblems": sp, "solutions": sol} |
| | | |
| | |
| | | self.type = FLOAT |
| | | except (ValueError, TypeError): |
| | | self.type = STRING |
| | | self.value=value |
| | | self.formatted_value=value |
| | | self.value = value |
| | | self.formatted_value = value |
| | | if formatting is not None: |
| | | self.format_float(formatting) |
| | | self.formatting = formatting |
| | | |
| | | def is_float(self): |
| | | if self.type==FLOAT: |
| | | return True |
| | | else: |
| | | return False |
| | | |
| | | def format_float(self, formatting=None): |
| | | if formatting is None: |
| | |
| | | if formatting is None: |
| | | formatting = self.formatting |
| | | formatter = FormatterFactory.get_formatter(formatting) |
| | | if formatting=="str": |
| | | if formatting == "str": |
| | | return formatter.toFormat(self.value) |
| | | elif(glyph is None and unit is None): |
| | | elif glyph is None and unit is None: |
| | | return ("${}$").format(formatter.toFormat(self.value)) |
| | | elif(glyph is None and unit is not None): |
| | | return ("${}\,\mathrm{{{}}}$").format(formatter.toFormat(self.value), unit) |
| | | elif(glyph is not None and unit is None): |
| | | return ("${}={}$").format(glyph,formatter.toFormat(self.value)) |
| | | elif glyph is None and unit is not None: |
| | | return ("${}~\mathrm{{{}}}$").format(formatter.toFormat(self.value), unit) |
| | | elif glyph is not None and unit is None: |
| | | return ("${}={}$").format(glyph, formatter.toFormat(self.value)) |
| | | else: |
| | | return ("${}={}\,\mathrm{{{}}}$").format(glyph,formatter.toFormat(self.value), unit) |
| | | return ("${}={}~\mathrm{{{}}}$").format( |
| | | glyph, formatter.toFormat(self.value), unit |
| | | ) |
| | | |
| | | def format_without_dollar(self, formatting=None): |
| | | if formatting is None: |
| | |
| | | |
| | | def get_formatted_value(self): |
| | | return self.formatted_value |
| | | #if self.type != STRING else self.value |
| | | # if self.type != STRING else self.value |
| | | |
| | | def __str__(self): |
| | | return str(self.format_as_tex()) |
| | |
| | | |
| | | if type == "sci": |
| | | return SciFloatFormatter(arglist) |
| | | elif type =="str": |
| | | elif type == "str": |
| | | return StringFormatter() |
| | | elif type =="eng": |
| | | elif type == "eng": |
| | | return EngFloatFormatter(arglist) |
| | | elif type =="dec": |
| | | elif type == "dec": |
| | | return DecFloatFormatter(arglist) |
| | | else: |
| | | return None |
| | |
| | | exp = self.fexp(num) |
| | | man = self.fman(num) |
| | | if exp == 0: |
| | | return ("{:." + str(self.precision - 1) + "f}").format(man) |
| | | return ( |
| | | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") |
| | | ) |
| | | else: |
| | | return ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}").format( |
| | | man, int(exp) |
| | | return ( |
| | | ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}") |
| | | .format(man, int(exp)) |
| | | .replace(".", ",\!") |
| | | ) |
| | | |
| | | def getValue(self, num): |
| | |
| | | |
| | | class DecFloatFormatter(SciFloatFormatter): |
| | | pass |
| | | |
| | | |
| | | class EngFloatFormatter(SciFloatFormatter): |
| | | pass |
| | | |