From cadcf7de22a1025cae97269e4541f420172db05f Mon Sep 17 00:00:00 2001 From: Mandeep Singh Date: Wed, 21 Apr 2021 23:48:08 -0400 Subject: [PATCH] Use the iteration behavior pattern project displays data by plotting graphs and comparing data. So, this pattern is a great help as it extracts the transversal behavior or a collection into a separate object --- covidify | 1 + src/covidify/data_visualization.py | 78 +++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 160000 covidify diff --git a/covidify b/covidify new file mode 160000 index 0000000..c3e722b --- /dev/null +++ b/covidify @@ -0,0 +1 @@ +Subproject commit c3e722b60824c8739045ac4c57b50b1478a995b2 diff --git a/src/covidify/data_visualization.py b/src/covidify/data_visualization.py index 8674540..61396df 100644 --- a/src/covidify/data_visualization.py +++ b/src/covidify/data_visualization.py @@ -22,6 +22,9 @@ from datetime import datetime import matplotlib.pyplot as plt from covidify.utils.utils import replace_arg_score +from __future__ import annotations +from collections.abc import Iterable, Iterator +from typing import Any, List # plt settings font = {'weight' : 'bold', @@ -137,7 +140,80 @@ def log_plot(tmp, col, fig_title): ax.set_title(fig_title) fig = ax.get_figure() fig.savefig(os.path.join(image_dir, create_save_file(col, country=None, graph_type='log'))) - + + class log_plot(Iterator): + """ + Concrete Iterators implement various traversal algorithms. These classes + store the current traversal position at all times. + """ + + """ + `position` attribute stores the current traversal position. An iterator may + have a lot of other fields for storing iteration state, especially when it + is supposed to work with a particular kind of collection. + """ + position: int = None + + """ + This attribute indicates the traversal direction. + """ + _reverse: bool = False + + def __init__(self, collection: daily_cases_file_name, reverse: bool = False) -> None: + self._collection = collection + self._reverse = reverse + self._position = -1 if reverse else 0 + + def __next__(self): + """ + The __next__() method must return the next item in the sequence. On + reaching the end, and in subsequent calls, it must raise StopIteration. + """ + try: + value = self._collection[self._position] + self._position += -1 if self._reverse else 1 + except IndexError: + raise StopIteration() + + return value + +class daily_cases_file_name(Iterable): + """ + Concrete Collections provide one or several methods for retrieving fresh + iterator instances, compatible with the collection class. + """ + + def __init__(self, collection: List[Any] = []) -> None: + self._collection = collection + + def __iter__(self) -> AlphabeticalOrderIterator: + """ + The __iter__() method returns the iterator object itself, by default we + return the iterator in ascending order. + """ + return AlphabeticalOrderIterator(self._collection) + + def get_reverse_iterator(self) -> AlphabeticalOrderIterator: + return AlphabeticalOrderIterator(self._collection, True) + + def add_item(self, item: Any): + self._collection.append(item) + + if __name__ == "__main__": + # The client code may or may not know about the Concrete Iterator or + # Collection classes, depending on the level of indirection you want to keep + # in your program. + collection = daily_cases_file_name() + collection.add_item("First") + collection.add_item("Second") + collection.add_item("Third") + + print("Straight traversal:") + print("\n".join(collection)) + print("") + + print("Reverse traversal:") + print("\n".join(collection.get_reverse_iterator()), end="") ##### Create Graphs ##### print('Creating graphs...') print('... Time Series Trend Line')