((* macro expand_function(function_name, function_contents, x = "Function") *)) \texttt{((( tex_escape(function_name) )))}: ((* if function_contents["present"] *)) \begin{itemize} \item Arguments: \pyth{((( function_contents["arguments"] )))} \item Documentation: ((( len_documentation(function_contents["documentation"]["comments"], function_contents["documentation"]["doc"]) ))) characters long ((* if tex_show_full_docs == "True" *)) \textbf{Comments:} ((*- if function_contents["documentation"]["comments"] == "None" *)) \errortext{No comments present.} ((* else *)) \begin{lstlisting} ((( function_contents["documentation"]["comments"] ))) \end{lstlisting} ((* endif *)) \textbf{Docstring}: ((*- if function_contents["documentation"]["doc"] == "None" *)) \errortext{No docstring present.} ((* else *)) \begin{lstlisting} ((( function_contents["documentation"]["doc"] ))) \end{lstlisting} ((* endif *)) ((* endif *)) \item Code: ((( get_source_numlines(function_contents["source_code"]) ))) ((* if tex_show_source == "True" *)) \begin{python} ((( function_contents["source_code"] ))) \end{python} ((* endif *)) \end{itemize} ((* else *)) \errortext{((( x ))) \texttt{((( tex_escape(function_name) )))} not present.} ((* endif *)) ((* endmacro *)) \documentclass{article} \usepackage{python-latex-highlighting/pythonhighlight} \usepackage[margin=1in]{geometry} % margins \usepackage{multicol} % columns \usepackage{float} % layout \usepackage{forest} % for the class tree \usepackage{pdfpages} % for importing the test results pdf \usepackage{xcolor} % colours \usepackage{listings} \lstset{ basicstyle=\small\ttfamily, columns=flexible, breaklines=true } \newcommand{\errortext}[1]{\textcolor{red}{\textbf{#1}}} \author{((( student_no )))} \title{((( name ))) - Automatic marking report} \begin{document} ((* if tex_columns != "1" *)) \begin{multicols}{((( tex_columns )))} ((* endif *)) \maketitle \section{Class Tree} \begin{figure}[H] \centering \begin{forest} ((( recurse_class_tree_forest(class_tree)|indent(8, False) ))) \end{forest} \caption{Class inheritance tree} \end{figure} \section{File Analysis} ((* set flat_files = flatten_struct(files) *)) ((* for filename, files_contents in flat_files.items() *)) \subsection{\texttt{((( filename )))}} ((* if files_contents["present"] *)) ((* if files_contents["has_exception"] *)) \errortext{File cannot be run - has compile time exception.} Please note that this file cannot be analysed or have tests preformed upon it- this can lead to the whole test suite failing if another module imports this. \textbf{Exception Type:} \texttt{((( files_contents["exception"]["type"] )))} \textbf{Exception String:} \texttt{((( files_contents["exception"]["str"] )))} \textbf{Full Traceback:} \begin{lstlisting} ((( files_contents["exception"]["traceback"] ))) \end{lstlisting} ((* else *)) \begin{itemize} \item \textbf{Documentation:} ((( len_documentation(files_contents["documentation"]["comments"], files_contents["documentation"]["doc"]) ))) characters long ((* if tex_show_full_docs == "True" *)) \item \textbf{Comments:} ((*- if files_contents["documentation"]["comments"] == "None" *)) \errortext{No comments present.} ((* else *)) \begin{lstlisting} ((( files_contents["documentation"]["comments"] ))) \end{lstlisting} ((* endif *)) \item \textbf{Docstring:} ((*- if files_contents["documentation"]["doc"] == "None" *)) \errortext{No docstring present.} ((* else *)) \begin{lstlisting} ((( files_contents["documentation"]["doc"] ))) \end{lstlisting} ((* endif *)) ((* endif *)) \end{itemize} ((* if "classes" in files_contents.keys() *)) \subsubsection{Classes} ((* set flat_classes = flatten_struct(files_contents["classes"]) *)) ((* for class_name, class_contents in flat_classes.items() *)) \begin{itemize} \item \texttt{((( class_name )))}: ((* if class_contents["present"] *)) \begin{itemize} \item \textbf{Documentation:} ((( len_documentation(class_contents["documentation"]["comments"], class_contents["documentation"]["doc"]) ))) characters long ((* if tex_show_full_docs == "True" *)) \item \textbf{Comments:} ((* if class_contents["documentation"]["comments"] == "None" -*)) \errortext{No comments present.} ((* else *)) \begin{lstlisting} ((( class_contents["documentation"]["comments"] ))) \end{lstlisting} ((* endif *)) \item \textbf{Docstring:} ((* if class_contents["documentation"]["doc"] == "None" -*)) \errortext{No docstring present.} ((* else *)) \begin{lstlisting} ((( class_contents["documentation"]["doc"] ))) \end{lstlisting} ((* endif *)) ((* if "methods" in class_contents.keys() *)) \item \textbf{Methods:} ((* set flat_methods = flatten_struct(class_contents["methods"]) *)) \begin{itemize} ((* for method_name, method_contents in flat_methods.items() *)) \item ((( expand_function(method_name, method_contents, x = "Method") ))) ((* endfor *)) \end{itemize} ((* endif *)) \end{itemize} ((* endif *)) ((* else *)) \errortext{Class not present.} ((* endif *)) \end{itemize} ((* endfor *)) ((* endif *)) ((* if "functions" in files_contents.keys() *)) \subsubsection{Functions} ((* set flat_functions = flatten_struct(files_contents["functions"]) *)) \begin{itemize} ((* for function_name, function_contents in flat_functions.items() *)) \item ((( expand_function(function_name, function_contents) ))) ((* endfor *)) \end{itemize} ((* endif *)) \subsubsection{Runtime Analysis} ((* set flat_runtime = flatten_struct(files_contents["run"]) *)) \begin{itemize} ((* for cmd, runtime_contents in flat_runtime.items() *)) \item Command: \texttt{((( tex_escape(cmd) )))} \item Monitor: ((*- if "monitor" in runtime_contents.keys() *)) \texttt{((( tex_escape(runtime_contents["monitor"]) )))} ((*- else *)) stdout ((*- endif *)) \item Regexes: ((* for regex_, results in runtime_contents["regexes"].items() *)) \begin{itemize} \item \texttt{((( tex_escape(regex_) )))}: \begin{itemize} \item Found occurrences: ((( len_(results) ))) ((* if txt_show_all_regex_occurrences == "True" and len_(results) > 0 *)) \item Occurences list: \begin{enumerate} ((* for result in results *)) \item \texttt{((( tex_escape(result.replace("\n", "\\n")) )))} ((* endfor *)) \end{enumerate} ((* endif *)) \end{itemize} \end{itemize} ((*- endfor -*)) ((* endfor *)) \end{itemize} ((* endif *)) ((* else *)) \errortext{File is not present.} ((* endif *)) ((* endfor *)) \section{Tests} ((* if test_results["pytest_report"] == "*** No Tests ***" *)) No tests were executed. ((* else *)) \includepdf[pages={1-},scale=1.0]{((( junit_xml_to_html(test_results["junitxml"], student_no) )))} ((* endif *)) ((* if tex_columns != "1" *)) \end{multicols} ((* endif *)) \end{document}