{ "info": { "author": "Chris Pyles", "author_email": "cpyles@berkeley.edu", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# Multiple Choice Autograder\n\n [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/chrispyles/mcautograder/master?filepath=demo/mcautograder-demo.ipynb)\n\nThis repository contains a small Python-based multiple-choice question autograder inteded for use in Jupyter Notebooks. It is meant to be packaged with each assignment so that they are easier for use on third-party servers, e.g. MyBinder.\n\n## Installation\n\nYou can install `mcautograder` using pip.\n\n```bash\npip install mcautograder\n```\n\n## Usage\n\nTo use the autograder, import the `mcautograder` package and make sure to your [tests file](#tests) is in the same directory as your notebook. When you load the notebook dependencies, import the file and initialize the grader by creating an instance of the `Notebook` class:\n\n```python\nimport mcautograder\ngrader = mcautograder.Notebook()\n```\n\n**The autpgrader automatically assumes that the tests file is stored as `\"./.tests.py\"`.** More details [below](#tests).\n\nIf you want the autograder to score the questions, make sure to set `scored=True` in your `Notebook` call. **The default behavior of the autograder is to allow students to submit answers until they get the correct one.** If you want to change this behavior, you must set the `max_attempts` argument to an integer, the maximum number of retakes allowed. If this is the case, when students hit that ceiling, the check cells will throw an `AssertionError` because they've hit the retake ceiling.\n\nAn example call for a scored notebook with a retake ceiling of 5 is given below.\n\n```python\ngrader = Notebook(scored=True, max_attempts=5)\n```\n\nTo use the autograder to check answers, have students assign their answers to variables in the notebook; these answers can strings of length 1 or single-digit integers. Then call the `Notebook.check()` function; the first argument should be the question identifier in your tests file and the second should be the variable the student created.\n\n```python\nmy_answer = \"A\"\ngrader.check(\"q1\", my_answer)\n```\n\nIf the student's response matches the test file, then `Correct.` will be printed; otherwise, `Try again.` will be printed. If the student enters an invalid response (e.g. `float`, answer of > 1 character, hit retake ceiling), the grader will throw an `AssertionError` with a descriptive message.\n\nTo get the score on a scored autograder, simply call `Notebook.score()`:\n\n```python\ngrader.score()\n```\n\nThe output will contain the fraction of earned points out of possible points and the percentage.\n\nFor a more descriptive introduction to the autograder, launch our [Binder](https://mybinder.org/v2/gh/chrispyles/mcautograder/master?filepath=demo/mcautograder-demo.ipynb).\n\n
\n\n## Tests\n\nThe autograder relies on a tests file to get the answers for the questions. In this repo, the file is `tests.py` and it is public; in practice, I usually distribute the answers as a hidden file, `.tests.py`. It is unhidden here so that you can peruse its structure and contents.\n\nThe `Notebook` constructor by default assumes that your tests are in the file `.tests.py`. If you have a different preferred location, you can pass the path to the file by setting the `tests` argument of the constructor:\n\n```python\ngrader = Notebook(tests=SOME_OTHER_PATH)\n```\n\nIn the file, we define a variable `answers` which is a list containing dictionaries, each of which represents a single question. Each dictionary should contain 3 keys: `\"identifier\"`, `\"answer\"`, and, optionally, `\"points\"`. If your assignment is unscored, you can leave off the `\"points\"` key. A description of the keys' values is given below:\n\n| Key | Value Type | Value Description |\n|-----|-----|-----|\n| `\"identifier\"` | `str` | a unique question identifier |\n| `\"answer\"` | `str`, `int` | the answer to the question; specifications below |\n| `\"points\"` | `int` | optional; the number of points assigned to that question |\n\nAnswers **must** be of length 1 (i.e. a single-character string or a single-digit integer). The autograder is currently set up to throw an `AssertionError` if an answer of length > 1 is submitted, although we do intend to add this functionality later.\n\nAn example of a file is given below.\n\n```python\nanswers = [\n\t{\n\t\t\"identifier\": \"q1\",\n\t\t\"answer\": 3,\n\t\t\"points\": 1,\n\t}, {\n\t\t\"identifier\": \"q2\",\n\t\t\"answer\": 2,\n\t\t\"points\": 2,\n\t}, {\n\t\t\"identifier\": \"q3\",\n\t\t\"answer\": \"D\",\n\t\t\"points\": 3,\n\t}\n]\n```\n\nThe identifiers have no set format. This is because the identifier is passed to `Notebook.check()` when you call it in the notebook.\n\n## Branches\n\nThe `master` branch contains the current state of `mcautograder` as it is hosted on PyPI. The `dev` branch contains the next version of `mcautograder` in development. _Do not commit directly to the `master` branch._ Make commits in the `dev` branch and then PR to the `master` branch before uploading to PyPI.\n\n## Changelog\n\n**v0.0.6:**\n\n* Added state serialization to prevent dead kernels from resetting notebooks\n* Added `\".tests.py\"` as default argument value for `Notebook` constructor\n* Added `AssertionError` for scored notebooks with 0 points\n* Added try/except statement for scored notebook identifiers without `\"points\"` key\n\n**v0.0.5:**\n\n* Changed `mcautograder.py` to `notebook.py` for less confusion\n* Changed `max_retakes` param to `max_attempts` for better understanding\n* Upadted docstring format for sphinx autodoc\n* Added license field for setuptools\n\n**v0.0.4:**\n\n* Moved utils to separate file for documentation\n\n**v0.0.3:**\n\n* Changed structure of tests file to be more intuitive\n* Added docstrings and better documentation\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/chrispyles/mcautograder", "keywords": "", "license": "BSD-3-Clause", "maintainer": "", "maintainer_email": "", "name": "mcautograder", "package_url": "https://pypi.org/project/mcautograder/", "platform": "", "project_url": "https://pypi.org/project/mcautograder/", "project_urls": { "Homepage": "https://github.com/chrispyles/mcautograder" }, "release_url": "https://pypi.org/project/mcautograder/0.0.6/", "requires_dist": null, "requires_python": "", "summary": "Small multiple choice question autograding library", "version": "0.0.6" }, "last_serial": 5705027, "releases": { "0.0.2": [ { "comment_text": "", "digests": { "md5": "cc97444a4990b36a7d864397ede8353a", "sha256": "921a4134df9f6ff3ea923d619c7b258609e9f6cba55604fc3c5ae2eb2989aaf8" }, "downloads": -1, "filename": "mcautograder-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "cc97444a4990b36a7d864397ede8353a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5149, "upload_time": "2019-06-25T00:20:37", "url": "https://files.pythonhosted.org/packages/ad/b1/d8cdc445df956730f13f9d06b4035a073e86b9c31e360f75460a549a41a8/mcautograder-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c57f9d8b90725781a7774121ee9fa55d", "sha256": "463efd6a0da5bffbc4b7fc160eb569ba1f9fee551e1561c9c4f87cae96f88b0e" }, "downloads": -1, "filename": "mcautograder-0.0.2.tar.gz", "has_sig": false, "md5_digest": "c57f9d8b90725781a7774121ee9fa55d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3710, "upload_time": "2019-06-25T00:20:39", "url": "https://files.pythonhosted.org/packages/6b/2e/9f18ca85a43a8e26488bd1dd959948c14e48457201f06ca55a542b943d29/mcautograder-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "8faf3c4bcaf7c16c267158ec93d54dd2", "sha256": "516be8ae9c1f3b665f2ff25528e435da04e3b6fa2679636ad54f5e6234534132" }, "downloads": -1, "filename": "mcautograder-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "8faf3c4bcaf7c16c267158ec93d54dd2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5708, "upload_time": "2019-06-26T02:55:24", "url": "https://files.pythonhosted.org/packages/aa/f0/f9e9cb319f310a794dd8bb07bbcd607105345e94e76ca31759748f89f90b/mcautograder-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b99f48da3c7a211839c5e8dbc1a2a656", "sha256": "c3b5b9fa5007ba4e8943bb371902a69de26bc31b213d88f3d2b244d3cbd5ad72" }, "downloads": -1, "filename": "mcautograder-0.0.3.tar.gz", "has_sig": false, "md5_digest": "b99f48da3c7a211839c5e8dbc1a2a656", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4407, "upload_time": "2019-06-26T02:55:25", "url": "https://files.pythonhosted.org/packages/83/d0/459d4a418725d7764c91601e2c7493d241742a9331a2aeab03ab6a0f8bc1/mcautograder-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "457302b02ab5325dd0ca2174beb08a52", "sha256": "95deb3bdc765601a510458ed764f93bad1f42b979c56143f3475d0803d0b3478" }, "downloads": -1, "filename": "mcautograder-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "457302b02ab5325dd0ca2174beb08a52", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5974, "upload_time": "2019-06-26T04:18:09", "url": "https://files.pythonhosted.org/packages/14/18/cfafd2b9f9012832e04f177cefd0cc67d4241a04899a20e8deb9e6d4f564/mcautograder-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c8b47f5e8648ba3d06c1e79ae158421e", "sha256": "311e822c101ae0254696bb025c88b7aae959f0f91a1e4517017a869e25e38d4f" }, "downloads": -1, "filename": "mcautograder-0.0.4.tar.gz", "has_sig": false, "md5_digest": "c8b47f5e8648ba3d06c1e79ae158421e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4474, "upload_time": "2019-06-26T04:18:11", "url": "https://files.pythonhosted.org/packages/80/e0/5c4f3b4011a94256217238883a1ce85d2e21a06191b37bd55af17482d19e/mcautograder-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "8075fb4bb34f5f327b83699897168a92", "sha256": "051b77183c860765c8a5cc71a362290a19dcf32e2dc82ae0fa901640a454a1c5" }, "downloads": -1, "filename": "mcautograder-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "8075fb4bb34f5f327b83699897168a92", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7570, "upload_time": "2019-06-28T05:32:31", "url": "https://files.pythonhosted.org/packages/89/14/bd9d4f56bbbdb0f6c77055f8e3e70ece6d0cef2d7071351668a3e2a2f16c/mcautograder-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4ec009096b4933224e15702c32ff7a88", "sha256": "a2f06fbc7a93e47dedc542395393ca4a212316a06d6f2bcb9b4ec4366abdbdf2" }, "downloads": -1, "filename": "mcautograder-0.0.5.tar.gz", "has_sig": false, "md5_digest": "4ec009096b4933224e15702c32ff7a88", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4688, "upload_time": "2019-06-28T05:32:32", "url": "https://files.pythonhosted.org/packages/70/8a/d025ddcd9acbbdad97d91583c06bfbd31521ca0a664c304fad3b11dfde4e/mcautograder-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "16f5bc003634348337648f538ac941f8", "sha256": "6fb59e45e144ee7b11383cdb5045b79c2e6036a1785549ec26f21664ee349291" }, "downloads": -1, "filename": "mcautograder-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "16f5bc003634348337648f538ac941f8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6954, "upload_time": "2019-08-20T18:56:01", "url": "https://files.pythonhosted.org/packages/53/c4/d2431555f0663f853eaa02084495af485ac9c586e30e8cf0b32a4b485ff5/mcautograder-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "09d72d6ac5af71060ff82dc0c86cf45b", "sha256": "7e911513646a99edeb28535170dab0c797cf6d2971ffc79f47fb0deba03e3369" }, "downloads": -1, "filename": "mcautograder-0.0.6.tar.gz", "has_sig": false, "md5_digest": "09d72d6ac5af71060ff82dc0c86cf45b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5420, "upload_time": "2019-08-20T18:56:03", "url": "https://files.pythonhosted.org/packages/d1/e5/bd5102dd17d7302705dc94d7491cd657b7db4d438544a18cc157ed5628be/mcautograder-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "16f5bc003634348337648f538ac941f8", "sha256": "6fb59e45e144ee7b11383cdb5045b79c2e6036a1785549ec26f21664ee349291" }, "downloads": -1, "filename": "mcautograder-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "16f5bc003634348337648f538ac941f8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6954, "upload_time": "2019-08-20T18:56:01", "url": "https://files.pythonhosted.org/packages/53/c4/d2431555f0663f853eaa02084495af485ac9c586e30e8cf0b32a4b485ff5/mcautograder-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "09d72d6ac5af71060ff82dc0c86cf45b", "sha256": "7e911513646a99edeb28535170dab0c797cf6d2971ffc79f47fb0deba03e3369" }, "downloads": -1, "filename": "mcautograder-0.0.6.tar.gz", "has_sig": false, "md5_digest": "09d72d6ac5af71060ff82dc0c86cf45b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5420, "upload_time": "2019-08-20T18:56:03", "url": "https://files.pythonhosted.org/packages/d1/e5/bd5102dd17d7302705dc94d7491cd657b7db4d438544a18cc157ed5628be/mcautograder-0.0.6.tar.gz" } ] }