from tkinter import * # Trial - Entry Validation v2 # Purpose: Refine the validation to use the has_errors flag pattern, # which is cleaner when there are multiple things to check. # This matches the pattern used in the Distance Converter. class ValidationTrial: def __init__(self): self.frame = Frame(padx=10, pady=10) self.frame.grid() self.heading = Label(self.frame, text="Entry Validation Trial - v2", font=("Arial", "16", "bold")) self.heading.grid(row=0) instructions = ("This version uses the has_errors flag pattern. " "It also checks if from and to units are the same.") Label(self.frame, text=instructions, wraplength=300, font=("Arial", "11"), fg="#666666").grid(row=1, pady=5) # Entry row self.input_row = Frame(self.frame) self.input_row.grid(row=2, pady=10) self.entry = Entry(self.input_row, font=("Arial", "14"), width=12) self.entry.grid(row=0, column=0, padx=(0, 10)) self.from_var = StringVar(value="km") OptionMenu(self.input_row, self.from_var, "km", "m", "cm", "mm").grid(row=0, column=1) # To unit row self.to_row = Frame(self.frame) self.to_row.grid(row=3, pady=5) Label(self.to_row, text="Convert to:", font=("Arial", "12")).grid(row=0, column=0, padx=(0, 10)) self.to_var = StringVar(value="m") OptionMenu(self.to_row, self.to_var, "km", "m", "cm", "mm").grid(row=0, column=1) # Answer / error label self.answer_error = Label(self.frame, text="Enter a distance above", font=("Arial", "13", "bold"), fg="#9C0000") self.answer_error.grid(row=4, pady=5) # Button row btn_frame = Frame(self.frame) btn_frame.grid(row=5, pady=5) Button(btn_frame, text="Convert", font=("Arial", "12", "bold"), bg="#009900", fg="#FFFFFF", width=10, command=self.check_input).grid(row=0, column=0, padx=5) Button(btn_frame, text="Clear", font=("Arial", "12", "bold"), bg="#666666", fg="#FFFFFF", width=10, command=self.clear_entry).grid(row=0, column=1, padx=5) def check_input(self): """ Uses a has_errors flag so multiple checks can be done cleanly. The error message is set inside each check, then displayed once at the end if has_errors == 'yes'. """ raw = self.entry.get() from_unit = self.from_var.get() to_unit = self.to_var.get() # Reset styling first self.answer_error.config(fg="#004C99", font=("Arial", "13", "bold")) self.entry.config(bg="#FFFFFF") error = "Please enter a valid positive number" has_errors = "no" try: value = float(raw) if value < 0: error = "Please enter a number greater than or equal to 0" has_errors = "yes" elif from_unit == to_unit: error = "Please choose two different units" has_errors = "yes" else: # All good - simulate a conversion result self.answer_error.config( text=f"Valid: converting {value} {from_unit} to {to_unit}", fg="#004C99" ) except ValueError: has_errors = "yes" # Display error if any check failed if has_errors == "yes": self.answer_error.config(text=error, fg="#9C0000") self.entry.config(bg="#F4CCCC") self.entry.delete(0, END) def clear_entry(self): self.entry.delete(0, END) self.entry.config(bg="#FFFFFF") self.answer_error.config( text="Enter a distance above", fg="#9C0000", font=("Arial", "13", "bold") ) # main routine if __name__ == "__main__": root = Tk() root.title("Validation Trial v2") ValidationTrial() root.mainloop()