{"id":40670084,"url":"https://github.com/ram6ler/ibdp_classes","last_synced_at":"2026-01-21T09:31:29.137Z","repository":{"id":62570118,"uuid":"409436179","full_name":"ram6ler/ibdp_classes","owner":"ram6ler","description":"A simple interpreter for playing around with pseudocode similar to that used in IBDP Computer Science exams. ","archived":false,"fork":false,"pushed_at":"2023-10-11T02:41:15.000Z","size":343,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2025-11-27T15:09:02.437Z","etag":null,"topics":["computer-science","ibdp","pseudocode","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ram6ler.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-09-23T03:36:36.000Z","updated_at":"2025-02-26T16:58:08.000Z","dependencies_parsed_at":"2023-10-11T04:48:17.193Z","dependency_job_id":null,"html_url":"https://github.com/ram6ler/ibdp_classes","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"2e8851d72adbc8a432f4e07febc606d0b37d79df"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ram6ler/ibdp_classes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ram6ler%2Fibdp_classes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ram6ler%2Fibdp_classes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ram6ler%2Fibdp_classes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ram6ler%2Fibdp_classes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ram6ler","download_url":"https://codeload.github.com/ram6ler/ibdp_classes/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ram6ler%2Fibdp_classes/sbom","scorecard":{"id":760562,"data":{"date":"2025-08-11","repo":{"name":"github.com/ram6ler/ibdp_classes","commit":"ee68e14b478bb48521fd8e7beb28e5d5d71b64c6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/18 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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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 'trunk'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-22T23:20:30.814Z","repository_id":62570118,"created_at":"2025-08-22T23:20:30.814Z","updated_at":"2025-08-22T23:20:30.814Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28631132,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["computer-science","ibdp","pseudocode","python"],"created_at":"2026-01-21T09:31:29.050Z","updated_at":"2026-01-21T09:31:29.114Z","avatar_url":"https://github.com/ram6ler.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IBDP Computer Science Pseudocode Classes\n\nThe IB Computer Science documents, *Approved notation for developing pseudocode* and *Pseudocode in Examinations*, describe pseudocode and a set of limited-functionality *array*, *collection*, *stack* and *queue* data structure classes that may come up and be used in exams.\n\nThis is a simple Python implementation of an IB pseudocode interpreter and the above restrictive classes, which can be used in programming activities to help familiarize students with the pseudocode and classes.\n\nUnder the hood, the classes are simple wrappers over a Python list and the interpreter simply runs some perfunctory tests, translates pseudocode into (really ugly) Python and then does its best to execute the translation and generate helpful error messages.\n\nYou can submit [issues and requests here](https://github.com/ram6ler/ibdp_classes/issues).\n\n## Install\n\n```text\npython -m pip install ibdp-classes\n````\n\n## Interpreting IB pseudocode\n\nWe can use the library to interpret pseudocode. For example:\n\n`example.pseudocode`\n\n```text\noutput \"Collection...\"\nITEMS = new Collection(1, 2, 3)\nITEMS.resetNext()\nloop while ITEMS.hasNext()\n    X = ITEMS.getNext()\n    output \"X =\", X\nend loop\n```\n\nAt the command line:\n\n```text\npython -m ibdp_classes example.pseudocode\n```\n\nOutput:\n\n```text\nCollection...\nX = 1\nX = 2\nX = 3\n```\n\nWe can also interpret IB pseudocode from within a Python script by creating and calling a `Pseudocode` instance. For example:\n\n```python\nimport ibdp_classes as ib\n\ncode = \"\"\"\noutput \"Array...\"\nXS = new Array(1, 2, 3, 4, 5)\nN = 5\nloop I from 0 to N - 1\n    output \"xs[\", I, \"] = \", XS[I]\nend loop\n\"\"\"\n\nscript = ib.Pseudocode(code)\noutput = script()\nprint(output)\n```\n\nOutput:\n\n```txt\nArray...\nxs[ 0 ] =  1\nxs[ 1 ] =  2\nxs[ 2 ] =  3\nxs[ 3 ] =  4\nxs[ 4 ] =  5\n```\n\n## Additions to IB pseudocode\n\n### `function` and `procedure`\n\nIn exams, IB pseudocode typically uses `output` to display results, and either doesn't explicitly define functions or procedures, or else does so informally and inconsistently. I have thus added `function` and `procedure` structures to the pseudocode definitions.\n\nFor example:\n\n```text\nfunction CONTAINS(NEEDLE, HAYSTACK, N)\n    // Where NEEDLE is a string, HAYSTACK is an Array\n    // of strings, and N is the length of HAYSTACK.\n    FOUND = false\n    loop K from 0 to N-1\n        if HAYSTACK[K] = NEEDLE then\n            FOUND = true\n        end if\n    end loop\n    return FOUND\nend function\n\nHAYSTACK = new Array(20, -3, 5, 7, 2, 13, 12, 19)\noutput \"HAYSTACK:\", HAYSTACK\n\noutput \"5 is in HAYSTACK?\"\noutput CONTAINS(5, HAYSTACK, 8)\n\noutput \"4 is in HAYSTACK?\"\noutput CONTAINS(4, HAYSTACK, 8)\n```\n\nOutput:\n\n```text\nHAYSTACK: Array { 20, -3, 5, 7, 2, 13, 12, 19 }\n5 is in HAYSTACK?\nTrue\n4 is in HAYSTACK?\nFalse\n```\n\n### Input types using `as`\n\nIn IBDP pseudocode, the keyword `input` is used to generically collect input from the user, and context is used to determine whether the input should be interpreted as a string, integer or floating point number. I have added `as int` and `as float` as appendages to the input statement for when we want to be explicit.\n\nFor example:\n\n```text\noutput \"Input an integer.\"\ninput COUNT as int\n\nif COUNT mod 2 = 0 then\n    output COUNT, \"is even...\"\nelse\n    output COUNT, \"is odd...\"\nend if\n```\n\n## Importing functionality\n\nIf we would like to give the pseudocode access to variables or functions defined in Python, we can pass the definitions as a dictionary when calling the `Pseudocode` instance:\n\n```python\nfrom random import random\nfrom math import floor\nimport ibdp_classes as ib\n\ncode = \"\"\"\nloop I from 1 to 10\n    output I, \":\", FLOOR(10 * RANDOM())\nend loop\n\"\"\"\n\nscript = ib.Pseudocode(code)\noutput = script({\"FLOOR\": floor, \"RANDOM\": random})\nprint(output)\n```\n\nExample output:\n\n```text\n1 : 5\n2 : 1\n3 : 9\n4 : 9\n5 : 7\n6 : 0\n7 : 4\n8 : 1\n9 : 7\n10 : 0\n```\n\nAlternatively, we can have the pseudocode in its own file and the definitions we want available in a separate Python file, and then set `-defs` to the name of the Python file when we interpret the pseudocode from the command line. For example:\n\n`defs.py`\n\n```python\nfrom random import random\nfrom math import floor\n\nRANDOM = random\nFLOOR = floor\n```\n\n`example.pseudo`\n\n```text\nloop I from 1 to 10\n    output I, \":\", FLOOR(10 * RANDOM())\nend loop\n```\n\nFrom the command line:\n\n```text\npython -m ibdp_classes -defs defs.py example.pseudo\n```\n\nExample output:\n\n```text\n1 : 5\n2 : 8\n3 : 4\n4 : 3\n5 : 1\n6 : 5\n7 : 3\n8 : 2\n9 : 3\n10 : 5\n```\n\n## Extensions\n\nIn addition to being able to add bespoke functionality using `-defs`, a few wrappers are available as extensions that are not defined by IB but that can be helpful in certain lesson scenarios. We can access these extensions using `-ext` and passing a string of extensions we would like to expose the pseudocode to.\n\nExtensions available:\n\n### `strings`\n\nThe `strings` extension exposes the following functions, which can helpful in activities involving string searches and manipulation.\n\n* `SUBSTRING(STRING, START, END)`\n\n  The substring of `STRING` starting at index `START` (inclusive) and ending at index `END` (exclusive).\n\n* `CHARACTER(STRING, INDEX)`\n\n  The character in `STRING` at index `INDEX`.\n\n* `UPPERCASE(STRING)` and `LOWERCASE(STRING)`\n\n  The uppercase and lowercase respectively of `STRING`.\n\n* `REPLACE(STRING, OLD, NEW)`\n\n  A copy of `STRING` with `OLD` replaced with `NEW`.\n\n* `CONTAINS(STRING, SUBSTRING)`\n\n  Whether `SUBSTRING` occurs in `STRING`.\n\n* `STRING_LENGTH(STRING)`\n\n  The length of `STRING`.\n\n* `REPEAT(STRING, N)`\n\n  A string consisting of `STRING` repeated `N` times.\n\n### `math`\n\nThe `math` extension exposes the following constants and functions, which can be helpful in activities involving math problems.\n\n* `PI`\n\n  An approximation of *π*.\n\n* `TO_DEGREES(X)`\n\n  Converts `X` radians to degrees.\n\n* `TO_RADIANS(X)`\n\n  Converts `X` degrees to radians.\n\n* `SIN(X)`, `COS(X)` \u0026 `TAN(X)`\n\n  The sine, cosine and tangent respectively of `X`.\n\n* `ARCSIN(X)`, `ARCCOS(X)` \u0026 `ARCTAN(X)`\n\n  The arcsine, arccosine and arctangent respectively of `X`.\n\n* `E`\n\n  An approximation of *e*.\n\n* `LOG(X)`\n\n  The base 10 logarithm of `X`.\n\n* `LN(X)`\n\n  The base *e* logarithm of `X`.\n\n* `LOG(X, B)`\n\n  The base `B` logarithm of `X`.\n\n* `EXP(X)`\n\n  The exponential of `X`.\n\n* `POWER(X, P)`\n\n  `X` raised to the power of `P`.\n\n* `SQUARE(X)`\n\n  The square of `X`.\n\n* `SQUARE_ROOT(X)`\n\n  The square root of `X`.\n\nExample:\n\n`examples/extensions/sine.pseudo`\n\n```text\nA = 30\nN = 20\n\nloop I from 0 to N - 1\n    SPACES = (A * (SIN(I * 2 * PI / N) + 1))\n    output REPEAT(\" \", SPACES), \"*\"\nend loop\n```\n\nFrom the command line:\n\n```text\npython -m ibdp_classes -ext 'strings math' examples/extensions/sine.pseudo \n```\n\nOutput:\n\n```text\n                               *\n                                        *\n                                                *\n                                                       *\n                                                           *\n                                                             *\n                                                           *\n                                                       *\n                                                *\n                                        *\n                               *\n                     *\n             *\n      *\n  *\n *\n  *\n      *\n             *\n                     *\n```\n\n### `bits`\n\nThe `bits` extension exposes the following functions, which can be helpful in activities involving bit manipulation.\n\n* `SET_BIT(X, P)`\n\n  Integer `X` with bit at position `P` set.\n\n* `UNSET_BIT(X, P)`\n\n  Integer `X` with bit at position `P` unset.\n\n* `BIT_IS_SET(X, P)`\n\n  Whether the bit at position `P` of integer `X` is set.\n\n* `BIT_AND(A, B)`, `BIT_OR(A, B)`, `BIT_XOR(A, B)`\n  \n  Bitwise conjunction, disjunction and exclusive disjunction respectively of integers `A` and `B`.\n\n* `BIT_NOT_8(X)`, `BIT_NOT_16(X)` and `BIT_NOT_32(X)`\n\n  Bitwise negation of integer `X` assuming 8, 16 or 32 bits respectively in the structure\n\nExample:\n\n`examples/extensions/binary.pseudo`\n\n```text\nTEMPLATE = \"[7][6][5][4][3][2][1][0]\"\n\noutput \"Input an integer from 0 to 255.\"\n\ninput VALUE as int\n\nloop I from 0 to 7\n    BIT_TEMPLATE = REPLACE(\"[I]\", \"I\", I)\n    if BIT_IS_SET(VALUE, I) then\n       TEMPLATE = REPLACE(TEMPLATE, BIT_TEMPLATE, 1)\n    else\n       TEMPLATE = REPLACE(TEMPLATE, BIT_TEMPLATE, 0)\n    end if\nend loop\n\noutput \"In binary,\", VALUE, \"is:\", TEMPLATE\n```\n\nIn the command line:\n\n```text\npython -m ibdp_classes -ext 'strings bits' examples/extensions/binary.pseudo\n```\n\nExample output:\n\n```text\nInput an integer from 0 to 255.\n42\nIn binary, 42 is: 00101010\n```\n\n### `turtle`\n\nThe `turtle` extension exposes some of the functionality of the Python turtle module, which can be helpful in fun, beginner-friendly (and more advanced) programming activities. See `src/extensions/turtle_defs.py` for details.\n\nExample:\n\n`examples/extensions/fractal.pseudo`\n\n```text\nprocedure FRACTAL(LENGTH, DEPTH)\n    DISTANCE = LENGTH / 3\n    if DEPTH = 0 then\n        GO_FORWARD(DISTANCE)\n        TURN_LEFT(60)\n        GO_FORWARD(DISTANCE)\n        TURN_RIGHT(120)\n        GO_FORWARD(DISTANCE)\n        TURN_LEFT(60)\n        GO_FORWARD(DISTANCE)\n    else\n        FRACTAL(DISTANCE, DEPTH - 1)\n        TURN_LEFT(60)\n        FRACTAL(DISTANCE, DEPTH - 1)\n        TURN_RIGHT(120)\n        FRACTAL(DISTANCE, DEPTH - 1)\n        TURN_LEFT(60)\n        FRACTAL(DISTANCE, DEPTH - 1)\n    end if\nend procedure\n\nWIDTH = 600\nY = -250\n\nloop DEPTH from 1 to 3\n   PEN_UP()\n   SET_X(-WIDTH / 2)\n   SET_Y(Y)\n   PEN_DOWN()\n   FRACTAL(WIDTH, DEPTH)\n   Y = Y + 200\nend loop\n\nHIDE_TURTLE()\nWAIT()\n```\n\nAt the command line:\n\n```text\npython -m ibdp_classes -ext turtle examples/extensions/fractal.pseudo  \n```\n\nOutput:\n\n![See screenshots/turtle.png](screenshots/turtle.png)\n\n## Using the classes within Python scripts\n\nThe classed defined by IB can be used directly in Python scripts. While there is not much of a use case for this, it might be helpful as an intermediate step in actually implementing pseudocode.\n\nFor example:\n\n```python\nfrom ibdp_classes import Array\n\ndef contains(needle: int, haystack: Array[int], n: int) -\u003e bool:\n    found = False\n    for k in range(n):\n        if haystack[k] == needle:\n            print(\"Found!\")\n            found = True\n    return found\n\nhaystack = Array(20, -3, 5, 7, 2, 13, 12, 19)\nprint(\"haystack:\", haystack)\n\nprint(\"5 is in haystack?\")\nprint(contains(5, haystack, 8))\n\nprint(\"4 is in haystack?\")\nprint(contains(4, haystack, 8))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fram6ler%2Fibdp_classes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fram6ler%2Fibdp_classes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fram6ler%2Fibdp_classes/lists"}