Commit aa50acdc authored by Vladimír Štill's avatar Vladimír Štill
Browse files

evalweb: Flake

parent a443f5e7
Pipeline #65648 passed with stage
in 53 seconds
[flake8]
ignore =
# usual defaults:
# continuation line under-indented for hanging indent
E121
# closing bracket does not match indentation of opening bracket’s line
E123
# continuation line over-indented for hanging indent
E126
# closing bracket is missing indentation
E133
# E226 missing whitespace around arithmetic operator
# E241 multiple spaces after ‘,’
# E242 tab after ‘,’
# multiple statements on one line (def)
E704
# line break before binary operator
W503
# W504 line break after binary operator
# W505 doc line too long (82 > 79 characters)
# other suppressions
# type annotation on self
ANN101
per-file-ignores =
evalweb/examples.py:FS003
# vim: expandtab ft=dosini
...@@ -34,13 +34,18 @@ types = {'DFA': 'DFA', ...@@ -34,13 +34,18 @@ types = {'DFA': 'DFA',
# forms from variants above # forms from variants above
class TypeForm(FlaskForm): class TypeForm(FlaskForm):
make = RadioField('Typ', choices=list(types.items()), default='DFA', coerce=str) make = RadioField('Typ', choices=list(types.items()), default='DFA',
coerce=str)
class TaskForm(FlaskForm): class TaskForm(FlaskForm):
make = RadioField('Task', choices=list(tasks.items()), default='DFA', coerce=str) make = RadioField('Task', choices=list(tasks.items()), default='DFA',
coerce=str)
class ConvertForm(FlaskForm): class ConvertForm(FlaskForm):
make = RadioField('Convert', choices=list(convs.items()), default='DFA', coerce=str) make = RadioField('Convert', choices=list(convs.items()), default='DFA',
coerce=str)
@bp.route('/compare', methods=('GET', 'POST')) @bp.route('/compare', methods=('GET', 'POST'))
...@@ -50,7 +55,7 @@ def compare(): ...@@ -50,7 +55,7 @@ def compare():
student_area = "" # areas remembers user input or replace it with examples student_area = "" # areas remembers user input or replace it with examples
teacher_area = "" teacher_area = ""
if request.method == 'POST' and 'submit_button' in request.form: # submit action if request.method == 'POST' and 'submit_button' in request.form:
teacher_type = teacher_form.make.data teacher_type = teacher_form.make.data
teacher_string = request.form['teacher_string'] teacher_string = request.form['teacher_string']
student_type = student_form.make.data student_type = student_form.make.data
...@@ -59,35 +64,46 @@ def compare(): ...@@ -59,35 +64,46 @@ def compare():
teacher_area = teacher_string teacher_area = teacher_string
if student_string == "" or teacher_string == "": if student_string == "" or teacher_string == "":
return render_template('parsing_error.html', error="Nebyl zadán vstupní formalismus.") return render_template('parsing_error.html',
error="Nebyl zadán vstupní formalismus.")
checker = WebChecker(student_string=student_string, task=student_type) checker = WebChecker(student_string=student_string, task=student_type)
result = checker.compare(teacher_string=teacher_string, teacher_type=teacher_type) result = checker.compare(teacher_string=teacher_string,
teacher_type=teacher_type)
if not isinstance(result, bool): if not isinstance(result, bool):
return render_template('parsing_error.html') return render_template('parsing_error.html')
extra_word_ce, missing_word_ce, inf = None, None, None extra_word_ce, missing_word_ce, inf = None, None, None
if not result and checker.eq is not None: # languages aren't equivalent if not result and checker.eq is not None: # languages not equivalent
extra_word_ce = checker.eq.left_counterexample extra_word_ce = checker.eq.left_counterexample
missing_word_ce = checker.eq.right_counterexample missing_word_ce = checker.eq.right_counterexample
inf = checker.eq.inf inf = checker.eq.inf
return render_template('result_compare.html', compare=True, ok=result,
return render_template('result_compare.html', compare=True, ok=result, inf=inf, inf=inf, task_solved=checker.task_solved,
task_solved=checker.task_solved, alphabets=checker.alphabets, alphabets=checker.alphabets,
extra_word_ce=extra_word_ce, missing_word_ce=missing_word_ce, extra_word_ce=extra_word_ce,
is_task=checker.is_task, img_src=checker.img_src, langs=checker.languages, missing_word_ce=missing_word_ce,
teacher=checker.teacher, student=checker.student, is_task=checker.is_task,
teacher_type_string=types[checker.teacher.task], student_type_string=tasks[checker.student.task]) img_src=checker.img_src,
langs=checker.languages,
teacher=checker.teacher,
student=checker.student,
teacher_type_string=types[checker.teacher.task],
student_type_string=tasks[checker.student.task])
if request.method == 'POST' and 'example_button' in request.form: if request.method == 'POST' and 'example_button' in request.form:
teacher_type = teacher_form.make.data # of which types examples should be # of which types examples should be
teacher_type = teacher_form.make.data
student_type = student_form.make.data student_type = student_form.make.data
if (teacher_type, student_type) in examples: if (teacher_type, student_type) in examples:
teacher_area, student_area = examples[(teacher_type, student_type)] teacher_area, student_area = examples[(teacher_type, student_type)]
return render_template('compare.html', student_form=student_form, teacher_form=teacher_form, return render_template('compare.html',
student_area=student_area, teacher_area=teacher_area) student_form=student_form,
teacher_form=teacher_form,
student_area=student_area,
teacher_area=teacher_area)
# analogical to compare, only with just one input formalism # analogical to compare, only with just one input formalism
...@@ -104,26 +120,32 @@ def convert(): ...@@ -104,26 +120,32 @@ def convert():
student_area = student_string student_area = student_string
if student_string == "": if student_string == "":
return render_template('parsing_error.html', error="Nebyl zadán vstupní formalismus.") return render_template('parsing_error.html',
error="Nebyl zadán vstupní formalismus.")
checker = WebChecker(student_string=student_string, task=task) checker = WebChecker(student_string=student_string, task=task)
try: try:
output = checker.convert(student_type=student_type) output = checker.convert(student_type=student_type)
except ParsingError as ex: except ParsingError:
return render_template('parsing_error.html') return render_template('parsing_error.html')
student = Language(string=student_string, task=student_type) student = Language(string=student_string, task=student_type)
is_task = student.gen_is_task(task=task) is_task = student.gen_is_task(task=task)
return render_template('result_convert.html', compare=False, student_string=student_string, return render_template('result_convert.html', compare=False,
student_type=types[student_type], task=tasks[task], output=output, is_task=is_task) student_string=student_string,
student_type=types[student_type],
task=tasks[task],
output=output,
is_task=is_task)
if request.method == 'POST' and 'example_button' in request.form: if request.method == 'POST' and 'example_button' in request.form:
student_type = student_form.make.data student_type = student_form.make.data
if student_type in convert_examples: if student_type in convert_examples:
student_area = convert_examples[student_type] student_area = convert_examples[student_type]
return render_template('convert.html', student_form=student_form, task_form=task_form, student_area=student_area) return render_template('convert.html', student_form=student_form,
task_form=task_form, student_area=student_area)
@bp.route('/userref') @bp.route('/userref')
......
...@@ -8,11 +8,12 @@ convert_examples: Dict[str, str] = {} ...@@ -8,11 +8,12 @@ convert_examples: Dict[str, str] = {}
teacher_dfa = "(0,a)=1 (1,b)=0 final={0}" teacher_dfa = "(0,a)=1 (1,b)=0 final={0}"
student_dfa = "(A,a)=B (B,b)=C (C,a)=B final={A,C}" student_dfa = "(A,a)=B (B,b)=C (C,a)=B final={A,C}"
teacher_dfa_total = parser.dfa_to_str(parser.str_to_dfa(teacher_dfa).total()) teacher_dfa_total = parser.dfa_to_str(parser.str_to_dfa(teacher_dfa).total())
teacher_efa = "(A,a)={B} (A,\e)={D} (B,b)={A} final={A,D}" teacher_efa = r"(A,a)={B} (A,\e)={D} (B,b)={A} final={A,D}"
student_nfa = parser.nfa_to_str(parser.str_to_nfa(teacher_efa).eliminate_epsilon()) student_nfa = parser.nfa_to_str(parser.str_to_nfa(teacher_efa)
student_gra = "S -> aS' | \e\nS' -> bA | b\nA -> aS'" .eliminate_epsilon())
student_gra = r"S -> aS' | \e\nS' -> bA | b\nA -> aS'"
student_reg = "(ab)^*" student_reg = "(ab)^*"
student_efa = "(A,a)={B} (A,\e)={D} (B,b)={C} (C,a)={B} final={C,D}" student_efa = r"(A,a)={B} (A,\e)={D} (B,b)={C} (C,a)={B} final={C,D}"
examples[('DFA', 'DFA')] = (teacher_dfa, student_dfa) examples[('DFA', 'DFA')] = (teacher_dfa, student_dfa)
examples[('DFA', 'TOT')] = (teacher_dfa, teacher_dfa_total) examples[('DFA', 'TOT')] = (teacher_dfa, teacher_dfa_total)
...@@ -49,4 +50,4 @@ examples[('REG', 'REG')] = (student_reg, student_reg) ...@@ -49,4 +50,4 @@ examples[('REG', 'REG')] = (student_reg, student_reg)
convert_examples['DFA'] = teacher_dfa convert_examples['DFA'] = teacher_dfa
convert_examples['EFA'] = student_nfa convert_examples['EFA'] = student_nfa
convert_examples['GRA'] = student_gra convert_examples['GRA'] = student_gra
convert_examples['REG'] = student_reg convert_examples['REG'] = student_reg
\ No newline at end of file
import lib.reg as reg import lib.reg as reg
from lib.parsing.parser import Parser, ParsingError from lib.parsing.parser import Parser, ParsingError
from lib.checker import transform, dfa_transform, nfa_transform, check_task, check_alphabets from lib.checker import transform, dfa_transform, nfa_transform, check_task, \
check_alphabets
from typing import List, Tuple from typing import List, Tuple
from enum import Enum from enum import Enum
import enum import enum
...@@ -14,7 +15,7 @@ class Size(Enum): ...@@ -14,7 +15,7 @@ class Size(Enum):
class Language: # contains information about formalism and its language class Language: # contains information about formalism and its language
def __init__(self, string: str, task: str = "DFA"): def __init__(self, string: str, task: str = "DFA") -> None:
self.string = string self.string = string
self.task = task self.task = task
self.dfa = None self.dfa = None
...@@ -24,7 +25,7 @@ class Language: # contains information about formalism and its language ...@@ -24,7 +25,7 @@ class Language: # contains information about formalism and its language
self.example = None self.example = None
self.gen_lang_html() self.gen_lang_html()
def gen_lang_html(self): def gen_lang_html(self) -> None:
parser = Parser() parser = Parser()
dfa = dfa_transform(self.string, self.task) dfa = dfa_transform(self.string, self.task)
self.minimal = parser.dfa_to_str(dfa.minimize().canonize()) self.minimal = parser.dfa_to_str(dfa.minimize().canonize())
...@@ -74,7 +75,8 @@ class WebChecker: ...@@ -74,7 +75,8 @@ class WebChecker:
try: try:
teacher = Language(string=teacher_string, task=teacher_type) teacher = Language(string=teacher_string, task=teacher_type)
student = Language(string=student_string, task=self.task) student = Language(string=student_string, task=self.task)
student_solution = transform(student_string, task) # only for task checking # only for task checking
student_solution = transform(student_string, task)
except ParsingError as ex: # Parsing error, don't continue except ParsingError as ex: # Parsing error, don't continue
return ex.args return ex.args
...@@ -83,15 +85,18 @@ class WebChecker: ...@@ -83,15 +85,18 @@ class WebChecker:
self.student = student self.student = student
self.is_task = teacher.gen_is_task(task=self.task) self.is_task = teacher.gen_is_task(task=self.task)
if isinstance(student_solution, reg.DFA) or isinstance(student_solution, reg.NFA): if isinstance(student_solution, reg.DFA) \
or isinstance(student_solution, reg.NFA):
self.task_solved = check_task(student_solution, task) self.task_solved = check_task(student_solution, task)
if teacher.size == Size.Empty and student.size == Size.Empty: if teacher.size == Size.Empty and student.size == Size.Empty:
return self.task_solved == "" return self.task_solved == ""
# if the alphabets aren't same, languages aren't equal (unless they are both empty) # if the alphabets aren't same, languages aren't equal (unless they are
# both empty)
alphabets = check_alphabets(student_alpha=student.dfa.characters, alphabets = check_alphabets(student_alpha=student.dfa.characters,
teacher_alpha=teacher.dfa.characters, task=task) teacher_alpha=teacher.dfa.characters,
task=task)
if alphabets != "": if alphabets != "":
self.alphabets = alphabets self.alphabets = alphabets
...@@ -99,25 +104,25 @@ class WebChecker: ...@@ -99,25 +104,25 @@ class WebChecker:
self.eq = reg.DFA.is_equivalent(student.dfa, teacher.dfa) self.eq = reg.DFA.is_equivalent(student.dfa, teacher.dfa)
self.img_src = self.relation(self.eq.left_counterexample is None and self.img_src = self.relation(self.eq.left_counterexample is None
self.eq.right_counterexample is None) and self.eq.right_counterexample is None)
if self.task_solved == "" and \ if self.task_solved == "" and \
self.eq.right_counterexample is None and \ self.eq.right_counterexample is None and \
self.eq.left_counterexample is None: self.eq.left_counterexample is None:
return True return True
return False return False
def compare(self, teacher_string: str, teacher_type: str): def compare(self, teacher_string: str, teacher_type: str):
#signal.alarm(50) # from fja_checker: here would kill the web # signal.alarm(50) # from fja_checker: here would kill the web
try: try:
return self.dfa_task(teacher_type=teacher_type, teacher_string=teacher_string, return self.dfa_task(teacher_type=teacher_type,
task=self.task, student_string=self.student_string) teacher_string=teacher_string,
task=self.task,
student_string=self.student_string)
except ParsingError as ex: except ParsingError as ex:
return ex.args return ex.args
#raise ParsingError(ex.args) # raise ParsingError(ex.args)
def convert(self, student_type): def convert(self, student_type):
try: try:
...@@ -141,10 +146,11 @@ class WebChecker: ...@@ -141,10 +146,11 @@ class WebChecker:
return parser.nfa_to_str(nfa) return parser.nfa_to_str(nfa)
if self.task == "GRA": if self.task == "GRA":
return parser.reggrammar_to_str(nfa.nfa_to_reggrammar().eliminate_useless()) return parser.reggrammar_to_str(nfa.nfa_to_reggrammar()
.eliminate_useless())
except ParsingError as ex: except ParsingError as ex:
return ex.args return ex.args # FIXME
# raise ParsingError(ex.args) # raise ParsingError(ex.args)
except Exception as ex: except Exception as ex:
...@@ -155,7 +161,8 @@ class WebChecker: ...@@ -155,7 +161,8 @@ class WebChecker:
teacher = self.teacher.dfa teacher = self.teacher.dfa
# language 0 on picture: complement of both # language 0 on picture: complement of both
self.languages[0] = self.language((reg.DFA.union(teacher, student)).complement()) self.languages[0] = self.language(
(reg.DFA.union(teacher, student)).complement())
if not eq: if not eq:
if self.eq.left_counterexample is not None: # extra word if self.eq.left_counterexample is not None: # extra word
...@@ -166,29 +173,36 @@ class WebChecker: ...@@ -166,29 +173,36 @@ class WebChecker:
self.languages[2] = self.student self.languages[2] = self.student
return "disjunction" return "disjunction"
else: else:
self.languages[1] = self.language(reg.DFA.subtraction(teacher, student)) self.languages[1] = self.language(reg.DFA.subtraction(
self.languages[2] = self.language(reg.DFA.subtraction(student, teacher)) teacher, student))
self.languages[3] = self.language(reg.DFA.intersection(teacher, student)) self.languages[2] = self.language(reg.DFA.subtraction(
student, teacher))
self.languages[3] = self.language(reg.DFA.intersection(
teacher, student))
return "intersection" return "intersection"
else: # teacher is subset of student else: # teacher is subset of student
self.languages[1] = self.teacher self.languages[1] = self.teacher
self.languages[2] = self.language(reg.DFA.subtraction(student, teacher)) self.languages[2] = self.language(reg.DFA.subtraction(
student, teacher))
picture = "t_in_s" picture = "t_in_s"
else: # student is subset of teacher else: # student is subset of teacher
self.languages[1] = self.language(reg.DFA.subtraction(teacher, student)) self.languages[1] = self.language(reg.DFA.subtraction(
teacher, student))
self.languages[2] = self.student self.languages[2] = self.student
picture = "s_in_t" picture = "s_in_t"
else: else:
#print(self.eq.left_counterexample, self.eq.right_counterexample) # print(self.eq.left_counterexample, self.eq.right_counterexample)
picture = "eq" picture = "eq"
self.languages[0] = self.language(teacher.complement()) self.languages[0] = self.language(teacher.complement())
self.languages[1] = self.teacher self.languages[1] = self.teacher
#if self.teacher.size == Size.Empty or self.student.size == Size.Universal: # if self.teacher.size == Size.Empty \
# picture += "_empty" # or self.student.size == Size.Universal:
if self.teacher.size == Size.Universal or self.student.size == Size.Universal: # picture += "_empty"
if self.teacher.size == Size.Universal \
or self.student.size == Size.Universal:
picture += "_universal" picture += "_universal"
if self.teacher.size == Size.Universal: if self.teacher.size == Size.Universal:
self.languages.pop(0) self.languages.pop(0)
...@@ -202,7 +216,5 @@ class WebChecker: ...@@ -202,7 +216,5 @@ class WebChecker:
parser = Parser() parser = Parser()
return Language(parser.dfa_to_str(dfa)) return Language(parser.dfa_to_str(dfa))
def DFA_lines(self, str): def DFA_lines(self, str_: str) -> None:
pass pass
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment