From 8492b8b73390e1081f32c8a96d87b0a6539ee9d3 Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 16:25:21 +0800 Subject: [PATCH 1/7] initialized project --- projects/computer-algebra/README.md | 3 +++ projects/computer-algebra/main.py | 0 projects/computer-algebra/requirements.txt | 2 ++ 3 files changed, 5 insertions(+) create mode 100644 projects/computer-algebra/README.md create mode 100644 projects/computer-algebra/main.py create mode 100644 projects/computer-algebra/requirements.txt diff --git a/projects/computer-algebra/README.md b/projects/computer-algebra/README.md new file mode 100644 index 000000000..14d0f3af6 --- /dev/null +++ b/projects/computer-algebra/README.md @@ -0,0 +1,3 @@ +# Computer Algebra + + diff --git a/projects/computer-algebra/main.py b/projects/computer-algebra/main.py new file mode 100644 index 000000000..e69de29bb diff --git a/projects/computer-algebra/requirements.txt b/projects/computer-algebra/requirements.txt new file mode 100644 index 000000000..42e607729 --- /dev/null +++ b/projects/computer-algebra/requirements.txt @@ -0,0 +1,2 @@ +requests==2.31.0 +beautifulsoup4==4.12.3 \ No newline at end of file From 27f442202429a66794a948e7402090a46dc9e8bc Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 16:27:34 +0800 Subject: [PATCH 2/7] feat: added command module for the base command --- projects/computer-algebra/command.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 projects/computer-algebra/command.py diff --git a/projects/computer-algebra/command.py b/projects/computer-algebra/command.py new file mode 100644 index 000000000..d621739b5 --- /dev/null +++ b/projects/computer-algebra/command.py @@ -0,0 +1,24 @@ +from typing import Any +from abc import abstractmethod, ABC +from urllib.parse import quote + + +class CmdBase(ABC): + """Base class for all the CAS (Computer Algebra System) API Commands.""" + + def __init__(self, operation: str, base_url: str): + self.operation = operation + self.base_url = base_url + + @abstractmethod + def command(self, expr: str) -> Any: + """ + Command for sending request to Newton CAS API with a given expression string and returns the result from + the API response. + """ + pass + + @staticmethod + def url_encode(inp_str: str) -> str: + """Encode the input string to a URL-safe format.""" + return quote(inp_str) From cd4247933c9d0ab6c78eadd11b5c6da077461794 Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 16:33:27 +0800 Subject: [PATCH 3/7] feat: added concrete implementations of command for newton api --- projects/computer-algebra/newton_command.py | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 projects/computer-algebra/newton_command.py diff --git a/projects/computer-algebra/newton_command.py b/projects/computer-algebra/newton_command.py new file mode 100644 index 000000000..794e4f397 --- /dev/null +++ b/projects/computer-algebra/newton_command.py @@ -0,0 +1,76 @@ +from dataclasses import dataclass + +import requests +from command import CmdBase + + +@dataclass(frozen=True) +class NewtonResponse: + """Newton API Response.""" + operation: str + expression: str + result: str + + +class NewtonCmdException(Exception): + """Base class for Newton Command Exceptions.""" + + +class NewtonCommand(CmdBase): + """Base class for all the Newton API Commands.""" + + def __init__(self, operation: str): + super().__init__(operation, 'https://newton.now.sh/api/v2') + + def command(self, expr: str) -> NewtonResponse: + """ + Command method for NewtonCommand class. + + Args: + expr (str): Mathematical expression to be evaluated. + + Returns: + NewtonResponse: Object containing the operation, expression, and result of the evaluated expression. + + Raises: + NewtonCmdException: If the HTTP request fails or returns a non-success status code, the exception is raised + with the error message. + """ + # Construct the Request URL + expr_encode = self.url_encode(expr) # URL Encode for Expression + request_url = f"{self.base_url}/{self.operation}/{expr_encode}" + + # Make the HTTP GET request + response = requests.get(request_url) + + # Check if the request was successful (status code 200) + if response.status_code == 200: + # Deserialize the JSON response into a dictionary + response_data = response.json() + + # Extract relevant data from the response + operation = response_data['operation'] + expression = response_data['expression'] + result = response_data['result'] + + # Create and return a NewtonResponse object + return NewtonResponse(operation=operation, expression=expression, result=result) + else: + raise NewtonCmdException(f'{response.text}') + + +newton_simplify = NewtonCommand('simplify').command +newton_factor = NewtonCommand('factor').command +newton_derive = NewtonCommand('derive').command +newton_integrate = NewtonCommand('integrate').command +newton_zeroes = NewtonCommand('zeroes').command +newton_tangent = NewtonCommand('tangent').command +newton_area = NewtonCommand('area').command +newton_cos = NewtonCommand('cos').command +newton_sin = NewtonCommand('sin').command +newton_tan = NewtonCommand('tan').command +newton_arc_cos = NewtonCommand('arccos').command +newton_arc_sin = NewtonCommand('arcsin').command +newton_arc_tan = NewtonCommand('arctan').command +newton_abs = NewtonCommand('abs').command +newton_log = NewtonCommand('log').command From d76bc8aac07742ffeed51fe6d70390d24ed56a3c Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 17:43:47 +0800 Subject: [PATCH 4/7] feat: added gui for the computer algebra app using dearpygui --- projects/computer-algebra/main.py | 109 ++++++++++++++++++++ projects/computer-algebra/newton_command.py | 18 ++++ projects/computer-algebra/requirements.txt | 2 +- 3 files changed, 128 insertions(+), 1 deletion(-) diff --git a/projects/computer-algebra/main.py b/projects/computer-algebra/main.py index e69de29bb..1f7ab27e0 100644 --- a/projects/computer-algebra/main.py +++ b/projects/computer-algebra/main.py @@ -0,0 +1,109 @@ +from newton_command import NEWTON_CMDS_DICT + +import dearpygui.dearpygui as dpg + + +def selection_cb(sender, app_data, user_data): + if user_data[1]: + print("User selected 'Ok'") + else: + print("User selected 'Cancel'") + + # delete window + dpg.delete_item(user_data[0]) + + +def show_info(title, message, selection_callback): + # Reference: https://github.com/hoffstadt/DearPyGui/discussions/1002 + + # guarantee these commands happen in the same frame + with dpg.mutex(): + viewport_width = dpg.get_viewport_client_width() + viewport_height = dpg.get_viewport_client_height() + + with dpg.window(tag='popup-window', label=title, modal=True, no_close=True) as modal_id: + dpg.add_text(message) + dpg.add_button(label="Ok", width=75, user_data=(modal_id, True), callback=selection_callback) + dpg.add_same_line() + dpg.add_button(label="Cancel", width=75, user_data=(modal_id, False), callback=selection_callback) + + # guarantee these commands happen in another frame + dpg.split_frame() + width = dpg.get_item_width(modal_id) + height = dpg.get_item_height(modal_id) + dpg.set_item_pos(modal_id, [viewport_width // 2 - width // 2, viewport_height // 2 - height // 2]) + + +# Callbacks and Helpers +def on_evaluate(sender, app_data, user_data): + # Get the Command + cmd = dpg.get_value('radio-cmds') + cmd_func = NEWTON_CMDS_DICT[cmd] + + # Get the Expression + expr = dpg.get_value('inp-expr') + + if expr.strip() in ['']: + show_info( + 'Error', + 'Please use valid mathematical expressions.', + selection_cb + ) + # Clear Expression + dpg.set_value('inp-expr', '') + return + + # Evaluate + response = cmd_func(expr) + result = response.result + + dpg.set_value('label-output', result) + + +dpg.create_context() +dpg.create_viewport(title='Computer Algebra', width=1300, height=750) + +with dpg.window(tag='inp-window', + label="Input", + pos=[0, 0], + autosize=True, + # width=1150, + # height=350, + no_collapse=True, + no_close=True, + ): + # Radio Button for Commands + dpg.add_radio_button( + horizontal=True, + tag='radio-cmds', + items=[cmd for cmd in NEWTON_CMDS_DICT.keys()] + ) + + # Text Area for Mathematical Expression + dpg.add_input_text( + tag='inp-expr', + width=int(1150 * 0.8), + ) + + # Button for Evaluating Command and Expression + dpg.add_button(label="Evaluate", callback=on_evaluate) + +with dpg.window(tag='out-window', + pos=[0, 100], + label="Output", + # width=700, + # height=350, + autosize=True, + no_collapse=True, + no_close=True, + ): + # Use Label for Output + dpg.add_text(tag='label-output', + label='Result', + show_label=True, + ) + +dpg.setup_dearpygui() +dpg.show_viewport() +dpg.start_dearpygui() +dpg.destroy_context() diff --git a/projects/computer-algebra/newton_command.py b/projects/computer-algebra/newton_command.py index 794e4f397..e38e1e889 100644 --- a/projects/computer-algebra/newton_command.py +++ b/projects/computer-algebra/newton_command.py @@ -74,3 +74,21 @@ def command(self, expr: str) -> NewtonResponse: newton_arc_tan = NewtonCommand('arctan').command newton_abs = NewtonCommand('abs').command newton_log = NewtonCommand('log').command + +NEWTON_CMDS_DICT = { + 'simplify': newton_simplify, + 'factor': newton_factor, + 'derive': newton_derive, + 'integrate': newton_integrate, + 'zeroes': newton_zeroes, + 'tangent': newton_tangent, + 'area': newton_area, + 'cos': newton_cos, + 'sin': newton_sin, + 'tan': newton_tan, + 'arccos': newton_arc_cos, + 'arcsin': newton_arc_sin, + 'arctan': newton_arc_tan, + 'abs': newton_abs, + 'log': newton_log +} diff --git a/projects/computer-algebra/requirements.txt b/projects/computer-algebra/requirements.txt index 42e607729..d9e5829ef 100644 --- a/projects/computer-algebra/requirements.txt +++ b/projects/computer-algebra/requirements.txt @@ -1,2 +1,2 @@ requests==2.31.0 -beautifulsoup4==4.12.3 \ No newline at end of file +dearpygui==1.11.1 \ No newline at end of file From cf5406ad4356f9ecac76df19447d59bfd02e740e Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 17:48:10 +0800 Subject: [PATCH 5/7] docs: added docstrings in main entrypoint --- projects/computer-algebra/main.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/computer-algebra/main.py b/projects/computer-algebra/main.py index 1f7ab27e0..dc6c36d48 100644 --- a/projects/computer-algebra/main.py +++ b/projects/computer-algebra/main.py @@ -4,6 +4,7 @@ def selection_cb(sender, app_data, user_data): + """Callback function for button selections in the message box.""" if user_data[1]: print("User selected 'Ok'") else: @@ -14,7 +15,12 @@ def selection_cb(sender, app_data, user_data): def show_info(title, message, selection_callback): - # Reference: https://github.com/hoffstadt/DearPyGui/discussions/1002 + """ + Display an information message box with title, message, and callback. + + References: + https://github.com/hoffstadt/DearPyGui/discussions/1002 + """ # guarantee these commands happen in the same frame with dpg.mutex(): @@ -36,6 +42,7 @@ def show_info(title, message, selection_callback): # Callbacks and Helpers def on_evaluate(sender, app_data, user_data): + """Callback function for the 'Evaluate' button.""" # Get the Command cmd = dpg.get_value('radio-cmds') cmd_func = NEWTON_CMDS_DICT[cmd] From a5a38903ca4eb1b6184d1812f5ee9862b7b0123b Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 15 May 2024 18:04:30 +0800 Subject: [PATCH 6/7] docs: created README for introducing the project --- projects/computer-algebra/README.md | 55 ++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/projects/computer-algebra/README.md b/projects/computer-algebra/README.md index 14d0f3af6..5d2af9df3 100644 --- a/projects/computer-algebra/README.md +++ b/projects/computer-algebra/README.md @@ -1,3 +1,56 @@ -# Computer Algebra +# Newton CAS Python Wrapper and GUI +This project aims to provide a Python wrapper and GUI for the Newton API, a Computer Algebra +System (CAS) that allows users to perform various mathematical computations. The GUI is built using +[DearPyGui](https://github.com/hoffstadt/DearPyGui) and +[Newton API](https://github.com/aunyks/newton-api). +## Features + +- **User-Friendly Interface:** The GUI provides an intuitive interface for users to interact with the Newton API + effortlessly. +- **Multiple Mathematical Operations:** Users can perform a variety of mathematical operations such as simplification, + factoring, differentiation, integration, finding zeroes, and more. +- **Real-Time Evaluation:** Expressions are evaluated in real-time, providing instant feedback to users. + +## Installation + +1. Clone the repository: + + ```bash + git clone https://github.com/Mrinank-Bhowmick/python-beginner-projects.git + ``` + +2. Navigate to the project directory: + + ```bash + cd python-beginner-projects/projects/computer-algebra + ``` + +3. Install dependencies using pip: + + ```bash + pip install -r requirements.txt + ``` + +## Usage + +1. Run the main script `main.py`: + + ```bash + python main.py + ``` + +2. The application window will appear, consisting of two sections: + - **Input Section:** Enter the mathematical expression you want to evaluate. + - **Output Section:** View the result of the evaluation. + +3. Choose the desired mathematical operation from the radio buttons. +4. Enter the expression in the input text box. + - See valid syntax from [Newton API](https://github.com/aunyks/newton-api). +5. Click the "Evaluate" button to perform the selected operation. +6. The result will be displayed in the output section. + +## Contact + +[GitHub Profile](https://github.com/ca20110820) From 7ca1dac0f6b3ef8fd70e34ad37576544af06d990 Mon Sep 17 00:00:00 2001 From: ca20110820 Date: Wed, 22 May 2024 13:17:15 +0800 Subject: [PATCH 7/7] docs: updated computer-algebra license --- projects/computer-algebra/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/computer-algebra/README.md b/projects/computer-algebra/README.md index 5d2af9df3..14c95d5cd 100644 --- a/projects/computer-algebra/README.md +++ b/projects/computer-algebra/README.md @@ -54,3 +54,7 @@ System (CAS) that allows users to perform various mathematical computations. The ## Contact [GitHub Profile](https://github.com/ca20110820) + +## License + +[![License](https://img.shields.io/static/v1?label=Licence&message=GPL-3-0&color=blue)](https://opensource.org/license/GPL-3-0)