{"id":15008920,"url":"https://github.com/python-utilities/hybrid-iterator","last_synced_at":"2026-03-08T20:39:31.683Z","repository":{"id":84902110,"uuid":"199251953","full_name":"python-utilities/hybrid-iterator","owner":"python-utilities","description":"Python 2/3 iterator cross-bred with a Dictionary","archived":false,"fork":false,"pushed_at":"2019-08-17T23:23:29.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-13T01:34:40.523Z","etag":null,"topics":["iterator","python-2","python-3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/python-utilities.png","metadata":{"files":{"readme":".github/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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-28T06:36:56.000Z","updated_at":"2020-11-01T23:08:40.000Z","dependencies_parsed_at":"2023-07-17T13:33:26.680Z","dependency_job_id":null,"html_url":"https://github.com/python-utilities/hybrid-iterator","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/python-utilities/hybrid-iterator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-utilities%2Fhybrid-iterator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-utilities%2Fhybrid-iterator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-utilities%2Fhybrid-iterator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-utilities%2Fhybrid-iterator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/python-utilities","download_url":"https://codeload.github.com/python-utilities/hybrid-iterator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/python-utilities%2Fhybrid-iterator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30272566,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:26:37.259Z","status":"ssl_error","status_checked_at":"2026-03-08T20:26:27.996Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["iterator","python-2","python-3"],"created_at":"2024-09-24T19:21:43.402Z","updated_at":"2026-03-08T20:39:31.655Z","avatar_url":"https://github.com/python-utilities.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hybrid Iterator Home\n[heading__title]:\n  #hybrid-iterator-home\n  \"\u0026#x2B06; Top of ReadMe File\"\n\n\nPython 2/3 iterator cross-bred with a Dictionary\n\n\n## [![Byte size of __init__.py][badge__master__hybrid_iterator__source_code]][hybrid_iterator__master__source_code] [![Open Issues][badge__issues__hybrid_iterator]][issues__hybrid_iterator] [![Open Pull Requests][badge__pull_requests__hybrid_iterator]][pull_requests__hybrid_iterator] [![Latest commits][badge__commits__hybrid_iterator__master]][commits__hybrid_iterator__master]\n\n\n\n------\n\n\n#### Table of Contents\n\n\n- [:arrow_up: Top of ReadMe File][heading__title]\n\n- [:zap: Quick Start][heading__quick_start]\n\n  - [:memo: Edit Your ReadMe File][heading__your_readme_file]\n  - [:snake: Utilize Hybrid Iterator][heading__utilize]\n  - [:floppy_disk: Commit and Push][heading__commit_and_push]\n\n- [\u0026#x1F5D2; Notes][heading__notes]\n\n- [\u0026#x2696; License][heading__license]\n\n\n------\n\n\n\n## Quick Start\n[heading__quick_start]:\n  #quick-start\n  \"\u0026#9889; Perhaps as easy as one, 2.0,...\"\n\n\n**Bash Variables**\n\n\n```Bash\n_module_name='hybrid-iterator'\n_module_https_url=\"https://github.com/python-utilities/${_module_name}.git\"\n_module_relative_path=\"lib/modules/${_module_name//-/_}\"\n```\n\n\n**Bash Submodule Commands**\n\n\n```Bash\ncd \"\u003cyour-git-project-path\u003e\"\n\ngit checkout masters\nmkdir -vp \"lib/modules\"\n\ngit submodule add\\\n -b master --name \"${_module_name}\"\\\n \"${_module_https_url}\" \"${_module_relative_path}\"\n```\n\n\n### Your ReadMe File\n[heading__your_readme_file]:\n  #your-readme-file\n  \"\u0026#x1F4DD; Suggested additions for your ReadMe.md file so everyone has a good time with submodules\"\n\n\nSuggested additions for your _`ReadMe.md`_ file so everyone has a good time with submodules\n\n\n```MarkDown\nClone with the following to avoid incomplete downloads\n\n\n    git clone --recurse-submodules \u003curl-for-your-project\u003e\n\n\nUpdate/upgrade submodules via\n\n\n    git submodule update --init --merge --recursive\n```\n\n\n### Utilize Hybrid Iterator\n[heading__utilize]:\n  #utilize-hybrid-iterator\n  \"\u0026#x1F40D; How to make use of this submodule within another project\"\n\n\n```Python\n#!/usr/bin/env python\n\n\nfrom lib.modules.hybrid_iterator import Hybrid_Iterator\n\n\nclass Priority_Buffer(Hybrid_Iterator):\n    \"\"\"\n    Priority_Buffer\n\n    ## Arguments\n\n    - `graph`, with `{name: sub_graph}` and `sub_graph[key_name]` to compare\n    - `buffer_size`, `int` of desired `{name: sub_graph}` pairs to buffer\n    - `priority`, dictionary containing the following data structure\n        - `key_name`, withing `graph` to compare with `_bound`s bellow\n        - `GE_bound`, buffers those greater than or equal to `graph[key_name]`\n        - `LE_bound`, buffers those less than or equal to `graph[key_name]`\n    - `step`, dictionary containing the following `{key: value}` pairs\n        - `amount`, to increment or decrement `_bound`s to ensure full buffer\n        - `GE_min`/`LE_max`, bounds the related `_bounds` above\n    - `modifier` if set __must__ accept `{key: value}` pairs from `graph`\n    \"\"\"\n\n    def __init__(self, graph, priority, buffer_size, step, modifier = None, **kwargs):\n        super(Priority_Buffer, self).__init__(**kwargs)\n        self.update(\n            graph = graph,\n            priority = priority,\n            buffer_size = buffer_size,\n            step = step,\n            modifier = modifier,\n            buffer = {})\n\n    @property\n    def is_buffered(self):\n        \"\"\"\n        Returns `True` if buffer is satisfied or graph is empty, `False`\n        otherwise. Used by `next()` to detect conditions to `return` on.\n        \"\"\"\n        if len(self['buffer'].keys()) \u003e= self['buffer_size']:\n            return True\n\n        if len(self['graph'].keys()) \u003c= 0:\n            return True\n\n        if self['step'].get('GE_min') is not None:\n            if self['priority']['GE_bound'] \u003c self['step']['GE_min']:\n                return True\n        elif self['step'].get('LE_max') is not None:\n            if self['priority']['LE_bound'] \u003e self['step']['LE_max']:\n                return True\n        else:\n            raise ValueError(\"self['priority'] missing step missing min/max\")\n\n        return False\n\n    def top_priority(self, graph = None):\n        \"\"\"\n        Yields `dict`s from `graph` where value of `graph[key_name]`,\n        as set by `self['priority']['key_name']`, is within range of\n        `self['GE_bound']` or `self['LE_bound']`\n\n        - `graph`, dictionary that is __destructively__ read (`pop`ed) from\n\n        \u003e if `graph` is `None` then `top_priority` reads from `self['graph']`\n        \"\"\"\n        if graph is None:\n            graph = self['graph']\n\n        key_name = self['priority']['key_name']\n        for name, node in graph.items():\n            if self['priority'].get('GE_bound') is not None:\n                if node[key_name] \u003e= self['priority']['GE_bound']:\n                    yield {name: graph.pop(name)}\n            elif self['priority'].get('LE_bound') is not None:\n                if node[key_name] \u003c= self['priority']['LE_bound']:\n                    yield {name: graph.pop(name)}\n            else:\n                raise ValueError('Misconfiguration, either `GE_`/`LE_bound`s ')\n\n        self.throw(GeneratorExit)\n\n    def next(self):\n        \"\"\"\n        Sets `self['buffer']` from `self.top_priority()` and returns `self`\n        \"\"\"\n        if not self['graph']:\n            self.throw(GeneratorExit)\n\n        self['buffer'] = {}\n        priority_gen = self.top_priority()\n        while not self.is_buffered:\n            try:\n            except (StopIteration, GeneratorExit):\n                if self['priority'].get('GE_bound'):\n                    self['priority']['GE_bound'] += self['step']['amount']\n                    priority_gen = self.top_priority()\n                elif self['priority'].get('LE_bound'):\n                    self['priority']['LE_bound'] += self['step']['amount']\n                    priority_gen = self.top_priority()\n                else:\n                    raise ValueError(\"self['priority'] missing bounds\")\n            else:\n                try:\n                    self['buffer'].update(self['modifier'](next_sub_graph))\n                except TypeError:\n                    self['buffer'].update(next_sub_graph)\n\n        return self\n\n\nif __name__ == '__main__':\n    \"\"\"\n    The following are run when this file is executed as\n    a script, eg. `python priority_buffer.py`\n    but not executed when imported as a module, thus a\n    good place to put unit tests.\n    \"\"\"\n    from random import randint\n\n    print(\"Initalizing unit test.\\n{0}\".format(\"\".join(['_' for x in range(9)])))\n    graph = {}\n    for i in range(0, 21, 1):\n        graph.update({\n            \"sub_graph_{0}\".format(i): {\n                'points': {},\n                'first_to_compute': randint(0, 9),\n            }\n        })\n\n    print(\"Sample graph head.\\n{0}\".format(\"\".join(['_' for x in range(9)])))\n    head_counter = 0\n    for k, v in graph.items():\n        print(\"{0} -\u003e {1}\".format(k, v))\n        head_counter += 1\n        if head_counter \u003e 3:\n            break\n\n    buffer = Priority_Buffer(\n        graph = graph,\n        priority = {'key_name': 'first_to_compute',\n                    'GE_bound': 7},\n        step = {'amount': -2,\n                'GE_min': -1},\n        buffer_size = 5,\n    )\n\n    print(\"Iterating over sample graph.\\n{0}\".format(\"\".join(['_' for x in range(9)])))\n    counter = 0\n    c_max = int(len(graph.keys()) / buffer['buffer_size'] + 1)\n    # ... (21 / 5) + 1 -\u003e int -\u003e 5\n    for chunk in buffer:\n        print(\"Chunk {count} of ~ {max}\".format(\n            count = counter, max = c_max - 1))\n\n        for key, val in chunk['buffer'].items():\n            print(\"\\t{k} -\u003e {v}\".format(**{\n                'k': key, 'v': val}))\n\n        counter += 1\n\n        if counter \u003e c_max:\n            raise Exception(\"Hunt for bugs!\")\n\n    print(\"Finished test.\\n{0}\".format(\"\".join(['_' for x in range(9)])))\n```\n\n\n### Commit and Push\n[heading__commit_and_push]:\n  #commit-and-push\n  \"\u0026#x1F4BE; It may be just this easy...\"\n\n\n```Bash\ngit add .gitmodules\ngit add lib/modules/hybrid_iterator\n\n\n## Add any changed files too\n\n\ngit commit -F- \u003c\u003c'EOF'\n:heavy_plus_sign: Adds `python-utilities/hybrid-iterator#1` submodule\n\n\n\n**Additions**\n\n\n- `.gitmodules`, tracks submodules AKA Git within Git _fanciness_\n\n- `README.md`, updates installation and updating guidance\n\n- `lib/modules/hybrid_iterator`, builds list of pages for a named collection\nEOF\n\n\ngit push origin master\n```\n\n\n**:tada: Excellent :tada:** your repository is now ready to begin unitizing code from this project!\n\n\n___\n\n\n## Notes\n[heading__notes]:\n  #notes\n  \"\u0026#x1F5D2; Additional resources and things to keep in mind when developing\"\n\n\nHybrid Iterator is intended for importing and modification, and **not** for stand-alone use.\n\n___\n\n\n## License\n[heading__license]:\n  #license\n  \"\u0026#x2696; Legal bits of Open Source software\"\n\n\nLegal bits of Open Source software\n\n\n```\nHybrid Iterator ReadMe documenting how things like this could be utilized\nCopyright (C) 2019  S0AndS0\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as published\nby the Free Software Foundation; version 3 of the License.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n```\n\n\n\n[badge__commits__hybrid_iterator__master]:\n  https://img.shields.io/github/last-commit/python-utilities/hybrid-iterator/master.svg\n\n[commits__hybrid_iterator__master]:\n  https://github.com/python-utilities/hybrid-iterator/commits/master\n  \"\u0026#x1F4DD; History of changes on this branch\"\n\n\n[hybrid_iterator__community]:\n  https://github.com/python-utilities/hybrid-iterator/community\n  \"\u0026#x1F331; Dedicated to functioning code\"\n\n\n[hybrid_iterator__gh_pages]:\n  https://github.com/python-utilities/hybrid-iterator/tree/gh-pages\n  \"Source code examples hosted thanks to GitHub Pages!\"\n\n\n\n[badge__demo__hybrid_iterator]:\n  https://img.shields.io/website/https/python-utilities.github.io/hybrid-iterator/index.html.svg?down_color=darkorange\u0026down_message=Offline\u0026label=Demo\u0026logo=Demo%20Site\u0026up_color=success\u0026up_message=Online\n\n[demo__hybrid_iterator]:\n  https://python-utilities.github.io/hybrid-iterator/index.html\n  \"\u0026#x1F52C; Check the example collection tests\"\n\n\n[badge__issues__hybrid_iterator]:\n  https://img.shields.io/github/issues/python-utilities/hybrid-iterator.svg\n\n[issues__hybrid_iterator]:\n  https://github.com/python-utilities/hybrid-iterator/issues\n  \"\u0026#x2622; Search for and _bump_ existing issues or open new issues for project maintainer to address.\"\n\n\n[badge__pull_requests__hybrid_iterator]:\n  https://img.shields.io/github/issues-pr/python-utilities/hybrid-iterator.svg\n\n[pull_requests__hybrid_iterator]:\n  https://github.com/python-utilities/hybrid-iterator/pulls\n  \"\u0026#x1F3D7; Pull Request friendly, though please check the Community guidelines\"\n\n\n[badge__master__hybrid_iterator__source_code]:\n  https://img.shields.io/github/size/python-utilities/hybrid-iterator/__init__.py.svg?label=__init__.py\n\n[hybrid_iterator__master__source_code]:\n  https://github.com/python-utilities/hybrid-iterator/blob/master/__init__.py\n  \"\u0026#x2328; Project source, one Python file of importable code!\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-utilities%2Fhybrid-iterator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpython-utilities%2Fhybrid-iterator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-utilities%2Fhybrid-iterator/lists"}