def process(
    hw_num: int,
    problems_to_do: Optional[Iterable[int]] = None,
    prefix: Optional[Path] = None,
    by_hand: Optional[Iterable[int]] = None,
) -> None:
    """Process the homework problems in ``prefix`` folder.

    Arguments
    ---------
    hw_num
        The number of this homework
    problems_to_do, optional
        A list of the problems to be processed
    prefix, optional
        A `~pathlib.Path` to this homework assignment folder
    by_hand, optional
        A list of the problems that should be labeled to be completed
        by hand and have an image with the solution included.

    """
    if prefix is None:
        prefix = Path(".")

    problems: Iterable[Path]

    if problems_to_do is None:
        # The glob syntax here means a the filename must start with
        # homework-, be followed the homework number, followed by a
        # dash, then a digit representing the problem number for this
        # homework number, then any number of characters (in practice
        # either nothing or, rarely, another digit), then the ipynb
        # extension. Examples:
        # homework-1-1.ipynb, homework-10-1.ipynb, homework-3-10.ipynb
        problems = list(prefix.glob(f"homework-{hw_num}-[0-9]*.ipynb"))
    else:
        problems = [prefix / f"homework-{hw_num}-{i}.ipynb" for i in problems_to_do]

    problems = sorted(problems, key=lambda k: k.stem[-1])

    output_directory: Path = (prefix / "output").resolve()
    fw = FilesWriter(build_directory=str(output_directory))

    assignment_zip_name = output_directory / f"homework-{hw_num}.zip"
    solution_zip_name = output_directory / f"homework-{hw_num}-soln.zip"

    assignment_pdfs: List[BytesIO] = []
    solution_pdfs: List[BytesIO] = []

    assignment_pdf: bytes
    solution_pdf: bytes
    assignment_nb: str
    solution_nb: str

    res: Dict[str, Union[str, bool]] = {
        "delete_pymarkdown": True,
        "global_content_filter": {"include_raw": False},
    }

    for problem in problems:
        print("Working on:", problem)
        res["unique_key"] = problem.stem
        problem_number = int(problem.stem.split("-")[-1])
        if by_hand is not None and problem_number in by_hand:
            res["by_hand"] = True
        else:
            res["by_hand"] = False
        problem_fname = str(problem.resolve())

        # Process assignments
        res["remove_solution"] = True
        assignment_pdf, _ = pdf_exp.from_filename(problem_fname, resources=res)
        assignment_pdfs.append(BytesIO(assignment_pdf))

        assignment_nb, _ = nb_exp.from_filename(problem_fname, resources=res)
        with ZipFile(assignment_zip_name, mode="a") as zip_file:
            zip_file.writestr(problem.name, assignment_nb)

        # Process solutions
        res["remove_solution"] = False
        solution_pdf, _ = pdf_exp.from_filename(problem_fname, resources=res)
        solution_pdfs.append(BytesIO(solution_pdf))

        solution_nb, _ = nb_exp.from_filename(problem_fname, resources=res)
        with ZipFile(solution_zip_name, mode="a") as zip_file:
            zip_file.writestr(problem.stem + "-soln" + problem.suffix, solution_nb)

    resources: Dict[str, Any] = {
        "metadata": {
            "name": f"homework-{hw_num}",
            "path": str(prefix),
            "modified_date": date.today().strftime("%B %d, %Y"),
        },
        "output_extension": ".pdf",
    }
    fw.write(combine_pdf_as_bytes(assignment_pdfs), resources, f"homework-{hw_num}")

    resources["metadata"]["name"] = f"homework-{hw_num}-soln"
    fw.write(combine_pdf_as_bytes(solution_pdfs), resources, f"homework-{hw_num}-soln")
def process ( hw_num : int , problems_to_do : Optional [ Iterable [ int ] ] = None , prefix : Optional [ Path ] = None , by_hand : Optional [ Iterable [ int ] ] = None , ) -> None : if prefix is None : prefix = Path ( "." ) problems : Iterable [ Path ] if problems_to_do is None : problems = list ( prefix . glob ( f"homework-{hw_num}-[0-9]*.ipynb" ) ) else : problems = [ prefix / f"homework-{hw_num}-{i}.ipynb" for i in problems_to_do ] problems = sorted ( problems , key = lambda k : k . stem [ - 1 ] ) output_directory : Path = ( prefix / "output" ) . resolve ( ) fw = FilesWriter ( build_directory = str ( output_directory ) ) assignment_zip_name = output_directory / f"homework-{hw_num}.zip" solution_zip_name = output_directory / f"homework-{hw_num}-soln.zip" assignment_pdfs : List [ BytesIO ] = [ ] solution_pdfs : List [ BytesIO ] = [ ] assignment_pdf : bytes solution_pdf : bytes assignment_nb : str solution_nb : str res : Dict [ str , Union [ str , bool ] ] = { "delete_pymarkdown" : True , "global_content_filter" : { "include_raw" : False } , } for problem in problems : print ( "Working on:" , problem ) res [ "unique_key" ] = problem . stem problem_number = int ( problem . stem . split ( "-" ) [ - 1 ] ) if by_hand is not None and problem_number in by_hand : res [ "by_hand" ] = True else : res [ "by_hand" ] = False problem_fname = str ( problem . resolve ( ) ) res [ "remove_solution" ] = True assignment_pdf , _ = pdf_exp . from_filename ( problem_fname , resources = res ) assignment_pdfs . append ( BytesIO ( assignment_pdf ) ) assignment_nb , _ = nb_exp . from_filename ( problem_fname , resources = res ) with ZipFile ( assignment_zip_name , mode = "a" ) as zip_file : zip_file . writestr ( problem . name , assignment_nb ) res [ "remove_solution" ] = False solution_pdf , _ = pdf_exp . from_filename ( problem_fname , resources = res ) solution_pdfs . append ( BytesIO ( solution_pdf ) ) solution_nb , _ = nb_exp . from_filename ( problem_fname , resources = res ) with ZipFile ( solution_zip_name , mode = "a" ) as zip_file : zip_file . writestr ( problem . stem + "-soln" + problem . suffix , solution_nb ) resources : Dict [ str , Any ] = { "metadata" : { "name" : f"homework-{hw_num}" , "path" : str ( prefix ) , "modified_date" : date . today ( ) . strftime ( "%B %d, %Y" ) , } , "output_extension" : ".pdf" , } fw . write ( combine_pdf_as_bytes ( assignment_pdfs ) , resources , f"homework-{hw_num}" ) resources [ "metadata" ] [ "name" ] = f"homework-{hw_num}-soln" fw . write ( combine_pdf_as_bytes ( solution_pdfs ) , resources , f"homework-{hw_num}-soln" )
Process the homework problems in ``prefix`` folder.

    Arguments
    ---------
    hw_num
        The number of this homework
    problems_to_do, optional
        A list of the problems to be processed
    prefix, optional
        A `~pathlib.Path` to this homework assignment folder
    by_hand, optional
        A list of the problems that should be labeled to be completed
        by hand and have an image with the solution included.