def stream_db_records(db_handler): while True: try: yield db_handler.read_n_records(10) except CustomException as e: logger.info("controlled error %r, continuing", e) except Exception as e: logger.info("unhandled error %r, stopping", e) db_handler.close() break
def search_nested_bad(array, desired_value): """Example of an iteration in a nested loop.""" coords = None for i, row in enumerate(array): for j, cell in enumerate(row): if cell == desired_value: coords = (i, j) break if coords is not None: break if coords is None: raise ValueError(f"{desired_value} not found") logger.info("value %r found at [%i, %i]", desired_value, *coords) return coords
def sequence(name, start, end): value = start logger.info("%s started at %i", name, value) while value < end: try: received = yield value logger.info("%s received %r", name, received) value += 1 except CustomException as e: logger.info("%s is handling %s", name, e) received = yield "OK" return end
def close(self): logger.debug("closing connection to database %r", self.db) self.is_closed = True def prepare_coroutine(coroutine): def wrapped(*args, **kwargs): advanced_coroutine = coroutine(*args, **kwargs) next(advanced_coroutine) return advanced_coroutine return wrapped @prepare_coroutine def stream_db_records(db_handler): retrieved_data = None page_size = 10 try: while True: page_size = (yield retrieved_data) or page_size retrieved_data = db_handler.read_n_records(page_size) except GeneratorExit: db_handler.close() if __name__ == '__main__': streamer = stream_db_records(DBHandler("testdb")) logger.info(f'next default - {next(streamer)}') streamer.send(3) logger.info(f'next 3 - {next(streamer)}')
try: received = yield value logger.info("%s received %r", name, received) value += 1 except CustomException as e: logger.info("%s is handling %s", name, e) received = yield "OK" return end def main(): step1 = yield from sequence("first", 0, 5) step2 = yield from sequence("second", step1, 10) return step1 + step2 if __name__ == '__main__': g = main() logger.info(next(g)) logger.info(next(g)) logger.info(g.send("첫 번째 제너레이터를 위한 인자 값")) logger.info(next(g)) logger.info(g.throw(CustomException("처리 가능한 예외 던지기"))) logger.info(next(g)) logger.info(next(g)) logger.info(next(g)) logger.info(next(g)) logger.info(next(g)) logger.info(next(g)) logger.info(next(g)) logger.info(next(g))
from dukim.log import logger class SequenceIterator: def __init__(self, start=0, step=1): self.current = start self.step = step # def __iter__(self): # return self def __next__(self): value = self.current self.current += self.step return value if __name__== '__main__': si = SequenceIterator(1, 2) logger.info(next(si)) logger.info(next(si)) logger.info(next(si)) # for n in SequenceIterator(): # if n >= 10: # break # logger.info(n)
from dukim.log import logger def _chain(*iterables): for it in iterables: for value in it: yield value def chain(*iterables): for it in iterables: yield from it if __name__ == '__main__': logger.info(list(_chain("hello", ["world"], ("tuple", " of ", "values.")))) logger.info(list(chain("hello", ["world"], ("tuple", " of ", "values."))))
if coords is None: raise ValueError(f"{desired_value} not found") logger.info("value %r found at [%i, %i]", desired_value, *coords) return coords def _iterate_array2d(array2d): for i, row in enumerate(array2d): for j, cell in enumerate(row): yield (i, j), cell def search_nested(array, desired_value): """"Searching in multiple dimensions with a single loop.""" try: coord = next(coord for (coord, cell) in _iterate_array2d(array) if cell == desired_value) except StopIteration: raise ValueError("{desired_value} not found") logger.debug("value %r found at [%i, %i]", desired_value, *coord) return coord if __name__ == "__main__": example = [[(col + 1) * (row + 1) for col in range(9)] for row in range(9)] logger.info(f'search_nested_bad : {search_nested_bad(example, 81)}') logger.info(f'search_nested : {search_nested(example, 81)}')
def read_n_records(self, limit): return [(i, f"row {i}") for i in range(limit)] def close(self): logger.debug("closing connection to database %r", self.db) self.is_closed = True class CustomException(Exception): """An exception of the domain model.""" def stream_db_records(db_handler): while True: try: yield db_handler.read_n_records(10) except CustomException as e: logger.info("controlled error %r, continuing", e) except Exception as e: logger.info("unhandled error %r, stopping", e) db_handler.close() break if __name__ == '__main__': streamer = stream_db_records(DBHandler("testdb")) logger.info(f'next {next(streamer)}') streamer.throw(CustomException) logger.info(f'CustomException {next(streamer)}') streamer.throw(RuntimeError) logger.info(f'RuntimeError {next(streamer)}')
self.seq = original_sequence def __getitem__(self, item): value = self.seq[item] logger.debug("%s getting %s", self.__class__.__name__, item) return value def __len__(self): return len(self.seq) class MappedRange: """Apply a transformation to a range of numbers.""" def __init__(self, transformation, start, end): self._transformation = transformation self._wrapped = range(start, end) def __getitem__(self, index): value = self._wrapped.__getitem__(index) result = self._transformation(value) logger.debug("Index %d: %s", index, result) return result def __len__(self): return len(self._wrapped) if __name__ == '__main__': mr = MappedRange(abs, -10, 5) logger.info(list(mr))
from dukim.log import logger class DBHandler: """Simulate reading from the database by pages.""" def __init__(self, db): self.db = db self.is_closed = False def read_n_records(self, limit): return [(i, f"row {i}") for i in range(limit)] def close(self): logger.debug("closing connection to database %r", self.db) self.is_closed = True def stream_db_records(db_handler): try: while True: yield db_handler.read_n_records(10) except GeneratorExit: db_handler.close() if __name__ == '__main__': streamer = stream_db_records(DBHandler("testdb")) logger.info(next(streamer)) logger.info(next(streamer)) streamer.close()