{"id":19408599,"url":"https://github.com/ninest/plibs","last_synced_at":"2026-05-12T21:36:55.386Z","repository":{"id":37224252,"uuid":"257842040","full_name":"ninest/plibs","owner":"ninest","description":"MadLibs, but in Python ♥️","archived":false,"fork":false,"pushed_at":"2022-12-08T09:54:09.000Z","size":60,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-07T14:23:25.601Z","etag":null,"topics":["madlibs","python","streamlit","text-game"],"latest_commit_sha":null,"homepage":"https://plibs.herokuapp.com/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ninest.png","metadata":{"funding":{"github":"ninest","patreon":null,"open_collective":null,"ko_fi":"parthkabra","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://www.buymeacoffee.com/ninest"]},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-22T08:39:24.000Z","updated_at":"2022-08-11T03:56:17.000Z","dependencies_parsed_at":"2023-01-25T09:30:48.676Z","dependency_job_id":null,"html_url":"https://github.com/ninest/plibs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninest%2Fplibs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninest%2Fplibs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninest%2Fplibs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninest%2Fplibs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ninest","download_url":"https://codeload.github.com/ninest/plibs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240587478,"owners_count":19825005,"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","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":["madlibs","python","streamlit","text-game"],"created_at":"2024-11-10T12:06:42.308Z","updated_at":"2026-05-12T21:36:55.325Z","avatar_url":"https://github.com/ninest.png","language":"Python","funding_links":["https://github.com/sponsors/ninest","https://ko-fi.com/parthkabra","https://www.buymeacoffee.com/ninest"],"categories":[],"sub_categories":[],"readme":"# [Plibs](https://plibs.herokuapp.com/)\n\u003e A Python implementation of MadLibs (that runs in the browser with Streamlit)\n\n![Made with Python](https://img.shields.io/badge/Made%20With-%20Python%20🐍%20-red?style=flat-square)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\n\n## Gallery\n- To be added\n\n## Demo\n[https://plibs.herokuapp.com/](https://plibs.herokuapp.com/)\n\n## Explanation\n\nBefore we start, it's important to understand what the following are:\n1. **Blanks**: Anything that is meant to be filled by the user. In the texts, blanks are surrounded by two underscores.\n\n    The following are blanks:\n      - `__verb__`: meant to be filled by a **verb**\n      - `__verb-ing__`: meant to be filled by a **verb** ending in __ing__.\n      - `__noun__`: meant to be filled by a **noun**\n\n    Blanks can contain anything, and they serve as a prompt to what the user should enter. The following are valid blanks:\n\n      - `__occupation__`\n      - `__animal__`\n\n2. **ID-ed blanks**: Just like blanks, but when the text only has a single one of the blanks. All blanks with a slash followed by a number are ID-ed blanks\n\n    A blank can be used for a name. For instance `__name/1__` and `__dog/1__` are valid ID-ed blanks.\n\n    See the example of a text below.\n\n3. **Fills**: These are what the user enters in a blank.\n\n4. **Texts**: The entire text, which contains blanks and ID-ed blanks for the users to fill. \n\nHere is an example of a **text**:\n\n### Example\n```\nMy dog's name is __dog/1__, and I __verb__ him. __dog/1__ was born in the year __year__. Him and I __verb__ around a lot.\n```\n\n**Blanks**:\n- `__verb__` *2\n- `__year__`\n\n**ID-ed blanks**\n- `__dog/1__`\n\nHere is an example of the possible **fills**:\n- `__verb__`: \"love\"\n- `__verb__`: \"play\"\n- `__year__`: \"2017\"\n- `__dog/1__`: \"Scruffy\"\n\nWith the above fills, the output will be:\n```\nMy dog's name is Scruffy, and I love him. Scruffy was born in the year 2017. Him and I play around a lot.\n```\n\n## How it works\n\nThe below text will be used as the example input **text**:\n```\nMy dog's name is __dog/1__, and I __verb__ him. __dog/1__ was born in the year __year__. Him and I __verb__ around a lot.\n```\n\n### 1. Reading the text file\nAll files in `texts/` are valid texts with **blanks** and **ID-ed blanks**. \n\nAll words are gone through. A word is a **blank** or **ID-ed blank** if it has two underscores before or after (\"__\"). They are added to a dictionary (`blanks_dict`), where the blank is the key:\n\n```\n# blanks_dict\n{\n  'dog/1': '',\n  'verb': [],\n  'year': []\n}\n```\n\nNote how the only **ID-ed blank** (`dog/1`) has the value of an empty string, while the other two have an empty list.\n\nAt the same time, `blanks_counter` is created, which stores the number of times each blank is in the text:\n\n```\n# blank_counter\nCounter({'verb': 2, 'year': 1})\n```\n\nNote how the **ID-ed blank** (`dog/1`) is not in the counter. This is because it has only one value.\n\n### 2. Filling the blanks\n\nTO fill **blanks**, `blanks_dict`'s keys are looped, and the user is prompted to enter **fills** for the **blanks**.\n\nFor the **ID-ed blanks**, only one **fill** is required.\n\nFor the above example, the user is asked for:\n- 3* `verb`s\n- 1* `year`\n- `dog/1`\n\nSo at the end of this step, `blanks_dict` could end up looking like this:\n\n```\n# blanks_dict\n{\n  'dog/1': 'Scruffy',\n  'verb': ['play', 'love'],\n  'year': ['1969']\n}\n```\n\nNote that the list of keys (`blanks_dict.keys()`) are shuffled before asking for **fills**.\n\n\n### 3. Creating the output text using the fills\n\nThis is probably the simplest. It only involves replacing the the **blanks** in the original text with **fills**, creating the new text. The only thing to look out for is ensuring that punctuation is added after words with blanks. The output for the example can be:\n\n\u003e My dog's name is **Scruffy**, and I **love** him. **Scruffy** was born in the year **1969**. Him and I **play** around a lot.\n\n## Pipenv commands\n```\npipenv install \u003cpackage-name\u003e\npipenv lock -r \u003e requirements.txt\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fninest%2Fplibs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fninest%2Fplibs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fninest%2Fplibs/lists"}