import os import matplotlib import pandas as pd matplotlib.use("Agg") import matplotlib.pyplot as plt # Constants PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__)) RESULTS_DIR = os.path.join(PROJECT_ROOT, "results") TABLE_DATA_FILE = os.path.join(RESULTS_DIR, "table_data.csv") # Ensure the results directory exists os.makedirs(RESULTS_DIR, exist_ok=True) def load_table_data(file_path): """Loads table data from a CSV file into a pandas DataFrame.""" return pd.read_csv(file_path) def format_number(x): """Formats a number to display in thousands (K) or millions (M).""" if x >= 1e9: return f"{x / 1e9:.2f}B" elif x >= 1e6: return f"{x / 1e6:.2f}M" elif x >= 1e3: return f"{x / 1e3:.2f}K" else: return f"{x:.0f}" def format_large_numbers(data): """Applies number formatting to all numeric columns except 'Input Size'.""" for column in data.columns[1:]: # Skip 'Input Size' data[column] = data[column].apply(format_number) return data def generate_table_markdown(data, output_path): """Generates a markdown file containing the formatted data table.""" with open(output_path, "w") as file: file.write("# Sorting Algorithm Comparison Tables\n\n") file.write(data.to_markdown(index=False)) print(f"Markdown table saved to {output_path}") def generate_table_image(data, image_output_path): """Generates and saves an image of the data table.""" # Create figure and axis fig, ax = plt.subplots(figsize=(18, 9)) ax.axis("tight") ax.axis("off") # Set font locally for this plot plt.rcParams["font.family"] = "Arial" # Adjust column labels: wrap words and handle "Non-decreasing"/"Non-increasing" separately def wrap_label(label): # Replace specific patterns with wrapped versions label = ( label.replace("(Random) ", "(Random)\n") .replace("(Deterministic) ", "(Deterministic)\n") .replace("Non-decreasing", "Non-\ndecreasing") .replace("Non-increasing", "Non-\nincreasing") ) # Handle special case when "Sort" is in the label if "Sort" in label: algorithm, *rest = label.split("Sort", 1) return f"{algorithm}Sort\n{rest[0].strip()}" if rest else f"{algorithm}Sort" # General word wrapping return "\n".join(label.split()) # Apply wrapping to all column labels col_labels = [wrap_label(label) for label in data.columns] # Generate the table table = ax.table( cellText=data.values, colLabels=col_labels, cellLoc="center", loc="center", ) table.set_fontsize(20) num_rows, num_cols = data.shape # Customize cell properties for (row, col), cell in table.get_celld().items(): # Set cell border color cell.set_edgecolor("#CCD3DB") if row == 0: # Header row formatting cell.set_text_props( weight="bold", ha="right" if col == 0 else "left", linespacing=1.5 ) cell.set_facecolor("#ffffff") cell.set_height(0.20) else: # Data row formatting if col == 0: # Make 'Input Size' column bold cell.set_text_props(weight="bold", ha="right") else: cell.set_text_props(ha="left") # Alternate row colors cell.set_facecolor("#ffffff" if (row - 1) % 2 == 0 else "#f6f8fa") cell.set_height(0.06) # Adjust column widths for col_index in range(num_cols): table.auto_set_column_width(col=[col_index]) # Add a title to the figure title_text = "Number of Comparisons Made by Sorting Algorithms for Various Input Sizes on Sorted Datasets" fig.text(0.5, 0.88, title_text, ha="center", fontsize=20, fontweight="bold") # Add a legend for "K" and "M" notation at the bottom legend_text = "* K: thousands\n* M: millions\n* B: billions" fig.text(0.05, 0.05, legend_text, ha="left", fontsize=14, fontweight="bold") # Apply tight layout to minimize white space plt.tight_layout() # Save the image with a tight bounding box plt.savefig(image_output_path, bbox_inches="tight", pad_inches=0.1, dpi=150) plt.close() print(f"Table image saved to {image_output_path}") def main(): # Load and format data table_data = load_table_data(TABLE_DATA_FILE) formatted_table_data = format_large_numbers(table_data.copy()) # Output file paths markdown_output_file = os.path.join(RESULTS_DIR, "comparison_table.md") image_output_file = os.path.join(RESULTS_DIR, "comparison_table.png") # Generate markdown and image outputs generate_table_markdown(formatted_table_data, markdown_output_file) generate_table_image(formatted_table_data, image_output_file) if __name__ == "__main__": main()