diff --git a/Gui.py b/Gui.py new file mode 100644 index 0000000..1e2282b --- /dev/null +++ b/Gui.py @@ -0,0 +1,542 @@ +from pathlib import Path +from tkinter import Tk, Canvas, Entry, Text, Button, PhotoImage + +OUTPUT_PATH = Path(__file__).parent +ASSETS_PATH = OUTPUT_PATH / Path(r"assets\\frame0") + +def relative_to_assets(path: str) -> Path: + return ASSETS_PATH / Path(path) + +window = Tk() + +window.geometry("456x819") +logo = PhotoImage(file=relative_to_assets("logo.png")) +window.iconphoto(True, logo) +window.title("Calculator") +window.configure(bg="#181818") + +canvas = Canvas( + window, + bg="#181818", + height=819, + width=456, + bd=0, + highlightthickness=0, + relief="ridge" +) + +canvas.place(x=0, y=0) + +# Entry widget to display the input and result +entry_image_1 = PhotoImage( + file=relative_to_assets("entry_1.png")) +entry_bg_1 = canvas.create_image( + 228.1484832763672, + 159.76105499267578, + image=entry_image_1 +) +entry_1 = Entry( + bd=0, + bg="#181818", + fg="#000716", + font=("INTER", 40, 'bold'), + foreground="White", + highlightthickness=0, + justify='right' +) +entry_1.place( + x=18.0, + y=122.0, + width=420.2969665527344, + height=73.52210998535156, +) + +# Variables to store the input and result +input_value = "" +result = 0 +is_percentage = False +percentage_operand = None + +# Function to handle button clicks +def button_click(value): + global input_value, is_percentage, percentage_operand + if value == "00": + input_value += "00" + elif value == "/": + input_value += "÷" + is_percentage = False + percentage_operand = None + elif value == "*": + input_value += "x" + is_percentage = False + percentage_operand = None + elif value == "%": + if input_value: + is_percentage = True + percentage_operand = float(input_value) + input_value += "%" + else: + input_value += value + else: + input_value += str(value) + is_percentage = False + percentage_operand = None + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + +# Function to clear the input +def clear_input(): + global input_value, is_percentage, percentage_operand + input_value = "" + is_percentage = False + percentage_operand = None + entry_1.delete(0, 'end') + +# Function to calculate the result +def calculate_result(): + global input_value, result + try: + if "%" in input_value: + percentage() + else: + # Replace operator symbols with their respective Python operators + expression = input_value.replace("÷", "/").replace("x", "*") + + # Split the expression into operands and operators + operands = [] + operators = [] + current_operand = "" + for char in expression: + if char.isdigit() or char == ".": + current_operand += char + else: + operands.append(float(current_operand)) + current_operand = "" + operators.append(char) + operands.append(float(current_operand)) + + # Evaluate the expression using the operands and operators + result = operands.pop(0) + for i, op in enumerate(operators): + operand = operands.pop(0) + if op == "+": + result += operand + elif op == "-": + result -= operand + elif op == "*": + result *= operand + elif op == "/": + result /= operand + + # Display result as integer if it's an integer, otherwise as float + if isinstance(result, int): + input_value = str(result) + else: + if result.is_integer(): + input_value = str(int(result)) + else: + input_value = str(result) + + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + except Exception as e: + input_value = "Error" + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + print(f"Error: {e}") + + +# Function to handle backspace +def backspace(): + global input_value + input_value = input_value[:-1] + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + +# Function to handle percentage +def percentage(): + global input_value, result + try: + if "%" in input_value: + # Replace operator symbols with their respective Python operators + expression = input_value.replace("÷", "/").replace("x", "*") + + # Split the expression into operands and operators + operands = [] + operators = [] + current_operand = "" + for char in expression: + if char.isdigit() or char == ".": + current_operand += char + elif char == "%": + operands.append(float(current_operand)) + current_operand = "" + operators.append("%") + else: + operands.append(float(current_operand)) + current_operand = "" + operators.append(char) + operands.append(float(current_operand)) + + # Evaluate the expression using the operands and operators + result = operands.pop(0) + for i, op in enumerate(operators): + operand = operands.pop(0) + if op == "+": + result += operand + elif op == "-": + result -= operand + elif op == "*": + result *= operand + elif op == "/": + result /= operand + elif op == "%": + result = (result * operand) / 100 + + # Display result as integer if it's an integer, otherwise as float + if isinstance(result, int): + input_value = str(result) + else: + if result.is_integer(): + input_value = str(int(result)) + else: + input_value = str(result) + + else: + input_value += "%" + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + return + + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + + except Exception as e: + input_value = "Error" + entry_1.delete(0, 'end') + entry_1.insert(0, input_value) + print(f"Error: {e}") + +# Button images and commands +button_image_1 = PhotoImage( + file=relative_to_assets("button_1.png")) +button_1 = Button( + image=button_image_1, + borderwidth=0, + highlightthickness=0, + command=clear_input, + relief="flat" +) +button_1.place( + x=15.0, + y=269.0, + width=87.0, + height=87.0 +) + + +button_image_2 = PhotoImage( + file=relative_to_assets("button_2.png")) +button_2 = Button( + image=button_image_2, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(7), + relief="flat" +) +button_2.place( + x=15.0, + y=377.0, + width=87.0, + height=87.0 +) + +button_image_3 = PhotoImage( + file=relative_to_assets("button_3.png")) +button_3 = Button( + image=button_image_3, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(4), + relief="flat" +) +button_3.place( + x=15.0, + y=485.0, + width=87.0, + height=87.0 +) + +button_image_4 = PhotoImage( + file=relative_to_assets("button_4.png")) +button_4 = Button( + image=button_image_4, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(1), + relief="flat" +) +button_4.place( + x=15.0, + y=593.0, + width=87.0, + height=87.0 +) + +button_image_5 = PhotoImage( + file=relative_to_assets("button_5.png")) +button_5 = Button( + image=button_image_5, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("00"), + relief="flat" +) +button_5.place( + x=15.0, + y=701.0, + width=87.0, + height=87.0 +) +button_image_6 = PhotoImage( + file=relative_to_assets("button_6.png")) +button_6 = Button( + image=button_image_6, + borderwidth=0, + highlightthickness=0, + command=percentage, + relief="flat" +) +button_6.place( + x=128.0, + y=269.0, + width=87.0, + height=87.0 +) + +button_image_7 = PhotoImage( + file=relative_to_assets("button_7.png")) +button_7 = Button( + image=button_image_7, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(8), + relief="flat" +) +button_7.place( + x=128.0, + y=377.0, + width=87.0, + height=87.0 +) + +button_image_8 = PhotoImage( + file=relative_to_assets("button_8.png")) +button_8 = Button( + image=button_image_8, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(5), + relief="flat" +) +button_8.place( + x=128.0, + y=485.0, + width=87.0, + height=87.0 +) + +button_image_9 = PhotoImage( + file=relative_to_assets("button_9.png")) +button_9 = Button( + image=button_image_9, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(2), + relief="flat" +) +button_9.place( + x=128.0, + y=593.0, + width=87.0, + height=87.0 +) + +button_image_10 = PhotoImage( + file=relative_to_assets("button_10.png")) +button_10 = Button( + image=button_image_10, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(0), + relief="flat" +) +button_10.place( + x=128.0, + y=701.0, + width=87.0, + height=87.0 +) + +button_image_11 = PhotoImage( + file=relative_to_assets("button_11.png")) +button_11 = Button( + image=button_image_11, + borderwidth=0, + highlightthickness=0, + command=backspace, + relief="flat" +) +button_11.place( + x=241.0, + y=269.0, + width=87.0, + height=87.0 +) + +button_image_12 = PhotoImage( + file=relative_to_assets("button_12.png")) +button_12 = Button( + image=button_image_12, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(9), + relief="flat" +) +button_12.place( + x=241.0, + y=377.0, + width=87.0, + height=87.0 +) + +button_image_13 = PhotoImage( + file=relative_to_assets("button_13.png")) +button_13 = Button( + image=button_image_13, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(6), + relief="flat" +) +button_13.place( + x=241.0, + y=485.0, + width=87.0, + height=87.0 +) + +button_image_14 = PhotoImage( + file=relative_to_assets("button_14.png")) +button_14 = Button( + image=button_image_14, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click(3), + relief="flat" +) +button_14.place( + x=241.0, + y=593.0, + width=87.0, + height=87.0 +) + +button_image_15 = PhotoImage( + file=relative_to_assets("button_15.png")) +button_15 = Button( + image=button_image_15, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("."), + relief="flat" +) +button_15.place( + x=241.0, + y=701.0, + width=87.0, + height=87.0 +) + +button_image_16 = PhotoImage( + file=relative_to_assets("button_16.png")) +button_16 = Button( + image=button_image_16, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("/"), + relief="flat" +) +button_16.place( + x=354.0, + y=269.0, + width=87.0, + height=87.0 +) + +button_image_17 = PhotoImage( + file=relative_to_assets("button_17.png")) +button_17 = Button( + image=button_image_17, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("*"), + relief="flat" +) +button_17.place( + x=354.0, + y=377.0, + width=87.0, + height=87.0 +) + +button_image_18 = PhotoImage( + file=relative_to_assets("button_18.png")) +button_18 = Button( + image=button_image_18, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("-"), + relief="flat" +) +button_18.place( + x=354.0, + y=485.0, + width=87.0, + height=87.0 +) + +button_image_19 = PhotoImage( + file=relative_to_assets("button_19.png")) +button_19 = Button( + image=button_image_19, + borderwidth=0, + highlightthickness=0, + command=lambda: button_click("+"), + relief="flat" +) +button_19.place( + x=354.0, + y=593.0, + width=87.0, + height=87.0 +) + +button_image_20 = PhotoImage( + file=relative_to_assets("button_20.png")) +button_20 = Button( + image=button_image_20, + borderwidth=0, + highlightthickness=0, + command=calculate_result, + relief="flat" +) +button_20.place( + x=354.0, + y=701.0, + width=87.0, + height=87.0 +) + +window.resizable(False, False) +window.mainloop() \ No newline at end of file diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..5354e10 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,55 @@ +# Calculator App + +This is a simple calculator app built using Python and the Tkinter library. The app provides a graphical user interface (GUI) to perform basic arithmetic operations like addition, subtraction, multiplication, division, and percentage calculations. + +## Features + +- User-friendly GUI with a sleek design +- Basic arithmetic operations (+, -, \*, /) +- Percentage calculations +- Support for decimal numbers +- Clear input and backspace functionality +- Error handling for invalid expressions + +## Requirements + +- Python 3.x +- Tkinter library (usually comes bundled with Python installations) + +## Installation + +1. Clone the repository or download the source code. +2. Make sure you have Python 3.x installed on your system. +3. No additional dependencies are required since the project uses the built-in Tkinter library. + +## Usage + +> Navigate to the project directory in your terminal or command prompt. +> Run the following command to start the application: + +```bash +python Main_Gui_Calculator.py +``` + +1. The calculator app window will open. +2. Use the on-screen buttons or your keyboard to enter numbers and perform arithmetic operations. +3. Click the "=" button or press the "Enter" key to get the result. +4. The app supports basic operations like addition, subtraction, multiplication, division, and percentage calculations. +5. Use the "C" button to clear the input field. +6. Use the backspace button to delete the last character from the input field. + +## Screenshots + +| ![Calculator App](/assets/frame0/ss1.png) | ![Calculator App](/assets/frame0/ss2.png) | +|--------------------------------------------|--------------------------------------------| +| *Screenshot 1* | *Screenshot 2* | + +## Contributing + +Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request. + +## Acknowledgments + +- The project uses the Tkinter library, which is part of the Python standard library. +- The app design and icons were created using [figma & retrived icon from icons8 plugin]. +- The UI design was inspired by Calculator App in Oneplus & iOS devices. diff --git a/assets/frame0/button_1.png b/assets/frame0/button_1.png new file mode 100644 index 0000000..c707e84 Binary files /dev/null and b/assets/frame0/button_1.png differ diff --git a/assets/frame0/button_10.png b/assets/frame0/button_10.png new file mode 100644 index 0000000..4e38b34 Binary files /dev/null and b/assets/frame0/button_10.png differ diff --git a/assets/frame0/button_11.png b/assets/frame0/button_11.png new file mode 100644 index 0000000..f2a1c84 Binary files /dev/null and b/assets/frame0/button_11.png differ diff --git a/assets/frame0/button_12.png b/assets/frame0/button_12.png new file mode 100644 index 0000000..16bc104 Binary files /dev/null and b/assets/frame0/button_12.png differ diff --git a/assets/frame0/button_13.png b/assets/frame0/button_13.png new file mode 100644 index 0000000..8136cb4 Binary files /dev/null and b/assets/frame0/button_13.png differ diff --git a/assets/frame0/button_14.png b/assets/frame0/button_14.png new file mode 100644 index 0000000..1c670e9 Binary files /dev/null and b/assets/frame0/button_14.png differ diff --git a/assets/frame0/button_15.png b/assets/frame0/button_15.png new file mode 100644 index 0000000..cc8ef9a Binary files /dev/null and b/assets/frame0/button_15.png differ diff --git a/assets/frame0/button_16.png b/assets/frame0/button_16.png new file mode 100644 index 0000000..e520993 Binary files /dev/null and b/assets/frame0/button_16.png differ diff --git a/assets/frame0/button_17.png b/assets/frame0/button_17.png new file mode 100644 index 0000000..59b116b Binary files /dev/null and b/assets/frame0/button_17.png differ diff --git a/assets/frame0/button_18.png b/assets/frame0/button_18.png new file mode 100644 index 0000000..e2c36dc Binary files /dev/null and b/assets/frame0/button_18.png differ diff --git a/assets/frame0/button_19.png b/assets/frame0/button_19.png new file mode 100644 index 0000000..00961fb Binary files /dev/null and b/assets/frame0/button_19.png differ diff --git a/assets/frame0/button_2.png b/assets/frame0/button_2.png new file mode 100644 index 0000000..78595a9 Binary files /dev/null and b/assets/frame0/button_2.png differ diff --git a/assets/frame0/button_20.png b/assets/frame0/button_20.png new file mode 100644 index 0000000..014c2b6 Binary files /dev/null and b/assets/frame0/button_20.png differ diff --git a/assets/frame0/button_3.png b/assets/frame0/button_3.png new file mode 100644 index 0000000..841d8dc Binary files /dev/null and b/assets/frame0/button_3.png differ diff --git a/assets/frame0/button_4.png b/assets/frame0/button_4.png new file mode 100644 index 0000000..ce3e09d Binary files /dev/null and b/assets/frame0/button_4.png differ diff --git a/assets/frame0/button_5.png b/assets/frame0/button_5.png new file mode 100644 index 0000000..117e102 Binary files /dev/null and b/assets/frame0/button_5.png differ diff --git a/assets/frame0/button_6.png b/assets/frame0/button_6.png new file mode 100644 index 0000000..7635f61 Binary files /dev/null and b/assets/frame0/button_6.png differ diff --git a/assets/frame0/button_7.png b/assets/frame0/button_7.png new file mode 100644 index 0000000..03576a4 Binary files /dev/null and b/assets/frame0/button_7.png differ diff --git a/assets/frame0/button_8.png b/assets/frame0/button_8.png new file mode 100644 index 0000000..edf28f9 Binary files /dev/null and b/assets/frame0/button_8.png differ diff --git a/assets/frame0/button_9.png b/assets/frame0/button_9.png new file mode 100644 index 0000000..c06f006 Binary files /dev/null and b/assets/frame0/button_9.png differ diff --git a/assets/frame0/entry_1.png b/assets/frame0/entry_1.png new file mode 100644 index 0000000..5232bbb Binary files /dev/null and b/assets/frame0/entry_1.png differ diff --git a/assets/frame0/logo.png b/assets/frame0/logo.png new file mode 100644 index 0000000..8fe0b63 Binary files /dev/null and b/assets/frame0/logo.png differ diff --git a/assets/frame0/ss1.png b/assets/frame0/ss1.png new file mode 100644 index 0000000..be84c2f Binary files /dev/null and b/assets/frame0/ss1.png differ diff --git a/assets/frame0/ss2.png b/assets/frame0/ss2.png new file mode 100644 index 0000000..0650926 Binary files /dev/null and b/assets/frame0/ss2.png differ