This midterm assignment involves creating a Python-based calculator application. The project emphasizes software engineering best practices, including writing maintainable code, implementing appropriate design patterns, incorporating comprehensive logging systems, utilizing environment variables for dynamic configuration, leveraging Pandas for data operations, and developing an interactive command-line interface (REPL) for user interaction.
- Python
- pip
- Clone the repository:
git clone https://github.com/srikargoud2002/Mid_Term
- Navigate to the project directory:
cd Mid_Term
- Install the required dependencies:
pip install -r requirements.txt
To start the calculator, run the following command
python main.py
This will launch the REPL interface, where you can perform arithmetic operations, manage calculation history, and access additional functionalities through plugins.
menu: Lists all available plugins.add <operand1> <operand2>: Performs addition of two numbers.subtract <operand1> <operand2>: Performs subtraction of two numbers.multiply <operand1> <operand2>: Performs multiplication of two numbers.divide <operand1> <operand2>: Performs division of two numbers.history_show: Displays the calculation history.history_clear: Clears the calculation history.history_save: Saves the history into a csv file with date and time.history_load: It is for loading the history from the available csv files.last_op: Shows the last operation performedexit: Exits the calculator application.
The calculator supports dynamic loading of plugins. Even the menu is fetched by loading all the plugins. If there is any new plugin added it will automatically load into the menu.
- Command-Line Interface (REPL): An interactive environment for performing arithmetic operations and managing calculation history.
- Plugin System: A system to extend functionalities through dynamically loaded plugins.
- Calculation History Management with Pandas: Leverages Pandas for robust management of calculation history.
- Comprehensive Logging: Implements detailed logging for operations, errors, and informational messages.
- Design Patterns:
- Facade Pattern : It is implemented in the history management.
- Command Pattern : It is implemented in the commands management.
- Factory Method : It is implemented in the calculation.py .
The design patterns used in this project promote modularity, extensibility, and maintainability. For more details on their implementation and impact, please refer to the respective sections in the source code.
The calculator application uses a comprehensive logging system to record detailed application operations, data manipulations, errors, and informational messages. The logging system supports different log levels (INFO, WARNING, ERROR) setting via environment variables.
Environment variables are used to set logging levels dynamically, output path of the logs, history saving path and the Environment.
LOG_LEVEL=DEBUG # INFO, WARNING, ERROR, CRITICAL
LOG_OUTPUT=./logs/app.log
HISTORY_PATH=./calculator_history
ENVIRONMENT= DEVELOPMENT
Run the following command to execute tests and ensure the application behaves as expected:
pytestRun this to get coverage
pytest --pylint --covLBYL(Look Before You Leap) This approach is used to validate conditions before attempting operations.
Code example
if command_name in self.command_handler.commands:
command = self.command_handler.commands[command_name]
if callable(command.execute):
command.execute(*args) if args else command.execute()
else:
print("Command is not executable")
else:
print(f"No such command: {command_name}")
Easier to Ask for Forgiveness than Permission)
This approach attempts execution directly and handles any resulting exceptions.
Code Example:
def _process_plugin_module(self, plugins_package: str, plugin_name: str):
try:
plugin_module = importlib.import_module(f'{plugins_package}.{plugin_name}')
self._register_commands_from_module(plugin_module, plugin_name)
except Exception as error:
self.logger.error("Error loading plugin %s: %s", plugin_name, str(error), exc_info=True)