diff --git a/.gitignore b/.gitignore index 2d1721f..eccc02f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ __pycache__/ .coverage mieda.egg-info htmlcov -build \ No newline at end of file +build +.ipynb_checkpoints diff --git a/comparisons/iterative.py b/comparisons/iterative.py new file mode 100644 index 0000000..0c3762c --- /dev/null +++ b/comparisons/iterative.py @@ -0,0 +1,77 @@ +def createInterval(start, finish, keys, key): + new_interval = {} + new_interval["start"] = start + new_interval["finish"] = finish + new_interval[key] = keys.copy() + return new_interval + + +def getMainPermutations(intervals, key): + conflicts = False + new_intervals = [] + for start_interval in intervals: + for compare_interval in intervals: + if start_interval["start"] >= compare_interval["finish"] or start_interval["finish"] <= compare_interval["start"]: + continue + conflicts = True + + first_finish = start_interval["start"] + if start_interval["start"] != compare_interval["start"]: + first_start = min(start_interval["start"], compare_interval["start"]) + first_finish = max(start_interval["start"], compare_interval["start"]) + keys = start_interval[key] if start_interval["start"] < compare_interval["start"] else compare_interval[key] + new_interval = createInterval(first_start, first_finish, keys, key) + if new_interval not in new_intervals: + new_intervals.append(new_interval) + + last_start = start_interval["finish"] + if start_interval["finish"] != compare_interval["finish"]: + last_start = min(start_interval["finish"], compare_interval["finish"]) + last_finish = max(start_interval["finish"], compare_interval["finish"]) + keys = start_interval[key] if start_interval["finish"] > compare_interval["finish"] else compare_interval[key] + new_interval = createInterval(last_start, last_finish, keys, key) + if new_interval not in new_intervals: + new_intervals.append(new_interval) + + new_interval = createInterval(first_finish, last_start, start_interval[key].union(compare_interval[key]), key) + if new_interval not in new_intervals: + new_intervals.append(new_interval) + return conflicts, new_intervals + + +def resolveConflicts(intervals, key): + resolved_intervals = [] + skip = {} + unresolved = False + for i, start_interval in enumerate(intervals): + if (start_interval["start"], start_interval["finish"]) in skip: + continue + + conflict = False + for j, compare_interval in enumerate(intervals): + if start_interval["start"] == compare_interval["start"] and start_interval["finish"] > compare_interval["finish"]: + compare_interval[key] = compare_interval[key].union(start_interval[key]) + conflict = True + break + + if start_interval["start"] < compare_interval["start"] < start_interval["finish"]: + unresolved = True + + elif (start_interval["start"], start_interval["finish"]) == (compare_interval["start"], compare_interval["finish"]): + start_interval[key] = start_interval[key].union(compare_interval[key]) + skip[(start_interval["start"], start_interval["finish"])] = True + + if not conflict: + resolved_intervals.append(start_interval) + return unresolved, resolved_intervals + +class Merge: + @staticmethod + def union(intervals: list, key: str = "set_items"): + while True: + conflict, intervals = getMainPermutations(intervals, key) + unresolved, intervals = resolveConflicts(intervals, key) if conflict else (False, intervals) + if not unresolved: + break + + return intervals \ No newline at end of file diff --git a/comparisons/iterative_optimized.py b/comparisons/iterative_optimized.py new file mode 100644 index 0000000..179d57d --- /dev/null +++ b/comparisons/iterative_optimized.py @@ -0,0 +1,110 @@ +from operator import itemgetter + + +def create_interval(start, finish, keys, key): + new_interval = {} + new_interval["start"] = start + new_interval["finish"] = finish + new_interval[key] = keys.copy() + return new_interval + + +def get_max_list_intervals(min_start, max_list, key): + intervals = [] + max_list = sorted(max_list, key=lambda x: x["point"]) + for i, end in enumerate(max_list): + if i == 0 or min_start["point"] == end["point"]: + if len(max_list) == 1: + intervals.append(create_interval(min_start["point"], end["point"], end["keys"], key)) + min_start["keys"] = min_start["keys"].union(end["keys"]) + continue + + keys = set() + if min_start["label"] == "start": + keys = min_start["keys"].union(intervals[-1][key]) if len(intervals) > 0 else min_start["keys"] + elif end["label"] == "finish": + if i + 1 < len(max_list): + if max_list[i+1]["label"] == "start" and intervals: + keys = intervals[-1][key].difference(max_list[i-1]["keys"]) + else: + keys = end["keys"].union(max_list[i+1]["keys"]) + else: + keys = end["keys"] + else: + keys = intervals[-1][key].difference(min_start["keys"]).difference(end["keys"]) + + intervals.append(create_interval(min_start["point"], end["point"], keys, key)) + min_start = end + return intervals + + +def merge_same_intervals(intervals, key): + new_intervals = [] + last_interval = intervals[0] + for interval in intervals[1:]: + if (last_interval["start"], last_interval["finish"]) == (interval["start"], interval["finish"]): + last_interval[key] = last_interval[key].union(interval[key]) + else: + new_intervals.append(last_interval) + last_interval = interval + if not new_intervals or new_intervals[-1] != last_interval: + new_intervals.append(last_interval) + return new_intervals + + +def create_vertex(interval, label, key): + vertex = {"point": interval[label], "keys": interval[key], "label": label} + return vertex + + +def get_main_permutations(intervals, key): + conflicts = False + new_intervals = [] + intervals = sorted(intervals, key=itemgetter("start", "finish")) + intervals = merge_same_intervals(intervals, key) + + min_start = create_vertex(intervals[0], "start", key) + max_end = intervals[0]["finish"] + max_list = [create_vertex(intervals[0], "start", key), create_vertex(intervals[0], "finish", key)] + for interval in intervals[1:]: + if min_start["point"] < interval["start"] < max_end: + max_list.append(create_vertex(interval, "start", key)) + max_list.append(create_vertex(interval, "finish", key)) + max_end = max(max_end, interval["finish"]) + elif min_start["point"] < interval["finish"] < max_end: + max_list.append(create_vertex(interval, "finish", key)) + elif min_start["point"] == interval["start"] and interval["finish"] > max_end: + min_start["keys"] = min_start["keys"].union(interval[key]) + max_list.append(create_vertex(interval, "finish", key)) + max_end = interval["finish"] + + if interval["start"] >= max_end: + new_intervals += get_max_list_intervals(min_start, max_list, key) + min_start = create_vertex(interval, "start", key) + max_list = [create_vertex(interval, "finish", key)] + new_intervals += get_max_list_intervals(min_start, max_list, key) + + return conflicts, new_intervals + + +def resolve_conflicts(intervals, key): + resolved_intervals = [] + current_interval = intervals[0] + for interval in intervals[1:]: + if interval["start"] > current_interval["start"]: + resolved_intervals.append(current_interval) + current_interval = interval + else: + current_interval[key] = current_interval[key].union(interval[key]) + resolved_intervals.append(current_interval) + return resolved_intervals + + +class Merge: + @staticmethod + def union(intervals: list, key: str = "set_items"): + conflict, intervals = get_main_permutations(intervals, key) + if conflict: + intervals = sorted(intervals, key=itemgetter("start", "finish")) + intervals = resolve_conflicts(intervals, key) + return intervals \ No newline at end of file diff --git a/notebooks/Speed Profiling.ipynb b/notebooks/Speed Profiling.ipynb index 92588df..0e95b98 100644 --- a/notebooks/Speed Profiling.ipynb +++ b/notebooks/Speed Profiling.ipynb @@ -30,7 +30,18 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'/usr/local/anaconda3/bin/python'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# let's make sure we are using the correct kernel \n", "import sys; sys.executable" @@ -42,7 +53,12 @@ "metadata": {}, "outputs": [], "source": [ - "from mieda.intervals import Merge" + "import os\n", + "import inspect\n", + "\n", + "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n", + "parentdir = os.path.dirname(currentdir)\n", + "sys.path.insert(0, parentdir)" ] }, { @@ -50,6 +66,17 @@ "execution_count": 3, "metadata": {}, "outputs": [], + "source": [ + "from mieda.intervals import Merge\n", + "from comparisons.iterative import Merge as it_merge\n", + "from comparisons.iterative_optimized import Merge as itop_merge" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], "source": [ "# plotting and other things \n", "import datetime\n", @@ -73,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -86,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -97,7 +124,7 @@ " 'set_items': {'1'}}]" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -108,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -117,7 +144,7 @@ "[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -130,18 +157,18 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "580945c0f4ce4e5e99a2c34cca804556", + "model_id": "12b5c0e1811a463c898b45c6a3d4deb8", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -184,7 +211,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -225,7 +252,7 @@ " 'set_items': {'9'}}]" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -237,7 +264,41 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def measureBulkTime(func, runs=10, time_limit=None):\n", + " run_interval_counts = list()\n", + " run_seconds_elapsed = list()\n", + "\n", + " measure_start_time = time.process_time()\n", + " for r in range(runs):\n", + " print(\"\\n--- run \" + str(r + 1) + \" ---\")\n", + " interval_count = list()\n", + " seconds_elapsed = list()\n", + " flops_used = list()\n", + " for i in tqdm(inputs):\n", + " interval_count.append(len(i))\n", + " start = time.process_time()\n", + " func(i)\n", + " seconds_elapsed.append(time.process_time() - start)\n", + " if time_limit and time.process_time() - measure_start_time > time_limit:\n", + " break\n", + "\n", + " run_interval_counts.append(interval_count)\n", + " run_seconds_elapsed.append(seconds_elapsed)\n", + " \n", + " if time_limit and time.process_time() - measure_start_time > time_limit:\n", + " break\n", + " \n", + " return (run_interval_counts, run_seconds_elapsed)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 11, "metadata": { "scrolled": true }, @@ -253,12 +314,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "4cf489b7ed9349e0ae885f82f1d7f889", + "model_id": "48998d7edbd142e78ba8865f56452c59", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -276,12 +337,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6ca343bc1c974b0685c398f4d77af479", + "model_id": "f58500f0c82746589d46341ef303e3fc", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -299,12 +360,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d73e4d6826714385b73313078b1191ca", + "model_id": "4c28f677e38646baa024383c6b2d6d03", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -322,12 +383,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "88d16360513b47c99031af600348de21", + "model_id": "111eb840d87b49b4bcf13f87f6bb103c", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -345,12 +406,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "1b1683e2390646829b735f71ee837268", + "model_id": "70e388f69d6049f89a78d4239c5efc10", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -368,12 +429,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9f78f2b4a9f44ffab9ab74856eeacd5c", + "model_id": "3d343a4223e745b792a4dae9e6e34be7", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -391,12 +452,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a0dea76a655048a184deccaaa30e5b3f", + "model_id": "2df1944894b34eee90c7dda8bca56a7f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -414,12 +475,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "deb9bf4092f0483fad5c378a6c74b93c", + "model_id": "4479425641944f0dba303da1099ceabd", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -437,12 +498,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e9b4e35d25f44b4ba204e60d4b9a6f98", + "model_id": "f33a2c779ea74c0f81e4765638e32fd8", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -460,12 +521,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3bf0f4f8e306443799f08063d51851c6", + "model_id": "cb5235edd20745c0903ec404431dad20", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, "metadata": {}, @@ -482,113 +543,437 @@ "source": [ "# for each, use mieda to overlap the intervals and create new sets in the intervals through a union merge \n", "# track how long it takes for each set of intervals to arrive at a profile of speed based on the input size \n", - "\n", - "runs = range(0, 10)\n", - "run_interval_counts = list()\n", - "run_seconds_elasped = list()\n", - "\n", - "for r in runs:\n", - " print(\"\\n--- run \" + str(r + 1) + \" ---\")\n", - " interval_count = list()\n", - " seconds_elapsed = list()\n", - " flops_used = list()\n", - " for i in tqdm(inputs):\n", - " interval_count.append(len(i))\n", - " start = time.process_time()\n", - " Merge.union(intervals=i)\n", - " seconds_elapsed.append(time.process_time() - start)\n", - " \n", - " run_interval_counts.append(interval_count)\n", - " run_seconds_elasped.append(seconds_elapsed)" + "run_interval_counts, run_seconds_elapsed = measureBulkTime(Merge.union, 10)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ - "# flatten the list of runs for plotting \n", - "flattened_interval_counts = [item for sublist in run_interval_counts for item in sublist]\n", - "flattened_seconds_elapsed = [item for sublist in run_seconds_elasped for item in sublist]" + "def plotMultiSpeed(trials):\n", + " # flatten the list of runs for plotting \n", + " flattened_interval_counts = []\n", + " flattened_seconds_elapsed = []\n", + " algorithm_used = []\n", + " algorithms = []\n", + " for i, trial in enumerate(trials):\n", + " flattened_trial_interval_counts = [item for sublist in trial[\"interval_count\"] for item in sublist]\n", + " flattened_trial_seconds_elapsed = [item for sublist in trial[\"seconds_elapsed\"] for item in sublist]\n", + " flattened_interval_counts += flattened_trial_interval_counts\n", + " flattened_seconds_elapsed += flattened_trial_seconds_elapsed\n", + " algorithm_used += [i] * len(flattened_trial_seconds_elapsed)\n", + " algorithms.append(trial[\"algorithm\"])\n", + "\n", + " df_runs = pd.DataFrame(\n", + " np.array([flattened_interval_counts, flattened_seconds_elapsed, algorithm_used]).T,\n", + " columns=[\"interval_count\", \"seconds_elapsed\", \"algorithm\"]\n", + " )\n", + " \n", + " g = sns.lmplot(\n", + " x=\"interval_count\", \n", + " y=\"seconds_elapsed\", \n", + " data=df_runs,\n", + " order=2,\n", + " height=7,\n", + " aspect=1.5,\n", + " legend_out=False,\n", + " hue=\"algorithm\",\n", + " palette=['#4daf4a','#1f78b4','#e41a1c','#7570b3'],\n", + " line_kws={\"lw\":4, 'ls':'--'}\n", + " )\n", + " g.set(ylim=(-.05, 1.5), xlim=(0, 1010))\n", + " ax = plt.gca()\n", + " ax.set_title('Seconds Elapsed by Interval Count')\n", + " ax.set(xlabel='\\nInterval Count', ylabel='Seconds Elapsed\\n')\n", + " \n", + " legend = g.axes[0, 0].get_legend()\n", + " for i, text in enumerate(legend.texts):\n", + " legend.texts[i].set_text(algorithms[i])" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ - "df_runs = pd.DataFrame(\n", - " np.array([flattened_interval_counts, flattened_seconds_elapsed]).T,\n", - " columns=[\"interval_count\", \"seconds_elapsed\"]\n", - ")" + "def plotSingleSpeed(run_interval_counts, run_seconds_elapsed):\n", + " # flatten the list of runs for plotting \n", + " flattened_interval_counts = [item for sublist in run_interval_counts for item in sublist]\n", + " flattened_seconds_elapsed = [item for sublist in run_seconds_elapsed for item in sublist]\n", + " df_runs = pd.DataFrame(\n", + " np.array([flattened_interval_counts, flattened_seconds_elapsed]).T,\n", + " columns=[\"interval_count\", \"seconds_elapsed\"]\n", + " )\n", + " \n", + " g = sns.lmplot(\n", + " x=\"interval_count\", \n", + " y=\"seconds_elapsed\", \n", + " data=df_runs,\n", + " order=2,\n", + " height=7,\n", + " aspect=1.5,\n", + " line_kws={'color': 'red'}\n", + " )\n", + " g.set(ylim=(-.05, 1.5))\n", + " ax = plt.gca()\n", + " ax.set_title('Seconds Elapsed by Interval Count')\n", + " ax.set(xlabel='\\nInterval Count', ylabel='Seconds Elapsed\\n')" ] }, { "cell_type": "code", - "execution_count": 17, - "metadata": { - "scrolled": false - }, + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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ci8iIiIiUiSU3IuIiIiIFAkl9yIiIiIiRULJvYiIiIhIkVByLyIiIiJSJJTci4iIiIgUCSX3IiIiIiJFQsm9iIiIiEiRUHIvIiIiIlIklNyLiIiIiBQJJfciIiIiIkViwiT3ZnaDmTWZ2ePDbHeKmWXM7MKxik1EREREZDKYMMk9cCNwzlAbmFkU+Crw67EISERERERkMpkwyb27rwf2DbPZR4GfAE2jH5GIiIiIyOQyYZL74ZjZkcD5wLcL2PYDZrbRzDbu3r179IMTEREREZkAJk1yD1wFfNLdM8Nt6O7XuvsSd19SV1c3BqGJiIiIiIy/2HgHcACWALeaGcAM4DwzS7v77eMbloiIiIjIxDBpknt3n9/zu5ndCPxCib2IiIiIyIsmTHJvZrcAy4AZZrYN+AIQB3D3YevsRUREREQOdxMmuXf3iw9g20tHMRQRERERkUlpMk2oFRERERGRISi5FxEREREpEkruRURERESKhJJ7EREREZEioeReRERERKRIKLkXERERESkSSu5FRERERIqEknsRERERkSKh5F5EREREpEgouRcRERERKRJK7kVEREREioSSexERERGRIqHkXkRERESkSCi5FxEREREpEkruRURERESKhJJ7EREREZEioeReRERERKRIKLkXERERESkSSu5FRERERIqEknsRERERkSKh5F5EREREpEgouRcRERERKRJK7kVEREREioSSexERERGRIqHkXkRERESkSCi5FxEREREpEkruRURERESKhJJ7EREREZEioeReRERERKRIKLkXERERESkSSu5FRERERIqEknsRERERkSKh5F5EREREpEgouRcRERERKRJK7kVEREREioSSexERERGRIqHkXkRERESkSCi5FxEREREpEkruRURERESKhJJ7EREREZEioeReRERERKRIKLkXERERESkSSu5FRERERIqEknsRERERkSKh5F5EREREpEgouRcRERERKRKx8Q5ARERERGQiWdfQxOr1jWxtTjC3toIVSxewbFH9eIdVEI3ci4iIiIiE1jU0sXLtJprauqgpj9PU1sXKtZtY19A03qEVRMm9iIiIiEho9fpG4lGjoiSGWfAajxqr1zeOd2gFmTDJvZndYGZNZvZ4nvWXmNlfwp8/mtlJYx2jiIiIiBS3rc0JyuPRPsvK41G2NSfGKaIDM2GS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H8Nfu3tH+I/hToILawaA97n7U/N+4jJnzGwL8Al3v8rM1hK05FcBO4F3u/uwmRUA3yW4JqMDuM7d9y/UOctLZ2bnEVxEnQT2A+8jaCRTfY8wM/scsJVghLSdwN8R9KFWfY8YM7sP2ALUAMcJRr35MbOs42b2twR5AOA2d//2vL4OhXsRERERkWhQtxwRERERkYhQuBcRERERiQiFexERERGRiFC4FxERERGJCIV7EREREZGIULgXEREREYkIhXsRERERkYhQuBcRERERiQiFexERERGRiFC4FxERERGJCIV7EREREZGIULgXEREREYkIhXsRERERkYhQuBcRERERiQiFexERERGRiFC4FxERERGJCIV7EREREZGIULgXEVmkzKxvBvt81MyK5uFc7jGza6d47BNmtsfMdpnZ783svXP83BVm9qG5PKaIyGKlcC8iEm0fBWYV7s0sPldPbmYfBN4CXOjurwYuAWyujh+qABTuRURQuBcRWfTMbIuZPWZmD4Qt5N+zwE3ACuBRM3s03PetZva4mf3OzH5gZiXh9oNmdquZ/Rr4pJn9Nuv4q83s2XD5VjPbEbbCbzezUwX1TwEfcvceAHfvdvd7w2NdamY7zew5M7vbzPKzzqUmXN5kZo+Fy58N93vMzPaHrw/gC8DLzOwZM/vXufidiogsVgr3IiLRcD5BK/2rgLXAG9z9a0Az8CZ3f1MYmD8NXObuG4GngI9nHWPI3d/o7rcDSTNbG27fCnw/XL7T3TeHrfCFwFVTnZCZlQKl7v5CjscKgHuAre7+GiAB/P0MXucG4HLgQuAzZpYH3Ay84O7nufs/zuAYIiKRpXAvIhINv3X3JndPA88Aq3PscxFB+P8/M3sG2Aasynr8/qzl7wPvDJe3Zj32JjN70syeA94M/Nk052SAT/HYK4AD7v6ncP1egi47p/JTdx929zagBaibwc+IiCwZiYU+ARERmRPDWctj5P77bsAj7n79FMfoz1q+H/iBmf0QcHffG7a2/xuwyd0Pm9lngYKpTsjde8ys38zWuvv+HOcylRQnGp9OPv5MXqeIyJKllnsRkWjrBUrD5SeAN5jZOgAzKzKzl+f6obArzRjwz5xotc8E7bawr37O0XFOcjvwdTMrC5+zzMxuBPYAqzPnArwH+EW4fBC4IFx+xwyeI/s1iogsaQr3IiLRth14yMwedfdW4AbgvvAC2ScI+rBP5X7g3YT97d29C/gP4Dngx8COGTz/N4BHgR1mtosgwA+4+xDwPoJvB54D0sC/hz/zOeAOM/sVwQeMabl7O0FXo126oFZEljpzn6o7pIiIiIiILCZquRcRERERiQiFexERERGRiFC4FxERERGJCIV7EREREZGIULgXEREREYkIhXsRERERkYhQuBcRERERiYj/B1FUwz6/KLhnAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Graph speed of mieda algorithm on increasing number of intervals\n", + "plotSingleSpeed(run_interval_counts, run_seconds_elapsed)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- run 1 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6bc908c2c2fa4c42a332296bd95f97d5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "iterative_counts, iterative_time = measureBulkTime(it_merge.union, 1, time_limit=60)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- run 1 ---\n" + ] + }, { "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "77d68462872f4bc18c44343e8ad069bd", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "[Text(6.675000000000004, 0.5, 'Seconds Elapsed\\n'),\n", - " Text(0.5, 6.800000000000011, '\\nInterval Count')]" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, - "execution_count": 17, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 2 ---\n" + ] }, { "data": { - "image/png": "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\n", + "application/vnd.jupyter.widget-view+json": { + "model_id": "a1bc2e6987ae499990b9952674b0ae2e", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "
" + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" ] }, - "metadata": { - "needs_background": "light" + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 3 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a9b6a66741cf4e9098b9d1315e6f48a0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] }, + "metadata": {}, "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 4 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "67ce0234bba3442abb9db336fa277976", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 5 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b5f474ff58d44f5aa4e45bc537a845fe", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 6 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "807d500019984258a4d5b3cc510f0c87", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 7 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f26b59cc9c5c4930a5c16a8cf19a2963", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 8 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4675736515d041dcbb7747bf8add1d1d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 9 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cf6370faa1274a8fa121359c1574167b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "--- run 10 ---\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cf99123dfdd04e44b3e09b7c9b142840", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] } ], "source": [ - "g = sns.lmplot(\n", - " x=\"interval_count\", \n", - " y=\"seconds_elapsed\", \n", - " data=df_runs,\n", - " order=2,\n", - " height=7,\n", - " aspect=1.5,\n", - " line_kws={'color': 'red'}\n", - ")\n", - "g.set(ylim=(-.05, 1.5))\n", - "ax = plt.gca()\n", - "ax.set_title('Seconds Elapsed by Interval Count')\n", - "ax.set(xlabel='\\nInterval Count', ylabel='Seconds Elapsed\\n')" + "iterative_opt_counts, iterative_opt_time = measureBulkTime(itop_merge.union, 10)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "algorithms = [\n", + " {\n", + " \"interval_count\": run_interval_counts,\n", + " \"seconds_elapsed\": run_seconds_elapsed,\n", + " \"algorithm\": \"mieda\"\n", + " },\n", + " {\n", + " \"interval_count\": iterative_counts,\n", + " \"seconds_elapsed\": iterative_time,\n", + " \"algorithm\": \"iterative\"\n", + " },\n", + " {\n", + " \"interval_count\": iterative_opt_counts,\n", + " \"seconds_elapsed\": iterative_opt_time,\n", + " \"algorithm\": \"iterative optimized\"\n", + " }\n", + "]" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "image/png": "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IiLSA7388stAegG83+9PeDw6gG+9V1eLDuCffvppBgwYkPT15513HjfccEM2upYxCuDjSGVu9+gA3qUMvIiIiHRS47PPsfdfLuazKaex918upvHZ5zrdZklJcKHJG264gRdeeIHx48dz22234ff7uf7665k8eTKVlZUsWbIEgHXr1jFjxgwuvfRSxo4dC8AFF1zAxIkTGT16NEuXLg2319jYyPjx48Mrsbbe6+KLL+bpp58O92HevHmsWrUq7j2j3XrrrYwZM4YxY8Zw++23A8EXkFGjRvGd73yHyspKLrroIhoaGli0aBG7d+9mxowZzJgxA4ARI0awb9++8DXz589nzJgxXHbZZaxdu5apU6dSUVHBq6++CsDy5cu55pprABg/fnz4p7CwkOeff57Dhw9z5ZVXMnnyZL74xS/y2GOPBf+9GhuZO3culZWVXHzxxTQ2Nsb4NJmhaSTjSGkWGr9KaERERCRzGp99jtqf/BTy8zAD+uPf4wlu/89/U3jGjE63f/PNN3PLLbfw5JNPArB06VL69+/Pa6+9RlNTE1OnTmXmzJkAvPrqq2zdupWRI0cCsGzZMgYOHEhjYyOTJ09mzpw53Hzzzdx5551s3ry53b3mzp3LypUrOffcc2lubuYf//gHixcv5p577ol5z9b7AGzatIl7772XV155BWstp556Kl/5ylcoKyvjvffe45577mHq1KlceeWV/P73v+e6667j1ltv5bnnnmPw4MHt+vLBBx/w0EMPsXTpUiZPnsyKFSt48cUXefzxx7npppt49NFH25zf+nmeeOIJfvOb33Daaafx85//nDPOOINly5Zx8OBBTjnlFM466yyWLFlCUVERW7ZsYcuWLUyYMKHT/07xKAOfAaqBFxERkUyqX3wX5OfhKCrCGIOjqAjy84L7s2DNmjXcf//9jB8/nlNPPZX9+/dTXV0NwCmnnNImqF60aBHjxo1jypQp7Ny5M3xePOeccw7PPvssTU1N/PWvf2XatGkUFhYmvGerF198kQsvvJDi4mJKSkqYPXs2L7zwAgDDhw9n6tSpAFx++eW8+OKLHX7OkSNHMnbsWBwOB6NHj+bMM8/EGMPYsWPZvn17zGuqq6u5/vrrWblyJXl5eaxZs4abb76Z8ePHM336dLxeLzt27GD9+vVcfvnlAFRWVlJZWdlhf9KlDHwcmgdeRERE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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plotMultiSpeed(algorithms)" + ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -598,7 +983,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -629,9 +1014,9 @@ ], "metadata": { "kernelspec": { - "display_name": "venv", + "display_name": "Python 3", "language": "python", - "name": "venv" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -643,7 +1028,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.7.3" } }, "nbformat": 4, diff --git a/tests/test_merge_iterative.py b/tests/test_merge_iterative.py new file mode 100644 index 0000000..08ea8cf --- /dev/null +++ b/tests/test_merge_iterative.py @@ -0,0 +1,732 @@ +# Authors: Valentino Constantinou , Asitang Mishra +# License: Apache 2.0 + +from comparisons.iterative import Merge + +import datetime +import pytest +from operator import itemgetter + + +# fixtures +@pytest.fixture() +def interval_inputs() -> list: + """ + This fixture generates a set of all possible scenarios for consideration of one interval against another. + :return: a list of intervals which contains all possible scenarios. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 3, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends before A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 3, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends at the same time as A also + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts wholly after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs() -> list: + """ + This fixture generates a set of correct outputs against the scenarios provided in the output of interval_inputs(). + :return: a list of intervals which contains the correct output for all possible scenarios. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1', '2'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 3, 1, 0), + 'set_items': {'2', '1'}}, + {'start': datetime.datetime(2020, 1, 3, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1'}} + ] + ) + + # B starts at the same time as A and ends after A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2'}} + ] + ) + + # B starts at the same time as A and ends before A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 3, 1, 0), + 'set_items': {'1', '2'}}, + {'start': datetime.datetime(2020, 1, 3, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1'}} + ] + ) + + # B starts at the same time as A and ends at the same time as A also + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}} + ] + ) + + # B starts wholly after A + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + return outputs + + +@pytest.fixture() +def complex_interval_inputs() -> list: + """ + This fixture generates a set of complex scenarios for consideration of one interval against another. + :return: a list of intervals which contains some more complex scenarios. + """ + + # create a list to store various interval types + intervals = list() + + # B starts after A, C starts at the same time as B but ends before B + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + ] + ) + + # B starts after A, C starts at the same time as B but ends after + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B, but A contains 2 items + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "A"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + # now however there is a "dangling" interval in isolation + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}}, + {"start": datetime.datetime(2020, 1, 11, 1, 0, 0), "finish": datetime.datetime(2020, 1, 12, 1, 0, 0), + "set_items": {"5"}} + ] + ) + + # test for the ability to handle more than one duplicate interval in the input data + intervals.append( + [ + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477939605, 'finish': 1477977748, 'set_items': {'4'}}, + {'start': 1477939605, 'finish': 1477977748, 'set_items': {'4'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}} + ] + ) + + return intervals + + +@pytest.fixture() +def complex_interval_outputs() -> list: + """ + This fixture generates a set of correct outputs against the scenarios provided in the output of + complex_interval_inputs(). + :return: a list of intervals which contains the correct output for all scenarios in complex_interval_inputs(). + """ + + # create a list to store the various outputs + outputs = list() + + # B starts after A, C starts at the same time as B but ends before B + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"3", "2", "1"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3", "2"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A, C starts at the same time as B but ends after + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1', '3'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}}, + {'start': datetime.datetime(2020, 1, 6, 1, 0), 'finish': datetime.datetime(2020, 1, 7, 1, 0), + 'set_items': {'3'}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1', '3'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B, but A contains 2 items + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1', 'A'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '3', '1', 'A'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "2", "3"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"2", "3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2", "4"}}, + {"start": datetime.datetime(2020, 1, 6, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + # now however there is a "dangling" interval in isolation + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "2", "3"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"2", "3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2", "4"}}, + {"start": datetime.datetime(2020, 1, 6, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}}, + {"start": datetime.datetime(2020, 1, 11, 1, 0, 0), "finish": datetime.datetime(2020, 1, 12, 1, 0, 0), + "set_items": {"5"}} + ] + ) + + # test for the ability to handle more than one duplicate interval in the input data + outputs.append( + [ + {'start': 1477875126, 'finish': 1477901090, 'set_items': {'1'}}, + {'start': 1477901090, 'finish': 1477915725, 'set_items': {'1', '2'}}, + {'start': 1477915725, 'finish': 1477920079, 'set_items': {'1', '2', '3'}}, + {'start': 1477920079, 'finish': 1477938541, 'set_items': {'2', '3'}}, + {'start': 1477938541, 'finish': 1477939605, 'set_items': {'3'}}, + {'start': 1477939605, 'finish': 1477961500, 'set_items': {'3', '4'}}, + {'start': 1477961500, 'finish': 1477977748, 'set_items': {'3', '4', '5'}}, + {'start': 1477977748, 'finish': 1477987473, 'set_items': {'3', '5'}}, + {'start': 1477987473, 'finish': 1478006402, 'set_items': {'5'}} + ] + ) + + + return outputs + + +@pytest.fixture() +def interval_inputs_integers() -> list: + """ + This fixture generates a set of intervals with integers as indices. + :return: a list of intervals to use for testing. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 6, "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 4, "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 3, "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs_integers() -> list: + """ + This fixture generates a set of correct outputs against intervals with integers as indices. + :return: a list of intervals which contains the correct output for the integer-indexed intervals. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 4, 'set_items': {'1', '2'}}, + {'start': 4, 'finish': 6, 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 4, 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 3, 'set_items': {'2', '1'}}, + {'start': 3, 'finish': 4, 'set_items': {'1'}} + ] + ) + + return outputs + + +@pytest.fixture() +def interval_inputs_strings() -> list: + """ + This fixture generates a set of intervals with strings as indices. + :return: a list of intervals to use for testing. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "F", "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "D", "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "C", "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs_strings() -> list: + """ + This fixture generates a set of correct outputs against intervals with strings as indices. + :return: a list of intervals which contains the correct output for the string-indexed intervals. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "D", 'set_items': {'1', '2'}}, + {'start': "D", 'finish': "F", 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "D", 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "C", 'set_items': {'2', '1'}}, + {'start': "C", 'finish': "D", 'set_items': {'1'}} + ] + ) + + return outputs + + +# tests +def test_interval_types(interval_inputs, interval_outputs) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs: A set of all types of interval overlaps. + :param interval_outputs: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs, interval_outputs): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +def test_complex_interval_types(complex_interval_inputs, complex_interval_outputs) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param complex_interval_inputs: A set of complex interval overlaps. + :param complex_interval_outputs: A set of outputs for all complex interval overlaps. + :return: None + """ + + for i, o in zip(complex_interval_inputs, complex_interval_outputs): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert len(out) == len(o) + + o = sorted(o, key=itemgetter('start', 'finish')) + assert out == o + for out, expected in zip(out, o): + assert out == expected + + +def test_interval_integers(interval_inputs_integers, interval_outputs_integers) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs_integers: A set of all types of interval overlaps. + :param interval_outputs_integers: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs_integers: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs_integers, interval_outputs_integers): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +def test_interval_strings(interval_inputs_strings, interval_outputs_strings) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs_strings: A set of all types of interval overlaps. + :param interval_outputs_strings: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs_strings: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs_strings, interval_outputs_strings): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +# def test_incorrect_format(interval_inputs) -> None: +# """ +# Ensures that the correct type and number of warnings are issued when the user uses a +# list of items instead of a set, which is the correct formatting. +# :param interval_inputs: A set of all types of interval overlaps. +# :return: None +# """ + +# # convert the set to a list, which is the incorrect input format +# for i in interval_inputs: + +# for j in i: +# j["set_items"] = sorted(j["set_items"]) + +# with pytest.warns(UserWarning) as record: + +# # try to do a merge with a list +# Merge.union(i) + + +def test_alternate_attribute_key(interval_inputs) -> None: + """ + Ensures that an attribute other than "set_items" can be used as input. + :param interval_inputs: A set of all types of interval overlaps. + :return: None + """ + + # first change the attribute from "set_items" to "items" + for i in interval_inputs: + for j in i: + j["items"] = j["set_items"] + del j["set_items"] + + # ensure there's some output and that the key is correct + for i in interval_inputs: + out = Merge.union(i, key="items") + for j in out: + assert "items" in j.keys() + + +# def test_return_graph(interval_inputs) -> None: +# """ +# Ensures that a netwworkx.DiGraph object is returned with 'return_graph' is +# set to True. +# :param interval_inputs: A set of all types of interval overlaps. +# :return: None +# """ + +# for i in interval_inputs: +# out = Merge.union(i, return_graph=True) +# assert type(out).__name__ == "DiGraph" + + +def test_nx_exception() -> None: + + """ + Tests an exception which may occur in some scenarios such as one in which a "waterfall" of intervals occurs. + :return: None + """ + + # create a seed interval + seed_interval = [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}} + ] + + # let's create 10 intervals + interval_counts = list(range(0, 100, 10)) + + inputs = list() + intervals = list() + + # create 10 intervals in a sequence with the same overlap + for i in interval_counts: + intervals = seed_interval + list() + for j in range(i): + + # get the last interval + update_interval = intervals[-1] + + # add 2 hours to the start and end times + new_interval = update_interval.copy() + new_interval["start"] = update_interval["start"] + datetime.timedelta(hours=2) + new_interval["finish"] = update_interval["finish"] + datetime.timedelta(hours=2) + + # update the set items + new_interval["set_items"] = {str(j)} + + # append the interval(s) + intervals.append(new_interval) + + inputs.append(intervals) + + # make sure we run without errors and return a result + out = Merge.union(intervals=intervals) + assert out is not None diff --git a/tests/test_merge_iterative_optimized.py b/tests/test_merge_iterative_optimized.py new file mode 100644 index 0000000..eba87b8 --- /dev/null +++ b/tests/test_merge_iterative_optimized.py @@ -0,0 +1,732 @@ +# Authors: Valentino Constantinou , Asitang Mishra +# License: Apache 2.0 + +from comparisons.iterative_optimized import Merge + +import datetime +import pytest +from operator import itemgetter + + +# fixtures +@pytest.fixture() +def interval_inputs() -> list: + """ + This fixture generates a set of all possible scenarios for consideration of one interval against another. + :return: a list of intervals which contains all possible scenarios. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 3, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends before A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 3, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts at the same time as A and ends at the same time as A also + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts wholly after A + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs() -> list: + """ + This fixture generates a set of correct outputs against the scenarios provided in the output of interval_inputs(). + :return: a list of intervals which contains the correct output for all possible scenarios. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1', '2'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 3, 1, 0), + 'set_items': {'2', '1'}}, + {'start': datetime.datetime(2020, 1, 3, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1'}} + ] + ) + + # B starts at the same time as A and ends after A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2'}} + ] + ) + + # B starts at the same time as A and ends before A + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 3, 1, 0), + 'set_items': {'1', '2'}}, + {'start': datetime.datetime(2020, 1, 3, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'1'}} + ] + ) + + # B starts at the same time as A and ends at the same time as A also + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1'}} + ] + ) + + # B starts wholly after A + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + return outputs + + +@pytest.fixture() +def complex_interval_inputs() -> list: + """ + This fixture generates a set of complex scenarios for consideration of one interval against another. + :return: a list of intervals which contains some more complex scenarios. + """ + + # create a list to store various interval types + intervals = list() + + # B starts after A, C starts at the same time as B but ends before B + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + ] + ) + + # B starts after A, C starts at the same time as B but ends after + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 7, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B, but A contains 2 items + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "A"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"3"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + # now however there is a "dangling" interval in isolation + intervals.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}}, + {"start": datetime.datetime(2020, 1, 11, 1, 0, 0), "finish": datetime.datetime(2020, 1, 12, 1, 0, 0), + "set_items": {"5"}} + ] + ) + + # test for the ability to handle more than one duplicate interval in the input data + intervals.append( + [ + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477875126, 'finish': 1477920079, 'set_items': {'1'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477901090, 'finish': 1477938541, 'set_items': {'2'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477915725, 'finish': 1477987473, 'set_items': {'3'}}, + {'start': 1477939605, 'finish': 1477977748, 'set_items': {'4'}}, + {'start': 1477939605, 'finish': 1477977748, 'set_items': {'4'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}}, + {'start': 1477961500, 'finish': 1478006402, 'set_items': {'5'}} + ] + ) + + return intervals + + +@pytest.fixture() +def complex_interval_outputs() -> list: + """ + This fixture generates a set of correct outputs against the scenarios provided in the output of + complex_interval_inputs(). + :return: a list of intervals which contains the correct output for all scenarios in complex_interval_inputs(). + """ + + # create a list to store the various outputs + outputs = list() + + # B starts after A, C starts at the same time as B but ends before B + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"3", "2", "1"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"3", "2"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2"}} + ] + ) + + # B starts after A, C starts at the same time as B but ends after + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1', '3'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}}, + {'start': datetime.datetime(2020, 1, 6, 1, 0), 'finish': datetime.datetime(2020, 1, 7, 1, 0), + 'set_items': {'3'}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '1', '3'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}} + ] + ) + + # B starts after A, C starts at the same time as B and ends at the same time as B, but A contains 2 items + outputs.append( + [ + {'start': datetime.datetime(2020, 1, 1, 1, 0), 'finish': datetime.datetime(2020, 1, 2, 1, 0), + 'set_items': {'1', 'A'}}, + {'start': datetime.datetime(2020, 1, 2, 1, 0), 'finish': datetime.datetime(2020, 1, 4, 1, 0), + 'set_items': {'2', '3', '1', 'A'}}, + {'start': datetime.datetime(2020, 1, 4, 1, 0), 'finish': datetime.datetime(2020, 1, 6, 1, 0), + 'set_items': {'2', '3'}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "2", "3"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"2", "3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2", "4"}}, + {"start": datetime.datetime(2020, 1, 6, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}} + ] + ) + + # B starts after A, but C starts at the same time as B and ends before. D starts at the end time of C and ends last. + # now however there is a "dangling" interval in isolation + outputs.append( + [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 2, 1, 0, 0), + "set_items": {"1"}}, + {"start": datetime.datetime(2020, 1, 2, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1", "2", "3"}}, + {"start": datetime.datetime(2020, 1, 4, 1, 0, 0), "finish": datetime.datetime(2020, 1, 5, 1, 0, 0), + "set_items": {"2", "3"}}, + {"start": datetime.datetime(2020, 1, 5, 1, 0, 0), "finish": datetime.datetime(2020, 1, 6, 1, 0, 0), + "set_items": {"2", "4"}}, + {"start": datetime.datetime(2020, 1, 6, 1, 0, 0), "finish": datetime.datetime(2020, 1, 8, 1, 0, 0), + "set_items": {"4"}}, + {"start": datetime.datetime(2020, 1, 11, 1, 0, 0), "finish": datetime.datetime(2020, 1, 12, 1, 0, 0), + "set_items": {"5"}} + ] + ) + + # test for the ability to handle more than one duplicate interval in the input data + outputs.append( + [ + {'start': 1477875126, 'finish': 1477901090, 'set_items': {'1'}}, + {'start': 1477901090, 'finish': 1477915725, 'set_items': {'1', '2'}}, + {'start': 1477915725, 'finish': 1477920079, 'set_items': {'1', '2', '3'}}, + {'start': 1477920079, 'finish': 1477938541, 'set_items': {'2', '3'}}, + {'start': 1477938541, 'finish': 1477939605, 'set_items': {'3'}}, + {'start': 1477939605, 'finish': 1477961500, 'set_items': {'3', '4'}}, + {'start': 1477961500, 'finish': 1477977748, 'set_items': {'3', '4', '5'}}, + {'start': 1477977748, 'finish': 1477987473, 'set_items': {'3', '5'}}, + {'start': 1477987473, 'finish': 1478006402, 'set_items': {'5'}} + ] + ) + + + return outputs + + +@pytest.fixture() +def interval_inputs_integers() -> list: + """ + This fixture generates a set of intervals with integers as indices. + :return: a list of intervals to use for testing. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 6, "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 4, "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": 1, "finish": 4, "set_items": {"1"}}, + {"start": 2, "finish": 3, "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs_integers() -> list: + """ + This fixture generates a set of correct outputs against intervals with integers as indices. + :return: a list of intervals which contains the correct output for the integer-indexed intervals. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 4, 'set_items': {'1', '2'}}, + {'start': 4, 'finish': 6, 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 4, 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': 1, 'finish': 2, 'set_items': {'1'}}, + {'start': 2, 'finish': 3, 'set_items': {'2', '1'}}, + {'start': 3, 'finish': 4, 'set_items': {'1'}} + ] + ) + + return outputs + + +@pytest.fixture() +def interval_inputs_strings() -> list: + """ + This fixture generates a set of intervals with strings as indices. + :return: a list of intervals to use for testing. + """ + + # create a list to store various interval types + intervals = list() + + # B starts and ends after A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "F", "set_items": {"2"}} + ] + ) + + # B starts after A but ends at the same time as A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "D", "set_items": {"2"}} + ] + ) + + # B starts after A and ends before A + intervals.append( + [ + {"start": "A", "finish": "D", "set_items": {"1"}}, + {"start": "B", "finish": "C", "set_items": {"2"}} + ] + ) + + return intervals + + +@pytest.fixture() +def interval_outputs_strings() -> list: + """ + This fixture generates a set of correct outputs against intervals with strings as indices. + :return: a list of intervals which contains the correct output for the string-indexed intervals. + """ + + # create a list to store the various outputs + outputs = list() + + # B starts and ends after A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "D", 'set_items': {'1', '2'}}, + {'start': "D", 'finish': "F", 'set_items': {'2'}} + ] + ) + + # B starts after A but ends at the same time as A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "D", 'set_items': {'2', '1'}} + ] + ) + + # B starts after A and ends before A + outputs.append( + [ + {'start': "A", 'finish': "B", 'set_items': {'1'}}, + {'start': "B", 'finish': "C", 'set_items': {'2', '1'}}, + {'start': "C", 'finish': "D", 'set_items': {'1'}} + ] + ) + + return outputs + + +# tests +def test_interval_types(interval_inputs, interval_outputs) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs: A set of all types of interval overlaps. + :param interval_outputs: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs, interval_outputs): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +def test_complex_interval_types(complex_interval_inputs, complex_interval_outputs) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param complex_interval_inputs: A set of complex interval overlaps. + :param complex_interval_outputs: A set of outputs for all complex interval overlaps. + :return: None + """ + + for i, o in zip(complex_interval_inputs, complex_interval_outputs): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert len(out) == len(o) + + o = sorted(o, key=itemgetter('start', 'finish')) + assert out == o + for out, expected in zip(out, o): + assert out == expected + + +def test_interval_integers(interval_inputs_integers, interval_outputs_integers) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs_integers: A set of all types of interval overlaps. + :param interval_outputs_integers: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs_integers: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs_integers, interval_outputs_integers): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +def test_interval_strings(interval_inputs_strings, interval_outputs_strings) -> None: + """ + For each of the available input types, tests whether the output is correct. + :param interval_inputs_strings: A set of all types of interval overlaps. + :param interval_outputs_strings: A set of outputs for all types of interval overlaps. + :return: None + """ + + for output in interval_outputs_strings: + for interval in output: + interval["set_items"] = set(sorted(interval["set_items"], reverse=True)) + + for i, o in zip(interval_inputs_strings, interval_outputs_strings): + out = sorted(Merge.union(i), key=itemgetter('start', 'finish')) + assert out == sorted(o, key=itemgetter('start', 'finish')) + + +# def test_incorrect_format(interval_inputs) -> None: +# """ +# Ensures that the correct type and number of warnings are issued when the user uses a +# list of items instead of a set, which is the correct formatting. +# :param interval_inputs: A set of all types of interval overlaps. +# :return: None +# """ + +# # convert the set to a list, which is the incorrect input format +# for i in interval_inputs: + +# for j in i: +# j["set_items"] = sorted(j["set_items"]) + +# with pytest.warns(UserWarning) as record: + +# # try to do a merge with a list +# Merge.union(i) + + +def test_alternate_attribute_key(interval_inputs) -> None: + """ + Ensures that an attribute other than "set_items" can be used as input. + :param interval_inputs: A set of all types of interval overlaps. + :return: None + """ + + # first change the attribute from "set_items" to "items" + for i in interval_inputs: + for j in i: + j["items"] = j["set_items"] + del j["set_items"] + + # ensure there's some output and that the key is correct + for i in interval_inputs: + out = Merge.union(i, key="items") + for j in out: + assert "items" in j.keys() + + +# def test_return_graph(interval_inputs) -> None: +# """ +# Ensures that a netwworkx.DiGraph object is returned with 'return_graph' is +# set to True. +# :param interval_inputs: A set of all types of interval overlaps. +# :return: None +# """ + +# for i in interval_inputs: +# out = Merge.union(i, return_graph=True) +# assert type(out).__name__ == "DiGraph" + + +def test_nx_exception() -> None: + + """ + Tests an exception which may occur in some scenarios such as one in which a "waterfall" of intervals occurs. + :return: None + """ + + # create a seed interval + seed_interval = [ + {"start": datetime.datetime(2020, 1, 1, 1, 0, 0), "finish": datetime.datetime(2020, 1, 4, 1, 0, 0), + "set_items": {"1"}} + ] + + # let's create 10 intervals + interval_counts = list(range(0, 100, 10)) + + inputs = list() + intervals = list() + + # create 10 intervals in a sequence with the same overlap + for i in interval_counts: + intervals = seed_interval + list() + for j in range(i): + + # get the last interval + update_interval = intervals[-1] + + # add 2 hours to the start and end times + new_interval = update_interval.copy() + new_interval["start"] = update_interval["start"] + datetime.timedelta(hours=2) + new_interval["finish"] = update_interval["finish"] + datetime.timedelta(hours=2) + + # update the set items + new_interval["set_items"] = {str(j)} + + # append the interval(s) + intervals.append(new_interval) + + inputs.append(intervals) + + # make sure we run without errors and return a result + out = Merge.union(intervals=intervals) + assert out is not None