import math import difflib import csv from datetime import datetime """this part of the coding is made to compare the user response to the valid answers for a question the script has asked. it also uses difflib to differentiate between wrong answer and right answer and then asks if 'this is the right answer or not'. """ def string_checker(question, valid_ans=("rectangle", "triangle", "square", "circle", "parallelogram", "exit")): error = f"Please enter a valid option: {', '.join(valid_ans)}" while True: user_response = input(question).strip().lower() if user_response in valid_ans: return user_response matches = [option for option in valid_ans if option.startswith(user_response)] if len(matches) == 1: return matches[0] close_match = difflib.get_close_matches(user_response, valid_ans, n=1, cutoff=0.4) if close_match: suggestion = close_match[0] confirm = input(f"Did you mean '{suggestion}'? (yes/no): ").strip().lower() if confirm in ["yes", "y"]: return suggestion print(error) """This part is the int_checker but renamed to the number_check as it also does decimals. What this feature is trying to do is stop any unknown characters from entering""" def number_check(question): while True: to_check = input(question) if to_check == "": return None try: response = float(to_check) if response <= 0: print("Please enter a number greater than 0.") else: return response except ValueError: print("Please enter a valid number or press Enter to skip.") """The calculation part of the script. After a user inputs the shape and dimensions, it calculates 👍. Each definition is question for the shape and bottom bit is calculation part,""" def rectangle_calculator(): length = number_check("Enter the length of the rectangle (in cm): ") width = number_check("Enter the width of the rectangle (in cm): ") # This part is if the user returns with nothing it prints nothing like '0cm' if length is None or width is None: return None, None # This part is the calculation bit area = length * width perimeter = 2 * (length + width) return area, perimeter def triangle_calculator(): base = number_check("Enter the base length of the triangle (in cm): ") height = number_check("Enter the height of the triangle (in cm): ") side_a = number_check("Enter the length of side A (in cm): ") side_b = number_check("Enter the length of side B (in cm): ") side_c = number_check("Enter the length of side C (in cm): ") # This part is if the user returns with nothing it prints nothing like '0cm' if None in (base, height, side_a, side_b, side_c): return None, None # This part is the calculation bit area = 0.5 * base * height perimeter = side_a + side_b + side_c return area, perimeter def square_calculator(): side = number_check("Enter the side length of the square (in cm): ") # This part is if the user returns with nothing it prints nothing like '0cm' if side is None: return None, None # This part is the calculation bit area = side ** 2 perimeter = 4 * side return area, perimeter def circle_calculator(): radius = number_check("Enter the radius of the circle (in cm): ") # This part is if the user returns with nothing it prints nothing like '0cm' if radius is None: return None, None # This part is the calculation bit area = math.pi * radius ** 2 perimeter = 2 * math.pi * radius return round(area, 2), round(perimeter, 2) def parallelogram_calculator(): base = number_check("Enter the base of the parallelogram (in cm): ") height = number_check("Enter the height of the parallelogram (in cm): ") side = number_check("Enter the side length of the parallelogram (in cm): ") # This part is if the user returns with nothing it prints nothing like '0cm' if None in (base, height, side): return None, None # This part is the calculation bit area = base * height perimeter = 2 * (base + side) return area, perimeter """This part of the script is the main part 'bread and butter' its what links calculater to the string_checker ect. It displays the welcome message, repeatedly asks what shape the user wants and calculates and stores the results.""" def main(): print("Geometry Calculator - Area & Perimeter") # This history section is where the coding goes when being sorted into a list history = [] # This while true statement calls the string_checker function, it validates the shape chosen by the user while True: shape = string_checker( "Choose a shape (rectangle, triangle, square, circle, parallelogram) or type 'exit' to end: ", valid_ans=("rectangle", "triangle", "square", "circle", "parallelogram", "exit") ) # If exit the program stops if shape == "exit": break # After shape's area and perimeter has been chosen it calls the definition for shape, comparing that to definition if shape == "rectangle": area, perimeter = rectangle_calculator() elif shape == "triangle": area, perimeter = triangle_calculator() elif shape == "square": area, perimeter = square_calculator() elif shape == "circle": area, perimeter = circle_calculator() elif shape == "parallelogram": area, perimeter = parallelogram_calculator() else: print("Shape not recognized.") continue # If text space is left empty ore invalid input it skips or restarts the loop if area is None or perimeter is None: continue # This prints the calculated area and perimeter. The history part adds the shape name while making sure it capitalize. print(f"\n✅ Area: {area} square cm\n✅ Perimeter: {perimeter} cm\n") history.append((shape.capitalize(), area, perimeter)) # After the user has exited the loop it prints the users history print("\n📘 Session History:") for i, (shape, area, perimeter) in enumerate(history, 1): print(f"{i}. Shape: {shape}, Area: {area} cm², Perimeter: {perimeter} cm") save_csv = string_checker("Would you like to save your session history as a CSV file? (yes/no): ", ("yes", "no")) # If question above is answers 'YES' program create a CSV file and writes all data into it, it also creates a custom file name using the 'from datetime import datetime' if save_csv == "yes": # Generate a timestamped filename timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") filename = f"session_history_{timestamp}.csv" # Save history to the new file with open(filename, mode="w", newline="") as csvfile: writer = csv.writer(csvfile) writer.writerow(["Shape", "Area (cm²)", "Perimeter (cm)"]) for shape, area, perimeter in history: writer.writerow([shape, area, perimeter]) print(f"\nSession history saved to '{filename}'. You can open it in Excel or Google Sheets.") if __name__ == "__main__": main()