Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into pr/weilycoder/160
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Python-in-China committed Dec 18, 2024
2 parents a3fa96f + b4faa53 commit a473e96
Show file tree
Hide file tree
Showing 22 changed files with 707 additions and 183 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
config.py
*.cpp
*.in
*.out
*.exe
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[MASTER]
py-version=3.5
py-version=3.6
disable=R0902,R0903,R0913,R0917,R0912
68 changes: 30 additions & 38 deletions cyaron/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


class CompareMismatch(ValueError):

def __init__(self, name, mismatch):
super(CompareMismatch, self).__init__(name, mismatch)
self.name = name
Expand All @@ -22,6 +23,7 @@ def __str__(self):


class Compare:

@staticmethod
def __compare_two(name, content, std, grader):
(result, info) = CYaRonGraders.invoke(grader, content, std)
Expand Down Expand Up @@ -67,21 +69,20 @@ def output(cls, *files, **kwargs):
max_workers = kwargs["max_workers"]
job_pool = kwargs["job_pool"]
if kwargs["stop_on_incorrect"] is not None:
log.warn("parameter stop_on_incorrect is deprecated and has no effect.")
log.warn(
"parameter stop_on_incorrect is deprecated and has no effect.")

if (max_workers is None or max_workers >= 0) and job_pool is None:
max_workers = cls.__normal_max_workers(max_workers)
try:
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=max_workers) as job_pool:
return cls.output(
*files,
std=std,
grader=grader,
max_workers=max_workers,
job_pool=job_pool
)
return cls.output(*files,
std=std,
grader=grader,
max_workers=max_workers,
job_pool=job_pool)
except ImportError:
pass

Expand Down Expand Up @@ -124,47 +125,44 @@ def program(cls, *programs, **kwargs):
max_workers = kwargs["max_workers"]
job_pool = kwargs["job_pool"]
if kwargs["stop_on_incorrect"] is not None:
log.warn("parameter stop_on_incorrect is deprecated and has no effect.")
log.warn(
"parameter stop_on_incorrect is deprecated and has no effect.")

if (max_workers is None or max_workers >= 0) and job_pool is None:
max_workers = cls.__normal_max_workers(max_workers)
try:
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=max_workers) as job_pool:
return cls.program(
*programs,
input=input,
std=std,
std_program=std_program,
grader=grader,
max_workers=max_workers,
job_pool=job_pool
)
return cls.program(*programs,
input=input,
std=std,
std_program=std_program,
grader=grader,
max_workers=max_workers,
job_pool=job_pool)
except ImportError:
pass

if not isinstance(input, IO):
raise TypeError(
"expect {}, got {}".format(type(IO).__name__, type(input).__name__)
)
raise TypeError("expect {}, got {}".format(
type(IO).__name__,
type(input).__name__))
input.flush_buffer()
input.input_file.seek(0)

if std_program is not None:

def get_std():
with open(
os.dup(input.input_file.fileno()), "r", newline="\n"
) as input_file:
with open(os.dup(input.input_file.fileno()), "r",
newline="\n") as input_file:
content = make_unicode(
subprocess.check_output(
std_program,
shell=(not list_like(std_program)),
stdin=input.input_file,
universal_newlines=True,
)
)
))
input_file.seek(0)
return content

Expand All @@ -188,24 +186,19 @@ def get_std():

def do(program_name):
timeout = None
if (
list_like(program_name)
and len(program_name) == 2
and int_like(program_name[-1])
):
if (list_like(program_name) and len(program_name) == 2
and int_like(program_name[-1])):
program_name, timeout = program_name
with open(
os.dup(input.input_file.fileno()), "r", newline="\n"
) as input_file:
with open(os.dup(input.input_file.fileno()), "r",
newline="\n") as input_file:
if timeout is None:
content = make_unicode(
subprocess.check_output(
program_name,
shell=(not list_like(program_name)),
stdin=input_file,
universal_newlines=True,
)
)
))
else:
content = make_unicode(
subprocess.check_output(
Expand All @@ -214,8 +207,7 @@ def do(program_name):
stdin=input_file,
universal_newlines=True,
timeout=timeout,
)
)
))
input_file.seek(0)
cls.__compare_two(program_name, content, std, grader)

Expand Down
5 changes: 2 additions & 3 deletions cyaron/consts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import absolute_import
import math
import string

"""Constants Package.
Constants:
ALPHABET_SMALL -> All the lower ascii letters
Expand All @@ -18,7 +17,7 @@
ALPHABET_CAPITAL = string.ascii_uppercase
ALPHABET = ALPHABET_SMALL + ALPHABET_CAPITAL
NUMBERS = string.digits
SENTENCE_SEPARATORS = ',,,,,,,;;:' # 70% ',' 20% ';' 10% ':'
SENTENCE_TERMINATORS = '....!' # 80% '.' 20% '!'
SENTENCE_SEPARATORS = ',,,,,,,;;:' # 70% ',' 20% ';' 10% ':'
SENTENCE_TERMINATORS = '....!' # 80% '.' 20% '!'

DEFAULT_GRADER = "NOIPStyle"
5 changes: 3 additions & 2 deletions cyaron/graders/fulltext.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from .graderregistry import CYaRonGraders
from .mismatch import HashMismatch


@CYaRonGraders.grader("FullText")
def fulltext(content, std):
content_hash = hashlib.sha256(content.encode('utf-8')).hexdigest()
std_hash = hashlib.sha256(std.encode('utf-8')).hexdigest()
return (True, None) if content_hash == std_hash else (False, HashMismatch(content, std, content_hash, std_hash))

return (True, None) if content_hash == std_hash else (
False, HashMismatch(content, std, content_hash, std_hash))
3 changes: 2 additions & 1 deletion cyaron/graders/graderregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class GraderRegistry:
_registry = dict()

def grader(self, name):

def wrapper(func):
self._registry[name] = func
return func
Expand All @@ -15,4 +16,4 @@ def check(self, name):
return name in self._registry


CYaRonGraders = GraderRegistry()
CYaRonGraders = GraderRegistry()
23 changes: 19 additions & 4 deletions cyaron/graders/mismatch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Mismatch(ValueError):
"""exception for content mismatch"""

def __init__(self, content, std, *args):
"""
content -> content got
Expand All @@ -9,25 +10,38 @@ def __init__(self, content, std, *args):
self.content = content
self.std = std


class HashMismatch(Mismatch):
"""exception for hash mismatch"""

def __init__(self, content, std, content_hash, std_hash):
"""
content -> content got
std -> content expected
content_hash -> hash of content
std_hash -> hash of std
"""
super(HashMismatch, self).__init__(content, std, content_hash, std_hash)
super(HashMismatch, self).__init__(content, std, content_hash,
std_hash)
self.content_hash = content_hash
self.std_hash = std_hash

def __str__(self):
return "Hash mismatch: read %s, expected %s" % (self.content_hash, self.std_hash)
return "Hash mismatch: read %s, expected %s" % (self.content_hash,
self.std_hash)


class TextMismatch(Mismatch):
"""exception for text mismatch"""
def __init__(self, content, std, err_msg, lineno=None, colno=None, content_token=None, std_token=None):

def __init__(self,
content,
std,
err_msg,
lineno=None,
colno=None,
content_token=None,
std_token=None):
"""
content -> content got
std -> content expected
Expand All @@ -37,7 +51,8 @@ def __init__(self, content, std, err_msg, lineno=None, colno=None, content_token
content_token -> the token of content mismatch
std_token -> the token of std
"""
super(TextMismatch, self).__init__(content, std, err_msg, lineno, colno, content_token, std_token)
super(TextMismatch, self).__init__(content, std, err_msg, lineno,
colno, content_token, std_token)
self.err_msg = err_msg.format(lineno, colno, content_token, std_token)
self.lineno = lineno
self.colno = colno
Expand Down
14 changes: 8 additions & 6 deletions cyaron/graders/noipstyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ def noipstyle(content, std):
i + 1, j + 1, content_lines[i][j:j + 5],
std_lines[i][j:j + 5]))
if len(std_lines[i]) > len(content_lines[i]):
return False, TextMismatch(
content, std, 'Too short on line {}.', i + 1, j + 1,
content_lines[i][j:j + 5], std_lines[i][j:j + 5])
return False, TextMismatch(content, std,
'Too short on line {}.', i + 1,
j + 1, content_lines[i][j:j + 5],
std_lines[i][j:j + 5])
if len(std_lines[i]) < len(content_lines[i]):
return False, TextMismatch(
content, std, 'Too long on line {}.', i + 1, j + 1,
content_lines[i][j:j + 5], std_lines[i][j:j + 5])
return False, TextMismatch(content, std,
'Too long on line {}.', i + 1,
j + 1, content_lines[i][j:j + 5],
std_lines[i][j:j + 5])

return True, None
Loading

0 comments on commit a473e96

Please sign in to comment.