from tkinter import * from datetime import date # Conversion functions def round_ans(val): return "{:.2f}".format(val) def cm_to_inches(value): return round_ans(value / 2.54) def m_to_feet(value): return round_ans(value * 3.28084) def km_to_miles(value): return round_ans(value * 0.621371) class MetricConverter: def __init__(self): self.history = [] # Store conversion history self.metric_frame = Frame(padx=10, pady=10) self.metric_frame.grid() self.heading = Label(self.metric_frame, text="Metric Converter", font=("Arial", 16, "bold")) self.heading.grid(row=0, column=0, columnspan=2, pady=10) # Entry for user input self.input_label = Label(self.metric_frame, text="Enter Value:") self.input_label.grid(row=1, column=0, sticky="w") self.input_entry = Entry(self.metric_frame) self.input_entry.grid(row=1, column=1) # Dropdown for conversions self.conversion_options = ["cm to inches", "m to feet", "km to miles"] self.selected_conversion = StringVar() self.selected_conversion.set(self.conversion_options[0]) self.dropdown = OptionMenu(self.metric_frame, self.selected_conversion, *self.conversion_options) self.dropdown.grid(row=2, column=0, columnspan=2, pady=5) # Convert button self.convert_button = Button(self.metric_frame, text="Convert", bg="#0000FF", fg="#FFFFFF", font=("Arial", 14, "bold"), command=self.perform_conversion) self.convert_button.grid(row=3, column=0, columnspan=2, pady=7) # Output label self.output_label = Label(self.metric_frame, font=("Arial", 12)) self.output_label.grid(row=4, column=0, columnspan=2, pady=5) # Help button self.to_help_button = Button(self.metric_frame, text="Help / Info", bg="#60A917", fg="#FFFFFF", font=("Arial", 12, "bold"), command=self.to_help) self.to_help_button.grid(row=5, column=0, columnspan=2, pady=10) # History/Export button self.to_history_button = Button(self.metric_frame, text="History / Export", bg="#60A917", fg="#FFFFFF", font=("Arial", 12, "bold"), command=self.to_history) self.to_history_button.grid(row=6, column=0, columnspan=2, pady=10) def perform_conversion(self): user_input = self.input_entry.get().strip() try: value = float(user_input) # Check for valid range if value < 0.1: self.output_label.config(text="Please enter a number\n0.1 or greater.", fg="#9C0000") self.input_entry.config(bg="#F4CCCC") return elif value > 10000: self.output_label.config(text="Please enter a number\n10,000 or below.", fg="#9C0000") self.input_entry.config(bg="#F4CCCC") return conversion = self.selected_conversion.get() # Reset entry background color (back to white or default) self.input_entry.config(bg="white") if conversion == "cm to inches": result = cm_to_inches(value) unit = "inches" elif conversion == "m to feet": result = m_to_feet(value) unit = "feet" elif conversion == "km to miles": result = km_to_miles(value) unit = "miles" else: result = "Invalid conversion" unit = "" # Store the calculation history history_entry = f"{value} {conversion} = {result} {unit}" self.history.append(history_entry) # Update the result on the interface self.output_label.config(text=f"{result} {unit}", fg="green") except ValueError: self.output_label.config(text="Please enter a valid number.", fg="#9C0000") self.input_entry.delete(0, END) # Clear the entry self.input_entry.config(bg="#F4CCCC") # Turn it red # display the error if necessary def to_help(self): DisplayHelp() def to_history(self): HistoryExport(self, self.history) class DisplayHelp: def __init__(self): background = "#FFFFFF" self.help_box = Toplevel() self.help_box.title("Help") self.help_frame = Frame(self.help_box, bg=background, padx=10, pady=10) self.help_frame.grid() self.help_heading_label = Label(self.help_frame, text="Help / Info", font=("Arial", "14", "bold"), bg=background) self.help_heading_label.grid(row=0) help_text = ( "To use this metric converter:\n\n" "- Enter the number you want to convert in the text box.\n" "- Choose the conversion type from the dropdown menu.\n" "- Click the 'Convert' button to see the result.\n\n" "Available conversions:\n" "• cm to inches\n" "• m to feet\n" "• km to miles\n\n" "Note: Only positive numbers are valid for length." ) self.help_text_label = Label(self.help_frame, text=help_text, wraplength=350, justify="left", bg=background) self.help_text_label.grid(row=1, pady=10) self.dismiss_button = Button(self.help_frame, text="Dismiss", font=("Arial", 12, "bold"), bg="#FF0000", fg="#FFFFFF", command=self.close_help) self.dismiss_button.grid(row=2) def close_help(self): self.help_box.destroy() class HistoryExport: def __init__(self, partner, history): self.history_box = Toplevel() self.history_box.title("History / Export") self.history_frame = Frame(self.history_box) self.history_frame.grid() # background color for history calc_back = "#C79FEF" if len(history) < 10 else "#7BC8F6" calc_amount = f"your recent calculations - showing {len(history)}" # labels for history section recent_intro_txt = f"Below are {calc_amount} calculations:" history_string = "\n".join(reversed(history)) history_labels_list = [ ["History / Export", ("Arial", "16", "bold"), None], [recent_intro_txt, ("Arial", "11"), None], [history_string, ("Arial", "14"), calc_back], ] history_label_ref = [] for count, item in enumerate(history_labels_list): make_label = Label(self.history_box, text=item[0], font=item[1], bg=item[2], wraplength=300, justify="left", pady=10, padx=20) make_label.grid(row=count) history_label_ref.append(make_label) self.export_filename_label = history_label_ref[2] # Buttons to export or close self.hist_button_frame = Frame(self.history_box) self.hist_button_frame.grid(row=3) button_details_list = [ ["Export", "#004C99", lambda: self.export_data(history), 0, 0], ["Close", "#FF0000", lambda: self.close_history(partner), 0, 1], ] for btn in button_details_list: self.make_button = Button(self.hist_button_frame, font=("Arial", "12", "bold"), text=btn[0], bg=btn[1], fg="#FFFFFF", width=12, command=btn[2]) self.make_button.grid(row=btn[3], column=btn[4], padx=10, pady=10) def export_data(self, history): today = date.today() day = today.strftime("%d") month = today.strftime("%m") year = today.strftime("%Y") file_name = f"metric_conversions_{year}_{month}_{day}.txt" success_string = f"Export Successful! The file is called {file_name}" self.export_filename_label.config(fg="#009900", text=success_string) # Write data to file with open(file_name, "w") as text_file: text_file.write(f"***** Metric Conversion History ******\n") text_file.write(f"Generated: {day}/{month}/{year}\n\n") text_file.write("Here is your conversion history (oldest to newest)...\n") for item in history: text_file.write(item + "\n") def close_history(self, partner): partner.to_help_button.config(state=NORMAL) self.history_box.destroy() # Main routine if __name__ == "__main__": root = Tk() root.title("Metric Converter") MetricConverter() root.mainloop()