{ "info": { "author": "Elmar Hinz", "author_email": "t3elmar@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Education", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 3", "Topic :: Education :: Computer Aided Instruction (CAI)" ], "description": "==================\nREADME: Challenges\n==================\n\nLibrary to assist programming, testing and execution of solutions for coding challenges like those on stepik.org or\nrosalind.info.\n\nFind the full documentation at Readthedocs_.\n\n.. _Readthedocs: http://challenges.readthedocs.io\n\n:State: beta\n:License: MIT\n:Author: Elmar Hinz\n:Repository: https://github.com/elmar-hinz/Python.Challenges\n:Documentation: http://challenges.readthedocs.io |badge|\n:Installation: https://pypi.org/project/challenges/\n\n.. |badge| image:: https://readthedocs.org/projects/challenges/badge/?version=latest\n :target: http://challenges.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\nHello world\n===========\n\n.. code-block:: python\n\n from challenges import Challenge\n\n class AddChallenge(Challenge):\n\n sample = '''\n 5, 6\n '''\n\n expect = '''\n 11\n '''\n\n def build(self):\n self.model = self.line_to_integers(0)\n\n def calc(self):\n self.result = self.model[0] + self.model[1]\n\n def format(self):\n self.output = str(self.result)\n\nThe class to write lets you focus on the core algorithms of the challenge while keeping stuff like opening, reading and\nwriting of files out of the way. You inherit several methods to set up the model or to format your result for writing.\n\nWhile the class attribute `sample` just holds a minimal example of the input, the actual input is later injected by\nthe **Challenge Runner** via the command line. In Bioinformatics this is often a large file of DNA.\n\n.. hint:: See a more verbose example of HelloWorld and other examples.\n\n * HelloWorldChallenge_\n * HelloWorldTest_\n * HelloFastaChallenge_\n * HelloFastaTest_\n * HelloGraphChallenge_\n * HelloGraphTest_\n\n.. _HelloWorldChallenge: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloWorld/challenge.py\n.. _HelloWorldTest: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloWorld/test.py\n.. _HelloFastaChallenge: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloFasta/challenge.py\n.. _HelloFastaTest: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloFasta/test.py\n.. _HelloGraphChallenge: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloGraph/challenge.py\n.. _HelloGraphTest: https://github.com/elmar-hinz/Python.Challenges/blob/master/HelloGraph/test.py\n\nFeatures\n========\n\n * listing available challenges\n * scaffolding a new challenge directory with a challenge class and a unit test class\n * executing the `sample` from the sample class attribute\n * reading input files from the command line\n * output formatted result on the command line\n * writing `sample.txt` and matching `result.txt` into the challenges directory\n * running the unit test case of a challenge\n * reading lines with integers\n * reading lines with floats\n * reading lines with words\n * reading fasta input\n\nDirectory layout\n================\n\nLets call the base directory of your challenges project `myChallenges/`. Name it however you like.\n\n.. code-block:: bash\n\n myChallenges/\n Challenge1/__init__.py\n Challenge1/challenge.py\n Challenge1/test.py\n Challenge2/__init__.py\n Challenge2/challenge.py\n Challenge2/test.py\n ... more challenges ...\n\nThe names `Challenge1` and `Challenge2` are just placeholders for the names you choose during scaffolding.\n\n.. hint::\n\n The files `__init__.py` are empty. They help unittest tools like *nosetest* to locate the files.\n\nChallenge runner\n================\n\n.. important::\n\n Always move into the base directory to use the **Challenge Runner**.\n\nList the available challenges\n-----------------------------\n\n.. code-block:: bash\n\n prompt> challenge --list\n * Challenge1\n * Challenge2\n * ...\n\nScaffolding a new challenge\n---------------------------\n\n.. code-block:: bash\n\n prompt> challenge --scaffold Challenge3\n\nYou now find the files:\n\n.. code-block:: bash\n\n myChallenges/\n Challenge3/__init__.py\n Challenge3/challenge.py\n Challenge3/test.py\n\nCheck it's working by running the unit test case.\n\n.. code-block:: bash\n\n prompt> challenge --unittest Challenge3\n .sss.\n ----------------------------------------------------------------------\n Ran 5 tests in 0.006s\n\n OK (skipped=3)\n\n\nRun from the class file\n--------------------------------\n\nThis is the small sample directly coded into the challenge class.\n\n.. code-block:: bash\n\n prompt> challenge --klass Challenge1\n [the result output goes here]\n\n.. hint::\n\n You will automatically find the latest output in two files, independent from the input method you choose.\n\n .. code-block:: bash\n\n myChallenges/Challenge1/latest.txt\n myChallenges/latest.txt\n\n These files are just for convenience and are overwritten by the next run.\n\n\nRead sample from an input file\n------------------------------\n\n.. code-block:: bash\n\n prompt> challenge Challenge1 --file ~/Downloads/data.txt\n [the result output goes here]\n\nStoring data and results\n------------------------\n\nDid you pass the challenge? Was the online grader content with the upload of `latest.txt`? Then you should store data\nand result.\n\n.. code-block:: bash\n\n prompt> challenge Challenge1 --file ~/Downloads/data.txt --write\n\nYou will find the files:\n\n.. code-block:: bash\n\n myChallenges/Challenge1/sample.txt\n myChallenges/Challenge1/result.txt\n\nThis files are stored until the next run with the `--write` flag.\n\nHelp\n----\n\nTo quickly see all available options.\n\n.. code-block:: bash\n\n challenge --help\n\n.. tip::\n\n For every double dashed option there is a single dashed one letter shortcut. Help lists them all.\n\n prompt> challenge Challenge1 --scaffold\n prompt> challenge Challenge1 -s\n\n.. tip::\n\n You can palce the dashed options behind the name of the challenge. This makes it easy to exchange them.\n Practical usage may look like this.\n\n .. code-block:: bash\n\n prompt> challenge ExampleProblem -s\n prompt> challenge ExampleProblem -u\n prompt> challenge ExampleProblem -k\n prompt> challenge ExampleProblem -f ~/Downloads/data.txt\n prompt> challenge ExampleProblem -f ~/Downloads/data.txt -w\n\n\nNaming conventions\n==================\n\nThe naming conventions follow the standards as defined by `PEP 8`_ **Style Guide for Python Code**\n\n.. _`PEP 8`: https://www.python.org/dev/peps/pep-0008/\n\nThere are two deliberate exceptions:\n\n1. Challenge module names are **CamelCase**:\n\n In contradiction to the style guide directories of the challenges are not all lowercase. Especially the\n first character must be uppercase. This is used to find and list the challenge directories between other modules.\n If the name of your challenge is **ExampleProblem** then this are the required names:\n\n :directory: ``ExampleProblem/``\n :challenge file: ``ExampleProblem/challenge.py``\n :unittest file: ``ExampleProblem/test.py``\n :full qualified challenge class: ``ExampleProblem.challenge.ExampleProblemChallenge``\n :full qualified test class: ``ExampleProblem.test.ExampleProblemTest``\n\n This is automatically wired up during scaffolding.\n\n Abbreviations or codes like on Rosalind_ may be all uppercase or camelcase, ``RSUB`` or ``Rsub``.\n\n2. Inherited class attributes and methods don't have a leading underscore:\n\n The inherited functions and methods of the challenge are not a public API and the style guides recommends leading\n underscores. As inheritance is a core concept of the challenge class, this would lead to a hell of leading\n underscores. For this reason we don't follow the style guide in this recommendation.\n\n .. _Rosalind: http://rosalind.info\n\n.. tip::\n\n One useful advantage of naming the directory just like your challenge is, that you can use the path expansion\n mechanism of the shell. Write the first characters of the directory name and hit . Now you can use the\n directory name as name of the challenge. A trailing slash is discarded. The following two inputs are equivalent.\n\n .. code-block:: bash\n\n prompt> challenge -k ExampleProblem\n prompt> challenge -k ExampleProblem/\n\nInstallation\n============\n\n.. important::\n\n This software requires Python 3.\n\nClone from Github\n-----------------\n\nYou can clone (or download) the Challenges project directly from Github. In this case the scripts and paths are not\nconfigured globally. Either you configure it globally or you place your challenges immediately into the projects folder\nso that the paths are detected relatively.\n\nPut your challenges immediately into the projects folder\n........................................................\n\nThis is the most simple setup to get started. After downloading change into the download folder an try to run the\n`HelloWorld` unit test. In this case the command is in the `bin` directory, you call it as `bin/challenge`.\n\n.. code-block:: bash\n\n prompt> bin/challenge --unittest HelloWorld\n ...\n ----------------------------------------------------------------------\n Ran 3 tests in 0.001s\n\n OK\n\nNow you are ready to create your challenge side-by-side with the `HelloWorld` challenge.\n\n.. code-block:: bash\n\n prompt> bin/challenge --scaffold MyChallenge\n\nUse to install \n---------------------------------\n\nIf you have a fully configured python 3 environment up and running you can install with pip3.\n\n.. code-block:: bash\n\n prompt> pip3 search challenges\n prompt> pip3 install challenges\n\nThe library will be included into the python class path. The runner will be globally available as `challenge`,\nalternatively as `stepik` or `rosalind`.\n\n.. code-block:: bash\n\n prompt> challenge --version\n challenge 0.8.0\n\n prompt> stepik --version\n stepik 0.8.0\n\n prompt> rosalind --version\n rosalind 0.8.0", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/elmar-hinz/Python.Challenges", "keywords": "education challenges bioinformatics Coursera Stepik Rosalind", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "challenges", "package_url": "https://pypi.org/project/challenges/", "platform": "", "project_url": "https://pypi.org/project/challenges/", "project_urls": { "Homepage": "https://github.com/elmar-hinz/Python.Challenges" }, "release_url": "https://pypi.org/project/challenges/1.4.0/", "requires_dist": null, "requires_python": "", "summary": "Library to assist programming, testing and execution of solutions for coding challenges like those on stepik.org orrosalind.info", "version": "1.4.0" }, "last_serial": 3512271, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "15c49138b9b100c01fef25c3f1a54f8a", "sha256": "074b7566a12c7d29ab78241f97a6b027a1a7d16e569f7c7fe4486280647388aa" }, "downloads": -1, "filename": "challenges-0.1.2.tar.gz", "has_sig": false, "md5_digest": "15c49138b9b100c01fef25c3f1a54f8a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 410377, "upload_time": "2017-03-08T16:24:17", "url": "https://files.pythonhosted.org/packages/06/85/73a9dfc3b318a83301f2c0cc75fd841c2af052e3df9583927f37f82e8adb/challenges-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "2ad8cd5d195a04f28b6455415cbbd5f9", "sha256": "afee1c82a312ba455add5b7ee3f166089921e6f9dbe513d881d8e5250efe964c" }, "downloads": -1, "filename": "challenges-0.1.3.tar.gz", "has_sig": false, "md5_digest": "2ad8cd5d195a04f28b6455415cbbd5f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 410500, "upload_time": "2017-03-08T16:44:27", "url": "https://files.pythonhosted.org/packages/9d/ff/5a687d741a6d266438fcbb82fbea59d44c044d6e2df01b8ff0723cc6bc72/challenges-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "fc94e3f007dd00429ab10a96afd934fe", "sha256": "5747a69f92d13670da6bf8eec344a5ce26ec3e70f9e9346664633dc27944533b" }, "downloads": -1, "filename": "challenges-0.1.4.tar.gz", "has_sig": false, "md5_digest": "fc94e3f007dd00429ab10a96afd934fe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 467789, "upload_time": "2017-03-08T20:53:35", "url": "https://files.pythonhosted.org/packages/4d/6b/e880c3d3b517dbe2dafa13cb1eba78702a953a8e8e43877e6f07353a34f9/challenges-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "70b1fb37fa473e905e7a37491ce1bda4", "sha256": "cad316a4d48e841fbfcf314826b68698cb0ae33a6a88d8207daf6765ec20ba12" }, "downloads": -1, "filename": "challenges-0.1.5.tar.gz", "has_sig": false, "md5_digest": "70b1fb37fa473e905e7a37491ce1bda4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 470737, "upload_time": "2017-03-08T21:57:30", "url": "https://files.pythonhosted.org/packages/17/8b/ce089cadbd8e8463d6c04ea5a6cee7afbf7afa753ab8cab65a478e32ba71/challenges-0.1.5.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "913f2c8485c3d462bac9f619458f750e", "sha256": "26aa896b3fd21ffb947e29b345808f510c0e53296b4c4e9a82bde48fe0e26af0" }, "downloads": -1, "filename": "challenges-0.2.0.tar.gz", "has_sig": false, "md5_digest": "913f2c8485c3d462bac9f619458f750e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 476069, "upload_time": "2017-03-09T17:07:40", "url": "https://files.pythonhosted.org/packages/4c/70/f13a3d6df7a805beea584ac134a1fe0b44f88927437e5ed672e578b07635/challenges-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "ff59d102fc4f78915d507d501bdc79e1", "sha256": "8881cf883c2ebce9dc18e76f25fefe5975ef5278501f841918b2504af9edf7bb" }, "downloads": -1, "filename": "challenges-0.3.0.tar.gz", "has_sig": false, "md5_digest": "ff59d102fc4f78915d507d501bdc79e1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 493785, "upload_time": "2017-03-09T21:05:55", "url": "https://files.pythonhosted.org/packages/a4/0e/3cec02627916eddaa6ca1381d73bdaa98b3863ea50121c579f6e8b4fbbc1/challenges-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "55328531bcc5e702246d117248a6d52d", "sha256": "00b375d863c8e3e086aa121e30959d6c0243437302361030ec0c29a905cd01b5" }, "downloads": -1, "filename": "challenges-0.4.0.tar.gz", "has_sig": false, "md5_digest": "55328531bcc5e702246d117248a6d52d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 463229, "upload_time": "2017-03-10T17:05:17", "url": "https://files.pythonhosted.org/packages/e1/2f/e00dd10524d347673e576eba63367c1c120f39c8a2a2af6fe56f15a1744f/challenges-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "8a05e48554a5178f1dfda10eed142d8d", "sha256": "59c5c5bac3479a32b70a11ef95da136c2ddd750497faa0b2eeabe4e8b74750fd" }, "downloads": -1, "filename": "challenges-0.5.0.tar.gz", "has_sig": false, "md5_digest": "8a05e48554a5178f1dfda10eed142d8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 488918, "upload_time": "2017-03-13T20:23:36", "url": "https://files.pythonhosted.org/packages/de/a0/785ba7cca28bc340fcc88e3f68a831d4a80f79c8ee76085ce31980d4bf06/challenges-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "46d4cba2b72b26dea1884759da061da2", "sha256": "809726097768bd59b4694dd2ebf38a300b40d707990f291ca69c202a0f3caeeb" }, "downloads": -1, "filename": "challenges-0.6.0.tar.gz", "has_sig": false, "md5_digest": "46d4cba2b72b26dea1884759da061da2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 498144, "upload_time": "2017-03-23T07:55:43", "url": "https://files.pythonhosted.org/packages/32/cc/fd2fcbd35facfe895d5f29b1bd7e86b3b76aff794f20201710bd47b8f34d/challenges-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "55f98f87809d2daa77122115eb38fbca", "sha256": "5a85dd2ae3d251218af4fd20c087ef6f2204c126f0752e3072aaa90b8b83f29a" }, "downloads": -1, "filename": "challenges-0.6.1.tar.gz", "has_sig": false, "md5_digest": "55f98f87809d2daa77122115eb38fbca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 510238, "upload_time": "2018-01-15T20:28:06", "url": "https://files.pythonhosted.org/packages/4b/e2/0f0acedb29d6a5172c877edf4926ab917840cb08fcf7a2a01fc8aed505a4/challenges-0.6.1.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "a634bf5b8c8a56bea0570709f7ba6747", "sha256": "db296860ca9108d2b9a4d2c5d5d4e8ab1f5a09cbe8bdefccffd2beb0907c761f" }, "downloads": -1, "filename": "challenges-0.7.0.tar.gz", "has_sig": false, "md5_digest": "a634bf5b8c8a56bea0570709f7ba6747", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 498202, "upload_time": "2018-01-16T10:50:18", "url": "https://files.pythonhosted.org/packages/c8/b0/374953db4574f2c8267eb90d48163e438f0db4eb6d02dea59b23a1a0775d/challenges-0.7.0.tar.gz" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "e3b58f6e294d8b1044b1905601c19a8b", "sha256": "4d9ca32fecea7ca1153b0c7996096d2ae575a0cd3d9b95001c27fa981a3b15ee" }, "downloads": -1, "filename": "challenges-0.7.1.tar.gz", "has_sig": false, "md5_digest": "e3b58f6e294d8b1044b1905601c19a8b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 498885, "upload_time": "2018-01-16T11:22:18", "url": "https://files.pythonhosted.org/packages/47/bf/c66a8f4a1b0f79625770014d6a5578ccffbc5d90b2139716863f43beac7a/challenges-0.7.1.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "183e6ccb74d51a7d6c8383bf3ac190cf", "sha256": "056761d4885c4c9cfabedc1449f033dff0c83e7442687adefa87026586eac1cb" }, "downloads": -1, "filename": "challenges-1.0.0.tar.gz", "has_sig": false, "md5_digest": "183e6ccb74d51a7d6c8383bf3ac190cf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 523411, "upload_time": "2018-01-16T15:26:15", "url": "https://files.pythonhosted.org/packages/26/8a/a991c7d124540b07a6e1325a92bd238259321dc1aa9932d8b6663770a26b/challenges-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "f9f8792d8621ab322a1fd516d797117d", "sha256": "1db5346590d3851c44d07d1c7d1a7e48e16f5dbfc0b0ca394466e452fe804cdb" }, "downloads": -1, "filename": "challenges-1.1.0.tar.gz", "has_sig": false, "md5_digest": "f9f8792d8621ab322a1fd516d797117d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 528818, "upload_time": "2018-01-19T13:31:46", "url": "https://files.pythonhosted.org/packages/c3/e8/b473b98a85af1380dd32e1b3bc454c77e39bda3540d90429e16ed1d7a339/challenges-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "1072bf86474e61888519e05c054902cd", "sha256": "ff915053f2bdd610290fc5e0759b3a69223eaabb95bc24e6ed62cd42abead706" }, "downloads": -1, "filename": "challenges-1.2.0.tar.gz", "has_sig": false, "md5_digest": "1072bf86474e61888519e05c054902cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 530032, "upload_time": "2018-01-20T15:33:48", "url": "https://files.pythonhosted.org/packages/85/91/0c8ee1e075e92c516927dbd759f67ce6992cda7f5e2e2609d7586f1e0840/challenges-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "13c16da8008d4b4a657f3534c4cee1fb", "sha256": "0102bfccbe1b27f1398bff4cbf0d2e05f3accd5d1450feb158e411a9d83b88f5" }, "downloads": -1, "filename": "challenges-1.2.1.tar.gz", "has_sig": false, "md5_digest": "13c16da8008d4b4a657f3534c4cee1fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 530564, "upload_time": "2018-01-20T15:55:26", "url": "https://files.pythonhosted.org/packages/20/44/b111fd8753661ad05f1ce98223ef1655c6925454790f3841ee9137cfc6b6/challenges-1.2.1.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "0604483dd52ad59378cc2132403118f4", "sha256": "b13e38baae060594d8c80649a2a2ef90ec0237c7f749b6c18a4b6eca0808599b" }, "downloads": -1, "filename": "challenges-1.3.0.tar.gz", "has_sig": false, "md5_digest": "0604483dd52ad59378cc2132403118f4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 533720, "upload_time": "2018-01-20T19:40:32", "url": "https://files.pythonhosted.org/packages/d6/bc/468a27ff4cc0cd2741d8efd76948388e0a5c4f3f22de23e4ca96c7370199/challenges-1.3.0.tar.gz" } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "f8a5bbdc512937a0b89a197749926d62", "sha256": "9fcf619050087006a7b469ef139a279d0dc6c6f2dcb1adfde145ac89bea89b65" }, "downloads": -1, "filename": "challenges-1.4.0.tar.gz", "has_sig": false, "md5_digest": "f8a5bbdc512937a0b89a197749926d62", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 555018, "upload_time": "2018-01-22T20:35:49", "url": "https://files.pythonhosted.org/packages/70/63/97d697d1cb9e92acb8ddc9061024f4b295450281972797a0a1188987d4bc/challenges-1.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f8a5bbdc512937a0b89a197749926d62", "sha256": "9fcf619050087006a7b469ef139a279d0dc6c6f2dcb1adfde145ac89bea89b65" }, "downloads": -1, "filename": "challenges-1.4.0.tar.gz", "has_sig": false, "md5_digest": "f8a5bbdc512937a0b89a197749926d62", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 555018, "upload_time": "2018-01-22T20:35:49", "url": "https://files.pythonhosted.org/packages/70/63/97d697d1cb9e92acb8ddc9061024f4b295450281972797a0a1188987d4bc/challenges-1.4.0.tar.gz" } ] }