Skip to content

Instantly share code, notes, and snippets.

@phronmophobic
Last active April 7, 2019 22:54
Show Gist options
  • Select an option

  • Save phronmophobic/8a842b5ce98d1a334dba984aefe39140 to your computer and use it in GitHub Desktop.

Select an option

Save phronmophobic/8a842b5ce98d1a334dba984aefe39140 to your computer and use it in GitHub Desktop.
python lens
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