-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c10bf64
commit a54cbf7
Showing
46 changed files
with
4,224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Python Algorithm Task Generator | ||
|
||
This python program generates tasks written in LaTeX (in englisch and german) for various algorithms. Most algorithms are based upon Cormen, Leiserson, Rivest, Stein. Introduction to Algorithms 4ed. 2022. MIT Press. Its aim is to provide students learning these algorithms a way to execute them on different inputs and to ease the work on creating such exercises for educators, as it is often required for undergraduate algorithm courses. | ||
|
||
## Requirements | ||
- [python 3.8+](https://www.python.org) | ||
- [pyaml](https://pypi.org/project/pyaml/) (for reading localisation files) | ||
- [pylatex](https://pypi.org/project/PyLaTeX/) (for generating LaTeX code) | ||
- [latexmk](https://ctan.org/pkg/latexmk) (for compiling LaTeX code) | ||
|
||
## How to Run | ||
Download the latest release, extract the files and execute python on the folder, e.g. | ||
|
||
python3 pyAlgoTask TASK_CATEGORY TASK [optional Arguments] | ||
|
||
Please not that you need to give at least the task category, the task and a file location for the exercise or for the solutuion for the program to do anything. | ||
|
||
Alternatively you can locally install the program using | ||
|
||
pip install ./pyAlgoTask | ||
|
||
and using | ||
|
||
pyAlgoTask TASK_CATEGORY TASK [optional Arguments] | ||
|
||
in the commandline. | ||
|
||
## How to Use | ||
We specify ever task in a category. We currently support the following categories and tasks: | ||
|
||
- Sorting | ||
- Bubblesort | ||
- Bucketsort (on numbers between 0 and 1) | ||
- Countingsort | ||
- Heapsort | ||
- Insertionsort | ||
- Mergesort | ||
- Quicksort with Lomutos partition scheme | ||
- Quicksort with Hoares partition scheme | ||
- Radixsort (on non-negative numbers) | ||
- Selectionsort | ||
|
||
- Hashing | ||
- Closed Hashing using double hashing | ||
- Closed Hashing using linear probing | ||
- Closed Hashing using quadratic probing | ||
- Open Hashing | ||
|
||
with the hash functions: | ||
- Divison method (modulo table size) | ||
- Multiplication method (scaling to table size) | ||
- Bit-shift method | ||
|
||
All tasks currently support only LaTeX output. You need to provide a file to write the source code into using parameters `-e` for exercise and `-s` for solution. Additionally you may use `--pdf` and `--view` to generate a pdf and directly view the pdf in a viewer respectively. | ||
|
||
Generally, for input the parameters `-i` are used for commandline input and `-f` for file input. The syntax of the input is explained in the help files for each task. If no input is given, a random input is generated with certain heuristical bounds. | ||
|
||
Further customization is possible and explained in the help for each task. | ||
|
||
## Project Structure | ||
This project is structured in five parts, the [Main part](#main-part), the [Tasks](#tasks), the [Inpud modules](#input), the [Randomizer modules](#randomizer) and the [Output modules](#output). Additionally, we use unittesting with [pytest](https://pytest.org/). | ||
|
||
### Main part | ||
The main class `src/pyAlgoTask/__man__` deals with reading the parser and calling all other modules. This includes error handling, to call the exporter `src/pyAlgoTask/export` for file export and allowing all tasks to register themself using the module `src/pyAlgoTask/tasks/tasks.py` and their argument parsers. Most modules have the possibility to register parser options themself (using [argparse](https://docs.python.org/3/library/argparse.html)) and to parse the parameter themself. | ||
|
||
### Tasks | ||
The folder `src/pyAlgoTask/tasks` contain one folder for each category, containing one file per task classes. Tasks classes handle the algorithm to generate a task for and the various modules surrounding this task. Theses are especially [Input Modules](#Input), [Randomizer Modules](#Randomizer), the language pick module `src/pyAlgoTask/language.py` and various data structures or wrapper classes from `src/pyAlgoTask/structures.py`. | ||
|
||
#### Algorithm Method | ||
The algorithm is implemented as a generator `def algorithm(self): ... `, that yields intermediate steps are required by the task. Usually, the generator yields a tuple, where the first entry is the actual output and the second are highlighting information, if used. The generator is called by the [Output Module](#Output) when the exercise and solution code is generated. | ||
|
||
### Input | ||
This module has various classes for handling various input types, e.g. arrays for sorting or insert/delete operations for data structures. They are generally assumes to register arguments to [argparse](https://docs.python.org/3/library/argparse.html) and to read them from argparse. | ||
|
||
### Randomizer | ||
Generally, every Input module also has a Randomizer module to generate a certain random input for in case no input was given. This design follows the parser-randomizer dualism. | ||
|
||
### Output | ||
Output modules are used to generate LaTeX code for certain types of tasks. Since tasks are rather diverse, so are their respective output modules. Generally speaking, the exercise file contains first some text, usually consisting of a pretext, the input for the algorithm, followed by a posttext. Lastly space for entering the solution is given. The space is roughly oriented on the solution, but sometimes a bit more space is given (i.e. for open hashing we offer sufficient place to insert every item at one position) | ||
|
||
### Testing | ||
The module `tests/...` offer various testing classes using [pytest](https://pytest.org/) with [mock](https://docs.python.org/3/library/unittest.mock.html). We use one testing file per category, where we try to test all algorithms in the same class similarly or even the same to enforce uniformity. | ||
|
||
### Documentation | ||
Documentation is designed for pydoctor using the command | ||
|
||
pydoctor --make-html --html-output=docs/api --docformat=restructuredtext src/pyalgotask | ||
|
||
in the root directory | ||
|
||
## How to Contribute | ||
Please open an issue if you found bugs or have feature requests. The feature requests may be added to the TODO file in this repository. | ||
|
||
If you would like to contribute code, please use the following tools: | ||
|
||
* pylint | ||
* black formatter | ||
* pydoctor | ||
* pytest | ||
|
||
And open an pull request detailing your contribution. | ||
|
||
## Credits | ||
This tool is developed by: | ||
* Ira Fesefedt | ||
|
||
## License | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2023 Ira Fesefeldt | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
this software and associated documentation files (the "Software"), to deal in | ||
the Software without restriction, including without limitation the rights to | ||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
the Software, and to permit persons to whom the Software is furnished to do so, | ||
subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
[project] | ||
name = "pyalgotask" | ||
version = "0.1.0" | ||
description = "Generates tasks for executing algorithms to better understand their innerworkings, as often used in algorithm classes." | ||
authors = [ | ||
{name = "Ira Fesefeldt", email="[email protected]"} | ||
] | ||
maintainers = [ | ||
{name = "Ira Fesefeldt", email="[email protected]"} | ||
] | ||
license = {file = "LICENSE.txt"} | ||
readme = "README.md" | ||
requires-python = ">=3.8" | ||
|
||
keywords = ["algorithm", "education", "tasks"] | ||
|
||
classifiers = [ | ||
"Development Status :: 2 - Pre-Alpha", | ||
"Private :: Do Not Upload", | ||
"Environment :: Console", | ||
"Natural Language :: English", | ||
"Topic :: Education :: Computer Aided Instruction (CAI)", | ||
"Programming Language :: Python :: 3", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.9", | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Programming Language :: Python :: 3 :: Only", | ||
] | ||
|
||
# Requirements: This is done differently by poetry! | ||
dependencies = [ | ||
"PyLaTeX", | ||
"pyaml" | ||
] | ||
|
||
#[project.urls] | ||
#homepage = "" | ||
#documentation = "" | ||
#repository = "" | ||
|
||
[project.scripts] | ||
pyAlgoTask = "pyalgotask.__main__:main" | ||
|
||
[tool.pytask.ini_options] | ||
paths = "src/pyalgotask" | ||
pythonpath = "src" | ||
|
||
[build-system] | ||
requires = ["setuptools"] | ||
build-backend = "setuptools.build_meta" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Content of setup.cfg | ||
|
||
[metadata] | ||
name = pyalgotask | ||
version = 0.1.0 | ||
|
||
[options] | ||
packages = find: | ||
package_dir = | ||
=src | ||
|
||
[options.packages.find] | ||
where = src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""A module to generate tasks for various algorithms and datastructures""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
"""Main module for pyAlgoTask handling calling other classes and the general work flow.""" | ||
import argparse | ||
import sys | ||
import logging | ||
|
||
import pyalgotask.__meta as meta | ||
import pyalgotask.__settings as settings | ||
import pyalgotask.tasks.task_base as task_base | ||
|
||
from pyalgotask.export import Exporter | ||
|
||
# let every task register itself | ||
import pyalgotask.tasks # pylint: disable=unused-import | ||
|
||
|
||
logging.basicConfig(level=settings.LOGGING_LEVEL) | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def main(): | ||
"""Main method of the algorithm and is called when executing the program on the folder.""" | ||
|
||
# create argument parser | ||
logger.debug("Creating argument parser.") | ||
parser = argparse.ArgumentParser( | ||
prog="pyAlgoEx", | ||
description="Generates exercises for your typical algorithms course.", | ||
epilog=( | ||
"Choose an algorithm for which an exercise is generated.\n" | ||
"If you choose no input method, a random input will be generated.\n" | ||
"If you choose no output file path, the generated files will not be written anywhere." | ||
), | ||
) | ||
parser.add_argument( | ||
"-v", | ||
"--version", | ||
action="version", | ||
version=f"%(prog)s {meta.__version__}", | ||
) | ||
|
||
exporter = Exporter() | ||
subparser = parser.add_subparsers(title="Task categories", dest="cat") | ||
subparser.metavar = "" | ||
cat_parsers = {} | ||
|
||
for cat in task_base.category_iterator(): | ||
(help_string, description) = task_base.get_category_info(cat) | ||
cat_parser = subparser.add_parser( | ||
cat, help=help_string, description=description | ||
) | ||
cat_parsers[cat] = cat_parser | ||
cat_subparser = cat_parser.add_subparsers(dest="cmd") | ||
for this_task in task_base.task_iterator(cat): | ||
task_parser = cat_subparser.add_parser( | ||
this_task.cmd_info.cmd, | ||
help=this_task.cmd_info.help, | ||
description=this_task.cmd_info.description, | ||
) | ||
exporter.init_parser(task_parser) | ||
this_task.init_argument_parser(task_parser) | ||
|
||
# parse arguments | ||
logger.debug("Argument parser working.") | ||
try: | ||
args = parser.parse_args() | ||
except ValueError as exception: | ||
parser.error(exception) | ||
|
||
# send help if no arguments present | ||
if len(sys.argv) == 1: | ||
parser.print_help() | ||
sys.exit() | ||
|
||
if not args.cat: | ||
parser.error("No category given!") | ||
|
||
if not args.cmd: | ||
cat_parsers[args.cat].print_help() | ||
sys.exit() | ||
|
||
# get requested task | ||
this_task = task_base.get_task_by_cmd(args.cat, args.cmd) | ||
logger.debug("Selected task: %s %s", args.cat, args.cmd) | ||
|
||
# parse arguments for task | ||
try: | ||
exporter.parse(args) | ||
this_task.parse(args) | ||
except ValueError as exception: | ||
parser.error(str(exception)) | ||
logger.debug("Arguments parsed by task %s.", this_task.cmd_info.cmd) | ||
|
||
# write exercise to file | ||
logger.debug("Writing exercise.") | ||
try: | ||
exporter.write_exercise(this_task) | ||
except ValueError as exception: | ||
parser.error(str(exception)) | ||
|
||
# write solution to file | ||
logger.debug("Writing solution.") | ||
try: | ||
exporter.write_solution(this_task) | ||
except ValueError as exception: | ||
parser.error(str(exception)) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
"""Various metadatas of this software.""" | ||
|
||
__author__ = "Ira Fesefeldt" | ||
__credits__ = ["Ira Fesefeldt"] | ||
__copyright__ = "Copyright 2023" | ||
|
||
__license__ = "MIT" | ||
__version__ = "0.1" | ||
__maintainer__ = "Ira Fesefeldt" | ||
__email__ = "[email protected]" | ||
__status__ = "Pre-Alpha" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
"""File for settings used by this program""" | ||
import logging | ||
|
||
LOGGING_LEVEL = logging.ERROR | ||
|
||
LANGUAGE = "deDE" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
"""Various exceptions used in this software""" | ||
|
||
|
||
class WrongParameterError(Exception): | ||
"""If the parameter from cli did not matched the expected side conditions""" |
Oops, something went wrong.