+ :param test_name: Test name to be modified.
+ :type test_name: str
+ :returns: Modified test name.
+ :rtype: str
+ """
+ test_name_mod = test_name.\
+ replace(u"-ndrpdrdisc", u""). \
+ replace(u"-ndrpdr", u"").\
+ replace(u"-pdrdisc", u""). \
+ replace(u"-ndrdisc", u"").\
+ replace(u"-pdr", u""). \
+ replace(u"-ndr", u""). \
+ replace(u"1t1c", u"1c").\
+ replace(u"2t1c", u"1c"). \
+ replace(u"2t2c", u"2c").\
+ replace(u"4t2c", u"2c"). \
+ replace(u"4t4c", u"4c").\
+ replace(u"8t4c", u"4c")
+
+ return re.sub(REGEX_NIC, u"", test_name_mod)
+
+
+def _tpc_modify_displayed_test_name(test_name):
+ """Modify a test name which is displayed in a table by replacing its parts.
+
+ :param test_name: Test name to be modified.
+ :type test_name: str
+ :returns: Modified test name.
+ :rtype: str
+ """
+ return test_name.\
+ replace(u"1t1c", u"1c").\
+ replace(u"2t1c", u"1c"). \
+ replace(u"2t2c", u"2c").\
+ replace(u"4t2c", u"2c"). \
+ replace(u"4t4c", u"4c").\
+ replace(u"8t4c", u"4c")
+
+
+def _tpc_insert_data(target, src, include_tests):
+ """Insert src data to the target structure.
+
+ :param target: Target structure where the data is placed.
+ :param src: Source data to be placed into the target stucture.
+ :param include_tests: Which results will be included (MRR, NDR, PDR).
+ :type target: list
+ :type src: dict
+ :type include_tests: str
+ """
+ try:
+ if include_tests == u"MRR":
+ target.append(src[u"result"][u"receive-rate"])
+ elif include_tests == u"PDR":
+ target.append(src[u"throughput"][u"PDR"][u"LOWER"])
+ elif include_tests == u"NDR":
+ target.append(src[u"throughput"][u"NDR"][u"LOWER"])
+ except (KeyError, TypeError):
+ pass
+
+
+def _tpc_sort_table(table):
+ """Sort the table this way:
+
+ 1. Put "New in CSIT-XXXX" at the first place.
+ 2. Put "See footnote" at the second place.
+ 3. Sort the rest by "Delta".
+
+ :param table: Table to sort.
+ :type table: list
+ :returns: Sorted table.
+ :rtype: list
+ """
+
+ tbl_new = list()
+ tbl_see = list()
+ tbl_delta = list()
+ for item in table:
+ if isinstance(item[-1], str):
+ if u"New in CSIT" in item[-1]:
+ tbl_new.append(item)
+ elif u"See footnote" in item[-1]:
+ tbl_see.append(item)
+ else:
+ tbl_delta.append(item)
+
+ # Sort the tables:
+ tbl_new.sort(key=lambda rel: rel[0], reverse=False)
+ tbl_see.sort(key=lambda rel: rel[0], reverse=False)
+ tbl_see.sort(key=lambda rel: rel[-1], reverse=False)
+ tbl_delta.sort(key=lambda rel: rel[-1], reverse=True)
+
+ # Put the tables together:
+ table = list()
+ # We do not want "New in CSIT":
+ # table.extend(tbl_new)
+ table.extend(tbl_see)
+ table.extend(tbl_delta)
+
+ return table
+
+
+def _tpc_generate_html_table(header, data, output_file_name):
+ """Generate html table from input data with simple sorting possibility.
+
+ :param header: Table header.
+ :param data: Input data to be included in the table. It is a list of lists.
+ Inner lists are rows in the table. All inner lists must be of the same
+ length. The length of these lists must be the same as the length of the
+ header.
+ :param output_file_name: The name (relative or full path) where the
+ generated html table is written.
+ :type header: list
+ :type data: list of lists
+ :type output_file_name: str
+ """
+
+ df_data = pd.DataFrame(data, columns=header)
+
+ df_sorted = [df_data.sort_values(
+ by=[key, header[0]], ascending=[True, True]
+ if key != header[0] else [False, True]) for key in header]
+ df_sorted_rev = [df_data.sort_values(
+ by=[key, header[0]], ascending=[False, True]
+ if key != header[0] else [True, True]) for key in header]
+ df_sorted.extend(df_sorted_rev)
+
+ fill_color = [[u"#d4e4f7" if idx % 2 else u"#e9f1fb"
+ for idx in range(len(df_data))]]
+ table_header = dict(
+ values=[f"<b>{item}</b>" for item in header],
+ fill_color=u"#7eade7",
+ align=[u"left", u"center"]
+ )
+
+ fig = go.Figure()
+
+ for table in df_sorted:
+ columns = [table.get(col) for col in header]
+ fig.add_trace(
+ go.Table(
+ columnwidth=[30, 10],
+ header=table_header,
+ cells=dict(
+ values=columns,
+ fill_color=fill_color,
+ align=[u"left", u"right"]
+ )
+ )
+ )
+
+ buttons = list()
+ menu_items = [f"<b>{itm}</b> (ascending)" for itm in header]
+ menu_items_rev = [f"<b>{itm}</b> (descending)" for itm in header]
+ menu_items.extend(menu_items_rev)
+ for idx, hdr in enumerate(menu_items):
+ visible = [False, ] * len(menu_items)
+ visible[idx] = True
+ buttons.append(
+ dict(
+ label=hdr.replace(u" [Mpps]", u""),
+ method=u"update",
+ args=[{u"visible": visible}],
+ )
+ )
+
+ fig.update_layout(
+ updatemenus=[
+ go.layout.Updatemenu(
+ type=u"dropdown",
+ direction=u"down",
+ x=0.03,
+ xanchor=u"left",
+ y=1.045,
+ yanchor=u"top",
+ active=len(menu_items) - 1,
+ buttons=list(buttons)
+ )
+ ],
+ annotations=[
+ go.layout.Annotation(
+ text=u"<b>Sort by:</b>",
+ x=0,
+ xref=u"paper",
+ y=1.035,
+ yref=u"paper",
+ align=u"left",
+ showarrow=False
+ )
+ ]
+ )
+
+ ploff.plot(fig, show_link=False, auto_open=False, filename=output_file_name)
+
+
+def table_perf_comparison(table, input_data):
+ """Generate the table(s) with algorithm: table_perf_comparison
+ specified in the specification file.