Commit 0f5aad35 authored by Kateřina Sloupová's avatar Kateřina Sloupová
Browse files

comments and cleanup

parent b8cdb4a5
Pipeline #62553 passed with stage
in 50 seconds
export PYTHONPATH=$PWD
export FLASK_APP=evalweb
flask run
......@@ -24,6 +24,7 @@ def create_app(test_config=None):
pass
@app.route('/')
# initial page is compare mode
def index():
return redirect(url_for('eval.compare'))
......
from flask import Blueprint, render_template, request
from flask_wtf import FlaskForm
from wtforms import RadioField
import sys
sys.path.append('~/eval')
from evalweb.web_checker import WebChecker, Language
from evalweb.examples import examples, convert_examples
bp = Blueprint('eval', __name__, url_prefix='/')
# radiobuttons: student task
tasks = {'DFA': 'DFA',
'TOT': 'Totální DFA',
'MIN': 'Minimální DFA',
......@@ -17,6 +16,7 @@ tasks = {'DFA': 'DFA',
'GRA': 'Regulární gramatika',
'REG': 'Regulární výraz'}
# radiobuttons: conversion possibilities
convs = {'DFA': 'DFA',
'TOT': 'Totální DFA',
'MIN': 'Minimální DFA',
......@@ -24,16 +24,17 @@ convs = {'DFA': 'DFA',
'NFA': 'NFA bez ε-kroků',
'GRA': 'Regulární gramatika'}
# radiobuttons: teacher input/formalism to convert
types = {'DFA': 'DFA',
'EFA': 'NFA (s ε-kroky)',
'GRA': 'Regulární gramatika',
'REG': 'Regulární výraz'}
# forms from variants above
class TypeForm(FlaskForm):
make = RadioField('Typ', choices=list(types.items()), default='DFA', coerce=str)
class TaskForm(FlaskForm):
make = RadioField('Task', choices=list(tasks.items()), default='DFA', coerce=str)
......@@ -45,10 +46,10 @@ class ConvertForm(FlaskForm):
def compare():
student_form = TaskForm(prefix='student_form')
teacher_form = TypeForm(prefix='teacher_form')
student_area = ""
student_area = "" # areas remembers user input or replace it with examples
teacher_area = ""
if request.method == 'POST' and 'submit_button' in request.form:
if request.method == 'POST' and 'submit_button' in request.form: # submit action
teacher_type = teacher_form.make.data
teacher_string = request.form['teacher_string']
student_type = student_form.make.data
......@@ -62,19 +63,19 @@ def compare():
return render_template('parsing_error.html', error=result)
extra_word_ce, missing_word_ce, inf = None, None, None
if not result and checker.eq is not None:
if not result and checker.eq is not None: # languages aren't equivalent
extra_word_ce = checker.eq.left_counterexample
missing_word_ce = checker.eq.right_counterexample
inf = checker.eq.inf
return render_template('result_compare.html', compare=True, ok=result,
inf=inf, task_solved=checker.task_solved, alphabets=checker.alphabets,
return render_template('result_compare.html', compare=True, ok=result, inf=inf,
task_solved=checker.task_solved, alphabets=checker.alphabets,
extra_word_ce=extra_word_ce, missing_word_ce=missing_word_ce,
is_task=checker.is_task, img_src=checker.img_src,
teacher=checker.teacher, student=checker.student)
if request.method == 'POST' and 'example_button' in request.form:
teacher_type = teacher_form.make.data
teacher_type = teacher_form.make.data # of which types examples should be
student_type = student_form.make.data
if (teacher_type, student_type) in examples:
teacher_area, student_area = examples[(teacher_type, student_type)]
......@@ -83,6 +84,7 @@ def compare():
student_area=student_area, teacher_area=teacher_area)
# analogical to compare, only with just one input formalism
@bp.route('/convert', methods=('GET', 'POST'))
def convert():
student_form = TypeForm(prefix='student_form')
......
......@@ -4,7 +4,6 @@
<h1>{% block title %}Porovnání formalismů{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
......
......@@ -82,6 +82,8 @@
</p>
<br><br><br><br><br>
<h3>Vygenerovaný řetězec pro odpovědník</h3>
{{ is_task }}
<div style="margin:10px 30px;">
<h3>Vygenerovaný řetězec pro odpovědník</h3>
{{ is_task }}
</div>
{% endblock %}
\ No newline at end of file
......@@ -12,7 +12,7 @@ class Size(Enum):
Universal = enum.auto()
class Language():
class Language: # contains information about formalism and its language
def __init__(self, string: str, task: str):
self.string = string
self.task = task
......@@ -67,26 +67,27 @@ class WebChecker:
self.is_task = None
self.img_src = "disjunction"
# nearly equivalent to dfa_task in fja_checker (for IS ROPOTs)
def dfa_task(self, teacher_type, teacher_string, task, student_string):
try:
teacher = Language(string=teacher_string, task=teacher_type)
student = Language(string=student_string, task=self.task)
student_solution = transform(student_string, task)
student_solution = transform(student_string, task) # only for task checking
except ParsingError as ex: # Parsing error, don't continue
return(ex.args)
except ParsingError as ex: # Parsing error, don't continue
return ex.args
self.teacher = teacher
self.student = student
self.is_task = teacher.gen_is_task(task=self.task)
if isinstance(student_solution, reg.DFA) or isinstance(student_solution, reg.NFA):
# "Odpověď splňuje požadovaný formalismus."
self.task_solved = check_task(student_solution, task)
if teacher.size == Size.Empty and student.size == Size.Empty:
return True
# if the alphabets aren't same, languages aren't equal (unless they are both empty)
alphabets = check_alphabets(student_alpha=student.dfa.characters,
teacher_alpha=teacher.dfa.characters, task=task)
if alphabets != "":
......@@ -102,7 +103,7 @@ class WebChecker:
def compare(self, teacher_string: str, teacher_type: str):
#signal.alarm(50) #
#signal.alarm(50) # from fja_checker: here would kill the web
try:
return self.dfa_task(teacher_type=teacher_type, teacher_string=teacher_string,
task=self.task, student_string=self.student_string)
......@@ -112,11 +113,8 @@ class WebChecker:
def convert(self, student_type):
#signal.alarm(50)
try:
parser = Parser()
if self.task in {"DFA", "TOT", "MIN"}:
dfa = dfa_transform(self.student_string, student_type)
......@@ -148,17 +146,17 @@ class WebChecker:
def relation(self, eq: bool) -> str: # TODO test
if not eq:
if self.eq.left_counterexample is not None: # extra word
if self.eq.left_counterexample is not None: # missing word
if self.eq.left_counterexample is not None: # extra word
if self.eq.left_counterexample is not None: # missing word
intersection = reg.DFA.intersection(self.student.dfa, self.teacher.dfa)
if intersection.is_empty(): # disjunction
if intersection.is_empty(): # disjunction
return "disjunction"
else:
return "intersection"
else: # teacher is subset of student
else: # teacher is subset of student
picture = "t_in_s"
else: # student is subset of teacher
else: # student is subset of teacher
picture = "s_in_t"
else:
......@@ -169,5 +167,5 @@ class WebChecker:
elif self.teacher.size == Size.Universal or self.student.size == Size.Universal:
picture += "_universal"
return picture
return picture # name of static image file to show in feedback
......@@ -19,7 +19,7 @@ def dfa_task(teacher_type, teacher_string, task, student_string):
student_solution = dfa_transform(student_string, task)
teacher_solution = dfa_transform(teacher_string, teacher_type)
except ParsingError as ex:
#print(ex.args)
print("Nastala chyba při parsování:", ex)
exit_incorrect()
check_empty(student_solution=student_solution,
......@@ -148,7 +148,6 @@ def main():
print(f"Invalid question type {task_prefix}")
exit(1)
# TODO K: get your exceptions together!
except Exception as ex:
print("Error inside of fja_checker:", ex.args)
exit(1)
......
......@@ -2,8 +2,9 @@ from typing import Tuple, Union
from lib import reg
from lib.parsing.parser import Parser, ParsingError
# support functions common for both fja_checker and web_checker
def get_task(string: str) -> Tuple[str, str]:
def get_task(string: str) -> Tuple[str, str]: # from IS task prefix
assert '-' in string, "Teacher solution could not be parsed correctly."
teacher_type, task = string.split("-", 1)
if '-' in task:
......@@ -11,7 +12,7 @@ def get_task(string: str) -> Tuple[str, str]:
assert len(teacher_type) != 0, "Teacher solution code must not ne empty"
assert len(task) != 0, "Task code must not be empty"
return (teacher_type, task)
return teacher_type, task
def dfa_transform(string: str, automaton_type: str) -> reg.DFA:
......@@ -43,7 +44,8 @@ def nfa_transform(string: str, automaton_type: str) -> reg.NFA:
except ParsingError as ex:
raise ParsingError(ex.args)
def transform(string: str, automaton_type: str) -> Union[reg.DFA, reg.NFA, reg.RegGrammar, reg.RegEx]:
try:
parser = Parser()
......@@ -99,6 +101,7 @@ def check_task(automaton: Union[reg.DFA, reg.NFA], task: str) -> str:
return output
def check_empty(student_solution, teacher_solution):
if teacher_solution.is_empty() and student_solution.is_empty():
exit_correct()
......@@ -116,7 +119,7 @@ def check_alphabets(student_alpha, teacher_alpha, task: str) -> str:
else:
output += " (abeceda je odvozena ze všech písmen objevujících se v přechodové funkci)."
# TODO ask also print both alphabets? Or difference?
# if wanna also print both alphabets:
#print("Studentova abeceda:" + reg.Parser.names_to_str(student_alpha))
#print("Abeceda zadaného jazyka:" + reg.Parser.names_to_str(teacher_alpha))
......
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