Last active
April 7, 2019 22:54
-
-
Save phronmophobic/8a842b5ce98d1a334dba984aefe39140 to your computer and use it in GitHub Desktop.
python lens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from pprint import pprint | |
| from copy import copy | |
| class KeyLens(object): | |
| def __init__(self, key): | |
| self.key = key | |
| def lget(self, data): | |
| return data[self.key] | |
| def __str__(self): | |
| return 'KeyLens("%s")' % self.key | |
| def lset(self, data, v): | |
| data = copy(data) | |
| data[self.key] = v | |
| return data | |
| class IndexLens(KeyLens): | |
| def __str__(self): | |
| return 'IndexLens("%s")' % self.key | |
| class ComposeLens(object): | |
| def __init__(self, *lenses): | |
| self.lenses = lenses | |
| def lget(self, data): | |
| for lens in self.lenses: | |
| data = lens.lget(data) | |
| return data | |
| def lset(self, data, v): | |
| original_data = [] | |
| outer_lenses = self.lenses[:-1] | |
| for lens in outer_lenses: | |
| original_data.append((lens, data)) | |
| data = lens.lget(data) | |
| data = self.lenses[-1].lset( data, v) | |
| for lens, original_datam in reversed(original_data): | |
| data = lens.lset(original_datam, data) | |
| return data | |
| todos = {"home": [{"description": "cook", | |
| "completed" : False}, | |
| {"description": "clean", | |
| "completed" : False} | |
| ], | |
| "work": [{"description": "program", | |
| "completed" : False}, | |
| {"description": "send emails", | |
| "completed" : False} | |
| ]} | |
| work_todos_lens = KeyLens("work") | |
| print work_todos_lens.lget(todos) | |
| # [{'completed': False, 'description': 'program'}, {'completed': False, 'description': 'send emails'}] | |
| first_work_todo_complete_lens = ComposeLens(KeyLens("work"), | |
| IndexLens(0), | |
| KeyLens("completed")) | |
| print first_work_todo_complete_lens.lget(todos) | |
| # False | |
| pprint(first_work_todo_complete_lens.lset(todos, True)) | |
| # {'home': [{'completed': False, 'description': 'cook'}, | |
| # {'completed': False, 'description': 'clean'}], | |
| # 'work': [{'completed': True, 'description': 'program'}, | |
| # {'completed': False, 'description': 'send emails'}]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment