Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions topcoder/Problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ def %s:

"""

## python class parameters ##
PYTHON_CLASS_TEMPLATE = """#!/usr/bin/python

class %s(object):
\"\"\"docstring for %s\"\"\"
def __init__(self, arg=None):
super(%s, self).__init__()
self.arg = arg

def %s:
pass

"""

## test icons ##
CHECK_MARK = 'Y' # u'\u2713'
CROSS_MARK = 'N' # u'\u2717'
Expand Down Expand Up @@ -115,6 +129,22 @@ def _generate_mini_signature(self):
signature += ")"
return signature

def _generate_mini_instancemethod_signature(self):
"""Returns the method signature for the problem, in the form
<name>(<name>, <name>, ...)
e.g. MyFunc(A, B)
"""
signature = "%s(self, " % self['definition']['method']
signature += ", ".join([str(x) for x in self['definition']['names']['input']])
signature += ")"
return signature

def _generate_mini_class_name(self):
"""Returns the class name for the problem
"""
classname = "%s" % self['definition']['class']
return classname

def _generate_filled_signature(self, inputs = None, output = None):
"""Returns the method signature for the problem with the given inputs
and output, in the form
Expand All @@ -124,7 +154,7 @@ def _generate_filled_signature(self, inputs = None, output = None):
Similarly, if no input is given, only adds the equals sign and the part
after it."""
signature = ""

# add inputs
if inputs != None:
signature += "%s(" % self['definition']['method']
Expand Down Expand Up @@ -268,13 +298,16 @@ def test_method(self, method):
def to_python(self, template = PYTHON_TEMPLATE):
"""Returns a Python file, with the method header, according to the
specified python template."""
return PYTHON_TEMPLATE % self._generate_mini_signature()
classname = self._generate_mini_class_name()
method_sig = self._generate_mini_instancemethod_signature()
return template % (classname, classname, classname, method_sig)

def to_python_file(self, filename, template = PYTHON_TEMPLATE):
def to_python_file(self, filename, template_name = "method"):
"""Saves Python text to a file, with the method header, according to the
specified python template."""
template_map = {"method":PYTHON_TEMPLATE, "class":PYTHON_CLASS_TEMPLATE}
python_file = open(filename, 'w')
python_file.write(self.to_python())
python_file.write(self.to_python(template_map[template_name]))
python_file.close()

# json output #
Expand Down
14 changes: 9 additions & 5 deletions topcoder/ProblemFolder.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def add_problem(self, problem, force = False):

# check if python file exists: if it doesn't, create it
if force or not os.access(python_path, os.F_OK):
problem.to_python_file(python_path)
problem.to_python_file(python_path, "class")

# create init file, if it doesn't exist
if force or not os.access(init_path, os.F_OK):
Expand All @@ -136,7 +136,7 @@ def del_problem(self, problem):

return len(problems_to_delete)

def test_problems(self, problems):
def test_problems(self, problems, template_type="class"):
"""Given a list of problem tuples (rel_path, number, name), runs the tests
for each problem.
Uses the method provided in the Python file in the problem directory."""
Expand All @@ -152,13 +152,17 @@ def test_problems(self, problems):
python_file = open(python_filename, 'rU')
exec python_file in ns
python_file.close()

# get method
method = ns[problem[P_PROBLEM_DEFINITION]['method']]
if template_type == "class":
cls = ns[problem[P_PROBLEM_DEFINITION]['class']]
method = getattr(cls(), problem[P_PROBLEM_DEFINITION]['method'])
elif template_type == "method":
method = ns[problem[P_PROBLEM_DEFINITION]['method']]

# run tests
problem.test_method(method)

def clean(self):
"""Refreshes and re-scans the directory for problems, as well as re-creating missing files.
The difference between this and __init__ is that this removes all directories that contain
Expand Down
2 changes: 1 addition & 1 deletion topcoder/scraper.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def get_topcoder_problem_ids(opener, n, end = None):
if args.test:
# test specified problems
for n in problem_input:
folder.test_problems(folder.find_problem(number = n))
folder.test_problems(folder.find_problem(number = n), template_type="class")

else:
# connect to TopCoder
Expand Down