├── .coverage ├── .github └── workflows │ └── ci.yml ├── ARCHITECTURE.md ├── ActivityDiagrams.md ├── Agile Document.docx ├── BugTriage.png ├── CHANGLOG.md ├── CONTRIBUTION.md ├── ClassDiagram.md ├── Domain_Model_Documentation.md ├── IterativeDevelopment.png ├── KanbanFull.jpg ├── KanbanPic1.png ├── KanbanPic2.png ├── Kanban_Explanation.md ├── Lisence.md ├── ProductBacklog.md ├── README.md ├── ROADMAP.md ├── Reflections.md ├── Specifications.md ├── SprintPlan.md ├── Stakeholder_Analysis.md ├── System_Requirements.md ├── TeamPlanning.png ├── Template_Analysis.md ├── Test_Case.md ├── Traceability.md ├── Transition&Activity_Reflections.md ├── TransitionDiagrams.md ├── Untitled diagram-2025-03-02-172106.png ├── UseCaseDiagram.png ├── UseCase_SPECIFICATIONS.md ├── UserStories.md ├── VotingResults.md ├── docs └── screenshots │ ├── BranchRules │ ├── Rules.png │ └── Rules1.png │ ├── Pull_Request │ └── pull_request.png │ ├── Run Test-Success.png │ ├── Test_Results_Success │ ├── Run Test-Success.png │ └── test.png │ ├── status_badge_in_readme │ ├── Badge.png │ ├── CI LIVE BADGE.png │ └── taks8 │ └── test.png ├── requirements.txt ├── src ├── Docs │ └── ApiDocs.png ├── Main.py ├── Models │ ├── Calculations.py │ ├── Calculator.py │ ├── ErrorHandler.py │ ├── Graph.py │ ├── History.py │ ├── Main.py │ ├── User.py │ ├── __init__.py │ └── __pycache__ │ │ ├── Calculations.cpython-312.pyc │ │ ├── Calculations.cpython-313.pyc │ │ ├── Calculator.cpython-312.pyc │ │ ├── Calculator.cpython-313.pyc │ │ ├── History.cpython-312.pyc │ │ ├── History.cpython-313.pyc │ │ ├── User.cpython-312.pyc │ │ ├── User.cpython-313.pyc │ │ ├── __init__.cpython-312.pyc │ │ └── __init__.cpython-313.pyc ├── Repositories │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-312.pyc │ │ ├── __init__.cpython-313.pyc │ │ ├── repository_interface.cpython-312.pyc │ │ ├── repository_interface.cpython-313.pyc │ │ ├── user_repository.cpython-312.pyc │ │ └── user_repository.cpython-313.pyc │ ├── inmemory │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-312.pyc │ │ │ └── inmemory_user_repo.cpython-312.pyc │ │ └── inmemory_user_repo.py │ ├── json_repo │ │ ├── __pycache__ │ │ │ ├── filesystem_user_repo.cpython-312.pyc │ │ │ └── filesystem_user_repo.cpython-313.pyc │ │ └── filesystem_user_repo.py │ ├── repository_interface.py │ └── user_repository.py ├── RepositoryFactory │ ├── Readme(Repository).md │ ├── __pycache__ │ │ ├── repository_factory.cpython-312.pyc │ │ └── repository_factory.cpython-313.pyc │ └── repository_factory.py ├── UpdatedClassDiagram.md ├── __init__.py ├── __pycache__ │ ├── Calculations.cpython-313.pyc │ ├── Calculator.cpython-313.pyc │ ├── History.cpython-313.pyc │ ├── Main.cpython-313.pyc │ ├── User.cpython-313.pyc │ ├── __init__.cpython-312.pyc │ └── __init__.cpython-313.pyc ├── api │ ├── __pycache__ │ │ ├── main_api.cpython-312.pyc │ │ └── user_routes.cpython-312.pyc │ ├── main_api.py │ └── user_routes.py ├── creational_patterns │ ├── Builders │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── __init__.cpython-313.pyc │ │ │ ├── calculation_builder.cpython-312.pyc │ │ │ └── calculation_builder.cpython-313.pyc │ │ └── calculation_builder.py │ ├── CalculatorFactory │ │ ├── CalculatorFactory.py │ │ └── __init__.py │ ├── Factories │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── __init__.cpython-313.pyc │ │ │ ├── calculator_factory.cpython-312.pyc │ │ │ ├── calculator_factory.cpython-313.pyc │ │ │ ├── results_formatter.cpython-312.pyc │ │ │ ├── results_formatter.cpython-313.pyc │ │ │ ├── ui_factory.cpython-312.pyc │ │ │ └── ui_factory.cpython-313.pyc │ │ ├── calculator_factory.py │ │ ├── results_formatter.py │ │ └── ui_factory.py │ ├── Main.py │ ├── Prototype │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── __init__.cpython-313.pyc │ │ │ ├── calculations_prototype.cpython-312.pyc │ │ │ └── calculations_prototype.cpython-313.pyc │ │ └── calculations_prototype.py │ └── Singletons │ │ ├── __init__.py │ │ ├── __pycache__ │ │ ├── __init__.cpython-312.pyc │ │ ├── __init__.cpython-313.pyc │ │ ├── logger.cpython-312.pyc │ │ └── logger.cpython-313.pyc │ │ └── logger.py ├── readme.md ├── run.py ├── services │ ├── __pycache__ │ │ └── user_service.cpython-312.pyc │ └── user_service.py ├── test_results.txt └── tests │ ├── Services │ └── test_user_service.py │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-312.pyc │ ├── test_calc_logic.cpython-312-pytest-8.3.5.pyc │ ├── test_calc_logic.cpython-312.pyc │ ├── test_calculation_builder.cpython-312-pytest-8.3.5.pyc │ ├── test_calculation_builder.cpython-312.pyc │ ├── test_calculation_prototype.cpython-312-pytest-8.3.5.pyc │ ├── test_calculation_prototype.cpython-312.pyc │ ├── test_calculator_factory.cpython-312-pytest-8.3.5.pyc │ ├── test_calculator_factory.cpython-312.pyc │ ├── test_dummy.cpython-312.pyc │ ├── test_formatter.cpython-312-pytest-8.3.5.pyc │ ├── test_formatter.cpython-312.pyc │ ├── test_logger.cpython-312-pytest-8.3.5.pyc │ ├── test_logger.cpython-312.pyc │ ├── test_ui_factory.cpython-312-pytest-8.3.5.pyc │ ├── test_ui_factory.cpython-312.pyc │ └── test_user_repo.cpython-312.pyc │ ├── peytest.ini │ ├── test_calc_logic.py │ ├── test_calculation_builder.py │ ├── test_calculation_prototype.py │ ├── test_calculator_factory.py │ ├── test_formatter.py │ ├── test_logger.py │ ├── test_ui_factory.py │ └── test_user_repo.py └── users.json /.coverage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/.coverage -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - SiphokaziCele-patch-1 8 | pull_request: 9 | branches: 10 | - main 11 | - SiphokaziCele-patch-1 12 | 13 | jobs: 14 | test: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: 🔄 Checkout Code 19 | uses: actions/checkout@v3 20 | 21 | - name: 🐍 Set up Python 22 | uses: actions/setup-python@v4 23 | with: 24 | python-version: "3.12" 25 | 26 | - name: 📦 Install Dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install -r requirements.txt 30 | 31 | - name: Set PYTHONPATH 32 | run: echo "PYTHONPATH=$(pwd)/src" >> $GITHUB_ENV 33 | 34 | - name: 🧪 Run Tests 35 | run: | 36 | python -m unittest discover -s src/tests 37 | -------------------------------------------------------------------------------- /ARCHITECTURE.md: -------------------------------------------------------------------------------- 1 | # Advanced Web-Based Calculator 2 | 3 | ## Domain: 4 | The calculator application falls within the **Educational/Utility Domain**. Its primary focus is to assist users with a wide range of mathematical operations, including basic arithmetic, advanced functions, and specialized operations. The tool is designed for both personal use and learning, aiding users in performing quick calculations while also offering a platform for exploring more complex mathematical concepts. 5 | 6 | ## Problem Statement: 7 | With the increasing reliance on online tools for educational and professional purposes, users need a more advanced and versatile calculator that supports both simple and complex operations. The current solutions often lack user-friendly interfaces, do not store calculation histories, or are limited in terms of available mathematical functions. 8 | 9 | ## System Purpose: 10 | The Advanced Web-Based Calculator aims to provide users with a rich, interactive experience for performing arithmetic, algebraic, and scientific calculations in an easy-to-use format. This calculator will support basic operations (addition, subtraction, etc.), advanced functions (exponentiation, logarithms, etc.), and optional features like calculation history storage. 11 | 12 | ## Individual Scope: 13 | The calculator will feature: 14 | - A web-based interface built using HTML, CSS, and JavaScript. 15 | - The ability to handle standard and advanced mathematical functions. 16 | - (Optional) History tracking to store and view past calculations. 17 | - A responsive and intuitive UI design. 18 | - (Optional) Integration with an API for extended features such as unit conversion and statistical functions. 19 | 20 | ## Feasibility Justification: 21 | Given the increasing prevalence of web technologies like HTML, CSS, and JavaScript, the proposed solution can be efficiently implemented with minimal resources. Additionally, cloud services such as Firebase or MySQL provide a scalable and cost-effective way to store user history, if desired. The modular approach allows for flexible development, starting with a basic calculator and adding more advanced features as needed. 22 | 23 | --- 24 | 25 | ## C4 Architecture Diagrams for Advanced Calculator 26 | 27 | graph LR; 28 | user[User] -->|Interacts with| system[Project Management System]; 29 | admin[Admin] -->|Manages| system; 30 | manager[Project Manager] -->|Assigns tasks| system; 31 | user -->|Updates progress| system; 32 | system -->|Generates reports| manager; 33 | system -->|Stores data| database[(Database)]; 34 | 35 | %% Container Diagram 36 | app[Web Application] -->|Sends requests to| backend[Backend API]; 37 | backend -->|Uses| database[(Database)]; 38 | backend -->|Sends email notifications| emailService[Email Service]; 39 | frontend[Mobile App] -->|Connects to| backend; 40 | backend -->|Interacts with| taskManager[Task Management Service]; 41 | %% Component Diagram 42 | backend[Backend API] -->|Handles tasks| taskService[Task Service]; 43 | backend -->|Handles users| userService[User Service]; 44 | taskService -->|Reads and writes tasks| taskDB[(Task Database)]; 45 | userService -->|Reads and writes user data| userDB[(User Database)]; 46 | backend -->|Authentication| authService[Authentication Service]; 47 | [View the C4 Diagrams in Mermaid Live Editor](https://www.mermaidchart.com/app/projects/ac19d35b-57d7-4e57-bfd8-c5bb398d3655/diagrams/49347f9c-40ed-4388-a153-c0fb89caae92/version/v0.1/edit ). 48 | [Diagrams](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/blob/main/Untitled%20diagram-2025-03-02-172106.png) 49 | 50 | ## ERD DIAGRAM: 51 | ```mermaid 52 | erDiagram 53 | USER ||--o{ CALCULATION : performs 54 | USER ||--o{ HISTORY : stores 55 | CALCULATION ||--|{ FUNCTION : uses 56 | HISTORY }|..|{ CALCULATION : references 57 | -------------------------------------------------------------------------------- /ActivityDiagrams.md: -------------------------------------------------------------------------------- 1 | ### Advanced Calculator System: Activity Diagrams & Explanations (GitHub-Ready Mermaid Format) 2 | --- 3 | 4 | ## 1. **User Registration Workflow** 5 | 6 | ```mermaid 7 | flowchart TD 8 | subgraph User 9 | A1(Start) --> A2[Enter Details] 10 | end 11 | 12 | subgraph System 13 | A2 --> B1[Validate Input] 14 | B1 -->|Invalid| B2[Show Error Message] 15 | B2 --> A2 16 | B1 -->|Valid| C1[Create Account] 17 | C1 --> C2[Send Confirmation Email] 18 | C2 --> D1(End) 19 | end 20 | ``` 21 | 22 | **Explanation:** 23 | - This workflow shows how users register. 24 | - Decision node checks if input is valid. 25 | - If valid, system proceeds with creation and email. 26 | - Addresses stakeholder need for secure sign-up. 27 | - Stakeholder Concern: Ensuring that user registrations are secure and validated. 28 | 29 | How It Addresses the Concern: The system first validates the user's input, ensuring that only valid data is accepted. If the input is invalid, an error message is displayed, prompting the user to correct the details. Once the input is valid, the account is created, and a confirmation email is sent to the user. This addresses concerns regarding secure sign-up and proper validation of user information. 30 | 31 | ## 2. **Login Workflow** 32 | 33 | ```mermaid 34 | flowchart TD 35 | subgraph User 36 | A1(Start) --> A2[Enter Credentials] 37 | end 38 | 39 | subgraph System 40 | A2 --> B1[Authenticate User] 41 | B1 -->|Failed| B2[Display Login Error] 42 | B2 --> A2 43 | B1 -->|Success| C1[Redirect to Dashboard] 44 | C1 --> D1(End) 45 | end 46 | ``` 47 | 48 | **Explanation:** 49 | - Shows how login is handled. 50 | - Branching logic validates credentials. 51 | - Addresses security concern from users. 52 | - Stakeholder Concern: Ensuring that only authenticated users can access the system. 53 | 54 | How It Addresses the Concern: The login process involves checking the user’s credentials. If the credentials are valid, the system grants access by redirecting the user to their dashboard. If the credentials are incorrect, an error is displayed, ensuring that unauthorized access is prevented. This addresses security concerns for both users and administrators. 55 | 56 | --- 57 | 58 | ## 3. **Perform Calculation** 59 | 60 | ```mermaid 61 | flowchart TD 62 | subgraph User 63 | A1(Start) --> A2[Enter Expression] 64 | end 65 | 66 | subgraph System 67 | A2 --> B1[Parse Input] 68 | B1 --> B2[Validate Expression] 69 | B2 -->|Invalid| B3[Display Error] 70 | B3 --> A2 71 | B2 -->|Valid| C1[Evaluate Expression] 72 | C1 --> D1[Display Result] 73 | D1 --> E1(End) 74 | end 75 | ``` 76 | 77 | **Explanation:** 78 | - Core calculator logic. 79 | - Ensures expressions are valid before evaluation. 80 | - Functional link: FR-001 (Basic Calculations). 81 | -Stakeholder Concern: Ensuring that the calculator performs accurate and error-free calculations. 82 | 83 | How It Addresses the Concern: The system first parses and validates the user’s input. If the expression is invalid, an error message is displayed, prompting the user to enter a valid expression. If the input is valid, the expression is evaluated, and the result is displayed. This ensures that the calculator performs accurate calculations and handles errors effectively, meeting the functional requirements for basic calculations. 84 | --- 85 | 86 | ## 4. **Graphing Calculator Workflow** 87 | 88 | ```mermaid 89 | flowchart TD 90 | subgraph User 91 | A1(Start) --> A2[Input Function] 92 | end 93 | 94 | subgraph System 95 | A2 --> B1[Parse Function] 96 | B1 --> B2[Generate Plot Data] 97 | B2 --> B3[Render Graph] 98 | B3 --> C1(End) 99 | end 100 | ``` 101 | 102 | **Explanation:** 103 | - Visualizes the advanced graphing feature. 104 | - Related to US-004 (Graphing). 105 | - Stakeholder Concern: Providing an advanced graphing feature for users. 106 | 107 | How It Addresses the Concern: This workflow demonstrates how the graphing feature works. The user inputs a mathematical function, which is then parsed and used to generate plot data. The system then renders the graph, providing a visual representation of the function. This workflow fulfills the need for advanced features like graphing, which appeals to users needing visualizations in their calculations. 108 | 109 | --- 110 | 111 | ## 5. **Save Calculation History** 112 | 113 | ```mermaid 114 | flowchart TD 115 | subgraph System 116 | A1(Start) --> A2[Check History Enabled] 117 | A2 -->|Disabled| B1(End) 118 | A2 -->|Enabled| C1[Store Result in DB] 119 | C1 --> D1(End) 120 | end 121 | ``` 122 | 123 | **Explanation:** 124 | - Stores user calculations if enabled. 125 | - Addresses FR-003 (History Logging). 126 | - Stakeholder Concern: Providing users with a way to track their past calculations. 127 | 128 | How It Addresses the Concern: If the user has enabled history logging, the system will store the result of each calculation in a database, allowing the user to review their past calculations. If history logging is disabled, the process ends without storing any data. This addresses the need for users to have a record of their past calculations, enhancing usability. 129 | 130 | --- 131 | 132 | ## 6. **Export History Workflow** 133 | 134 | ```mermaid 135 | flowchart TD 136 | A1([Start]) --> A2[User clicks Export Button] 137 | A2 --> B1[System generates file - PDF or CSV] 138 | B1 --> C1[System triggers download] 139 | C1 --> D1([End]) 140 | 141 | 142 | ``` 143 | 144 | **Explanation:** 145 | - Enables data portability. 146 | - Fulfills FR-008 (Export History). 147 | - Stakeholder Concern: Allowing users to export their calculation history for offline use. 148 | 149 | How It Addresses the Concern: This workflow enables the user to export their calculation history in a format such as PDF or CSV. The system generates the file and triggers the download, ensuring users can keep records of their calculations. This feature addresses the need for portability and usability, particularly for users who want to keep a history of their work for future reference. 150 | 151 | --- 152 | 153 | ## 7. **Unit Conversion Workflow** 154 | 155 | ```mermaid 156 | flowchart TD 157 | subgraph User 158 | A1(Start) --> A2[Enter Value & Units] 159 | end 160 | 161 | subgraph System 162 | A2 --> B1[Lookup Conversion Formula] 163 | B1 --> B2[Perform Conversion] 164 | B2 --> C1[Display Result] 165 | C1 --> D1(End) 166 | end 167 | ``` 168 | 169 | **Explanation:** 170 | - Provides a unit converter. 171 | - Functional mapping to US-005. 172 | - Stakeholder Concern: Providing users with a way to convert units easily. 173 | 174 | How It Addresses the Concern: The system allows users to enter a value and specify the units they want to convert. It then looks up the appropriate conversion formula and performs the conversion, displaying the result. This workflow addresses the need for a simple and accurate unit conversion tool, ensuring that users can easily convert values across various units. 175 | 176 | --- 177 | 178 | ## 8. **Encryption Option Workflow** 179 | 180 | ```mermaid 181 | flowchart TD 182 | subgraph User 183 | A1(Start) --> A2[Enable Encryption in Settings] 184 | end 185 | 186 | subgraph System 187 | A2 --> B1[Apply Encryption to Stored Data] 188 | B1 --> C1(End) 189 | end 190 | ``` 191 | 192 | **Explanation:** 193 | - Secures user data. 194 | - Matches US-009 (Data Encryption). 195 | - Stakeholder Concern: Ensuring user data is secure and encrypted. 196 | 197 | How It Addresses the Concern: This workflow addresses data security by allowing users to enable encryption through the settings. Once enabled, the system encrypts any stored data, ensuring it is protected from unauthorized access. This feature enhances user trust and ensures compliance with security best practices. 198 | 199 | --- 200 | 201 | -------------------------------------------------------------------------------- /Agile Document.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/Agile Document.docx -------------------------------------------------------------------------------- /BugTriage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/BugTriage.png -------------------------------------------------------------------------------- /CHANGLOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | --- 6 | 7 | ## [1.1.0] - 2025-04-20 8 | ### Added 9 | - Implemented Singleton pattern for the Encryption Manager to ensure secure and consistent encryption handling. 10 | - Added unit tests for Singleton instance validation. 11 | - Export calculation history feature (US-008). 12 | - Graphing mathematical functions (US-004). 13 | 14 | ### Fixed 15 | - Corrected file structure by moving generated test reports into the `src` directory. 16 | - Resolved issue with `pytest` not recognized by using `python -m pytest`. 17 | 18 | --- 19 | 20 | ## [1.0.0] - 2025-04-15 21 | ### Added 22 | - Core calculator logic including arithmetic, trigonometric, and logarithmic functions. 23 | - Calculation Builder pattern implementation. 24 | - Factory pattern for calculator creation. 25 | - Unit conversion feature (US-005). 26 | - User story management using GitHub Projects. 27 | - CI-ready test cases and coverage report integration. 28 | 29 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # Contributing to Advanced Calculator System 2 | 3 | Thank You for condering contributing! 4 | 5 | ## Setup Instructions 6 | 1. Fork this repository. 7 | 2. Clone your fork: 8 | ``` 9 | git clone https://github.com/SiphokaziCele/Assignment3AdvancedCalcualtor.git -------------------------------------------------------------------------------- /ClassDiagram.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | classDiagram 3 | class User { 4 | -userID: String 5 | -name: String 6 | -password: String 7 | +register(): void 8 | +login(): void 9 | +logout(): void 10 | } 11 | 12 | class Calculator { 13 | -calculatorID: String 14 | -type: String 15 | +calculateExpression(expression: String): String 16 | +validateInput(expression: String): Boolean 17 | +displayResults(result: String): void 18 | } 19 | 20 | class Calculation { 21 | -calculationID: String 22 | -expression: String 23 | -result: String 24 | -timestamp: Date 25 | +perform(): String 26 | +saveToHistory(): void 27 | } 28 | 29 | class Graph { 30 | -graphId: String 31 | -functionExpression: String 32 | -graphImage: String 33 | +generateGraph(): void 34 | +renderGraph(): void 35 | } 36 | 37 | class History { 38 | -historyID: String 39 | -userID: String 40 | -listOfCalculations: List~Calculation~ 41 | +addEntry(calc: Calculation): void 42 | +viewHistory(): List~Calculation~ 43 | +clearHistory(): void 44 | } 45 | 46 | class ErrorHandler { 47 | -errorCode: String 48 | -errorMessage: String 49 | +catchInputError(): void 50 | +logError(): void 51 | } 52 | 53 | User "1" -- "1" History : owns 54 | User "1" -- "0..*" Calculation : performs 55 | Calculator "1" -- "0..*" Calculation : executes 56 | Calculation <|-- Graph 57 | Calculation "1" -- "1" ErrorHandler : handledBy 58 | ``` 59 | --- 60 | 61 | ## Updated Class Diagram 62 | ```mermaid 63 | classDiagram 64 | 65 | %% ====== Core Models ====== 66 | class User { 67 | -userID: String 68 | -name: String 69 | -password: String 70 | +register(): void 71 | +login(): void 72 | +logout(): void 73 | } 74 | 75 | class Calculator { 76 | -calculatorID: String 77 | -type: String 78 | +calculateExpression(expression: String): String 79 | +validateInput(expression: String): Boolean 80 | +displayResults(result: String): void 81 | } 82 | 83 | class Calculation { 84 | -calculationID: String 85 | -expression: String 86 | -result: String 87 | -timestamp: Date 88 | +perform(): String 89 | +saveToHistory(): void 90 | } 91 | 92 | class Graph { 93 | -graphId: String 94 | -functionExpression: String 95 | -graphImage: String 96 | +generateGraph(): void 97 | +renderGraph(): void 98 | } 99 | 100 | class History { 101 | -historyID: String 102 | -userID: String 103 | -listOfCalculations: List~Calculation~ 104 | +addEntry(calc: Calculation): void 105 | +viewHistory(): List~Calculation~ 106 | +clearHistory(): void 107 | } 108 | 109 | class ErrorHandler { 110 | -errorCode: String 111 | -errorMessage: String 112 | +catchInputError(): void 113 | +logError(): void 114 | } 115 | 116 | %% ====== Repository Layer ====== 117 | class Repository~T, ID~ { 118 | <> 119 | +save(entity: T): void 120 | +findById(id: ID): T 121 | +findAll(): List~T~ 122 | +delete(id: ID): void 123 | } 124 | 125 | class UserRepository { 126 | <> 127 | } 128 | 129 | class InMemoryUserRepository { 130 | } 131 | 132 | class FileSystemUserRepository { 133 | } 134 | 135 | %% ====== Relationships ====== 136 | User "1" -- "1" History : owns 137 | User "1" -- "0..*" Calculation : performs 138 | Calculator "1" -- "0..*" Calculation : executes 139 | Calculation <|-- Graph 140 | Calculation "1" -- "1" ErrorHandler : handledBy 141 | 142 | %% ====== Repository Relationships ====== 143 | Repository~User, String~ <|-- UserRepository 144 | UserRepository <|-- InMemoryUserRepository 145 | UserRepository <|-- FileSystemUserRepository 146 | User "1" --> "1" UserRepository : persists via 147 | 148 | -------------------------------------------------------------------------------- /Domain_Model_Documentation.md: -------------------------------------------------------------------------------- 1 | 2 | ## Domain Model 3 | 4 | | **Entity** | **Attributes** | **Methods** | **Relationships** | 5 | |-------------------|----------------------------------------------------------------------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| 6 | | **User** | `userId`, `name`, `email`, `password` | `register()`, `login()`, `logout()` | Can perform Calculations, owns CalculationHistory | 7 | | **Calculator** | `calculatorId`, `type` (basic, scientific, graphing) | `calculateExpression()`, `validateInput()`, `displayResult()` | Linked to Calculation, used by User | 8 | | **Calculation** | `calculationId`, `expression`, `result`, `timestamp` | `perform()`, `saveToHistory()` | Created by Calculator, belongs to User | 9 | | **Graph** | `graphId`, `functionExpression`, `graphImage` | `generateGraph()`, `renderGraph()` | Subclass of Calculation, visualized by Calculator | 10 | | **History** | `historyId`, `userId`, `listOfCalculations` | `addEntry()`, `viewHistory()`, `clearHistory()` | Associated with User, stores multiple Calculations | 11 | | **ErrorHandler** | `errorCode`, `errorMessage` | `catchInputError()`, `logError()` | Handles invalid inputs during Calculation and Graph generation | 12 | -------------------------------------------------------------------------------- /IterativeDevelopment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/IterativeDevelopment.png -------------------------------------------------------------------------------- /KanbanFull.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/KanbanFull.jpg -------------------------------------------------------------------------------- /KanbanPic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/KanbanPic1.png -------------------------------------------------------------------------------- /KanbanPic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/KanbanPic2.png -------------------------------------------------------------------------------- /Kanban_Explanation.md: -------------------------------------------------------------------------------- 1 | ## What is a Kanban Board? 2 | 3 | A Kanban board is a visual project management tool that helps teams track work as it moves through different stages of completion. It is based on the Kanban methodology, which aims to improve workflow efficiency by limiting work in progress (WIP) and ensuring continuous delivery. 4 | 5 | A typical Kanban board consists of: 6 | 7 | - **Columns** representing different stages of work (e.g., "Backlog," "Ready," "In Progress," "In Review," "Testing," "Blocked," "Done"). 8 | - **Cards** representing tasks, user stories, or issues that move across columns as progress is made. 9 | 10 | ## How My Kanban Board Works 11 | 12 | ### 1. Visualizing Workflow 13 | The board provides a clear overview of tasks and their current status. Tasks progress through the following stages: 14 | 15 | - **Backlog** → Tasks waiting to be worked on. 16 | - **Ready** → Tasks ready to be started. 17 | - **In Progress** → Tasks actively being worked on. 18 | - **In Review** → Tasks awaiting review or approval. 19 | - **Testing** → Tasks under quality assurance. 20 | - **Blocked** (Custom Column) → Tasks facing obstacles. 21 | - **Done** → Completed tasks. 22 | 23 | ### 2️. Limiting Work in Progress (WIP) 24 | To maintain efficiency and avoid overload, a limit of 3 active tasks per column is set. This prevents bottlenecks, ensuring tasks move smoothly through the workflow. If too many tasks are in the "In Progress" column, it signals the team to finish ongoing tasks before starting new ones. 25 | 26 | ### 3️. Supporting Agile Principles 27 | The Kanban board helps in continuous delivery and iterative development. Teams can quickly adapt to changes by rearranging tasks based on priority. Task dependencies and blockers are immediately visible, improving team collaboration. 28 | 29 | ### Example of Kanban in Action 30 | **Scenario:** 31 | If a task remains in the "In Progress" column for more than 2 days, it automatically moves to "Blocked" to highlight the delay. This ensures the team addresses issues early and prevents stagnation. 32 | 33 | ## Key Benefits of My Kanban Board 34 | 35 | - **Real-time visibility** – Team members see project status instantly. 36 | - **Better efficiency** – Limiting WIP ensures smoother workflow. 37 | - **Flexibility** – Tasks can be reprioritized based on project needs. 38 | - **Faster problem-solving** – Blocked tasks are identified early. 39 | 40 | ## Customization Choices 41 | 42 | I customized my Kanban board to better align with the specific needs of my project. Here are the key changes I made: 43 | 44 | - **Added 'Testing' column**: This was added to ensure tasks under quality assurance are clearly tracked and managed separately from the "In Progress" column. This helps in distinguishing tasks that are actively being developed versus those that are under review for quality and correctness. 45 | 46 | - **Added 'Blocked' column**: This column was introduced to highlight tasks that are facing obstacles. It ensures that any issues causing delays are immediately visible to the team so that they can be addressed promptly. 47 | 48 | - **Included 'Ready' column**: This new column was added to separate tasks that are ready to be worked on from the ones in the "Backlog". This makes it easier for the team to pick up tasks that are fully prepared to be started. 49 | 50 | These customizations improve the clarity of the workflow and ensure that all phases of development, testing, and review are properly tracked. 51 | . 52 | 53 | 54 | ## Kanban Screenshots 55 | 56 | ![Kanban Full Board](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/KanbasFull.jpg) 57 | 58 | ![Kanban Half Board](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/KanbanPic1.png) 59 | 60 | ![Kanban Half 2 Board](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/KanbanPic2.png) 61 | -------------------------------------------------------------------------------- /Lisence.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Siphokazi Cele 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ProductBacklog.md: -------------------------------------------------------------------------------- 1 | | **Story ID** | **User Story** | **Priority (MoSCoW)** | **Effort Estimate (Story Points)** | **Dependencies** | 2 | |-------------|--------------|-----------------|----------------------|--------------| 3 | | US-001 | Perform basic calculations | Must-have | 3 | None | 4 | | US-002 | Save calculation history | Must-have | 5 | US-001 | 5 | | US-003 | Clear calculation history | Should-have | 2 | US-002 | 6 | | US-004 | Graph mathematical functions | Must-have | 8 | US-001 | 7 | | US-005 | Perform unit conversions | Should-have | 3 | None | 8 | | US-006 | Access logarithmic and trigonometric functions | Must-have | 5 | US-001 | 9 | | US-007 | Save frequently used calculations | Could-have | 3 | US-002 | 10 | | US-008 | Export calculation history | Could-have | 4 | US-002 | 11 | | US-009 | Encrypt user data for security | Must-have | 5 | None | 12 | | US-010 | Optimize calculator load time | Must-have | 2 | None | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Assignment3AdvancedCalculator 2 | ## Project Title: Advanced Calculator System 3 | [![Run Tests](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/actions/workflows/ci.yml/badge.svg)](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/actions/workflows/ci.yml) 4 | 5 | Description: A web-based calculator that supports basic and advanced operations like addition, subtraction, multiplication, division, exponentiation, and logarithms. 6 | Links to: 7 | 8 | [Specifications.md](Specifications.md) 9 | 10 | [Architecture.md](Architecture.md) 11 | 12 | [Reflections.md](Reflections.md) 13 | 14 | [Stakeholder_Analysis.md](Stakeholder_Analysis.md) 15 | 16 | [System_Requirements.md](System_Requirements.md) 17 | 18 | [Functional_Requirements.md](Functional_Requirements.md) 19 | 20 | [User_Stories.md](User_Stories.md) 21 | 22 | [Sprint_Tasks.md](Sprint_Tasks.md) 23 | 24 | [BugTriage.png](BugTriage.png) 25 | 26 | [IterativeDevelopment.png](IterativeDevelopment.png) 27 | 28 | [Kanban_Explanation.md](Kanban_Explanation.md) 29 | 30 | [ProductBacklog.md](ProductBacklog.md) 31 | 32 | [SprintPlan.md](SprintPlan.md) 33 | 34 | [Template_Analysis.md](Template_Analysis.md) 35 | 36 | [Test_Case.md](Test_Case.md) 37 | 38 | [Domain_Model_Documentation.md](Domain_Model_Documentation.md) 39 | 40 | [Class Diagram.md](ClassDiagram.md) 41 | 42 | 43 | ## Pictures 44 | [KanbanPic1.png](KanbanPic1.png) 45 | 46 | [KanbanPic2.png](KanbanPic2.png) 47 | 48 | [KanbanFull.png](KanbanFull.png) 49 | 50 | ### Activity Diagrams and explanations 51 | This document provides detailed explanations and diagrams for various activity workflows within the system, covering the processes from user registration to encryption options. 52 | 53 | [ActivityDiagrams.md](ActivityDiagrams.md) 54 | 55 | ### Transition Diagrams and Explanation 56 | In this document, the transition diagrams describe the states and transitions of the system, helping to visualize the flow and behavior of key features. 57 | 58 | [TransistionDiagrams.md](TransitionDiagrams.md) 59 | 60 | ### Traceability 61 | This file traces the relationships between functional requirements, user stories, and sprint tasks, helping to connect the diagrams to the overall project objectives and development goals. 62 | 63 | [Traceability.md](Traceability.md) 64 | 65 | ### Activity diagrams Links 66 | 67 | - [User Registration Workflow](https://www.mermaidchart.com/raw/37f5f7b5-2b06-4f47-af30-bcd8baa1b8e2?theme=light&version=v0.1&format=svg) 68 | - [Login Workflow](https://www.mermaidchart.com/raw/c3c0a77b-ecb3-43a4-a46e-f7023bf38f6c?theme=light&version=v0.1&format=svg) 69 | - [Perform Calculation Workflow](https://www.mermaidchart.com/raw/38715718-de2b-4ec5-8c5d-ce6f669e07a2?theme=light&version=v0.1&format=svg) 70 | - [Graphing Calculator Workflow](https://www.mermaidchart.com/raw/91558cfb-f535-4525-a8bd-6fad6ef71a66?theme=light&version=v0.1&format=svg) 71 | - [Save Calculation History Workflow](https://www.mermaidchart.com/raw/df731fbf-4167-4bca-8bf4-c5bec9c0d7de?theme=light&version=v0.1&format=svg) 72 | - [Export History Workflow](https://www.mermaidchart.com/raw/ccd7b04b-d1dd-43ef-be4d-161d51bd0589?theme=light&version=v0.1&format=svg) 73 | - [Unit Conversion Workflow](https://www.mermaidchart.com/raw/24e32ebe-44f7-4cf8-87f0-2ab0b41d4398?theme=light&version=v0.1&format=svg) 74 | - [Encryption Option Workflow](https://www.mermaidchart.com/raw/a2974b2e-27a8-4bb8-a746-e05be11bace5?theme=light&version=v0.1&format=svg) 75 | 76 | ### Domain Model 77 | This document outlines the core entities of the Advanced Calculator System (e.g., User, Calculator, History) along with their attributes, methods, and relationships. It helps visualize how data flows and how components interact within the system at a high level. 78 | 79 | [Domain_Model_Documentation.md](Domain_Model_Documentation.md) 80 | 81 | ### Class Diagram 82 | The class diagram provides a technical blueprint of the system using object-oriented principles. It includes classes, attributes, methods, inheritance, and associations, illustrating how the system is structured for implementation. 83 | 84 | [Class_Diagram.md](ClassDiagram.md) 85 | 86 | ## Links to the codes 87 | ### `src/` Directory Overview 88 | 89 | ## Key Project Folders and Files 90 | 91 | - [**src/Models/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/Models) 92 | Contains data structures and logic models used in calculator operations. 93 | 94 | - [**src/creational_patterns/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/creational_patterns) 95 | Implements common creational design patterns like Singleton, Factory, and Builder. 96 | 97 | - [**src/tests/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/tests) 98 | Unit tests for validating each component of the application. 99 | 100 | - [**src/test_results.txt**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/blob/main/src/test_results.txt) 101 | Output log of test results generated by pytest. 102 | 103 | ## Assignment 11 104 | 105 | ### Links to the code: 106 | [**src/Repositories/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/Repositories) 107 | Contains all repository-related classes and interfaces. 108 | Includes: **Repository** (generic interface), **UserRepository**, **InMemoryUserRepository**, and **JSON_Repo** for saving and retrieving user data. 109 | 110 | [**src/RepositoryFactory/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/RepositoryFactory) 111 | Contains the **RepositoryFactory** class. 112 | This factory dynamically creates the correct repository instance (either memory-based or file-based) at runtime based on the selected storage type. 113 | 114 | [**src/UpdatedClassDiagram.md/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/UpdatedClassDiagram.md) 115 | Contains the updated UML Class Diagram (using Mermaid) showing both the original system models and the newly added repository layer with interfaces and implementations. 116 | 117 | ## Assignment 14 – Project Infrastructure & DevOps Enhancements 118 | 119 | This section documents the infrastructure and automation improvements completed for Assignment 14, including: 120 | 121 | - Branch protection configuration 122 | - Pull request automation 123 | - GitHub Actions CI workflow 124 | - Status badge integration 125 | - Repository organization 126 | 127 | --- 128 | 129 | ### Task 1: Branch Protection Rules 130 | 131 | - Enforced **pull request-based contributions** to the `main` branch 132 | - Enabled **required status checks** using CI 133 | - Prevented force pushes and direct commits 134 | 135 | Screenshot: 136 | [`docs/screenshots/branchRules/Rules.png`](docs/screenshots/BranchRules/Rules.png) 137 | [`docs/screenshots/branchRules/Rules1.png`](docs/screenshots/BranchRules/Rules1.png) 138 | 139 | 140 | --- 141 | 142 | ### Task 2: Pull Request Template 143 | 144 | Created a reusable pull request template that auto-fills when contributors open PRs. 145 | This ensures consistency and clarity in contributions. 146 | 147 | File: 148 | [`/.github/pull_request_template.md`](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/pull/12) 149 | Screenshot: 150 | [`docs/screenshots/Pull_Request/pull_request.png`](docs/screenshots/Pull_Request/pull_request.png) 151 | 152 | --- 153 | 154 | ### Task 3: CI Workflow with GitHub Actions 155 | 156 | - Built a GitHub Actions workflow (`ci.yml`) under `.github/workflows/` 157 | - Automatically runs tests on each push or pull request to `main` 158 | 159 | Workflow file: 160 | [`/.github/workflows/ci.yml`](.github/workflows/ci.yml) 161 | Screenshot of successful test run: 162 | [`docs/screenshots/Test_Results_Success/Run Test-Success.png`](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/blob/main/docs/screenshots/Test_Results_Success/Run%20Test-Success.png) 163 | 164 | --- 165 | 166 | ### Task 4: CI Status Badge in README 167 | 168 | Integrated a live status badge at the top of the README to reflect build/test status. 169 | 170 | Badge: 171 | [![Run Tests](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/actions/workflows/ci.yml/badge.svg)](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/actions/workflows/ci.yml) 172 | 173 | Screenshot: 174 | [`docs/screenshots/status_badge_in_readme.png`](docs/screenshots/status_badge_in_readme/Badge.png) 175 | 176 | --- 177 | 178 | ## 🧑‍🤝‍🧑 Assignment 14: Open Source Collaboration & Community Engagement 179 | 180 | ### Community Stats 181 | 182 | - ⭐ **Stars Received**: 38 183 | - 🍴 **Forks**: 31 184 | - ✅ Good First Issues Tagged: 5+ 185 | - ✅ Feature Requests Tagged: 3+ 186 | 187 | ### 🔗 Contribution Files 188 | 189 | - [Voting Results.md](VotingResults.md) – Includes stats, issue responses, improvements from feedback, and future collaboration plans. 190 | - [Reflections.md](Reflections.md) – A reflection on engaging with the open-source community, challenges, and learning outcomes. 191 | 192 | ### 💬 Contributor Support 193 | 194 | - `good-first-issue` and `feature-request` labels were added to help guide contributors. 195 | - Improved documentation and tooltips based on user feedback. 196 | - Added Pull Request and Issue templates under `.github/` for consistent collaboration. 197 | 198 | ### 🗺️ Roadmap 199 | The roadmap outlines completed features, ongoing work, and planned enhancements for the Advanced Calculator System. It helps contributors and users understand the project’s direction and priorities. 200 | 201 | [View Roadmap.md](ROADMAP.md) 202 | 203 | ### 🛠️ CI Badge (Above) 204 | 205 | Your project is CI-enabled and contributions are automatically tested via [GitHub Actions](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/actions). 206 | 207 | --- 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | ``` markdown 2 | # Advanced Calculator Roadmap 3 | 4 | ## v1.0 (Complete) 5 | - Basic and advanced math operations 6 | - History tracking 7 | - Unit conversions 8 | - Graph plotting 9 | - Export functionality 10 | 11 | ## v1.1 (In progress) 12 | - REST API support via FastAPI 13 | - Repoitory abtraction layer (Memory + File) 14 | - Swagger UI intergration 15 | 16 | ## v1.1 (In planned) 17 | - User aunthentication 18 | - Redis cache intergration 19 | - CI badge and pull request templates 20 | - Deployment on Heroku and Render 21 | - Mobile responsive UI 22 | 23 | ## Community wishlist 24 | - Dark/Light theme toogle 25 | - Multi-Language support 26 | - User roles (admin, guest) 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Reflections.md: -------------------------------------------------------------------------------- 1 | ## Reflection: Balancing Stakeholder Needs 2 | 3 | Developing the Advanced Calculator System involved balancing the needs of different groups, each with their own priorities. One of the main challenges was finding the right balance between simplicity and advanced features. Students and casual users wanted an easy-to-use interface, while researchers and professionals needed more complex functions like logarithms and graphing. To solve this, I created two modes: a simple one for everyday calculations and a more advanced one for technical tasks. 4 | 5 | Security and performance were also a concern. The IT team wanted to make sure the system kept data safe, while users cared about how fast the system worked. To address both, I used strong encryption to protect sensitive data, while also ensuring calculations were completed quickly, in less than two seconds. 6 | 7 | Another challenge was making the system work well on different devices and handle a lot of users at once. To do this, I designed the system to adjust to different screen sizes and organized the backend so it could manage many requests at the same time. 8 | 9 | In the end, the project showed me how important it is to keep improving the system based on feedback. By building the system in a flexible way, I made sure it could be easily updated in the future while keeping it simple, secure, and fast. 10 | 11 | # **Reflection: Challenges in Translating Requirements to Use Cases & Tests** 12 | 13 | Translating stakeholder requirements into use cases and test cases posed several challenges in ensuring that all functional and non-functional aspects of the Advanced Calculator System were properly covered. One key difficulty was ensuring completeness—making sure that each stakeholder concern was properly addressed in a relevant use case. While the functional requirements from Assignment 4 provided a strong foundation, defining clear preconditions, postconditions, and alternative flows required deeper analysis of how users interact with the system. Every requirement had to be carefully scrutinized to ensure that it was not only reflected in the system design but also captured in the use cases and corresponding test cases. 14 | 15 | Another challenge was handling complex interactions between different use cases. Some use cases, such as Perform Calculation and View History, were straightforward, but others, like Graphing a Function or Exporting History, involved multiple steps and dependencies. These use cases often had a cascade effect—one action would trigger another, and it was crucial to identify and map these interactions. Ensuring that these use cases remained modular while still supporting the overall system flow was essential. For instance, the Graph Function use case required seamless integration with Advanced Functions, where users would need to access more sophisticated mathematical features. Similarly, Export History not only relied on the data in View History but also involved exporting the data in a usable format. Managing such complex interactions without introducing confusion or redundancy was one of the key challenges in both the design and testing stages. 16 | 17 | For test cases, mapping functional requirements to concrete validation steps was critical. Writing clear expected results for each test case required thinking about not only normal user behavior but also edge cases and error conditions. Non-functional tests, such as performance under high load or security validation, were particularly challenging, as they required consideration of real-world constraints like response time and encryption mechanisms. Testing for security was also complicated, given the sensitive nature of personal data that might be processed, making it essential to test for potential vulnerabilities and ensure that all transactions were encrypted and protected. 18 | 19 | Finally, the balance between simplicity and usability was a recurring challenge. While the system needed to support advanced mathematical functions, it also had to remain accessible to general users. This required iterative adjustments to the use cases and test cases to refine error handling, accessibility, and performance considerations. The user interface needed to be intuitive, ensuring that both novices and advanced users could interact with the system effectively. In this process, feedback from stakeholders played a crucial role in fine-tuning the design to meet their expectations while maintaining a high level of functionality. 20 | 21 | Overall, this process reinforced the importance of structured requirement analysis, iterative design, and comprehensive testing to ensure a robust and user-friendly system. 22 | 23 | # Reflection: Challenges in Prioritization, Estimation, and Aligning Agile with Stakeholder Needs. 24 | 25 | One of the most difficult aspects was determining which features should be implemented first. With no external stakeholders to validate decisions, I had to rely on my judgment and technical feasibility assessments. Initially, it was tempting to work on the more complex and visually appealing features, such as graphing (US-004), rather than the core calculator functions (US-001). However, prioritizing based on MoSCoW principles helped bring clarity, ensuring that basic calculations and history management took precedence over enhancements like unit conversions (US-005) and exporting history (US-008). Despite this structured approach, there were moments of doubt—was I making the right call? Would I regret postponing certain features? This internal conflict made prioritization an ongoing challenge. 26 | 27 | Estimating effort was another area where I struggled. Without a team to discuss complexity levels, I had to rely on personal experience and best guesses to assign story points. Initially, I underestimated the complexity of features like encryption (US-009) and optimization (US-010), assigning them lower story points when, in reality, they required deeper research and testing. Conversely, I overestimated tasks like clearing history (US-003), which turned out to be straightforward. The lack of peer validation made estimation feel more like a guessing game rather than a structured process. I learned that breaking tasks into smaller increments and tracking time spent on each helped refine future estimates. 28 | 29 | Since I was both the decision-maker and executor, there were times when internal resistance slowed my progress. Without external accountability, I found myself procrastinating on certain tasks, especially those outside my comfort zone, like UI design and testing. Moving tasks across the GitHub Project Board from "In Progress" to "In Review" required self-discipline—there was no team pushing me to complete them. To combat this, I introduced structured self-check-ins and deadlines, treating each sprint review as if I were presenting to an external stakeholder. While this helped, the lack of external validation still made some tasks feel less urgent than they would in a traditional Agile team setting. 30 | 31 | This experience reinforced the importance of self-discipline, structured prioritization, and adaptability. If I were to redo this project, I would integrate external feedback earlier—perhaps seeking input from potential users or mentors—to validate priorities. I also realized the value of time tracking and reflection in improving estimation skills. Moving forward, refining Agile practices through self-imposed deadlines and simulated stakeholder reviews will be key to maintaining motivation and structured progress. 32 | 33 | Navigating Agile development as a solo stakeholder has been both rewarding and challenging. While the flexibility allowed me to structure the project on my terms, the absence of external accountability made prioritization, estimation, and execution difficult. By acknowledging these challenges and implementing structured self-discipline techniques, I can refine my Agile approach and ensure continued project. 34 | 35 | # Reflection on Using a Kanban Board 36 | 37 | ## 1. Understanding Kanban as a Project Management Tool 38 | The Kanban board provided a structured way to visualize tasks and manage workflow efficiently. By breaking down work into stages—Backlog, Ready, In Progress, In Review, Testing, Blocked, and Done —I could track progress clearly and identify bottlenecks. 39 | 40 | ## 2. Challenges Faced 41 | - **Adapting to the Workflow:** Initially, understanding how to properly transition tasks between columns was challenging. Sometimes, tasks were incorrectly placed, leading to confusion. 42 | - **Task Overload:** Without Work-In-Progress (WIP) limits, multiple tasks were in progress at once, making it difficult to focus. Implementing a limit helped improve efficiency. 43 | - **Blocked Tasks:** Some tasks remained in "Blocked" for extended periods, which slowed overall progress. Identifying the causes early helped mitigate this issue. 44 | 45 | ## 3. Key Takeaways & Learning Experience 46 | - **Improved Time Management:** The board forced prioritization of tasks, reducing time spent switching between unfinished work. 47 | - **Better Collaboration:** If used in a team setting, Kanban ensures that everyone knows task statuses and dependencies. 48 | - **Flexibility:** Unlike rigid project management tools, Kanban allows continuous improvement, adapting workflows as needed. 49 | 50 | ## 4. How This Will Be Applied in Future Projects 51 | Using Kanban has improved my ability to plan and track tasks** effectively. Moving forward, I will: 52 | - Set realistic WIP limits to maintain focus. 53 | - Use automation (if available) to transition tasks based on completion criteria. 54 | - Regularly review the board to remove stale or unnecessary tasks. 55 | 56 | # Reflections for Object state modeling and activity workflow objective. 57 | ## 1. Challenges in Choosing Granularity for States/Actions 58 | 59 | One of the main challenges in modeling was deciding the level of granularity. Too much detail makes diagrams cluttered and hard to follow, while too little detail risks missing important transitions or activities. For example, in the Advanced Calculator System, modeling every calculation type as a separate state/action made the diagrams too complex. To balance this, similar actions (like different types of unit conversions) were grouped under broader categories like “Perform Conversion” for simplicity and better readability. 60 | 61 | ## 2. Aligning Diagrams with Agile User Stories 62 | 63 | Another challenge was mapping diagrams accurately to Agile user stories. Agile focuses on delivering small, incremental value through user-centric stories, which sometimes lacked the technical specificity needed for precise diagramming. For example, a user story like “As a user, I want to export my results” required interpreting what backend processes that entails (e.g., generating files, triggering downloads). Ensuring diagrams reflect this functionality without making assumptions required collaboration with stakeholders or clarification of acceptance criteria. 64 | 65 | ## 3. Comparing State Diagrams vs. Activity Diagrams 66 | Aspect State Diagrams Activity Diagrams 67 | Focus Object behavior over time Step-by-step process flow 68 | Best for Lifecycle of a single object Modeling workflows and system processes 69 | Example Use Calculator session: Idle → Active → Closed Export workflow, registration, calculations 70 | Visual Elements States, transitions, events, guards Actions, decisions, concurrency, swimlanes 71 | Challenge Hard to model parallel actions Less suited for object-level behavior 72 | 73 | Summary: State diagrams were ideal for showing how the calculator or user account changes states due to events (e.g., login, session expired), while activity diagrams effectively captured end-to-end workflows such as performing calculations or exporting results. 74 | 75 | # Reflections for designing the domain model and class diadram 76 | Designing the domain model and class diagram for the Advanced Calculator System posed several intellectual and practical challenges. One of the first hurdles was deciding the appropriate level of granularity for domain entities. Initially, there was a temptation to overcomplicate the model by introducing too many minor classes for operations like trigonometric functions, algebraic simplifications, or expression parsing. However, these would clutter the model and hinder readability. After several iterations, I chose to abstract these operations under the Calculator class, with different type values like basic, scientific, and graphing. 77 | 78 | Another challenge involved defining clear responsibilities between the User, Calculator, and Calculation classes. To maintain separation of concerns, user authentication was kept strictly within the User class, while all evaluation logic remained in the Calculator class. This decision aligns well with object-oriented principles and ensures flexibility in future extensions such as admin roles or advanced calculators. 79 | 80 | Aligning the domain model and class diagram with prior assignments required revisiting the use cases and state/activity diagrams created in Assignment 8. For example, the state transitions for “Perform Calculation” and “Generate Graph” directly informed the methods and class responsibilities in the diagram. The activity diagram's decision points also influenced the inclusion of a centralized ErrorHandler class to manage invalid inputs. 81 | 82 | A particularly tricky decision involved inheritance and composition. Initially, the Graph class was modeled as a standalone entity. However, since it shares common attributes like expression and result with Calculation, inheritance was introduced, making Graph a subclass of Calculation. This not only reduced redundancy but also aligned better with real-world object hierarchies, where graphing is an extension of standard calculations. 83 | 84 | The process also highlighted the importance of traceability in Agile development. The class diagram directly maps to user stories such as “As a user, I want to calculate an expression” or “As a user, I want to view my history.” Sprint tasks like implementing graph generation and input validation are now clearly associated with the respective methods and classes. 85 | 86 | One limitation was that Mermaid.js, while simple and readable, lacks advanced features like visibility modifiers for associations or detailed notes inline. Despite this, it was adequate for representing the key classes, attributes, and methods. 87 | 88 | This exercise reinforced the importance of designing software systems with extensibility and maintainability in mind. By creating an abstract yet comprehensive model, future requirements like multi-user collaboration or advanced computation modules can be integrated with minimal structural changes. I also learned that revisiting earlier work—like user stories, functional requirements, and behavior diagrams—ensures that design decisions remain grounded in user and system needs. 89 | 90 | In conclusion, this assignment not only deepened my understanding of domain modeling and class diagrams but also illustrated the value of cohesive design in software engineering. 91 | 92 | ## Assignment 14 Reflections 93 | # Reflection on Open Source Engagement 94 | 95 | Engaging with the open-source community has been both eye-opening and rewarding. At first, I was unsure how others would perceive my Advanced Calculator System. However, seeing the project receive 38 stars and 31 forks reassured me that my effort, structure, and attention to detail were recognized. 96 | 97 | Through tagging issues as good-first-issue and feature-request, I made it easier for contributors to get involved. Watching other developers interact with my work, raise suggestions, and show interest made me feel like I was contributing to a broader ecosystem. 98 | 99 | One challenge I faced was learning how to structure and write clear issue descriptions for others. It made me think about my work from an outsider’s perspective. Additionally, handling GitHub Actions, templates, and badges taught me the importance of continuous integration in modern development. 100 | 101 | This experience made me realize that collaboration isn't always about code contribution. It includes clarity, openness, and appreciation for community feedback. Going forward, I aim to maintain this project actively and welcome more contributors with a stronger support framework, including documentation and contributor guidelines. 102 | 103 | Being part of an open-source community transforms a personal project into a shared vision. That is the true power of open collaboration. 104 | 105 | -------------------------------------------------------------------------------- /Specifications.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | 3 | The Advanced Calculator System is a web-based application designed to address the need for a versatile calculator that offers features beyond basic arithmetic, such as history tracking, unit conversions, and graphing capabilities. Built using HTML, CSS, and JavaScript, this lightweight tool aims to enhance productivity and education by providing an easily accessible solution from any device. With minimal computational requirements and the efficient handling of operations through JavaScript, the system ensures high feasibility and usability, catering to users seeking advanced functionality in a simple, web-based format. 4 | 5 | Project Title: Advanced Calculator System 6 | 7 | Domain: Education & Productivity 8 | 9 | Problem Statement: 10 | The current market has basic and scientific calculators, but users need a web-based version that is accessible anywhere and provides extended functionalities such as history tracking, 11 | unit conversions, and graphing capabilities. 12 | Individual Scope (Feasibility Justification): 13 | The system will be a lightweight web application developed using HTML, CSS, and JavaScript. It will store previous calculations and allow users to perform advanced operations. The 14 | feasibility is high because: 15 | JavaScript can handle arithmetic operations efficiently. 16 | The system does not require high computational power. 17 | Web-based calculators are widely used for learning and work purposes. 18 | -------------------------------------------------------------------------------- /SprintPlan.md: -------------------------------------------------------------------------------- 1 | | **Task ID** | **Task Description** | **Assigned To** | **Estimated Hours** | **Status (To Do/In Progress/Done)** | 2 | |------------|-----------------|--------------|----------------|----------------| 3 | | T-001 | Develop calculation logic | Dev Team | 8 | To Do | 4 | | T-002 | Create UI for calculator | UI Team | 6 | In Progress | 5 | 6 | Sprint Goal Statement: 7 | This sprint focuses on implementing the core features for basic calculations, calculation history tracking, unit conversions, and essential UI improvements. These functionalities are vital for the Minimum Viable Product (MVP) as they enable users to perform basic and advanced calculations, store and view their calculation history, and convert units. By the end of the sprint, we will have the foundational features that provide immediate value to users and align with the core mission of the application, ensuring that users can perform essential tasks with ease, even with a minimal set of features. 8 | 9 | How it contributes to the MVP: 10 | Core Features: The basic calculation and history tracking functionalities are essential to the MVP, ensuring that users can perform fundamental tasks right away. 11 | 12 | User Engagement: By allowing users to save and reference past calculations, the app starts to add more value, increasing engagement and usability. 13 | 14 | Flexibility: The unit conversion feature adds versatility to the app, making it useful in a wider range of scenarios for the user. 15 | 16 | Foundation for Future Development: These features provide a solid foundation for the next iterations and future features such as graphing and advanced mathematical functions. 17 | -------------------------------------------------------------------------------- /Stakeholder_Analysis.md: -------------------------------------------------------------------------------- 1 | # Stakeholder Analysis for Advanced Calculator System 2 | 3 | ## **Stakeholder Analysis Table** 4 | 5 | | **Stakeholder** | **Role** | **Key Concerns** | **Pain Points** | **Success Metrics** | 6 | |------------------------|----------------------------------------------|-------------------------------------------------|------------------------------------------------------|-------------------------------------------------| 7 | | **Students** | Use the calculator for academic calculations | Accurate results, user-friendly interface | Limited access to advanced features in basic calculators | Ability to perform complex calculations efficiently | 8 | | **Teachers/Lecturers** | Use it for teaching and demonstrations | Availability of advanced mathematical functions | Lack of graphing and visualization tools | Enhanced learning through interactive calculations | 9 | | **Researchers** | Utilize the system for complex computations | Support for higher-level functions like logarithms | No history tracking in traditional calculators | Ability to save and reference previous calculations | 10 | | **Professionals** | Use it for work-related calculations | Performance and accuracy | Inability to perform batch calculations | Reliable and fast computation speeds | 11 | | **Developers** | Maintain and enhance the system | Ease of debugging and scalability | Lack of API support for integrations | Code maintainability and extension possibilities | 12 | | **IT Support Team** | Ensure system uptime and security | System stability, secure data handling | Potential security vulnerabilities | Secure and smooth operation of the calculator | 13 | -------------------------------------------------------------------------------- /System_Requirements.md: -------------------------------------------------------------------------------- 1 | # System Requirements Document (SRD) for Advanced Calculator System 2 | 3 | ## **1. Functional Requirements** 4 | 5 | | **ID** | **Requirement** | **Acceptance Criteria** | 6 | |--------|------------------------------------------------------|------------------------------------------------------| 7 | | FR-01 | The system shall perform basic arithmetic operations (addition, subtraction, multiplication, division). | Users can enter numbers and receive accurate results. | 8 | | FR-02 | The system shall support advanced functions (exponentiation, logarithms, trigonometry). | Advanced calculations return correct values. | 9 | | FR-03 | The system shall allow users to store and retrieve previous calculations. | Users can view a history of their calculations. | 10 | | FR-04 | The system shall have a clear, user-friendly interface. | Users can navigate easily without confusion. | 11 | | FR-05 | The system shall provide a graphing feature for functions. | Users can input a function and see a plotted graph. | 12 | | FR-06 | The system shall support unit conversions (length, weight, temperature). | Users can convert values accurately. | 13 | | FR-07 | The system shall allow users to clear their history. | Users can reset their stored calculations. | 14 | | FR-08 | The system shall be accessible from multiple devices. | The calculator works on desktops, tablets, and smartphones. | 15 | | FR-09 | The system shall support keyboard input for calculations. | Users can use the keyboard to input numbers and operations. | 16 | | FR-10 | The system shall provide error handling for invalid inputs. | The calculator prevents and warns users of errors. | 17 | 18 | ## **2. Non-Functional Requirements** 19 | 20 | | **Category** | **Requirement** | 21 | |--------------------|------------------------------------------------------| 22 | | **Usability** | The interface shall comply with accessibility standards (WCAG 2.1). | 23 | | **Deployability** | The system shall be deployable on Windows, Mac, and Linux. | 24 | | **Maintainability** | The codebase shall be modular for easy updates and debugging. | 25 | | **Scalability** | The system shall support 1,000 concurrent users. | 26 | | **Security** | All user data shall be encrypted using AES-256. | 27 | | **Performance** | The system shall return results within 2 seconds. | 28 | | **Availability** | The system shall have 99.9% uptime for accessibility. | 29 | | **Extensibility** | The system shall support API integration for future features. | 30 | 31 | This document defines the core functional and non-functional requirements to ensure the success of the Advanced Calculator System. 32 | -------------------------------------------------------------------------------- /TeamPlanning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/TeamPlanning.png -------------------------------------------------------------------------------- /Template_Analysis.md: -------------------------------------------------------------------------------- 1 | # GitHub Project Template Analysis 2 | 3 | ## Templates Comparison 4 | 5 | ### GitHub Project Template Analysis 6 | 7 | | Template Name | Columns & Workflow | Automation Features | Agile Suitability | 8 | |----------------------------|--------------------------------------------------|-------------------------------------------|-----------------------------------------------------------------------------------| 9 | | **Automated Kanban** | New, In Progress, Review, Done | Auto-moves issues when updated | Ideal for sprint tracking and iterative work. | 10 | | **Bug Triage** | New Issues, High Priority, In Progress, Done | Auto-labels and sorts bug reports | Best for bug tracking and issue management. | 11 | | **Team Planning** | Backlog, To Do, In Progress, Done | Automates backlog organization | Good for structured Agile team workflows. | 12 | | **Iterative Development** | Backlog, To Do, In Progress, Review, Done | Auto-moves issues and prioritizes work for iterations | Specifically designed for **iterative development**, helping teams organize and track work in short, repeatable sprints, supporting continuous feedback and delivery. | 13 | 14 | --- 15 | 16 | ## **Selected Template: Automated Kanban** 17 | 18 | ### **Reason for Selection:** 19 | - Supports **sprint tracking** with built-in automation. 20 | - **Automatically updates** issue status based on progress. 21 | - Reduces **manual effort** in task management. 22 | - Best suited for **Agile workflows**, ensuring smooth progress tracking. 23 | 24 | --- 25 | ## Templates Screenshots 26 | 27 | ### **Automated Kanban Template Picture** 28 | ![Kanbas Image](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/KanbanPic1.png) 29 | 30 | ### **Iterative Development Template Picture** 31 | 32 | ![Kanbas Image](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/IterativeDevelopment.png) 33 | 34 | ### **Bug Triage Template Picture** 35 | 36 | ![Kanbas Image](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/BugTriage.png) 37 | 38 | ### **Team Planning Template Picture** 39 | 40 | ![Kanbas Image](https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/main/TeamPlanning.png) 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Test_Case.md: -------------------------------------------------------------------------------- 1 | # Test Cases for Advanced Calculator System 2 | 3 | ## **Functional Test Cases** 4 | 5 | | **Test Case ID** | **Requirement ID** | **Description** | **Steps** | **Expected Result** | **Actual Result** | **Status (Pass/Fail)** | 6 | |-----------------|------------------|---------------|----------|-----------------|-----------------|-----------------| 7 | | TC-001 | FR-01 | Perform basic arithmetic operations | 1. Enter two numbers. 2. Select an operation. 3. Click Calculate. | The correct result is displayed. | - | - | 8 | | TC-002 | FR-03 | View calculation history | 1. Perform calculations. 2. Navigate to history. | Past calculations are displayed. | - | - | 9 | | TC-003 | FR-07 | Clear calculation history | 1. Navigate to history. 2. Click clear history. | History is cleared, and a confirmation message is shown. | - | - | 10 | | TC-004 | FR-05 | Graph a mathematical function | 1. Enter a valid function. 2. Click Graph. | The system displays the graph. | - | - | 11 | | TC-005 | FR-06 | Perform unit conversion | 1. Select units. 2. Enter value. 3. Click Convert. | The converted value is displayed. | - | - | 12 | | TC-006 | FR-08 | Use keyboard input for calculations | 1. Enter values using the keyboard. 2. Press Enter. | The correct result is displayed. | - | - | 13 | | TC-007 | FR-10 | Error handling for invalid input | 1. Enter invalid input. 2. Click Calculate. | An error message is displayed. | - | - | 14 | | TC-008 | FR-09 | Export calculation history | 1. Navigate to history. 2. Click Export. | A file is generated and downloaded. | - | - | 15 | 16 | ## **Non-Functional Test Cases** 17 | 18 | | **Test Case ID** | **Requirement ID** | **Description** | **Steps** | **Expected Result** | **Actual Result** | **Status (Pass/Fail)** | 19 | |-----------------|------------------|---------------|----------|-----------------|-----------------|-----------------| 20 | | TC-009 | NFR-01 | Performance test for calculations | 1. Perform 100 calculations. | System responds within 2 seconds. | - | - | 21 | | TC-010 | NFR-02 | Security test for data encryption | 1. Enter and store data. 2. Access database. | User data is encrypted using AES-256. | - | - | 22 | 23 | This document contains functional and non-functional test cases to validate the behavior of the Advanced Calculator System. 24 | 25 | -------------------------------------------------------------------------------- /Traceability.md: -------------------------------------------------------------------------------- 1 | 2 | # Traceability 3 | ## For activity Diagrams 4 | The following section shows how each diagram relates to the functional requirements and user stories: 5 | 6 | ### 1. **User Registration Workflow** 7 | - **Functional Requirements (Assignment 4):** 8 | - FR-002: User must be able to register by entering their details, and the system must validate the input before creating an account. 9 | - **User Stories (Assignment 6):** 10 | - US-001: As a user, I want to create an account by entering my details so that I can access the advanced calculator system. 11 | - **Sprint Task:** 12 | - Implement the user registration form, including input validation and confirmation email. 13 | - **Diagram Explanation:** 14 | - This diagram shows the user registration process. It validates input and ensures users are registered securely. This addresses stakeholder needs for a secure sign-up process. 15 | 16 | --- 17 | 18 | ### 2. **Login Workflow** 19 | - **Functional Requirements (Assignment 4):** 20 | - FR-001: Users must be able to log in to access the system securely. 21 | - **User Stories (Assignment 6):** 22 | - US-002: As a user, I want to log in using my credentials so that I can access my personalized dashboard. 23 | - **Sprint Task:** 24 | - Implement login functionality with authentication and error handling. 25 | - **Diagram Explanation:** 26 | - This workflow illustrates the login process, ensuring that users can only access the system with valid credentials. It ensures security as per the functional requirements. 27 | 28 | --- 29 | 30 | ### 3. **Perform Calculation Workflow** 31 | - **Functional Requirements (Assignment 4):** 32 | - FR-001: The system must allow the user to input a mathematical expression and display the result. 33 | - FR-004: The system must ensure that the input is a valid expression before evaluation. 34 | - **User Stories (Assignment 6):** 35 | - US-003: As a user, I want to enter an expression and get the result so that I can perform basic calculations. 36 | - **Sprint Task:** 37 | - Implement input parsing and expression validation for the calculator. 38 | - **Diagram Explanation:** 39 | - The core calculation logic is demonstrated here, validating the input and ensuring only valid expressions are evaluated. This fulfills the functional requirement for basic calculations. 40 | 41 | --- 42 | 43 | ### 4. **Graphing Calculator Workflow** 44 | - **Functional Requirements (Assignment 4):** 45 | - FR-005: The system must provide the ability to input a mathematical function and generate a graphical representation of it. 46 | - **User Stories (Assignment 6):** 47 | - US-004: As a user, I want to input a function and see its graph so that I can visualize the relationship between variables. 48 | - **Sprint Task:** 49 | - Implement the graphing functionality, including function parsing 50 | --- 51 | ### 5.Save Calculation History Workflow 52 | - **Functional Requirements (Assignment 4):** 53 | - FR-006: The system must allow users to save and access a history of their previous calculations. 54 | - **User Stories (Assignment 6):** 55 | - US-005: As a user, I want to be able to view my calculation history so that I can track what I’ve done before. 56 | - **Sprint Task:** 57 | - Implement a backend history feature and connect it to the user interface. 58 | --- 59 | ### 6. Export Results Workflow 60 | - **Functional Requirements (Assignment 4):** 61 | - FR-007: The system must allow users to export calculation results as a PDF or CSV. 62 | - **User Stories (Assignment 6):** 63 | - US-006: As a user, I want to download my results in a readable format so that I can share or store them. 64 | - **Sprint Task:** 65 | - Implement export functionality using file generation libraries. 66 | --- 67 | ### 7. Unit Conversion Workflow 68 | 69 | - **Functional Requirements (Assignment 4):** 70 | - FR-008: The system must provide the ability to convert between different units (e.g., length, weight, temperature). 71 | 72 | - **User Stories (Assignment 6):** 73 | - US-007: As a user, I want to convert between different units so that I can complete everyday or academic tasks more efficiently. 74 | 75 | - **Sprint Task:** 76 | - Implement unit selection, conversion logic, and error handling. 77 | --- 78 | ### 8. Advanced Functions Workflow (Trigonometry, Logarithms, etc.) 79 | 80 | - **Functional Requirements (Assignment 4):** 81 | - FR-009: The system must support advanced mathematical functions including trigonometry, logarithms, and powers. 82 | 83 | - **User Stories (Assignment 6):** 84 | - US-008: As a user, I want to perform complex scientific calculations so that I can use the tool for academic purposes. 85 | 86 | - **Sprint Task:** 87 | - Implement advanced function parsing and integrate with the core calculation engine. 88 | ## For State Transition diagrams 89 | ### 1. User Account 90 | 91 | - **Functional Requirements (Assignment 4):** 92 | - **FR-003:** Allow users to delete their accounts. 93 | - **FR-007:** Admin can suspend accounts for violations. 94 | 95 | - **User Stories (Assignment 6):** 96 | - **US-002:** As a user, I want to verify my account to activate it. 97 | - **US-003:** As an admin, I want to suspend user accounts that violate the rules. 98 | - **US-004:** As an admin, I want to delete user accounts when necessary. 99 | 100 | - **Sprint Task:** 101 | - Implement account suspension and deletion functionality for admins. 102 | - Implement email verification for users to activate their accounts. 103 | 104 | --- 105 | 106 | ### 2. Calculation Process 107 | 108 | - **Functional Requirements (Assignment 4):** 109 | - **FR-010:** Perform calculations efficiently. 110 | 111 | - **User Stories (Assignment 6):** 112 | - **US-006:** As a user, I want to select an operation to start a calculation. 113 | - **US-007:** As a user, I want to view the result of the calculation after the system processes it. 114 | 115 | - **Sprint Task:** 116 | - Implement a calculation feature that processes the input and returns results efficiently. 117 | - Ensure smooth transition between calculation steps (from idle to computing to displaying results). 118 | 119 | --- 120 | 121 | ### 3. History Recorded 122 | 123 | - **Functional Requirements (Assignment 4):** 124 | - **FR-015:** Allow users to save calculations to view later. 125 | 126 | - **User Stories (Assignment 6):** 127 | - **US-005:** As a user, I want to save my calculations so I can view them later. 128 | - **US-008:** As a user, I want to delete my saved calculations if they are no longer needed. 129 | 130 | - **Sprint Task:** 131 | - Implement functionality to save and delete calculation history. 132 | - Develop a user interface for displaying saved calculations. 133 | 134 | --- 135 | 136 | ### 4. Graphing Function 137 | 138 | - **Functional Requirements (Assignment 4):** 139 | - **FR-020:** Provide graphing capabilities. 140 | 141 | - **User Stories (Assignment 6):** 142 | - **US-010:** As a user, I want to generate a graph from my data so I can visualize the results. 143 | - **US-011:** As a user, I want to view the graph once it has been generated. 144 | 145 | - **Sprint Task:** 146 | - Implement the graphing functionality to process data and generate graphs. 147 | - Develop the interface to display the generated graph to the user. 148 | 149 | --- 150 | 151 | ### 5. Unit Conversion 152 | 153 | - **Functional Requirements (Assignment 4):** 154 | - **FR-025:** Enable unit conversions. 155 | 156 | - **User Stories (Assignment 6):** 157 | - **US-012:** As a user, I want to convert between different units. 158 | - **US-013:** As a user, I want to see the result of my unit conversion. 159 | 160 | - **Sprint Task:** 161 | - Implement unit conversion functionality for various units. 162 | - Create a user interface to display the conversion results. 163 | 164 | --- 165 | 166 | ### 6. Session Management 167 | 168 | - **Functional Requirements (Assignment 4):** 169 | - **FR-030:** Auto-logout after inactivity. 170 | 171 | - **User Stories (Assignment 6):** 172 | - **US-014:** As a user, I want the system to log me out after inactivity for security. 173 | - **US-015:** As a user, I want to manually log out from the system. 174 | 175 | - **Sprint Task:** 176 | - Implement automatic logout feature after a specified time of inactivity. 177 | - Implement a manual logout option for users. 178 | 179 | --- 180 | 181 | ### 7. Setting Configuration 182 | 183 | - **Functional Requirements (Assignment 4):** 184 | - **FR-035:** Allow users to personalize settings. 185 | 186 | - **User Stories (Assignment 6):** 187 | - **US-016:** As a user, I want to customize my settings to match my preferences. 188 | - **US-017:** As a user, I want to reset my settings to the default values. 189 | 190 | - **Sprint Task:** 191 | - Implement user settings customization options. 192 | - Provide the ability to reset settings to their default values. 193 | -------------------------------------------------------------------------------- /Transition&Activity_Reflections.md: -------------------------------------------------------------------------------- 1 | # Reflections for Object state modeling and activity workflow objective. 2 | ## 1. Challenges in Choosing Granularity for States/Actions 3 | 4 | One of the main challenges in modeling was deciding the level of granularity. Too much detail makes diagrams cluttered and hard to follow, while too little detail risks missing important transitions or activities. For example, in the Advanced Calculator System, modeling every calculation type as a separate state/action made the diagrams too complex. To balance this, similar actions (like different types of unit conversions) were grouped under broader categories like “Perform Conversion” for simplicity and better readability. 5 | ## 2. Aligning Diagrams with Agile User Stories 6 | 7 | Another challenge was mapping diagrams accurately to Agile user stories. Agile focuses on delivering small, incremental value through user-centric stories, which sometimes lacked the technical specificity needed for precise diagramming. For example, a user story like “As a user, I want to export my results” required interpreting what backend processes that entails (e.g., generating files, triggering downloads). Ensuring diagrams reflect this functionality without making assumptions required collaboration with stakeholders or clarification of acceptance criteria. 8 | ## 3. Comparing State Diagrams vs. Activity Diagrams 9 | 10 | Aspect State Diagrams Activity Diagrams Focus Object behavior over time Step-by-step process flow Best for Lifecycle of a single object Modeling workflows and system processes Example Use Calculator session: Idle → Active → Closed Export workflow, registration, calculations Visual Elements States, transitions, events, guards Actions, decisions, concurrency, swimlanes Challenge Hard to model parallel actions Less suited for object-level behavior 11 | 12 | Summary: State diagrams were ideal for showing how the calculator or user account changes states due to events (e.g., login, session expired), while activity diagrams effectively captured end-to-end workflows such as performing calculations or exporting results. 13 | -------------------------------------------------------------------------------- /TransitionDiagrams.md: -------------------------------------------------------------------------------- 1 | # State Transition Diagrams for Calculator System 2 | 3 | ## 1.User Account 4 | ```mermaid 5 | stateDiagram-v2 6 | [*] --> Created 7 | Created --> Active : User verifies email 8 | Active --> Suspended : Admin suspends account 9 | Suspended --> Active : Admin reinstates account 10 | Active --> Deleted : Admin deletes account 11 | Suspended --> Deleted : Admin deletes account 12 | Deleted --> [*] 13 | ``` 14 | ### Explanation 15 | The user account starts in the Created sate when a user registers. 16 | 17 | It transition to Active once the email is verified. 18 | 19 | If the user violates the terms, the account can be suspended. 20 | 21 | Suspended acounts can be restored by an admin. 22 | 23 | Users can permanently delete their accounts. 24 | 25 | ### Mapping to Functional Requirements 26 | Dleted states maps to FR-003: Allow users to delete their accounts. 27 | 28 | Suspended states maps to FR-007: Admin can suspend accounts for violations. 29 | 30 | ## 2.Calculation Process 31 | ``` mermaid 32 | stateDiagram-v2 33 | [*] --> Idle 34 | Idle --> Inputing: User enters numbers 35 | Inputing --> Computing: User selcts an operation 36 | Computing --> DisplayingResults: Calculation completes 37 | DisplayingResults --> Idle: User starts a new calculation 38 | ``` 39 | ### Explanation 40 | The system waits in Idle unti the usr provides input. 41 | 42 | Moves to Computing once an operation is selected. 43 | 44 | Displayingesults shows the answer before returning to Idle. 45 | 46 | ### Mapping to Functional Requirements. 47 | Computing states maps to FR-010: Perform calculations efficiently. 48 | 49 | ## 3. History Recorded 50 | ```mermaid 51 | stateDiagram-v2 52 | [*] --> NewEntry 53 | NewEntry --> Saved : User saves hiatory 54 | Saved --> Deleted: User deletes entry 55 | Deleted --> [*] 56 | ``` 57 | ### Explanation 58 | Each calculation starts in NewEntry. 59 | It is Saved if the user chooses to keep history. 60 | Users can Delete records anytime. 61 | 62 | ### Mapping to Functional Requirements 63 | Saved states maps to FR-015: Allow users to save calculations. 64 | 65 | ## Graphing Function 66 | ``` mermaid 67 | stateDiagram-v2 68 | [*] --> Ready 69 | Ready --> GeneratingGraph : User inputs data 70 | GeneratingGraph--> DisplayingGraph : Graph renders 71 | DisplayingGraph --> Ready: User resets 72 | ``` 73 | ### Explanation 74 | The system is Ready before a graph is requested. 75 | 76 | Moves to GenratingGraph when the data is procesed. 77 | 78 | The graph appears in DisplayingGraph. 79 | 80 | ### Mapping to Functional Requirements 81 | GeneratingGraph maps to FR-020: Provide graphing capabilities. 82 | 83 | ## Unit Conversion 84 | ``` mermaid 85 | stateDiagram-v2 86 | [*] --> Idle 87 | Idle --> InputingData: User enters value 88 | InputingData--> Converting: System proccesses conversion 89 | Converting --> DisplayingResult: Converted value shown 90 | DisplayingResult -->Idle: User starts another conversion 91 | ``` 92 | ### Explanation 93 | Similar to the calculator , this process follows input to process to output. 94 | 95 | ### Mapping to Functional Requirements 96 | Converting state maps to FR-025: Enable unit conversions. 97 | 98 | ## Session Manangement 99 | ``` mermaid 100 | stateDiagram-v2 101 | [*] --> LoggedOut 102 | LoggedOut --> LoggedIn: User logs in 103 | LoggedIn --> Timeout : Inactivity detected 104 | Timeout --> LoggedOut: Auto logout 105 | LoggedIn --> LoggedOut: User logs out 106 | ``` 107 | ### Explanation 108 | The system logs out users after inactivity( Timeout). 109 | 110 | Users can manually log out anytime. 111 | 112 | ### Mapping of Functional Requirements 113 | Timeout state maps to FR-030: Auto-logout after inactivity. 114 | 115 | ## Setting Configuaration 116 | ```mermaid 117 | stateDiagram-v2 118 | [*] --> DefaultSettings 119 | DefaultSettings --> CustomSettings : User modifies settings 120 | CustomSettings--> DefaultSettings: User resets settings 121 | ``` 122 | ### Explanation 123 | Settings start in DefualtSettings. 124 | 125 | Users can Customize, then Reset. 126 | 127 | ### Mapping of Functional Requirements 128 | CustomSetting stste maps to FR-035: Allow users to personalize settings. 129 | -------------------------------------------------------------------------------- /Untitled diagram-2025-03-02-172106.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/Untitled diagram-2025-03-02-172106.png -------------------------------------------------------------------------------- /UseCaseDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/UseCaseDiagram.png -------------------------------------------------------------------------------- /UseCase_SPECIFICATIONS.md: -------------------------------------------------------------------------------- 1 | # Calculator System Use Cases 2 | 3 | ## Overview 4 | 5 | The Calculator System is a web-based application that provides basic and advanced mathematical operations, unit conversions, and other utilities for users. It includes functionality to view calculation history, graph functions, and export data, making it useful for students, teachers, researchers, and developers. 6 | 7 | ## Actors 8 | 9 | 1. **Student**: A primary user who interacts with the basic and advanced calculator functions. 10 | 2. **Teacher**: An educator who uses the system to perform calculations and track student progress. 11 | 3. **Admin**: A system administrator responsible for managing user accounts and monitoring usage stats. 12 | 4. **Researcher**: A user who needs advanced functions for data analysis and exports calculation history. 13 | 5. **Parent**: A user (typically a guardian) who monitors the calculation history of their child/student. 14 | 6. **Developer**: A person responsible for system maintenance, bug fixes, and feature additions. 15 | 16 | ## Use Cases 17 | 18 | ### **Use Case 1: Perform Calculation** 19 | - **Actor(s):** Student, Teacher, Admin, Researcher, Parent, Developer 20 | - **Description:** Allows users to perform basic and advanced mathematical operations. 21 | - **Preconditions:** User has entered valid input. 22 | - **Postconditions:** The result of the calculation is displayed. 23 | - **Basic Flow:** 24 | 1. User enters numbers and selects an operation. 25 | 2. System processes the calculation. 26 | 3. System displays the result. 27 | - **Alternative Flow:** 28 | - If invalid input is entered, the system displays an error message. 29 | 30 | ### **Use Case 2: View Calculation History** 31 | - **Actor(s):** Student, Teacher 32 | - **Description:** Allows users to view past calculations. 33 | - **Preconditions:** User has previously performed calculations. 34 | - **Postconditions:** Past calculations are displayed. 35 | - **Basic Flow:** 36 | 1. User navigates to the history section. 37 | 2. System retrieves and displays stored calculations. 38 | - **Alternative Flow:** 39 | - If no history exists, the system informs the user. 40 | 41 | ### **Use Case 3: Clear Calculation History** 42 | - **Actor(s):** Student, Teacher, Admin 43 | - **Description:** Allows users to delete stored calculations. 44 | - **Preconditions:** Calculation history exists. 45 | - **Postconditions:** History is cleared. 46 | - **Basic Flow:** 47 | 1. User selects the clear history option. 48 | 2. System deletes stored calculations. 49 | 3. System confirms deletion. 50 | - **Alternative Flow:** 51 | - If history is already empty, the system notifies the user. 52 | 53 | ### **Use Case 4: Graph a Mathematical Function** 54 | - **Actor(s):** Student, Teacher, Researcher 55 | - **Description:** Users can input a function and view a graph. 56 | - **Preconditions:** User enters a valid function. 57 | - **Postconditions:** Graph is displayed. 58 | - **Basic Flow:** 59 | 1. User enters a function. 60 | 2. System processes and generates the graph. 61 | 3. System displays the graph. 62 | - **Alternative Flow:** 63 | - If input is invalid, system prompts for correction. 64 | 65 | ### **Use Case 5: Perform Unit Conversion** 66 | - **Actor(s):** Student, Teacher, Admin 67 | - **Description:** Allows users to convert between different measurement units. 68 | - **Preconditions:** User selects valid units and enters a value. 69 | - **Postconditions:** Converted value is displayed. 70 | - **Basic Flow:** 71 | 1. User selects units and enters a value. 72 | 2. System processes the conversion. 73 | 3. System displays the converted value. 74 | - **Alternative Flow:** 75 | - If invalid units are selected, the system displays an error. 76 | 77 | ### **Use Case 6: Access Advanced Functions** 78 | - **Actor(s):** Student, Teacher, Researcher 79 | - **Description:** Allows users to access advanced operations like logarithms and trigonometry. 80 | - **Preconditions:** User selects an advanced function. 81 | - **Postconditions:** System calculates and displays the result. 82 | - **Basic Flow:** 83 | 1. User selects an advanced function. 84 | 2. System processes the calculation. 85 | 3. System displays the result. 86 | - **Alternative Flow:** 87 | - If input is invalid, system prompts the user to enter a valid input. 88 | 89 | ### **Use Case 7: Save Favorite Calculations** 90 | - **Actor(s):** Student, Teacher 91 | - **Description:** Users can save frequently used calculations for quick access. 92 | - **Preconditions:** User has performed a calculation. 93 | - **Postconditions:** Calculation is stored under favorites. 94 | - **Basic Flow:** 95 | 1. User selects "Save to Favorites." 96 | 2. System saves the calculation. 97 | 3. System confirms the action. 98 | - **Alternative Flow:** 99 | - If memory is full, system informs the user. 100 | 101 | ### **Use Case 8: Export Calculation History** 102 | - **Actor(s):** Student, Teacher, Admin, Researcher, Developer 103 | - **Description:** Users can export their calculation history as a file. 104 | - **Preconditions:** User has history data. 105 | - **Postconditions:** History is exported as a file. 106 | - **Basic Flow:** 107 | 1. User selects the export option. 108 | 2. System generates a file with past calculations. 109 | 3. System prompts the user to download. 110 | - **Alternative Flow:** 111 | - If no history exists, system notifies the user. 112 | 113 | ## Use Case Diagram 114 | 115 | A **Use Case Diagram** for this Calculator System is provided below. It shows the interactions between the actors and the system’s functionalities. 116 | 117 | ![Use Case Diagram](UseCaseDiagram.png) 118 | 119 | ## **Use Case Diagram Link to Mermaid.js** 120 | 121 | ![Use Case Diagram](https://www.mermaidchart.com/app/projects/ac19d35b-57d7-4e57-bfd8-c5bb398d3655/diagrams/735bcc0a-d0ca-41b1-b83b-5a4ac1123f1d/version/v0.1/edit) 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /UserStories.md: -------------------------------------------------------------------------------- 1 | | **Story ID** | **User Story** | **Acceptance Criteria** | **Priority (High/Medium/Low)** | 2 | |-------------|--------------|----------------------|----------------------| 3 | | US-001 | As a user, I want to perform basic calculations so that I can quickly get results. | The system correctly computes addition, subtraction, multiplication, and division. | High | 4 | | US-002 | As a student, I want to save my calculation history so that I can refer to past results. | Users can view, delete, and export calculation history. | High | 5 | | US-003 | As a user, I want to clear my calculation history so that I can remove old data. | The system provides an option to clear history with a confirmation prompt. | Medium | 6 | | US-004 | As a user, I want to graph mathematical functions so that I can visualize calculations. | Users can input a function and generate an accurate graph. | High | 7 | | US-005 | As a user, I want to perform unit conversions so that I can quickly switch between different measurement systems. | The system allows unit conversions for length, weight, and temperature. | Medium | 8 | | US-006 | As an advanced user, I want access to logarithmic and trigonometric functions so that I can solve complex equations. | The system supports advanced functions like logarithms, sine, cosine, and tangent. | High | 9 | | US-007 | As a user, I want to save frequently used calculations so that I can access them easily. | The system allows users to store and retrieve saved calculations. | Medium | 10 | | US-008 | As a user, I want to export my calculation history so that I can use it in external reports. | The system provides export options in CSV and PDF formats. | Medium | 11 | | US-009 | As an admin, I want user data to be encrypted so that security compliance is met. | All sensitive data is encrypted using AES-256. | High | 12 | | US-010 | As a user, I want the calculator to load quickly so that I can start using it without delays. | The system loads within 2 seconds of access. | High | 13 | -------------------------------------------------------------------------------- /VotingResults.md: -------------------------------------------------------------------------------- 1 | # Peer Voting Results 2 | 3 | # Community Engagement Report 4 | 5 | ## Community Stats 6 | 7 | - ⭐ Total Stars Received: **38** 8 | - 🍴 Total Forks: **31** 9 | 10 | ## Engagement Summary 11 | 12 | The community has shown strong interest in the Advanced Calculator System. With 38 stars, developers appreciate the features, design patterns, and overall structure. The 31 forks suggest many developers are interested in building upon or experimenting with the system. 13 | 14 | ## Issue Comments 15 | 16 | I responded to user questions on: 17 | - Feature requests (e.g., dark mode toggle) 18 | - Repository setup and usage instructions 19 | - Request for clearer error messages 20 | 21 | ## Improvements After Feedback 22 | 23 | - Added more tooltips for better usability. 24 | - Updated README to include clearer installation steps. 25 | - Added `good-first-issue` tags to make it easier for new contributors. 26 | 27 | ## Future Plans 28 | 29 | - Merge pull requests from contributors. 30 | - Continue improving test coverage and API documentation. 31 | - Encourage collaboration through open discussions and more beginner-friendly issues. 32 | 33 | -------------------------------------------------------------------------------- /docs/screenshots/BranchRules/Rules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/BranchRules/Rules.png -------------------------------------------------------------------------------- /docs/screenshots/BranchRules/Rules1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/BranchRules/Rules1.png -------------------------------------------------------------------------------- /docs/screenshots/Pull_Request/pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/Pull_Request/pull_request.png -------------------------------------------------------------------------------- /docs/screenshots/Run Test-Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/Run Test-Success.png -------------------------------------------------------------------------------- /docs/screenshots/Test_Results_Success/Run Test-Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/Test_Results_Success/Run Test-Success.png -------------------------------------------------------------------------------- /docs/screenshots/Test_Results_Success/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/Test_Results_Success/test.png -------------------------------------------------------------------------------- /docs/screenshots/status_badge_in_readme/Badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/status_badge_in_readme/Badge.png -------------------------------------------------------------------------------- /docs/screenshots/status_badge_in_readme/CI LIVE BADGE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/status_badge_in_readme/CI LIVE BADGE.png -------------------------------------------------------------------------------- /docs/screenshots/status_badge_in_readme/taks8: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/docs/screenshots/test.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pydantic==2.11.4 2 | 3 | -------------------------------------------------------------------------------- /src/Docs/ApiDocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Docs/ApiDocs.png -------------------------------------------------------------------------------- /src/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | # Add current script directory to the sys.path for importing 5 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) 6 | 7 | if __name__ == "__main__": 8 | # === Models === 9 | try: 10 | from Models.User import User 11 | from Models.Calculations import Calculation 12 | except ImportError: 13 | print("Models import skipped. Running without Models.") 14 | 15 | # === Creational Patterns === 16 | from creational_patterns.Factories.calculator_factory import CalculatorFactory 17 | from creational_patterns.Factories.results_formatter import PlainTextFormatter 18 | from creational_patterns.Factories.ui_factory import DarkThemeFactory 19 | from creational_patterns.Builders.calculation_builder import CalculationBuilder 20 | from creational_patterns.Prototype.calculations_prototype import CalculationPrototype 21 | from creational_patterns.Singletons.logger import Logger 22 | 23 | print("🚀 Starting Advanced Calculator System...\n") 24 | 25 | # --- Singleton: Logger --- 26 | logger = Logger() 27 | logger.log("Application launched") 28 | 29 | # --- Simple Factory --- 30 | calc = CalculatorFactory.get_calculator("Scientific") 31 | print("🧮 Factory Calculator Result:", calc.calculateExpressions("2 + 2 * 5")) 32 | 33 | # --- Factory Method --- 34 | formatter = PlainTextFormatter() 35 | print("📝 Formatted Output:", formatter.format(20)) 36 | 37 | # --- Abstract Factory --- 38 | theme = DarkThemeFactory() 39 | button = theme.create_button() 40 | label = theme.create_label() 41 | print("🎨 UI Elements:") 42 | print(button.draw()) 43 | print(label.render()) 44 | 45 | # --- Builder Pattern --- 46 | builder = CalculationBuilder() 47 | custom_calc = builder.set_id("C1001").set_expression("10 / 3").set_precision(4).build() 48 | print("🧱 Builder Result:", custom_calc.perform()) 49 | 50 | # --- Prototype Pattern --- 51 | original = CalculationPrototype("C001", "5 + 3", 8) 52 | copy = original.clone() 53 | copy.calc_id = "C002" 54 | print("🧬 Prototype Original:", original) 55 | print("🧬 Prototype Clone:", copy) 56 | 57 | # --- Logger logs --- 58 | print("\n📜 Logger Logs:") 59 | for entry in logger.get_logs(): 60 | print("→", entry) 61 | 62 | # === Assignment 11: Repository Layer Test === 63 | print("\n💾 Testing Repository Layer (Assignment 11)") 64 | 65 | from RepositoryFactory.repository_factory import RepositoryFactory 66 | 67 | # Choose storage type: "MEMORY" or "FILE" 68 | storage_type = "FILE" # or change to "MEMORY" to use InMemoryUserRepository 69 | 70 | user_repo = RepositoryFactory.get_user_repository(storage_type) 71 | 72 | # Save a user 73 | user = User("U011", "Sisipho Repo", "repo@example.com", "secure123") 74 | user_repo.save(user) 75 | print("✅ User saved to", storage_type, "repository.") 76 | 77 | # Retrieve user 78 | retrieved = user_repo.find_by_id("U011") 79 | if retrieved: 80 | print(f"🔍 Retrieved: {retrieved.name} ({retrieved.email})") 81 | 82 | # List all users 83 | users = user_repo.find_all() 84 | print("📋 All Users in Repo:") 85 | for u in users: 86 | print("→", u.name) 87 | 88 | # Delete the user 89 | user_repo.delete("U011") 90 | print("🗑️ User deleted.") 91 | 92 | # Confirm deletion 93 | if not user_repo.find_by_id("U011"): 94 | print("✅ Deletion confirmed.") 95 | -------------------------------------------------------------------------------- /src/Models/Calculations.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | class Calculation: 4 | def __init__(self, calculationID, expression, precision=2, rounding=True): 5 | self.calculationID= calculationID 6 | self.expression=expression 7 | self.result = None 8 | self.timestamp = datetime.now () 9 | self.precision = precision # New attribute for precision 10 | self.rounding = rounding 11 | 12 | 13 | def perform (self): 14 | try: 15 | self.result= eval (self.expression) 16 | except Exception: 17 | self.result = "Error" 18 | return self.result 19 | 20 | def SaveToHistory(self): 21 | # user.add(self) 22 | print("Sure, Jan") -------------------------------------------------------------------------------- /src/Models/Calculator.py: -------------------------------------------------------------------------------- 1 | class Calculator: 2 | def __init__(self, calculatorID, type): # Use __init__ (double underscores) 3 | self.calculatorID = calculatorID 4 | self.type = type 5 | 6 | def calculateExpressions(self, expression): 7 | try: 8 | result = eval(expression) 9 | return result 10 | except Exception as e: 11 | return f"Error: {e}" 12 | 13 | def validateInput(self, expression): 14 | return isinstance(expression, str) and expression.strip() != "" 15 | 16 | def displayResults(self, result): # Fixed typo: "displayReults" -> "displayResults" 17 | print(f"Result: {result}") 18 | -------------------------------------------------------------------------------- /src/Models/ErrorHandler.py: -------------------------------------------------------------------------------- 1 | class ErrorHanndler: 2 | def _init_(self): 3 | self.errorCode = None 4 | self.errorMessage = None 5 | 6 | def catchInputError(self, expression): 7 | if not expression: 8 | self.errorCode = "ERR001" 9 | self.errorMessage = "Invalid input" 10 | self.logError() 11 | 12 | def logError(self): 13 | print(f"Error [{self.errorCode}]: {self.errorMessage}") -------------------------------------------------------------------------------- /src/Models/Graph.py: -------------------------------------------------------------------------------- 1 | from Calculations import Calculation 2 | 3 | class Graph(Calculation): 4 | def _init_(self, graphID, functionExpression): 5 | super()._init_(graphID, functionExpression) 6 | self.graphImage = None 7 | 8 | def generateGraph(self): 9 | self.graphImage= f"Graph of {self.expression}" 10 | def renderGraph(self): 11 | print (f"Rendering: {self.graphImage}") 12 | 13 | -------------------------------------------------------------------------------- /src/Models/History.py: -------------------------------------------------------------------------------- 1 | class History: 2 | def __init__(self, userID): 3 | self.userID=userID 4 | self.calculations = [] 5 | 6 | def addEntry(self, calculation): 7 | self.calculations.append(calculation) 8 | 9 | def viewHistory(self): 10 | return self.calculations 11 | 12 | def clearHistory(self): 13 | self.calculations.clear() -------------------------------------------------------------------------------- /src/Models/Main.py: -------------------------------------------------------------------------------- 1 | from User import User 2 | from Calculator import Calculator 3 | from Calculations import Calculation 4 | 5 | # Step 1: Create a user and log them in 6 | user = User("u01", "Siphokazi", "sisi@example.com", "1234") 7 | user.login() 8 | 9 | # Step 2: Create a Calculator instance and validate input 10 | calc = Calculator("c01", "Basic") 11 | expression = "5 + 3 * 2" # Example expressiongit add . 12 | 13 | if calc.validateInput(expression): 14 | result = calc.calculateExpressions(expression) 15 | calc.displayResults(result) 16 | 17 | # Step 3: Create a Calculation object and perform the calculation 18 | # c = Calculation("calc01", expression) 19 | #c = Calculation() 20 | c = Calculation("calc01", expression, precision=4, rounding=True) # Added necessary arguments 21 | 22 | c.perform() # Perform the calculation 23 | c.SaveToHistory() # Save the result to the user's history 24 | 25 | # Step 4: View the history 26 | print([f"{calc.expression} = {calc.result}" for calc in user.history.viewHistory()]) 27 | -------------------------------------------------------------------------------- /src/Models/User.py: -------------------------------------------------------------------------------- 1 | # src/Models/User/user.py 2 | 3 | from src.Models.History import History 4 | from pydantic import BaseModel 5 | 6 | # Business Logic Class (NOT used as response model) 7 | class User: 8 | def __init__(self, userID: int, name: str, email: str, password: str): 9 | self.user_id = userID 10 | self.name = name 11 | self.email = email 12 | self.password = password 13 | self.history = History(userID) 14 | 15 | def register(self): 16 | print(f"{self.name} registered successfully.") 17 | 18 | def login(self): 19 | print(f"{self.name} logged in.") 20 | 21 | def logout(self): 22 | print(f"{self.name} logged out.") 23 | 24 | def add(self): 25 | print("booyakasha.") 26 | 27 | # ✅ Pydantic model used in response_model= 28 | class UserResponse(BaseModel): 29 | user_id: int 30 | name: str 31 | email: str 32 | 33 | class Config: 34 | from_attributes = True # ✅ Pydantic v2 replacement for orm_mode 35 | -------------------------------------------------------------------------------- /src/Models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__init__.py -------------------------------------------------------------------------------- /src/Models/__pycache__/Calculations.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/Calculations.cpython-312.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/Calculations.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/Calculations.cpython-313.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/Calculator.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/Calculator.cpython-312.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/Calculator.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/Calculator.cpython-313.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/History.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/History.cpython-312.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/History.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/History.cpython-313.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/User.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/User.cpython-312.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/User.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/User.cpython-313.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/Models/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Models/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/Repositories/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__init__.py -------------------------------------------------------------------------------- /src/Repositories/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/Repositories/__pycache__/repository_interface.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/repository_interface.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/__pycache__/repository_interface.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/repository_interface.cpython-313.pyc -------------------------------------------------------------------------------- /src/Repositories/__pycache__/user_repository.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/user_repository.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/__pycache__/user_repository.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/__pycache__/user_repository.cpython-313.pyc -------------------------------------------------------------------------------- /src/Repositories/inmemory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/inmemory/__init__.py -------------------------------------------------------------------------------- /src/Repositories/inmemory/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/inmemory/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/inmemory/__pycache__/inmemory_user_repo.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/inmemory/__pycache__/inmemory_user_repo.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/inmemory/inmemory_user_repo.py: -------------------------------------------------------------------------------- 1 | from Repositories.user_repository import UserRepository 2 | from src.Models.User import User 3 | from typing import Optional 4 | 5 | class InMemoryUserRepository(UserRepository): 6 | def __init__(self): 7 | self._storage = {} 8 | 9 | def save(self, user: User) -> None: 10 | self._storage[user.user_id] = user 11 | 12 | def find_by_id(self, user_id: str) -> Optional[User]: 13 | return self._storage.get(user_id) 14 | 15 | def find_all(self): 16 | return list(self._storage.values()) 17 | 18 | def delete(self, user_id: str) -> None: 19 | if user_id in self._storage: 20 | del self._storage[user_id] 21 | -------------------------------------------------------------------------------- /src/Repositories/json_repo/__pycache__/filesystem_user_repo.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/json_repo/__pycache__/filesystem_user_repo.cpython-312.pyc -------------------------------------------------------------------------------- /src/Repositories/json_repo/__pycache__/filesystem_user_repo.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/Repositories/json_repo/__pycache__/filesystem_user_repo.cpython-313.pyc -------------------------------------------------------------------------------- /src/Repositories/json_repo/filesystem_user_repo.py: -------------------------------------------------------------------------------- 1 | from src.Repositories.user_repository import UserRepository 2 | from src.Models.User import User 3 | from typing import Optional 4 | import json 5 | import os 6 | 7 | class FileSystemUserRepository(UserRepository): 8 | def __init__(self, file_path="users.json"): 9 | self.file_path = file_path 10 | if not os.path.exists(file_path): 11 | with open(file_path, "w") as f: 12 | json.dump({}, f) 13 | 14 | def save(self, user: User) -> None: 15 | data = self._read_data() 16 | data[user.user_id] = { 17 | "user_id": user.user_id, 18 | "name": user.name, 19 | "email": user.email, 20 | "password": user.password 21 | } 22 | self._write_data(data) 23 | 24 | def find_by_id(self, user_id: str) -> Optional[User]: 25 | data = self._read_data() 26 | if user_id in data: 27 | user_data = data[user_id] 28 | return User(**user_data) 29 | return None 30 | 31 | def find_all(self): 32 | data = self._read_data() 33 | return [User(**info) for info in data.values()] 34 | 35 | def delete(self, user_id: str) -> None: 36 | data = self._read_data() 37 | if user_id in data: 38 | del data[user_id] 39 | self._write_data(data) 40 | 41 | def _read_data(self): 42 | with open(self.file_path, "r") as f: 43 | return json.load(f) 44 | 45 | def _write_data(self, data): 46 | with open(self.file_path, "w") as f: 47 | json.dump(data, f, indent=2) 48 | -------------------------------------------------------------------------------- /src/Repositories/repository_interface.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import TypeVar, Generic, Optional, List 3 | 4 | T = TypeVar('T') # Entity type 5 | ID = TypeVar('ID') # ID type 6 | 7 | class Repository(ABC, Generic[T, ID]): 8 | @abstractmethod 9 | def save(self, entity: T) -> None: 10 | pass 11 | 12 | @abstractmethod 13 | def find_by_id(self, id: ID) -> Optional[T]: 14 | pass 15 | 16 | @abstractmethod 17 | def find_all(self) -> List[T]: 18 | pass 19 | 20 | @abstractmethod 21 | def delete(self, id: ID) -> None: 22 | pass 23 | -------------------------------------------------------------------------------- /src/Repositories/user_repository.py: -------------------------------------------------------------------------------- 1 | from src.Repositories.repository_interface import Repository 2 | from src.Models.User import User 3 | 4 | class UserRepository(Repository[User, str]): 5 | pass 6 | -------------------------------------------------------------------------------- /src/RepositoryFactory/Readme(Repository).md: -------------------------------------------------------------------------------- 1 | ## Dependency Management Approach 2 | 3 | For this project, a **Factory Pattern** approach was chosen instead of full **Dependency Injection (DI)**. 4 | 5 | ### Reason for Choosing Factory Pattern: 6 | 7 | - The system is relatively small and focused. 8 | - Factory allows **dynamic object creation** (e.g., choosing between `InMemoryUserRepository` and `FileSystemUserRepository`) without needing a large DI framework. 9 | - Factory keeps the design **simple and understandable** while still supporting future scalability. 10 | - DI frameworks (e.g., in Java/Spring) are more suitable for **large, complex systems** with hundreds of dependencies. 11 | 12 | --- 13 | 14 | ### Summary: 15 | 16 | - A `/factories` directory was created. 17 | - `RepositoryFactory` dynamically instantiates the correct repository type (`MEMORY` or `FILE`). 18 | - This keeps the code **modular**, **scalable**, and **easy to extend**. 19 | 20 | If the system grows bigger, adding a proper **Dependency Injection Container** would be the next step. 21 | -------------------------------------------------------------------------------- /src/RepositoryFactory/__pycache__/repository_factory.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/RepositoryFactory/__pycache__/repository_factory.cpython-312.pyc -------------------------------------------------------------------------------- /src/RepositoryFactory/__pycache__/repository_factory.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/RepositoryFactory/__pycache__/repository_factory.cpython-313.pyc -------------------------------------------------------------------------------- /src/RepositoryFactory/repository_factory.py: -------------------------------------------------------------------------------- 1 | from src.Repositories.json_repo.filesystem_user_repo import FileSystemUserRepository 2 | 3 | class RepositoryFactory: 4 | @staticmethod 5 | def get_user_repository(storage_type="MEMORY"): 6 | if storage_type == "MEMORY": 7 | from Repositories.inmemory.inmemory_user_repo import InMemoryUserRepository 8 | return InMemoryUserRepository() 9 | elif storage_type == "FILE": 10 | return FileSystemUserRepository() 11 | else: 12 | raise ValueError("Invalid storage type") 13 | -------------------------------------------------------------------------------- /src/UpdatedClassDiagram.md: -------------------------------------------------------------------------------- 1 | ## Updated Class Diagram 2 | ```mermaid 3 | classDiagram 4 | 5 | %% ====== Core Models ====== 6 | class User { 7 | -userID: String 8 | -name: String 9 | -password: String 10 | +register(): void 11 | +login(): void 12 | +logout(): void 13 | } 14 | 15 | class Calculator { 16 | -calculatorID: String 17 | -type: String 18 | +calculateExpression(expression: String): String 19 | +validateInput(expression: String): Boolean 20 | +displayResults(result: String): void 21 | } 22 | 23 | class Calculation { 24 | -calculationID: String 25 | -expression: String 26 | -result: String 27 | -timestamp: Date 28 | +perform(): String 29 | +saveToHistory(): void 30 | } 31 | 32 | class Graph { 33 | -graphId: String 34 | -functionExpression: String 35 | -graphImage: String 36 | +generateGraph(): void 37 | +renderGraph(): void 38 | } 39 | 40 | class History { 41 | -historyID: String 42 | -userID: String 43 | -listOfCalculations: List~Calculation~ 44 | +addEntry(calc: Calculation): void 45 | +viewHistory(): List~Calculation~ 46 | +clearHistory(): void 47 | } 48 | 49 | class ErrorHandler { 50 | -errorCode: String 51 | -errorMessage: String 52 | +catchInputError(): void 53 | +logError(): void 54 | } 55 | 56 | %% ====== Repository Layer ====== 57 | class Repository~T, ID~ { 58 | <> 59 | +save(entity: T): void 60 | +findById(id: ID): T 61 | +findAll(): List~T~ 62 | +delete(id: ID): void 63 | } 64 | 65 | class UserRepository { 66 | <> 67 | } 68 | 69 | class InMemoryUserRepository { 70 | } 71 | 72 | class FileSystemUserRepository { 73 | } 74 | 75 | %% ====== Relationships ====== 76 | User "1" -- "1" History : owns 77 | User "1" -- "0..*" Calculation : performs 78 | Calculator "1" -- "0..*" Calculation : executes 79 | Calculation <|-- Graph 80 | Calculation "1" -- "1" ErrorHandler : handledBy 81 | 82 | %% ====== Repository Relationships ====== 83 | Repository~User, String~ <|-- UserRepository 84 | UserRepository <|-- InMemoryUserRepository 85 | UserRepository <|-- FileSystemUserRepository 86 | User "1" --> "1" UserRepository : persists via 87 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__init__.py -------------------------------------------------------------------------------- /src/__pycache__/Calculations.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/Calculations.cpython-313.pyc -------------------------------------------------------------------------------- /src/__pycache__/Calculator.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/Calculator.cpython-313.pyc -------------------------------------------------------------------------------- /src/__pycache__/History.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/History.cpython-313.pyc -------------------------------------------------------------------------------- /src/__pycache__/Main.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/Main.cpython-313.pyc -------------------------------------------------------------------------------- /src/__pycache__/User.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/User.cpython-313.pyc -------------------------------------------------------------------------------- /src/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/api/__pycache__/main_api.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/api/__pycache__/main_api.cpython-312.pyc -------------------------------------------------------------------------------- /src/api/__pycache__/user_routes.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/api/__pycache__/user_routes.cpython-312.pyc -------------------------------------------------------------------------------- /src/api/main_api.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI 2 | from src.api.user_routes import router as user_router 3 | 4 | 5 | app = FastAPI(title="Advanced Calculator API") 6 | 7 | app.include_router(user_router) 8 | -------------------------------------------------------------------------------- /src/api/user_routes.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter, HTTPException 2 | from src.Models.User import UserResponse 3 | from src.services.user_service import UserService 4 | from src.RepositoryFactory.repository_factory import RepositoryFactory 5 | 6 | router = APIRouter(prefix="/api/users", tags=["Users"]) 7 | user_service = UserService(RepositoryFactory.get_user_repository("FILE")) 8 | 9 | @router.post("/", response_model=UserResponse) 10 | def create_user(user: UserResponse): 11 | try: 12 | return user_service.register_user(user.user_id, user.name, user.email, user.password) 13 | except ValueError as e: 14 | raise HTTPException(status_code=400, detail=str(e)) 15 | 16 | @router.get("/{user_id}", response_model=UserResponse) 17 | def get_user(user_id: str): 18 | try: 19 | return user_service.get_user(user_id) 20 | except ValueError as e: 21 | raise HTTPException(status_code=404, detail=str(e)) 22 | -------------------------------------------------------------------------------- /src/creational_patterns/Builders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Builders/__init__.py -------------------------------------------------------------------------------- /src/creational_patterns/Builders/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Builders/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Builders/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Builders/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Builders/__pycache__/calculation_builder.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Builders/__pycache__/calculation_builder.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Builders/__pycache__/calculation_builder.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Builders/__pycache__/calculation_builder.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Builders/calculation_builder.py: -------------------------------------------------------------------------------- 1 | #--Builder--# 2 | 3 | from src.Models.Calculations import Calculation 4 | 5 | class CalculationBuilder: 6 | def __init__(self): 7 | self.calculation_id = None 8 | self.expression = "" 9 | self.precision = 2 10 | self.rounding = True 11 | 12 | def set_id(self, calc_id): 13 | self.calculation_id = calc_id 14 | return self 15 | 16 | def set_expression(self, expr): 17 | self.expression = expr 18 | return self 19 | 20 | def set_precision(self, precision): 21 | self.precision = precision 22 | return self 23 | 24 | def disable_rounding(self): 25 | self.rounding = False 26 | return self 27 | 28 | def build(self): 29 | # Return an instance of the Calculation class instead of CustomCalculation 30 | return Calculation( 31 | self.calculation_id, 32 | self.expression, 33 | self.precision, 34 | self.rounding 35 | ) 36 | -------------------------------------------------------------------------------- /src/creational_patterns/CalculatorFactory/CalculatorFactory.py: -------------------------------------------------------------------------------- 1 | #--Simple Factory--# 2 | #--Factory Method--# 3 | 4 | from Models.Calculator import Calculator 5 | 6 | 7 | class CalculatorFactory: 8 | @staticmethod 9 | def get_calculator(calculator_type): 10 | if calculator_type == "Basic": 11 | return Calculator("Basic") 12 | elif calculator_type == "Scientific": 13 | return Calculator("Scientific") 14 | elif calculator_type == "Graphing": 15 | return Calculator("Graphing") 16 | else: 17 | raise ValueError("Invalid calculator type") 18 | -------------------------------------------------------------------------------- /src/creational_patterns/CalculatorFactory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/CalculatorFactory/__init__.py -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__init__.py: -------------------------------------------------------------------------------- 1 | # This file can be empty or include metadata if needed 2 | -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/calculator_factory.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/calculator_factory.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/calculator_factory.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/calculator_factory.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/results_formatter.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/results_formatter.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/results_formatter.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/results_formatter.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/ui_factory.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/ui_factory.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/__pycache__/ui_factory.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Factories/__pycache__/ui_factory.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Factories/calculator_factory.py: -------------------------------------------------------------------------------- 1 | from src.Models.Calculator import Calculator 2 | 3 | class CalculatorFactory: 4 | @staticmethod 5 | def get_calculator(calculator_type): 6 | calculatorID = "Calc001" # You can change this to a dynamic ID generation logic 7 | if calculator_type == "Basic": 8 | return Calculator(calculatorID, "Basic") 9 | elif calculator_type == "Scientific": 10 | return Calculator(calculatorID, "Scientific") 11 | elif calculator_type == "Graphing": 12 | return Calculator(calculatorID, "Graphing") 13 | else: 14 | raise ValueError("Invalid calculator type") 15 | -------------------------------------------------------------------------------- /src/creational_patterns/Factories/results_formatter.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | class ResultFormatter(ABC): 4 | @abstractmethod 5 | def format(self, result): 6 | pass 7 | 8 | class PlainTextFormatter(ResultFormatter): 9 | def format(self, result): 10 | return str(result) 11 | 12 | class JsonFormatter(ResultFormatter): 13 | def format(self, result): 14 | return {"result": result} 15 | -------------------------------------------------------------------------------- /src/creational_patterns/Factories/ui_factory.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | # Product Interfaces 4 | class Button(ABC): 5 | @abstractmethod 6 | def draw(self): 7 | pass 8 | 9 | class Label(ABC): 10 | @abstractmethod 11 | def render(self): 12 | pass 13 | 14 | # Concrete Products 15 | class DarkButton(Button): 16 | def draw(self): 17 | return "Drawing dark button" 18 | 19 | class LightButton(Button): 20 | def draw(self): 21 | return "Drawing light button" 22 | 23 | class DarkLabel(Label): 24 | def render(self): 25 | return "Rendering dark label" 26 | 27 | class LightLabel(Label): 28 | def render(self): 29 | return "Rendering light label" 30 | 31 | # Abstract Factory 32 | class UIFactory(ABC): 33 | @abstractmethod 34 | def create_button(self): pass 35 | 36 | @abstractmethod 37 | def create_label(self): pass 38 | 39 | # Concrete Factories 40 | class DarkThemeFactory(UIFactory): 41 | def create_button(self): 42 | return DarkButton() 43 | def create_label(self): 44 | return DarkLabel() 45 | 46 | class LightThemeFactory(UIFactory): 47 | def create_button(self): 48 | return LightButton() 49 | def create_label(self): 50 | return LightLabel() 51 | -------------------------------------------------------------------------------- /src/creational_patterns/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | # Add current script directory to the sys.path for importing 5 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) 6 | 7 | if __name__ == "__main__": 8 | # === Models === (only import if running this script directly, not when Models is its own main) 9 | try: 10 | from Models.User import User 11 | from Models.Calculations import Calculation 12 | except ImportError: 13 | print("Models import skipped. Running without Models.") 14 | 15 | # === Factories === 16 | from creational_patterns.Factories.calculator_factory import CalculatorFactory 17 | from creational_patterns.Factories.results_formatter import PlainTextFormatter 18 | from creational_patterns.Factories.ui_factory import DarkThemeFactory 19 | 20 | # === Builders === 21 | from creational_patterns.Builders.calculation_builder import CalculationBuilder 22 | 23 | # === Prototype === 24 | from creational_patterns.Prototype.calculations_prototype import CalculationPrototype 25 | 26 | # === Singleton === 27 | from creational_patterns.Singletons.logger import Logger 28 | 29 | print("🚀 Starting Advanced Calculator System...\n") 30 | 31 | # --- Logger (Singleton) --- 32 | logger = Logger() 33 | logger.log("Application launched") 34 | 35 | # --- Simple Factory --- 36 | calc = CalculatorFactory.get_calculator("Scientific") 37 | print("Factory Calculator Result:", calc.calculateExpressions("2 + 2 * 5")) 38 | 39 | 40 | # --- Factory Method --- 41 | formatter = PlainTextFormatter() 42 | print("Formatted Output:", formatter.format(20)) 43 | 44 | # --- Abstract Factory --- 45 | theme = DarkThemeFactory() 46 | button = theme.create_button() 47 | label = theme.create_label() 48 | print(button.draw()) 49 | print(label.render()) 50 | 51 | # --- Builder Pattern --- 52 | builder = CalculationBuilder() 53 | custom_calc = builder.set_id("C1001").set_expression("10 / 3").set_precision(4).build() 54 | print("Builder Result:", custom_calc.perform()) 55 | 56 | # --- Prototype --- 57 | original = CalculationPrototype("C001", "5 + 3", 8) 58 | copy = original.clone() 59 | copy.calc_id = "C002" 60 | print("Prototype Original:", original) 61 | print("Prototype Clone:", copy) 62 | 63 | # --- Logger logs --- 64 | print("\n📜 Logs:") 65 | for entry in logger.get_logs(): 66 | print("→", entry) 67 | -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Prototype/__init__.py -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Prototype/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Prototype/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/__pycache__/calculations_prototype.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Prototype/__pycache__/calculations_prototype.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/__pycache__/calculations_prototype.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Prototype/__pycache__/calculations_prototype.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Prototype/calculations_prototype.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | class CalculationPrototype: 4 | def __init__(self, calc_id, expression, result): 5 | self.calc_id = calc_id 6 | self.expression = expression 7 | self.result = result 8 | 9 | def clone(self): 10 | return copy.deepcopy(self) 11 | 12 | def __str__(self): 13 | return f"[{self.calc_id}] {self.expression} = {self.result}" 14 | -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Singletons/__init__.py -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Singletons/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Singletons/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/__pycache__/logger.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Singletons/__pycache__/logger.cpython-312.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/__pycache__/logger.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/creational_patterns/Singletons/__pycache__/logger.cpython-313.pyc -------------------------------------------------------------------------------- /src/creational_patterns/Singletons/logger.py: -------------------------------------------------------------------------------- 1 | class Logger: 2 | _instance = None 3 | 4 | def __new__(cls): 5 | if cls._instance is None: 6 | cls._instance = super(Logger, cls).__new__(cls) 7 | cls._instance.logs = [] 8 | return cls._instance 9 | 10 | def log(self, message): 11 | self.logs.append(message) 12 | print(f"[LOG] {message}") 13 | 14 | def get_logs(self): 15 | return self.logs 16 | -------------------------------------------------------------------------------- /src/readme.md: -------------------------------------------------------------------------------- 1 | ## Implemented Patterns & Justifications 2 | ### 1. Simple Factory Pattern 3 | 4 | Used For: Creating different types of calculators (Basic, Scientific, Graphing). 5 | 6 | Why: Centralizes object creation based on type. Simplifies how external components request calculators. 7 | 8 | Class: CalculatorFactory 9 | 10 | Location: Factories/calculator_factory.py 11 | 12 | ### 2. Factory Method Pattern 13 | 14 | Used For: Formatting results in different styles. 15 | 16 | Why: Allows result formatting to be extended (e.g., JSON, plain text) without modifying the formatter logic. 17 | 18 | Classes: ResultFormatter (abstract), PlainTextFormatter, JsonFormatter 19 | 20 | Location: Factories/results_formatter.py 21 | 22 | ### 3. Abstract Factory Pattern 23 | 24 | Used For: Generating UI components (buttons and labels) for light and dark themes. 25 | 26 | Why: Provides an interface to create families of related objects without specifying their concrete classes. 27 | 28 | Classes: UIFactory, DarkThemeFactory, LightThemeFactory, DarkButton, LightButton, etc. 29 | 30 | Location: Factories/ui_factory.py 31 | 32 | ### 4. Builder Pattern 33 | 34 | Used For: Building complex Calculation objects with optional attributes like rounding and precision. 35 | 36 | Why: Offers a step-by-step approach to constructing objects with multiple configuration options. 37 | 38 | Class: CalculationBuilder 39 | 40 | Location: Builders/calculation_builder.py 41 | 42 | ### 5. Prototype Pattern 43 | 44 | Used For: Cloning calculation objects to avoid re-initializing them from scratch. 45 | 46 | Why: Enables efficient duplication of objects with the same state and structure. 47 | 48 | Class: CalculationPrototype 49 | 50 | Location: Prototype/calculations_prototype.py 51 | 52 | ### 6. Singleton Pattern 53 | 54 | Used For: Central logging service. 55 | 56 | Why: Ensures a single global logger instance throughout the application. 57 | 58 | Class: Logger 59 | 60 | Location: Singletons/logger.py 61 | --- 62 | ## Language Choice: Python 63 | 64 | Why Python? 65 | Python was selected due to its simplicity, readability, and strong community support. It allowed for quick development of both core 66 | calculator logic and unit testing using built-in and third-party libraries. 67 | 68 | ### Key benefits: 69 | 70 | Ease of prototyping – Ideal for testing out design ideas quickly. 71 | 72 | Rich standard library – Modules like math, unittest, and external ones like pytest made testing and implementation seamless. 73 | 74 | Cross-platform compatibility – Works on Windows, Mac, and Linux, making the app widely accessible. 75 | 76 | Clear syntax – Encourages clean, readable, and maintainable code. 77 | 78 | ## Key Design Decisions 79 | 80 | ### Modular Architecture 81 | 82 | Code is separated into logical modules: 83 | 84 | calc_logic.py: Core logic. 85 | 86 | formatter.py: Responsible for formatting outputs. 87 | 88 | logger.py: Handles system logging. 89 | 90 | ui_factory.py & calculator_factory.py: Implements Factory pattern for UI and calculator type creation. 91 | 92 | Why? Improves maintainability, scalability, and testing. 93 | 94 | ### Design Patterns 95 | 96 | Singleton Pattern used in logger.py: 97 | 98 | Ensures only one instance of the logger is used throughout the application. 99 | 100 | Prevents duplicate or inconsistent logs. 101 | 102 | Factory Pattern used in calculator_factory.py: 103 | 104 | Decouples object creation from logic. 105 | 106 | Makes it easier to add new calculator types without modifying existing code. 107 | 108 | ### Test-Driven Development (TDD) 109 | 110 | Tests were written using pytest before or alongside implementation. 111 | 112 | Coverage tools ensured code was well-tested. 113 | 114 | 🧪 Ensured reliability and made debugging easier. 115 | 116 | ### User Stories → Code 117 | 118 | The project follows user-centric requirements, for example: 119 | 120 | Graphing functions (matplotlib) 121 | 122 | Saving frequently used calculations 123 | 124 | Exporting history 125 | 126 | Performing unit conversions 127 | 128 | Each feature maps directly to a user story on the backlog. 129 | 130 | ### Security Consideration 131 | 132 | In user data features (planned or implemented), encryption is considered for secure handling of sensitive data. 133 | ## Links to the codes 134 | ### `src/` Directory Overview 135 | 136 | ## 📁 Key Project Folders and Files 137 | 138 | - [**src/Models/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/Models) 139 | Contains data structures and logic models used in calculator operations. 140 | 141 | - [**src/creational_patterns/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/creational_patterns) 142 | Implements common creational design patterns like Singleton, Factory, and Builder. 143 | 144 | - [**src/tests/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/tests) 145 | Unit tests for validating each component of the application. 146 | 147 | - [**src/test_results.txt**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/blob/main/src/test_results.txt) 148 | Output log of test results generated by pytest. 149 | 150 | ## Assignment 11 151 | 152 | ### Links to the code: 153 | [**src/Repositories/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/Repositories) 154 | Contains all repository-related classes and interfaces. 155 | Includes: **Repository** (generic interface), **UserRepository**, **InMemoryUserRepository**, and **JSON_Repo** for saving and retrieving user data. 156 | 157 | [**src/RepositoryFactory/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/RepositoryFactory) 158 | Contains the **RepositoryFactory** class. 159 | This factory dynamically creates the correct repository instance (either memory-based or file-based) at runtime based on the selected storage type. 160 | 161 | [**src/UpdatedClassDiagram.md/**](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/UpdatedClassDiagram.md) 162 | Contains the updated UML Class Diagram (using Mermaid) showing both the original system models and the newly added repository layer with interfaces and implementations. 163 | 164 | # ✅ Assignment 12 Summary: User Registration Feature 165 | 166 | ## 📌 Overview 167 | This assignment implements a **User Registration Feature** using layered architecture. The components include: 168 | 169 | - Service Layer for business logic 170 | - REST API endpoints using FastAPI 171 | - FastAPI application with Swagger documentation 172 | - Unit tests for service logic 173 | 174 | --- 175 | 176 | ## 📁 Project Structure & Locations 177 | 178 | ### 1. 🧠 User Registration Service Layer 179 | - **Purpose**: Contains core business logic for registering users. 180 | - **File**: [src/services/user_service.py](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/services/user_service.py) 181 | - **Functionality**: 182 | - register_user(user_data: dict): Validates and stores a new user 183 | - **Dependencies**: Relies on `UserRepository` for user data operations. 184 | 185 | --- 186 | 187 | ### 2. 🌐 REST API Endpoints 188 | - **Purpose**: Exposes HTTP endpoints for user registration via FastAPI. 189 | - **File**: [`src/api/user_routes.py`](https://github.com/SiphokaziCele/Assignment3AdvancedCalculator/tree/main/src/api/user_routes.py) 190 | - **Base Route**: `/api/users` 191 | 192 | #### Endpoints 193 | | Method | Route | Description | 194 | |--------|-------|-------------| 195 | | POST | `/api/users/register` | Register a new user | 196 | 197 | **Example request (JSON):** 198 | ```json 199 | { 200 | "username": "testuser", 201 | "email": "test@example.com", 202 | "password": "password123" 203 | } 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'Models'))) 5 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'Calculator factory'))) 6 | 7 | from Models.Calculator import Calculator 8 | from CalculatorFactory import CalculatorFactory 9 | 10 | if __name__ == "__main__": 11 | calc = CalculatorFactory.get_calculator("Basic") 12 | result = calc.calculate("5 + 5 * 2") 13 | print(f"Result: {result}") 14 | -------------------------------------------------------------------------------- /src/services/__pycache__/user_service.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/services/__pycache__/user_service.cpython-312.pyc -------------------------------------------------------------------------------- /src/services/user_service.py: -------------------------------------------------------------------------------- 1 | from src.Repositories.user_repository import UserRepository 2 | from src.Models.User import User 3 | 4 | class UserService: 5 | def __init__(self, repo: UserRepository): 6 | self.repo = repo 7 | 8 | def register_user(self, user_id: str, name: str, email: str, password: str) -> User: 9 | if self.repo.find_by_id(user_id): 10 | raise ValueError("User already exists") 11 | user = User(user_id, name, email, password) 12 | self.repo.save(user) 13 | return user 14 | 15 | def get_user(self, user_id: str) -> User: 16 | user = self.repo.find_by_id(user_id) 17 | if not user: 18 | raise ValueError("User not found") 19 | return user 20 | -------------------------------------------------------------------------------- /src/test_results.txt: -------------------------------------------------------------------------------- 1 | ============================= test session starts ============================= 2 | platform win32 -- Python 3.12.5, pytest-8.3.5, pluggy-1.5.0 3 | rootdir: C:\Users\Halala Cele\Desktop\Assignment3AdvancedCalculator 4 | plugins: cov-6.1.1 5 | collected 13 items 6 | 7 | src\tests\test_calc_logic.py ..... [ 38%] 8 | src\tests\test_calculation_builder.py . [ 46%] 9 | src\tests\test_calculation_prototype.py . [ 53%] 10 | src\tests\test_calculator_factory.py .. [ 69%] 11 | src\tests\test_formatter.py . [ 76%] 12 | src\tests\test_logger.py .. [ 92%] 13 | src\tests\test_ui_factory.py . [100%] 14 | 15 | ============================= 13 passed in 0.39s ============================== 16 | -------------------------------------------------------------------------------- /src/tests/Services/test_user_service.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from services.user_service import UserService 3 | from Repositories.inmemory.inmemory_user_repo import InMemoryUserRepository 4 | 5 | class TestUserService(unittest.TestCase): 6 | def setUp(self): 7 | self.repo = InMemoryUserRepository() 8 | self.service = UserService(self.repo) 9 | 10 | def test_register_and_get_user(self): 11 | user = self.service.register_user("U1", "Test", "test@example.com", "pass") 12 | self.assertEqual(user.name, "Test") 13 | retrieved = self.service.get_user("U1") 14 | self.assertEqual(retrieved.email, "test@example.com") 15 | 16 | def test_duplicate_user(self): 17 | self.service.register_user("U1", "Test", "test@example.com", "pass") 18 | with self.assertRaises(ValueError): 19 | self.service.register_user("U1", "Test", "test@example.com", "pass") 20 | -------------------------------------------------------------------------------- /src/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__init__.py -------------------------------------------------------------------------------- /src/tests/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calc_logic.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calc_logic.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calc_logic.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calc_logic.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculation_builder.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculation_builder.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculation_builder.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculation_builder.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculation_prototype.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculation_prototype.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculation_prototype.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculation_prototype.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculator_factory.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculator_factory.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_calculator_factory.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_calculator_factory.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_dummy.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_dummy.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_formatter.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_formatter.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_formatter.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_formatter.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_logger.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_logger.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_logger.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_logger.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_ui_factory.cpython-312-pytest-8.3.5.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_ui_factory.cpython-312-pytest-8.3.5.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_ui_factory.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_ui_factory.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/__pycache__/test_user_repo.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/__pycache__/test_user_repo.cpython-312.pyc -------------------------------------------------------------------------------- /src/tests/peytest.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiphokaziCele/Assignment3AdvancedCalculator/01a7ec9c796751b09bbc46035ad5df83d2139754/src/tests/peytest.ini -------------------------------------------------------------------------------- /src/tests/test_calc_logic.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from src.Models.Calculator import Calculator 3 | 4 | class TestCalculatorLogic(unittest.TestCase): 5 | 6 | def test_addition(self): 7 | calc = Calculator("c01","Basic") 8 | result = calc.calculateExpressions("2 + 3") 9 | self.assertEqual(result, 5) 10 | 11 | def test_multiplication_precedence(self): 12 | calc = Calculator("c01", "Basic") 13 | result = calc.calculateExpressions("2 + 3 * 4") 14 | self.assertEqual(result, 14) # 3*4=12 + 2 = 14 15 | 16 | def test_parentheses(self): 17 | calc = Calculator("c01", "Basic") 18 | result = calc.calculateExpressions("(2 + 3) * 4") 19 | self.assertEqual(result, 20) 20 | 21 | def test_invalid_expression(self): 22 | calc = Calculator("c01","Basic") 23 | result = calc.calculateExpressions("5 + ") 24 | self.assertTrue("Error" in str(result)) 25 | 26 | def test_division_by_zero(self): 27 | calc = Calculator("c01","Basic") 28 | result = calc.calculateExpressions("10 / 0") 29 | self.assertTrue("Error" in str(result)) 30 | 31 | if __name__ == '__main__': 32 | unittest.main() 33 | -------------------------------------------------------------------------------- /src/tests/test_calculation_builder.py: -------------------------------------------------------------------------------- 1 | from src.creational_patterns.Builders.calculation_builder import CalculationBuilder 2 | from src.Models.Calculations import Calculation 3 | import unittest 4 | 5 | class TestCalculationBuilder(unittest.TestCase): 6 | def test_build_custom_calc(self): 7 | builder = CalculationBuilder() 8 | calc = builder.set_id("C001").set_expression("10 / 4").set_precision(2).build() 9 | 10 | # Perform the calculation 11 | calc.perform() # Perform calculation, this will update the `result` attribute 12 | 13 | # Access the result from the `Calculation` object 14 | result = calc.result # This accesses the `result` attribute which should now contain the calculated value 15 | 16 | # Now test the result 17 | self.assertAlmostEqual(result, 2.5, places=2) # Check if the result is approximately 2.5 18 | -------------------------------------------------------------------------------- /src/tests/test_calculation_prototype.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from src.creational_patterns.Prototype.calculations_prototype import CalculationPrototype 3 | 4 | class TestCalculationPrototype(unittest.TestCase): 5 | def test_clone(self): 6 | original = CalculationPrototype("C001", "3 + 3", 6) 7 | clone = original.clone() 8 | self.assertEqual(clone.result, 6) 9 | self.assertNotEqual(original.calc_id, "C002") 10 | -------------------------------------------------------------------------------- /src/tests/test_calculator_factory.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | from src.creational_patterns.Factories.calculator_factory import CalculatorFactory 4 | 5 | class TestCalculatorFactory(unittest.TestCase): 6 | def test_scientific_calculator(self): 7 | calc = CalculatorFactory.get_calculator("Scientific") 8 | self.assertEqual(calc.calculateExpressions("2 + 3 * 2"), 8) 9 | 10 | def test_invalid_type_raises(self): 11 | with self.assertRaises(ValueError): 12 | CalculatorFactory.get_calculator("Alien") 13 | -------------------------------------------------------------------------------- /src/tests/test_formatter.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | from src.creational_patterns.Factories.results_formatter import PlainTextFormatter 4 | 5 | class TestFormatter(unittest.TestCase): 6 | def test_format_plain_text(self): 7 | formatter = PlainTextFormatter() 8 | self.assertEqual(formatter.format(10), "10") 9 | -------------------------------------------------------------------------------- /src/tests/test_logger.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from src.creational_patterns.Singletons.logger import Logger 3 | 4 | class TestLogger(unittest.TestCase): 5 | def test_singleton_behavior(self): 6 | logger1 = Logger() 7 | logger2 = Logger() 8 | self.assertIs(logger1, logger2) 9 | 10 | def test_log_capture(self): 11 | logger = Logger() 12 | logger.log("Test entry") 13 | self.assertIn("Test entry", logger.get_logs()) 14 | -------------------------------------------------------------------------------- /src/tests/test_ui_factory.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | from src.creational_patterns.Factories.ui_factory import DarkThemeFactory 4 | 5 | 6 | class TestUIFactory(unittest.TestCase): 7 | def test_dark_theme_elements(self): 8 | factory = DarkThemeFactory() 9 | button = factory.create_button() 10 | label = factory.create_label() 11 | self.assertIn("dark", button.draw().lower()) 12 | self.assertIn("dark", label.render().lower()) 13 | -------------------------------------------------------------------------------- /src/tests/test_user_repo.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from src.Repositories.inmemory.inmemory_user_repo import InMemoryUserRepository 3 | from src.Models.User import User 4 | 5 | class TestInMemoryUserRepository(unittest.TestCase): 6 | def test_crud_operations(self): 7 | repo = InMemoryUserRepository() 8 | user = User("U001", "Siphokazi", "siphokazi@gmail.com", "1234") 9 | 10 | repo.save(user) 11 | self.assertEqual(repo.find_by_id("U001").name, "Siphokazi") 12 | 13 | all_users = repo.find_all() 14 | self.assertEqual(len(all_users), 1) 15 | 16 | repo.delete("U001") 17 | self.assertIsNone(repo.find_by_id("U001")) 18 | -------------------------------------------------------------------------------- /users.json: -------------------------------------------------------------------------------- 1 | {} --------------------------------------------------------------------------------