def check_files_exist(*files, **extra): """ Checks to see if the given files provided as arguments exist. They must be files as defined by `os.path.isfile() <http://docs.python.org/2/library/os.path.html#os.path.isfile>`_. :param \*files: The files to check for existance. Note this is not a list, rather you should pass in each file as a seperate arugment. See the examples below. :param \*\*extra: extra parameters. If extra["basename"] is True, then os.path.basename is applied to all filenames before printing. :returns: Returns a TestResult object that will be passing iff *all* of the files exist. .. code-block:: python # The current directory contains only a main.cpp file. >>> print check_files_exist("main.cpp", "foo.cpp", "foo.h") Score: 0 out of 1 This test ensures that all of the necessary files are present. * You are missing foo.cpp and foo.h. *(Note that this function really does return a TestResult object, but TestResult.__str__() which transforms the TestResult into a string that can be printed formats it specially as seen above)* """ if extra.get("basename", False): missing_files = [os.path.basename(i) for i in files if not os.path.isfile(i)] else: missing_files = [i for i in files if not os.path.isfile(i)] result = core.TestResult( brief="This test ensures that all of the necessary files are " "present.", default_message="Great job! All the necessary files are present.", ) if missing_files: result.add_message( core.TestResult.Message( "You are missing {missing_files_}.", missing_files_=pretty.pretty_list(missing_files), missing_files=missing_files, dscore=-1, type="interact/filesexist/basic_files_exist", ) ) result.set_passing(False) else: result.set_passing(True) return result
def check_indentation(files, max_score=10, allow_negative=False): """ Checks to see if code is indented properly. Currently code is indented properly iff every block of code is indented strictly more than its parent block. :param files: A list of file paths that will each be opened and examined. :param max_score: For every improperly indented line of code, a point is taken off from the total score. The total score starts at ``max_score``. :param allow_negative: If True, a negative total score will be possible, if False, 0 will be the lowest score possible. :returns: A ``TestResult`` object. .. code-block:: python >>> print open("main.cpp").read() #include <iostream> using namespace std; int main() { if (true) { foo(); } else { dothings(); while (false) { dootherthings(); } cout << "{}{}{{{{{}}}{}{}{}}}}}}}}{{{{"<< endl; } return 0; } >>> print open("foo.cpp").read() #include <iostream> using namespace std; int main() { return 0; } >>> print check_indentation(["main.cpp", "foo.cpp"]) Score: 6 out of 10 This test checks to ensure you are indenting properly. Make sure that every time you start a new block (curly braces delimit blocks) you indent more. * Lines 14, 13, and 10 in main.cpp are not indented more than the outer block. * Line 5 in foo.cpp is not indented more than the outer block. """ result = core.TestResult( brief="This test checks to ensure you are indenting properly. Make " "sure that every time you start a new block (curly braces " "delimit blocks) you indent more.", default_message="**Great job!** We didn't find any problems with " "your indentation!", max_score=max_score, ) for current_file in files: with open(current_file) as f: code = f.read() if code == "": continue # Transform tjhe code into a list of Line objects lines = parse.Line.make_lines(code.splitlines()) # Break the code up into blocks. blocks = parse.grab_blocks(lines) # Get a list of all the badly indented lines. problems = parse.find_bad_indentation(blocks) if problems: result.add_message( core.TestResult.Message( "{lines_} {line_numbers_} in {file_name} {are_} not indented more " "than the outer block.", line_numbers_=pretty.pretty_list(sorted([i.line_number for i in problems], reverse=True)), are_="are" if len(problems) > 1 else "is", lines_=pretty.plural_if("Line", len(problems)), lines=problems, file_name=current_file, dscore=-len(problems), type="interact/indentation/basic_indent_level", ) ) # The score is just the sum of the dscores for each message plus the max # score (since dscores are negative this makes sense). score = max_score + sum(i.dscore for i in result.messages) if not allow_negative: score = max(0, score) result.score = score return result