{"id":14981033,"url":"https://github.com/robbert-harms/ybe","last_synced_at":"2025-10-10T09:07:04.940Z","repository":{"id":62590525,"uuid":"266551860","full_name":"robbert-harms/ybe","owner":"robbert-harms","description":"Yaml Based Exams","archived":false,"fork":false,"pushed_at":"2021-04-23T16:13:53.000Z","size":840,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-02T17:56:41.342Z","etag":null,"topics":["assessment","exams","exams-management-system","latex","markdown","plain-text","qti","yaml"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robbert-harms.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-24T13:56:38.000Z","updated_at":"2024-06-10T16:50:43.000Z","dependencies_parsed_at":"2022-11-03T17:57:04.422Z","dependency_job_id":null,"html_url":"https://github.com/robbert-harms/ybe","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/robbert-harms/ybe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robbert-harms%2Fybe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robbert-harms%2Fybe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robbert-harms%2Fybe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robbert-harms%2Fybe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robbert-harms","download_url":"https://codeload.github.com/robbert-harms/ybe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robbert-harms%2Fybe/sbom","scorecard":{"id":779800,"data":{"date":"2025-08-18","repo":{"name":"github.com/robbert-harms/ybe","commit":"d3f676afa5232a080889fef3a6624f03527ea854"},"scorecard":{"version":"v5.2.1-41-g40576783","commit":"40576783fda6698350fcbbeaea760ff827433034"},"score":1.7,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"23 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2019-217 / GHSA-462w-v97r-4m45","Warn: Project is vulnerable to: PYSEC-2014-8 / GHSA-8r7q-cvjq-x353","Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: PYSEC-2014-82 / GHSA-fqh9-2qgg-h84h","Warn: Project is vulnerable to: PYSEC-2021-66 / GHSA-g3rq-g295-4j3m","Warn: Project is vulnerable to: GHSA-h5c8-rqwp-cp95","Warn: Project is vulnerable to: GHSA-h75v-3vvj-5mfj","Warn: Project is vulnerable to: PYSEC-2019-220 / GHSA-hj2j-77xm-mc5v","Warn: Project is vulnerable to: GHSA-q2x7-8rv6-6q7h","Warn: Project is vulnerable to: GHSA-55x5-fj6c-h6m8","Warn: Project is vulnerable to: PYSEC-2014-9 / GHSA-57qw-cc2g-pv5p","Warn: Project is vulnerable to: PYSEC-2021-19 / GHSA-jq4v-f5q6-mjqq","Warn: Project is vulnerable to: GHSA-pgww-xf46-h92r","Warn: Project is vulnerable to: PYSEC-2022-230 / GHSA-wrxv-2j5q-m38w","Warn: Project is vulnerable to: PYSEC-2018-12 / GHSA-xp26-p53h-6h2p","Warn: Project is vulnerable to: PYSEC-2021-856 / GHSA-5545-2q6w-2gh6","Warn: Project is vulnerable to: PYSEC-2021-854 / GHSA-6p56-wp2h-9hxr","Warn: Project is vulnerable to: PYSEC-2019-108 / GHSA-9fq2-x9r6-wfmf","Warn: Project is vulnerable to: PYSEC-2021-857 / GHSA-f7c7-j99h-c22f","Warn: Project is vulnerable to: PYSEC-2021-855 / GHSA-fpfv-jqm9-f5jm","Warn: Project is vulnerable to: PYSEC-2017-1 / GHSA-frgw-fgh6-9g52","Warn: Project is vulnerable to: PYSEC-2023-102","Warn: Project is vulnerable to: PYSEC-2023-114"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T04:38:21.354Z","repository_id":62590525,"created_at":"2025-08-23T04:38:21.354Z","updated_at":"2025-08-23T04:38:21.354Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279003390,"owners_count":26083579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assessment","exams","exams-management-system","latex","markdown","plain-text","qti","yaml"],"created_at":"2024-09-24T14:02:46.178Z","updated_at":"2025-10-10T09:07:04.919Z","avatar_url":"https://github.com/robbert-harms.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"######################\nYBE - Yaml Based Exams\n######################\nYbe is a software package supporting a `YAML \u003chttps://en.wikipedia.org/wiki/YAML\u003e`_ based file format for importing,\nexporting and storing exams in a plain text file. It supports multiple-choice, multiple-response and essay questions.\nDue to the extensive meta-data storage, storing exams in ybe allows you to easily search, annotate and recombine questions into new exams.\nExams can be written as a LaTeX file, or be exported to the QTI format and be imported by Canvas and other educational software.\n\n********\nExamples\n********\nQuestions can be stored in a plain text file using `YAML \u003chttps://en.wikipedia.org/wiki/YAML\u003e`_ for structure and\n`Markdown \u003chttps://en.wikipedia.org/wiki/Markdown\u003e`_ , HTML or plain text, for the content of the questions.\n\n\nMinimal .ybe file\n=================\n\nFor example, a minimal example of a multiple choice question is given by:\n\n.. code-block:: yaml\n\n    ybe_version: 0.2.0\n\n    questions:\n    - multiple_choice:\n        id: q1\n        title: Optional title\n        points: 1\n        text: !markdown Example *multiple* choice question.\n        answers:\n            - answer:\n                text: First answer\n            - answer:\n                text: Second answer\n                correct: true\n\n\nThis defines a list of questions with only one question. The ``id`` is meant to be provide\na unique identifier to every question and should be unique for every question in an .ybe file.\nThe points define the worth of the question.\nBy prefixing the text with ``!markdown`` we indicate that that the text is in Markdown format\nand as such allows all Markdown operators.\nThe answers are not prefixed with ``!markdown`` making them plain text.\nThe item ``correct`` marks the correct answer.\n\n\nExporting to QTI\n================\nIf you would copy the previous Ybe content into a text file named ``example.ybe``, you could export it to a QTI using:\n\n.. code-block:: python\n\n    from ybe import read_ybe_file, YbeToQTI_v1p2\n\n    ybe_exam = read_ybe_file('example.ybe')\n\n    # QTI v1.2 for use in Canvas\n    YbeToQTI_v1p2(convert_canvas_equations=True).convert(ybe_exam, 'qti_canvas.zip')\n\n\nExporting to other formats\n==========================\nAlternatively, you could export your Ybe exam file to other formats like Latex, Markdown, HTML or Docx/ODT:\n\n.. code-block:: python\n\n    from ybe import read_ybe_file, \\\n        YbeToLatex, YbeToMarkdown, YbeToDocx, YbeToODT, YbeToHTML\n\n    ybe_exam = read_ybe_file('example.ybe')\n\n    YbeToLatex().convert(ybe_exam, '/tmp/ybe/latex/main.tex', copy_resources=True)\n    YbeToMarkdown().convert(ybe_exam, '/tmp/ybe/markdown/main.md', copy_resources=True)\n    YbeToHTML().convert(ybe_exam, '/tmp/ybe/html/main.html', copy_resources=True)\n    YbeToDocx().convert(ybe_exam, '/tmp/ybe/main.docx')\n    YbeToODT().convert(ybe_exam, '/tmp/ybe/main.odt')\n\n\nThis compiles all your questions in a single Latex, Markdown, HTML or docx/odt file for printing or further processing.\nFor technical minded people, this uses a Jinja2 templating system which can be fully adapted for your specific needs.\n\n\nSupported question types\n========================\nYbe supports multiple choice, multiple response, text-only and open/essay questions.\nAn example of an ybe file with all supported questions and some file meta data is given by:\n\n.. code-block:: yaml\n\n    ybe_version: 0.2.0\n\n    info:\n        title: Example questions\n        description: Example of all questions.\n        document_version: 0.1.0\n        date: 2020-05-24\n        authors:\n            - The Author\n\n    questions:\n    - multiple_choice:\n        id: q1\n        title: Questions can have a title\n        points: 1\n        text: Example multiple choice question.\n        answers:\n            - answer:\n                text: First answer\n            - answer:\n                text: Second answer\n                correct: true\n        feedback:\n            general: Here's the explanation for\n                    the correct and incorrect\n                    answer (or \"general comments\")\n            on_correct: Here's the explanation for\n                        the correct answer.\n            on_incorrect: Here's the explanation\n                          for the incorrect answer.\n\n    - open:\n        id: q2\n        points: 3\n        text: Example open question.\n\n    - multiple_response:\n        id: q3\n        points: 2\n        text: !html A multiple response \u003cb\u003equestion\u003cb/\u003e is a\n            multiple choice question, where\n            multiple answers are possible.\n        answers:\n            - answer:\n                text: First answer\n                correct: true\n                hint: Multiple choice/response answers\n                      can have hints.\n            - answer:\n                text: Second answer\n                hint: This is not correct!\n            - answer:\n                text: Third answer\n                correct: true\n            - answer:\n                text: Fourth answer\n\n    - text_only:\n        id: q4\n        text: !markdown |-\n            This text is prefixed with !markdown, meaning you can\n            use Markdown syntax to markup your document.\n\n            For example:\n\n            1. this is a list\n            2. *with this in italics*\n            3. **and in bold**\n\n            This is a famous formula inline: $E=mc^2$\n            and this is a basic displayed formula:\n\n            $$ a^2 = b^2 + c^2 $$\n\n\nSupport for hints and explanations\n==================================\nYbe supports comments to the answer of a question by means of ``hints`` and ``explanations``.\nExplanations can be added to any question and allow commenting on the provided answer.\nHints are meant as a comment to a selected multiple choice or multiple response answer.\nIn Ybe, these can be added as follows:\n\n.. code-block:: yaml\n\n    questions:\n    - multiple_choice:\n        id: q1\n        points: 1\n        text: Example multiple choice question.\n        answers:\n            - answer:\n                text: First answer\n                hint: This is the wrong answer\n            - answer:\n                text: Second answer\n                correct: true\n                hint: This is the correct answer\n        feedback:\n            general: General comment after finishing the question.\n            on_correct: Here's the explanation for the correct answer.\n            on_incorrect: Here's the explanation for the incorrect answer.\n\n\nThat is, every ``answer`` can contain a ``hint``, and every ``question`` can contain a ``feedback`` element.\nWhat to do with this information is application dependent.\n\n\nAdding meta-data\n================\nIn addition, Ybe supports adding meta-data to your questions.\nA full example of all the available meta-data options is given below.\nNot all the options need to be used, one can leave one or more out if not needed.\nA full example:\n\n.. code-block:: yaml\n\n    questions:\n    - open:\n        id: q5\n        points: 1\n        text: Example with meta data\n        meta_data:\n            general:\n                description: Some description\n                keywords: [alpha, beta]\n                language: en\n                creation_date: 2020-05-29\n                authors:\n                    - John Doe\n                module: Science\n                chapters:\n                    - Some book, ed. 2, ch. 1\n                    - Some book, ed. 3, ch. 2\n                skill_type: Knowledge\n                difficulty: 1\n            analytics:\n                - exam:\n                    name: 2020_qz1\n                    participants: 1\n                    nmr_correct: 0\n                - exam:\n                    name: 2020_qz1\n                    participants: 200\n                    nmr_correct: 25\n\n\nSearching your questions\n========================\nIf you would save the above in a file ``example.ybe``, you could then search through the questions easily.\nFor example, finding all questions that yield exactly one point can be done like:\n\n.. code-block:: python\n\n    from ybe import read_ybe_file\n\n    ybe_exam = read_ybe_file('example.ybe')\n\n    for question in ybe_exam.questions:\n        if question.points == 1:\n            print(question)\n\n\n\nImporting from QTI\n==================\nIf you already have questions in `Canvas \u003chttps://canvas.instructure.com\u003e`_ or other software packages, you can export\nthese to QTI file and convert those into an .ybe file:\n\n.. code-block:: python\n\n    from ybe import read_qti_zip, write_ybe_file\n    from ybe.lib.utils import copy_ybe_resources\n\n    ybe_exam = read_qti_zip('qti_file.zip')\n\n    # write the ybe file and the resources (images)\n    write_ybe_file(ybe_exam, './qti_to_ybe.ybe', copy_resources=True)\n\n\n*******\nSummary\n*******\nIn general:\n\n* Storing exams in a plain-text ``.ybe`` file\n* Importing and exporting to and from QTI\n* Write exams to LaTeX\n* API for scripting exams\n\nTechnical details:\n\n* Free software: GPL v3 license\n* Full documentation: https://ybe.readthedocs.io\n* Project home: https://github.com/robbert-harms/ybe\n\n\n************************\nQuick installation guide\n************************\nYbe requires Python 3.8+. Either use your package manager, or install a Python distribution like `Anaconda \u003chttps://www.anaconda.com/distribution/\u003e`_.\nAfter that it is typically as simple as:\n\n.. code-block:: bash\n\n    pip install ybe\n\n\n**Linux**\n\nFor Ubuntu 18.xx you need to install Python 3.8 first, for example see here: https://linuxize.com/post/how-to-install-python-3-8-on-ubuntu-18-04/.\nAfterwards, simply install using:\n\n.. code-block:: bash\n\n    pip3 install ybe\n\nFor other Linux distributions the setup is typically similar, install Python 3.8 and then install ybe.\n\n**Windows**\n\n* Install Anaconda Python 3.8\n* Open an Anaconda shell and type: ``pip install ybe``\n\n\n**Mac**\n\n* Install Anaconda Python 3.8\n* Open an Anaconda shell and type: ``pip install ybe``\n\n\n************\nContributors\n************\n* Software by Dr. Harms\n* Commissioned by Asst.Prof.Dr.Ir. S. Schoenmakers, Eindhoven University.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobbert-harms%2Fybe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobbert-harms%2Fybe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobbert-harms%2Fybe/lists"}