0% found this document useful (0 votes)
5 views

CalculatorApplicationWithUnittesting-2 (2)

The document is a project report for a Calculator Application developed by Bitra Bhavani, focusing on unit testing to ensure accuracy and reliability of mathematical operations. It outlines the project's objectives, technologies used (Python, Tkinter, unittest), and the structured workflow for testing the application. The report emphasizes the importance of automated testing in software development, particularly for applications requiring high precision and robust error handling.

Uploaded by

7bhi7bhi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

CalculatorApplicationWithUnittesting-2 (2)

The document is a project report for a Calculator Application developed by Bitra Bhavani, focusing on unit testing to ensure accuracy and reliability of mathematical operations. It outlines the project's objectives, technologies used (Python, Tkinter, unittest), and the structured workflow for testing the application. The report emphasizes the importance of automated testing in software development, particularly for applications requiring high precision and robust error handling.

Uploaded by

7bhi7bhi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

CALCULATOR APPLICATION WITH UNIT

TESTING

A project report submitted in partial fulfillment of the


requirements for the award of credits to

Python a Skill Enhancement Course of


Bachelor of Technology
In
DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING –
ARTIFICIAL INTELLIGENCE & MACHINE LEARNING (CSM)

By

Bitra Bhavani

23BQ1A4220

VASIREDDY VENKATADRI INSTITUTE OF TECHNOLOGY


(Approved by AICTE and permanently affiliated to

JNTUK)Accredited by NBA and NAAC with 'A' Grade

NAMBUR (V), PEDAKAKANI (M), GUNTUR-522 508


DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING –
ARTIFICIAL INTELLIGENCE & MACHINE LEARNING (CSM)
VASIREDDY VENKATADRI INSTITUTE OF TECHNOLOGY: NAMBUR
JAWAHARLAL NEHRU TECHNOLOGICAL UNIVERSITY KAKINADA

CERTIFICATE

This is to certify that the project titled “Calculator Application With Unit
Testing” is a bonafide record of work done by Ms. Bitra Bhavani under the guidance
of Mr. M. Pardha Saradhi, Associate Professor in partial fulfillment of the
requirement for the award of credits to Python - a skill enhancement course of
Bachelor of Technology in Computer Science & Engineering – Artificial Intelligence &
Machine Learning (CSM), JNTUK during the academic year 2024-25.

M.Pardha Saradhi Prof. K. Suresh Babu


Course Instructor Head of the Department
DECLARATION

I, BITRA BHAVANI (23BQ1A4220), hereby declare that the Project Report entitled
“CALCULATOR APPLICATION WITH UNIT TESTING” done by me under the
guidance of Mr. M. Pardha Saradhi, Associate Professor is submitted in partial
fulfillment of the requirements for the award of degree of BACHELOR OF
TECHNOLOGY in COMPUTER SCIENCE & ENGINEERING – ARTIFICIAL
INTELLIGENCE & MACHINE LEARNING (CSM).

DATE : SIGNATURE OF THE CANDIDATE

PLACE :

NAME OF THE STUDENT

Bitra Bhavani
ACKNOWLEDGEMENT

We express our sincere thanks wherever due.

We extend our heartfelt gratitude to the Chairman of Vasireddy


Venkatadri Institute of Technology, Sri Vasireddy Vidya Sagar, for
providing us well equipped infrastructure and a conducive environment.

Our sincere thanks to Dr. Y. Mallikarjuna Reddy, Principal of


Vasireddy Venkatadri Institute of Technology, Nambur, for providing the
necessary resources for carrying out the project.

We express our sincere thanks to Dr. K. Giribabu, Dean of


Academics for providing support and a stimulating environment for the
development of the project.

Our sincere thanks to Dr. K. Suresh Babu, Head of the Department


of CSM, for his cooperation and guidance, which helped us successfully
complete the project in all aspects.

We are also grateful to our guide, Mr. M. Pardha Saradhi, Associate


Professor, Department of CSM, for motivating us to make our project
successful and complete. We deeply appreciate his precious valuable
guidance and suggestions.

We also place our floral gratitude to all other teaching staff and
lab technicians for their constant support and advice throughout the
project.

Bitra Bhavani
23BQ1A4220
Abstract
This project focuses on the development and testing of a scientific calculator application using
Python, with an emphasis on unit testing to ensure the accuracy and reliability of its
operations. The calculator is designed with a comprehensive set of mathematical functions,
including basic arithmetic (addition, subtraction, multiplication, and division), advanced
operations such as square roots, powers, logarithms, and trigonometric functions (sine,
cosine, tangent), as well as special functions like factorials and percentages. These operations
are implemented in the Calculator class, which serves as the core computational engine.
The project integrates a graphical user interface (GUI) built with Python's Tkinter library,
offering an intuitive, user-friendly design. The GUI allows users to interact with the calculator
through buttons for each operation, an entry field for displaying input/output, and error
handling for invalid operations such as division by zero, taking square roots of negative
numbers, and attempting to compute the logarithm of non-positive values.
To ensure the calculator performs accurately across all operations, unit testing is employed
using Python’s unittest framework. The testing suite validates each mathematical function,
ensuring that the calculator provides the correct results for both typical cases and edge cases,
such as division by zero or factorial calculations for negative numbers. Additionally, error
handling is rigorously tested to confirm that appropriate exceptions are raised in response to
invalid inputs. These tests are designed to ensure the robustness and precision of the
calculator.
The application also utilizes multithreading to run the Tkinter-based GUI in a separate thread,
preventing the interface from freezing during calculations. The project, therefore, not only
offers a fully functional scientific calculator but also demonstrates the importance of unit
testing in software development to guarantee both performance and reliability. This
combination of GUI development, mathematical computation, and testing ensures the tool’s
effectiveness for both casual users and those requiring advanced mathematical functions.
Chapter 1: Introduction to Calculator application
with unit testing

Overview of the Project:


The primary aim of this project is to Test the Calculator Application to ensure that its
functionality is correct and reliable. The Calculator Application, built using Python’s Tkinter for
the graphical user interface (GUI), performs basic arithmetic operations (addition, subtraction,
multiplication, division) as well as advanced functions such as square roots, trigonometry,
logarithms, and factorials.
Instead of focusing on building the calculator, this project centers on unit testing to verify that
each function of the calculator operates correctly. The tests are implemented using Python’s
unittest framework, which automates the process of validating mathematical calculations and
handling edge cases (e.g., division by zero or calculating the square root of a negative
number).

Objectives:
The primary objectives of this project are:
1. Test Calculator Accuracy and Reliability: Verify that each mathematical operation works
correctly and produces accurate results.
2. Automate Error Handling: Ensure the calculator handles edge cases (e.g., invalid inputs)
gracefully, such as raising appropriate errors for division by zero.
3. Create a Robust Test Suite: Implement automated tests using the unittest framework to
ensure that each function (addition, subtraction, etc.) is correctly implemented and behaves
as expected.
4. Enhance Software Quality: By using automated testing, ensure the calculator maintains
high reliability and can be safely modified or extended in the future without introducing bugs.

Key Technologies Used:


1. Python: The primary language for implementing both the Calculator Application and its unit
tests. Python’s simplicity and robust libraries make it ideal for the project.
2. unittest: Python's built-in unittest module is used to write and execute automated tests. It
ensures that each calculator function is tested under different conditions and edge cases.
3. Tkinter: Used for the GUI of the Calculator Application, allowing the user to interact with
the calculator visually. While the focus is on testing, the GUI is part of the overall application.
4. Regular Expressions: Employed for handling special mathematical operations such as
factorials (e.g., `5!`), ensuring they are processed correctly.
5. Multithreading: While not central to testing, threading ensures that the GUI runs smoothly
in a separate thread, allowing the tests to be executed in parallel.

Project Workflow:
The project follows a structured workflow focused on testing the Calculator Application:
1. Design Test Cases: Identify and create test cases for each calculator function (addition,
subtraction, trigonometric functions, etc.), including typical and edge cases (e.g., handling
division by zero).
2. Write Unit Tests: Implement unit tests using unittest to check each function's correctness
and ensure that invalid inputs are handled appropriately.
3. Run and Debug Tests: Execute the unit tests and fix any issues revealed by failed tests. This
step ensures that each mathematical operation and error condition is correctly handled.
4. Regression Testing: After changes or updates to the application, run the tests again to
ensure new code does not introduce new issues.
5. Continuous Integration: If applicable, integrate the tests into a CI pipeline for automated
testing after every code change.

Applications:
The testing of the Calculator Application has several practical applications:
1. Software Quality Assurance: This project highlights how unit testing ensures that each
function of a software application is reliable and works correctly.
2. Automated Regression Testing: The unit tests allow for automated regression testing,
ensuring that future updates or modifications do not break existing functionality.
3. Educational Tool: The project serves as a learning resource for those interested in unit
testing, showing how to write tests for mathematical functions and handle common errors.
4. Enhancement Foundation: The test suite can be extended as new features are added to the
calculator (e.g., advanced graphing capabilities, additional scientific functions).
This project’s main focus is to test the Calculator Application to ensure that all of its
mathematical functions work as intended and handle edge cases appropriately. By utilizing
the unittest framework, the tests automate the validation process, making it easier to ensure
software reliability and robustness.
The use of automated tests improves the quality of the software and facilitates easier
maintenance, allowing future developers to confidently make changes without fear of
introducing new bugs. This project demonstrates the significance of unit testing in software
development, especially for applications that require high accuracy and robust error handling,
such as a calculator.
Chapter 2: Introduction to Libraries and Tools Used for
Calculator application with unit testing

In the development of any software application, choosing the right libraries and tools is crucial
to ensuring its functionality, efficiency, and scalability. For the Calculator Application, a
carefully selected set of libraries and tools was leveraged to create a user-friendly, responsive,
and high-performance solution. This chapter introduces and explores the various libraries and
tools employed during the development process.
We begin with the Python programming language, which serves as the foundation of the
application, providing a simple yet powerful environment for writing the code. From there,
we move on to specific libraries like Tkinter, which powers the graphical user interface (GUI),
enabling the creation of a clean, intuitive layout. For handling more advanced mathematical
functions and operations, we incorporated the math library, which extends the application’s
capabilities far beyond basic arithmetic.
Additionally, we discuss how the use of threading ensures that the application remains
responsive even when performing computationally intensive tasks. Regular expressions (re)
are also utilized for input validation, helping to process user inputs in an efficient and error-
free manner. Finally, we highlight the importance of unit testing with Python's built-in unittest
library, which was used to rigorously test the individual components of the application to
ensure that everything works as expected.
By examining the purpose, functionality, and integration of each of these tools, this chapter
will provide a comprehensive understanding of how they collectively contributed to the
development of the Calculator Application. Each tool has been carefully chosen to address
specific needs and enhance the overall user experience, creating a robust and reliable final
product.

Key Libraries and Tools for Development


At the core of the Calculator Application, we utilize the Python programming language,
alongside several important libraries and tools designed for specific tasks. Each library
provides unique capabilities, from developing the user interface to performing complex
mathematical operations. Understanding how each of these libraries was selected and how
they function within the application is key to understanding the overall architecture.

1. Python Programming Language


Python is a powerful, versatile, and widely used high-level programming language. It is often chosen
for projects due to its simplicity, ease of learning, and readability, making it an ideal language for both
beginners and experienced developers.
Why Python Was Chosen?
• Ease of Use: Python has a minimalistic and straightforward syntax, allowing developers
to write clean, readable code. It prioritizes human-readable code and helps to
minimize errors, making the development process faster and more efficient.
• Cross-Platform: Python is platform-independent, meaning that Python applications
can be run on any major operating system without requiring significant changes to the
code.
• Extensive Libraries: Python boasts a rich set of libraries and frameworks that
significantly enhance productivity. These libraries cover various aspects, from web
development to scientific computing, making Python a one-stop solution for a wide
variety of applications.
• Strong Community Support: Python has one of the largest programming communities,
ensuring access to documentation, tutorials, and third-party tools.
Python was selected for the development of the Calculator Application due to its balance of
simplicity, performance, and broad ecosystem. Python allows for the development of the
application quickly, without sacrificing performance.
Example of Python Code for Basic Mathematical Operations:
def add(x, y):
"""Add two numbers"""
return x + y

def subtract(x, y):


"""Subtract y from x"""
return x - y

These functions serve as the building blocks for the Calculator Application. The functions are
straightforward and handle basic arithmetic operations, a necessity for any calculator.

2. Tkinter (Graphical User Interface)


Tkinter is the standard GUI toolkit for Python, providing tools to create windows, dialogs,
buttons, and other interactive widgets. It is integrated with Python, making it easy to create
desktop applications with graphical interfaces.

Key Features of Tkinter:


• Widget Set: Tkinter comes with a wide range of GUI widgets, including buttons, labels,
entry fields, and menus. These widgets can be used to build interactive applications.
• Event-Driven Programming: Tkinter uses an event-driven model, where the user’s
actions (like clicking a button or typing in a text field) trigger events that the program
can respond to.
• Geometry Management: Tkinter provides various layout managers (pack, grid, place)
that allow you to control the arrangement and alignment of widgets in the window.
• Cross-Platform: Like Python itself, Tkinter is cross-platform, meaning the same
application will work on Windows, macOS, and Linux with minimal changes.

Why Tkinter for GUI Development?


Tkinter is lightweight, simple to use, and well-integrated with Python, making it an excellent
choice for building a small-scale GUI like the Calculator Application. Unlike more heavyweight
frameworks such as PyQt or Kivy, Tkinter allows for rapid development and a straightforward
interface design.
Example of Tkinter Code for Calculator Layout:
import tkinter as tk

class CalculatorApp:
def __init__(self, root):
self.root = root
self.root.title("Simple Calculator")

self.input_var = tk.StringVar()
self.entry = tk.Entry(root, textvariable=self.input_var,
font=("Arial", 20), bd=5, relief="sunken", justify="right")
self.entry.grid(row=0, column=0, columnspan=4, padx=5, pady=5)

self.create_buttons()

def create_buttons(self):
button_texts = [
('7', 1, 0), ('8', 1, 1), ('9', 1, 2),
('4', 2, 0), ('5', 2, 1), ('6', 2, 2),
('1', 3, 0), ('2', 3, 1), ('3', 3, 2),
('0', 4, 1), ('+', 1, 3), ('-', 2, 3),
('*', 3, 3), ('/', 4, 3), ('=', 4, 2)
]

for (text, row, col) in button_texts:


button = tk.Button(self.root, text=text, font=("Arial", 14),
width=5, height=2, command=lambda t=text: self.on_button_click(t))
button.grid(row=row, column=col, padx=5, pady=5)

def on_button_click(self, text):


current_input = self.input_var.get()
if text == "=":
try:
result = eval(current_input)
self.input_var.set(result)
except Exception as e:
self.input_var.set("Error")
else:
self.input_var.set(current_input + text)

In this example, the CalculatorApp class initializes a Tkinter window with a basic layout for a
calculator, using Entry for the display area and Button widgets for each digit and operation.
3. Math (Mathematical Functions)
The math module in Python is a standard library that provides a variety of mathematical
functions, such as trigonometric functions, logarithms, and constants like pi and e.

Why Math Was Used in the Calculator?


The math module is essential for performing complex mathematical operations that go
beyond simple arithmetic. For the Calculator Application, it provides functions like square
root, power, trigonometric operations, and logarithms, ensuring the app can handle both
simple and advanced calculations.

Key Math Functions Used in the Calculator:


• math.sqrt(x): Calculates the square root of x.
• math.pow(x, y): Calculates x raised to the power of y.
• math.log(x, base): Calculates the logarithm of x to a given base.
• math.factorial(x): Returns the factorial of x.
Example of Using Math Functions in Calculator:
import math

def calculate_square_root(x):
if x < 0:
raise ValueError("Cannot calculate square root of a negative
number")
return math.sqrt(x)

def calculate_power(x, y):


return math.pow(x, y)

These functions allow the calculator to handle more advanced operations like square roots
and powers, expanding its capabilities beyond basic arithmetic.

4. Threading (Handling Long-Running Operations)


In a graphical user interface, it’s crucial to keep the interface responsive, even when
performing long-running tasks. Threading in Python helps manage multiple tasks
concurrently, ensuring that the user interface doesn’t freeze during intensive operations.

Why Threading Was Necessary:


For our calculator, threading is useful when implementing time-consuming operations, such
as calculating large factorials or handling very large numbers. Without threading, the user
interface would become unresponsive, leading to a poor user experience.
Example of Using Threading for Calculator Operations:
import threading
import math
def calculate_factorial_async(n):
def calculate():
result = math.factorial(n)
print(f"The factorial of {n} is {result}")

threading.Thread(target=calculate).start()

This code creates a new thread to calculate the factorial asynchronously. The Thread is launched
without blocking the main GUI thread, ensuring that the user interface remains responsive.

5. Regular Expressions (Validating Input)


The re module allows Python to work with regular expressions, which are patterns used to match
sequences of characters in strings. This is especially useful for validating and processing user inputs.

Why Regular Expressions?


Regular expressions allow for sophisticated input validation, ensuring that the user enters valid
numbers, operations, or expressions. For example, ensuring that only numeric input is accepted, or
properly handling user input for operations like factorial (e.g., 5!).

Example of Using Regular Expressions in the Calculator:

import re

def is_valid_expression(expression):
pattern = r'^[0-9+\-*/^(). ]+$'
return bool(re.match(pattern, expression))

def handle_factorial(expression):
match = re.search(r'(\d+)!', expression)
if match:
number = int(match.group(1))
return math.factorial(number)
return expression
In this example, regular expressions are used to validate input and identify factorial expressions in the
format 5!, which are then processed accordingly.

Testing Tools: Unit Testing with unittest


The unittest library is Python’s standard tool for writing and running tests. It is an essential component
for ensuring that the Calculator Application works as expected in various scenarios.

Why Unit Testing Was Used:


Unit testing ensures that individual components of the calculator (such as arithmetic functions, GUI
responsiveness, and input validation) work correctly. By writing unit tests, we can catch errors early in
the development process, making the application more reliable.
Example of Unit Tests in the Calculator:

import unittest

class TestCalculator(unittest.TestCase):

def test_addition(self):
self.assertEqual(add(2, 3), 5)

def test_subtraction(self):
self.assertEqual(subtract(5, 3), 2)

def test_square_root(self):
self.assertEqual(calculate_square_root(4), 2)

if __name__ == '__main__':
unittest.main()

These tests check whether basic arithmetic functions work as expected, which helps ensure the
integrity of the application.

In this chapter, we have examined the key libraries and tools used in the development of the Calculator
Application, including Python, Tkinter, math, threading, re, and unittest. Each tool played a critical
role in the successful development of the application:

• Python’s simplicity and cross-platform compatibility made it an ideal choice.

• Tkinter provided the necessary framework to build an interactive graphical interface.

• The math module enhanced the calculator's functionality with advanced mathematical
operations.

• Threading ensured that long-running operations did not interfere with the user experience.

• Regular expressions were instrumental in input validation and processing.

• Unit testing with unittest ensured that the application was thoroughly tested, minimizing bugs
and ensuring reliable performance.

Each of these tools was chosen carefully to enhance the overall user experience, functionality, and
maintainability of the Calculator Application.

In the next chapter, we will dive deeper into the design and implementation of the application's test
cases, focusing on how each part of the application was validated to ensure proper functionality under
various conditions.
Chapter 3: Design and Implementation of Unit Tests
for Calculator Application
Introduction
Unit testing is an essential practice in software development that helps ensure the accuracy
and functionality of an application. In this chapter, we’ll discuss the design and
implementation of unit tests for the Calculator Application built in Python. The tests will
cover both basic and advanced mathematical operations that the calculator performs,
including arithmetic operations (addition, subtraction, multiplication, division) and more
complex mathematical functions (square root, power, trigonometry, factorial, and
logarithms).
By writing unit tests, we can ensure that each component of the application behaves as
expected, handle edge cases properly, and deal with potential errors. The unittest framework
in Python is used to structure and run the tests.

Test Design Strategy


A good unit testing strategy focuses on ensuring that all the critical functionalities of an
application are thoroughly tested. In our case, we’re focusing on the following key areas of
the calculator:
1. Basic Arithmetic Operations: Addition, subtraction, multiplication, and division.
2. Advanced Mathematical Functions: Square root, power, percentage, factorial, and
trigonometric functions like sine, cosine, and tangent.
3. Error Handling: Ensuring the application throws the correct errors when the input is
invalid or when operations are mathematically undefined (e.g., division by zero).
4. Edge Cases: Ensuring the application works correctly with extreme or boundary values.
The tests are designed to include positive tests (valid input), negative tests (invalid input), and
edge cases.

Unit Test Implementation:


Testing Basic Arithmetic Operations
In this section, we will create unit tests to validate the basic arithmetic operations: addition,
subtraction, multiplication, and division.

Addition Test
The add() method in the calculator adds two numbers. The test case ensures that this
operation produces the expected result.
import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):
def setUp(self):
self.calculator = Calculator()

def test_add(self):
self.assertEqual(self.calculator.add(2, 3), 5) #
Adding 2 and 3
self.assertEqual(self.calculator.add(-1, 1), 0) #
Adding -1 and 1

if __name__ == '__main__':
unittest.main()
Explanation:
• test_add: This test checks if the addition method works for both positive and negative
numbers. The first assertion checks that adding 2 and 3 results in 5. The second checks
that adding -1 and 1 results in 0.
Expected Output:

test_add (TestCalculator) ... ok

Subtraction Test
The subtract() method subtracts two numbers. The test case for subtraction ensures that the
operation works correctly, both when subtracting smaller numbers from larger ones and vice
versa.
def test_subtract(self):
self.assertEqual(self.calculator.subtract(5, 3), 2) # 5 - 3 = 2
self.assertEqual(self.calculator.subtract(3, 5), -2) # 3 - 5 = -
2
Explanation:
• test_subtract: The test checks two cases: subtracting 3 from 5, and subtracting 5 from
3. This verifies that the calculator correctly handles both positive and negative results.
Expected Output:

test_subtract (TestCalculator) ... ok

Multiplication Test
The multiply() method multiplies two numbers. Here’s the test for multiplication:
def test_multiply(self):
self.assertEqual(self.calculator.multiply(3, 4), 12) # 3 * 4 = 12
self.assertEqual(self.calculator.multiply(-3, 4), -12) # -3 * 4
= -12
Explanation:
• test_multiply: The test checks whether multiplication works for both positive and
negative numbers. It verifies that multiplying 3 and 4 results in 12 and that multiplying
-3 and 4 results in -12.
Expected Output:

test_multiply (TestCalculator) ... ok

Division Test
The divide() method performs division. A critical part of the test is checking for division by
zero, which should raise an exception.
def test_divide(self):
self.assertEqual(self.calculator.divide(10, 2), 5) # 10 / 2 = 5
with self.assertRaises(ValueError):
self.calculator.divide(10, 0) # Division by zero should raise
an error
Explanation:
• test_divide: The first assertion checks whether dividing 10 by 2 gives the correct result,
5. The second assertion checks if dividing by zero raises a ValueError, which is handled
by the calculator.
Expected Output:

test_divide (TestCalculator) ... ok

Testing Advanced Mathematical Functions


Now we test more complex mathematical functions provided by the calculator, including
square roots, exponents, percentages, factorials, and trigonometric functions.

Square Root Test


The sqrt() method computes the square root of a number. We test it for a valid input (16) and
an invalid input (-1, since the square root of a negative number is undefined).
def test_sqrt(self):
self.assertEqual(self.calculator.sqrt(16), 4) #sqrt(16)=4
with self.assertRaises(ValueError):
self.calculator.sqrt(-1) # Cannot compute sqrt of
negative numbers
Explanation:
• test_sqrt: The first assertion checks that the square root of 16 equals 4. The second
assertion ensures that attempting to calculate the square root of a negative number
raises a ValueError.
Expected Output:

test_sqrt (TestCalculator) ... ok

Power Test
The power() method computes exponentiation (a raised to the power of b). We test it with
both positive and zero exponents.
def test_power(self):
self.assertEqual(self.calculator.power(2, 3), 8) # 2^3 = 8
self.assertEqual(self.calculator.power(5, 0), 1) # 5^0 = 1
Explanation:
• test_power: The first assertion checks that 2^3 equals 8. The second assertion tests
that any number raised to the power of 0 is 1.
Expected Output:

test_power (TestCalculator) ... ok

Factorial Test
The factorial() method calculates the factorial of a number. We test it for valid and invalid
inputs (e.g., negative numbers).
def test_factorial(self):
self.assertEqual(self.calculator.factorial(5), 120) # 5! = 120
with self.assertRaises(ValueError):
self.calculator.factorial(-1) # Factorial is not defined for
negative numbers
Explanation:
• test_factorial: The first assertion checks that the factorial of 5 is 120. The second
assertion ensures that attempting to calculate the factorial of a negative number raises
a ValueError.
Expected Output:

test_factorial (TestCalculator) ... ok

Trigonometric Functions Test (sin, cos, tan)


We test the trigonometric functions: sin(), cos(), and tan(). For example, the sine of π/2 should
be 1, and the tangent of π/4 should be 1.
def test_sin(self):
self.assertAlmostEqual(self.calculator.sin(math.pi / 2), 1) #
sin(π/2) = 1
def test_tan(self):
self.assertAlmostEqual(self.calculator.tan(math.pi / 4), 1) #
tan(π/4) = 1
with self.assertRaises(ValueError):
self.calculator.tan(math.pi / 2) # tan(π/2) is undefined
Explanation:
• test_sin: The test checks if the sine of π/2 is correctly evaluated as 1.
• test_tan: The first assertion checks that tan(π/4) is 1. The second checks that tan(π/2)
raises a ValueError because tangent is undefined at π/2.
Expected Output:

test_sin (TestCalculator) ... ok


test_tan (TestCalculator) ... ok

Error Handling Tests


We need to test the proper handling of invalid input, such as division by zero or the logarithm
of zero.

Invalid Logarithm Test


The log() method computes the logarithm of a
number. This test ensures that the method raises an error for zero or negative values.
def test_log(self):
self.assertEqual(self.calculator.log(10), 1) # log(10) = 1
with self.assertRaises(ValueError):
self.calculator.log(0) # log(0) is undefined
Explanation:
• test_log: The first assertion checks that the logarithm of 10 is 1. The second ensures
that log(0) raises a ValueError, as logarithms for non-positive numbers are undefined.
Expected Output:

test_log (TestCalculator) ... ok

Edge Case Handling


Edge cases test the behavior of the application under extreme or boundary conditions. We
will test operations with large and small numbers.

Large Number Test


def test_large_number(self):
self.assertEqual(self.calculator.multiply(1000000, 1000000),
1000000000000) # Test with large numbers
Explanation:
• test_large_number: This test checks if the calculator can handle large numbers
correctly.
Expected Output:

test_large_number (TestCalculator) ... ok

Small Number Test


def test_small_number(self):
self.assertEqual(self.calculator.multiply(0.0001, 10000), 1) #
Test with small numbers
Explanation:
• test_small_number: This test checks if the calculator can handle very small numbers.
Expected Output:

test_small_number (TestCalculator) ... ok

In this chapter, a comprehensive suite of unit tests for the Calculator Application was
implemented to ensure that the application performs its intended operations correctly and
handles various edge cases and errors gracefully. The tests covered a range of functionalities,
including:
• Basic arithmetic operations (addition, subtraction, multiplication, and division)
• Advanced mathematical functions such as square roots, powers, factorials, and
trigonometric calculations
• Error handling for invalid inputs and mathematically undefined operations (e.g.,
division by zero, logarithms of zero or negative numbers)
• Edge cases involving large and small numbers, ensuring the application can handle
extreme values.
Using Python's built-in unittest framework, each functionality was systematically verified in
isolation. This ensures that individual components work as expected, making the calculator
more reliable and robust.
Through these tests, it was confirmed that the application meets its design requirements and
provides a foundation for future development and maintenance. As the application evolves,
these unit tests will help detect regressions, allowing developers to confidently implement
new features without breaking existing functionality.
In summary, the implementation of unit tests is crucial in ensuring software reliability and
maintainability. It also fosters a development environment where bugs can be identified and
resolved early in the process, reducing long-term costs and improving the overall quality of
the application.
Chapter 4: Results and Discussion for the Calculator
Application with Unit Testing
Results
The Calculator Application with Unit Testing successfully performs various mathematical
operations and provides an intuitive user interface. The application is designed to handle basic
arithmetic, advanced mathematical functions, and display results efficiently. It also includes
automated unit testing to ensure the correctness of the operations. The results can be
categorized into the following areas:

1. Functionality:
o The calculator performs basic arithmetic operations such as addition,
subtraction, multiplication, and division accurately.
o Advanced mathematical functions like square root, power, percentage,
factorial, and trigonometric operations (sin, cos, tan) are implemented
correctly.
o Logarithmic functions and exponential calculations also return expected
results.
o The calculator displays appropriate error messages for invalid inputs, such as
division by zero or attempting the square root of a negative number.
Example of input and output:
o Addition: 2 + 3 = 5
o Division: 10 / 2 = 5
o Factorial: 5! = 120
o Sine: sin(pi/2) = 1
o Logarithm: log(10) = 1

2. Graphical User Interface (GUI):


o The GUI is intuitive and user-friendly, with a clear layout of buttons for each
operation. The result is displayed dynamically after each calculation.
o The application supports input through a numeric keypad, and users can delete
the last character using the backspace functionality.
o The calculator is built using Python’s Tkinter library, ensuring a smooth and
responsive user experience.

3. Unit Testing:
o The unit tests cover all major operations, including basic arithmetic, advanced
functions, and error handling.
o The tests confirm that all operations return accurate results for various inputs.
o The error handling mechanisms are verified, ensuring that the calculator raises
appropriate errors for invalid operations (e.g., division by zero, invalid square
roots).
Example of test results:

test_add (__main__.TestCalculator) ... ok


test_subtract (__main__.TestCalculator) ... ok
test_multiply (__main__.TestCalculator) ... ok
test_divide (__main__.TestCalculator) ... ok
test_sqrt (__main__.TestCalculator) ... ok
test_power (__main__.TestCalculator) ... ok
test_percentage (__main__.TestCalculator) ... ok
test_factorial (__main__.TestCalculator) ... ok
test_sin (__main__.TestCalculator) ... ok
test_cos (__main__.TestCalculator) ... ok
test_tan (__main__.TestCalculator) ... ok
test_exp (__main__.TestCalculator) ... ok
test_log (__main__.TestCalculator) ... ok

----------------------------------------------------------------------
Ran 13 tests in 0.004s

OK

Discussion
1. Ease of Use:
o The application provides a user-friendly GUI that makes it easy to perform
calculations with a few button presses.
o Unlike traditional calculators that use physical buttons, the digital interface
allows for clear input and result display, making it easy for users to interact with
the application.

2. Automation and Accuracy:


o The calculator automates the computation process, providing accurate results
for various mathematical operations.
o The unit tests verify that the functions work correctly for a wide range of
inputs, ensuring the application performs as expected under different
conditions.
o Automated testing saves time and reduces human error, which would be
common in manual validation of each operation.

3. Error Handling:
o The calculator includes robust error handling for invalid operations. For
example, it raises errors when attempting to divide by zero or when taking the
square root of negative numbers.
o These error messages are displayed to the user, ensuring that the application
doesn’t crash and provides feedback on why the operation failed.

4. Performance:
o The calculator runs efficiently, with instant feedback provided for calculations,
even for more complex operations such as factorial or trigonometric functions.
o The error handling and input validation mechanisms ensure that the
application continues to run smoothly without crashes or incorrect results.

5. Testing and Validation:


o The unit tests cover the core functionalities of the calculator, ensuring that all
operations (addition, subtraction, multiplication, division, etc.) work correctly.
o The tests also ensure that edge cases, such as division by zero or invalid square
roots, are handled correctly by the application.
o This testing framework ensures the reliability of the application and confirms
that all features are working as expected.

Limitations
1. Limited Functionality:
o While the calculator performs essential operations, it could be extended to
include more advanced mathematical functions, such as matrix operations or
statistical calculations.
o The calculator currently supports only basic mathematical constants and
functions. More advanced scientific or financial functions could be added in
future iterations.

2. GUI Limitations:
o The GUI is functional but could be enhanced further with more advanced
features such as a history log to track previous calculations, or an advanced
mode for scientific calculations.
o The design of the GUI is basic, and could be improved with more visually
appealing elements or additional customization options for the user.

3. Error Handling:
o Although the error handling for basic invalid operations is in place, there is
room to improve it further. For example, the calculator could handle more
complex errors, such as malformed input or unbalanced parentheses.
o Additionally, the error messages could be made more descriptive to guide the
user better.

Potential Improvements
1. Additional Mathematical Functions:
o Future versions of the calculator could include support for more advanced
operations such as matrix multiplication, integration, or differentiation.
o Implementing support for complex numbers or fractions would make the
calculator more versatile and suitable for more complex mathematical tasks.

2. GUI Enhancements:
o The GUI could be enhanced by incorporating interactive features such as drag-
and-drop or customizable themes.
o A more sophisticated layout with a scientific mode or unit conversion mode
could be added to meet the needs of more advanced users.

3. Performance Optimization:
o While the current performance is adequate for most calculations, adding a
multithreading or multiprocessing approach could speed up the computation
for larger or more complex calculations.
o Implementing a more optimized evaluation method (instead of using eval())
could also enhance performance and security.

4. Advanced Error Handling:


o More detailed error messages and custom exceptions could be implemented
to guide users in case of an error.
o Handling edge cases such as mismatched parentheses, invalid characters, or
extremely large numbers could be incorporated to make the application more
robust.

Performance Analysis
1. Execution Time:
o The calculator responds quickly to inputs, with each operation typically
completing in milliseconds.
o The time complexity of each operation (addition, subtraction, multiplication,
etc.) is constant, ensuring that the calculator remains responsive for all inputs.

2. Scalability:
o The application can be extended to handle more complex mathematical tasks
or a larger set of operations, such as scientific calculations or unit conversions.
o Scalability is also achievable by optimizing the backend code to handle larger
input sizes or more complex algorithms.

3. Accuracy:
o The accuracy of the calculator's results is confirmed by the successful execution
of unit tests, which match expected outcomes for a wide range of
mathematical operations.

4. Visualization Efficiency:
o While the application is primarily focused on computations, adding
visualization features, such as plotting graphs for mathematical functions,
could enhance its functionality.
o Integrating libraries like matplotlib or plotly could allow users to visualize the
results of functions like sine, cosine, or exponential curves.

The Calculator Application with Unit Testing successfully fulfills its purpose of providing a user-
friendly tool for mathematical calculations. With a clean and functional GUI, reliable
functionality, and rigorous unit testing to ensure correctness, the application is well-suited for
both basic and advanced calculations. While there are opportunities for improvement in areas
like GUI design, error handling, and additional functionality, the current implementation offers
a robust and efficient solution for everyday calculations. Further development could focus on
enhancing the user experience and extending the functionality to cater to more complex
mathematical tasks.
Chapter 5: Summary, Conclusions, and Future Scope
for the Testing Calculator Project with Unit Testing
The Testing Calculator project was developed to create a reliable and functional calculator
with various mathematical operations, validated through unit testing. The primary aim of the
project was to build a Calculator class that supports basic arithmetic, advanced mathematical
functions, and error handling, integrated into a Tkinter-based graphical user interface (GUI).
The Calculator class includes operations like addition, subtraction, multiplication, division,
square root, trigonometric functions, and factorials, among others.
The project employed Python's unittest framework to validate the correctness of
mathematical methods and ensure the calculator handles edge cases and exceptions, such as
division by zero or invalid input. The GUI allows users to interact with the calculator by
inputting expressions and viewing results in real time. Manual testing of the user interface
was conducted to ensure seamless functionality between the GUI and the Calculator class.
Overall, the calculator serves as both a tool for everyday use and a robust system for
mathematical computation.
The Testing Calculator project successfully demonstrates the power of Python for creating a
simple yet powerful calculator with a user-friendly interface and a solid foundation in
automated testing. The key conclusions drawn from the project include:

1. Accurate and Reliable Mathematical Operations:


o The Calculator class passed all unit tests for core functions, including basic
arithmetic, trigonometric functions, factorials, and square roots. These
operations were tested across a variety of valid and invalid inputs, ensuring the
calculator functions correctly under all conditions.

2. Effective Error Handling:


o The calculator handles common input errors like division by zero, invalid
mathematical operations (e.g., square root of a negative number), and
factorials of negative numbers. These exceptions are appropriately caught and
error messages are displayed to guide the user.

3. Seamless User Experience:


o The Tkinter-based GUI successfully allows users to input expressions and view
results in an intuitive way. Buttons corresponding to numbers and operations
were validated to ensure they function as expected, with special attention to
non-standard operations like "C" (clear), "←" (backspace), and "=" (equals).

4. Comprehensive Unit Testing:


o The use of unit testing for each individual method of the Calculator class
proved crucial in ensuring the accuracy and stability of the application. Tests
were run to check for correct outputs and exception handling, helping to
identify any issues early in development.

5. Manual Validation:
o Manual testing of the GUI confirmed that all buttons are responsive, display
inputs correctly, and produce the correct results when pressed. Error messages
and validation were manually tested to ensure they are clear and user-friendly.

Future Scope:
While the Testing Calculator project is fully functional, there are several opportunities for
further enhancement and improvement:

1. Advanced Mathematical Functions:


o Graphing Functions: Adding support for plotting graphs (e.g., plotting functions
like y = x^2) would expand the calculator's capabilities for users involved in
higher mathematics.
o Matrix Operations: Implementing matrix arithmetic (addition, multiplication,
inversion, etc.) could be useful for users working with linear algebra or related
fields.

2. Performance Optimization:
o Caching Results: For operations like factorials, especially for large numbers,
performance can be enhanced by caching results of previous calculations to
avoid redundant computations.
o Handling Large Numbers: Further optimizations could be made to handle large
numbers or computationally expensive functions efficiently, reducing the time
required for complex calculations.

3. Cross-Platform Compatibility:

o The project could be extended to support deployment across various


platforms, including Windows, macOS, and Linux. Packaging the application
using tools like PyInstaller or cx_Freeze would allow the application to be easily
distributed to users without requiring them to install Python separately.

4. Mobile and Web Versions:


o The project could be adapted into a mobile application using frameworks like
Kivy, React Native, or Flutter, allowing users to access the calculator on the go.
o A web version of the calculator could also be developed using technologies like
Flask or Django to make it accessible via a browser.

5. Enhanced Error Handling:


o Implementing more sophisticated input validation could help users avoid
entering complex or non-mathematical expressions. For example, a more
advanced expression parser could evaluate mathematical strings directly,
handling complex expressions like "2 + 3 * (4 - 1)" correctly.

6. Voice Commands:
o Integrating voice recognition could offer hands-free operation for users who
prefer voice commands for input. This feature could be particularly useful for
users with disabilities or those looking for greater accessibility.

7. Unit Testing Expansion:


o Additional tests could be added to ensure that the calculator handles edge
cases more thoroughly, including testing the calculator with complex
expressions and large datasets.
o Automated GUI testing could also be implemented to further ensure that user
interactions, like button clicks and input entries, are consistently validated.

8. Personalization:
o The application could be enhanced by allowing users to customize the
calculator's appearance, for example by changing themes, fonts, or layout
preferences. This would make the tool more appealing and adaptable to
different user preferences.

9. Integration with Other Tools:


o The calculator could be integrated with other tools or platforms, such as
exporting calculation results to CSV files or integrating with scientific tools like
Mathematica or Wolfram Alpha for more advanced analysis.
The Testing Calculator project achieved its goal of building a functional and reliable calculator
application with comprehensive unit testing. It provides an intuitive user interface and
supports essential mathematical functions, making it suitable for general use. The project also
serves as a strong foundation for further development, with numerous possibilities for
expanding its capabilities, enhancing performance, and improving user experience. By
implementing the outlined future improvements, this project could become a versatile and
powerful tool for a wider range of users, from students to professionals working in fields like
engineering, finance, and science
References
1. Python Software Foundation. (2024). Python Documentation. Python Software
Foundation. Retrieved from https://docs.python.org/3/
2. Tkinter Documentation. (2024). Tkinter - Python Interface to Tcl/Tk. Python
Software Foundation. Retrieved from
https://docs.python.org/3/library/tkinter.html
3. Math Module - Python Docs. (2024). math - Mathematical Functions. Python
Software Foundation. Retrieved from https://docs.python.org/3/library/math.html
4. Unit Testing - Python Docs. (2024). unittest — Unit testing framework. Python
Software Foundation. Retrieved from
https://docs.python.org/3/library/unittest.html
5. Wang, J. (2020). Creating a Calculator with Tkinter and Python. Stack Overflow.
Retrieved from https://stackoverflow.com/questions/57557867/creating-a-
calculator-with-tkinter-and-python
6. Math Factorial Function - Python Docs. (2024). math.factorial. Python Software
Foundation. Retrieved from
https://docs.python.org/3/library/math.html#math.factorial
7. Tkinter Widgets. (2024). Tkinter Widgets: Entry, Button, and More. TutorialsPoint.
Retrieved from
https://www.tutorialspoint.com/python/python_gui_programming.htm
8. Müller, F. (2018). Unit Testing for Python Developers. O'Reilly Media. ISBN 978-
1491946347.
Appendix
import tkinter as tk
from tkinter import messagebox
import math
import threading

# The Calculator class (updated)


class Calculator:
def add(self, a, b):
return a + b

def subtract(self, a, b):


return a - b

def multiply(self, a, b):


return a * b

def divide(self, a, b):


if b == 0:
raise ValueError("Cannot divide by zero")
return a / b

def sqrt(self, a):


"""Returns the square root of a number."""
if a < 0:
raise ValueError("Cannot compute the square root
of a negative number")
return math.sqrt(a)

def power(self, a, b):


"""Returns a raised to the power of b (a^b)."""
return math.pow(a, b)

def percentage(self, a, b):


"""Returns b% of a."""
return (a * b) / 100

def factorial(self, a):


"""Returns the factorial of a number."""
if a < 0:
raise ValueError("Cannot compute factorial of a
negative number")
return math.factorial(a)

def sin(self, a):


"""Returns the sine of a number (in radians)."""
return math.sin(a)

def cos(self, a):


"""Returns the cosine of a number (in radians)."""
return math.cos(a)

def tan(self, a):


"""Returns the tangent of a number (in radians).
Returns an error for angles near odd multiples of pi/2
(undefined tangent).
"""
tolerance = 1e-10
if abs(math.cos(a)) < tolerance:
raise ValueError("Tangent is undefined at this
angle (cos(a) is 0)")
return math.tan(a)
def exp(self, a):
"""Returns e raised to the power of a."""
return math.exp(a)

def log(self, a):


"""Returns the logarithm of a number with base 10."""
if a <= 0:
raise ValueError("Logarithm is undefined for non-
positive numbers")
return math.log10(a) # Perform log base 10

# GUI Application with Tkinter


class CalculatorApp:
def _init_(self, root):
self.root = root
self.root.title("Calculator")
self.root.geometry("400x600")

# Create an instance of the Calculator class


self.calculator = Calculator()

# String variable for the entry widget


self.input_var = tk.StringVar()

# Entry widget for displaying the input/output


self.entry = tk.Entry(root,
textvariable=self.input_var, font=('Arial', 24), bd=10,
relief="sunken", justify='right')
self.entry.grid(row=0, column=0, columnspan=5, padx=5,
pady=5)
# Button layout (button text and its row/column
position)
buttons = [
# Row 1 (log, exp, sqrt, (, ))
('log', 1, 0), ('exp', 1, 1), ('sqrt', 1, 2),
('(', 1, 3), (')', 1, 4),

# Row 2 (sin, cos, tan, ^, !)


('sin', 2, 0), ('cos', 2, 1), ('tan', 2, 2), ('^',
2, 3), ('!', 2, 4),

# Row 3 (7, 8, 9, Backspace, Clear)


('7', 3, 0), ('8', 3, 1), ('9', 3, 2), ('←', 3,
3), ('C', 3, 4),

# Row 4 (4, 5, 6, *, -)
('4', 4, 0), ('5', 4, 1), ('6', 4, 2), ('*', 4,
3), ('-', 4, 4),

# Row 5 (1, 2, 3, +, /)
('1', 5, 0), ('2', 5, 1), ('3', 5, 2), ('+', 5,
3), ('/', 5, 4),

# Row 6 (0, 00, ., %, =)


('0', 6, 0), ('00', 6, 1), ('.', 6, 2), ('%', 6,
3), ('=', 6, 4)
]

# Create and place the buttons with a smaller size


for (text, row, col) in buttons:
button = tk.Button(root, text=text, width=5,
height=2, font=('Arial', 14), command=lambda t=text:
self.on_button_click(t))
button.grid(row=row, column=col, padx=5, pady=5)

def on_button_click(self, text):


"""Handles button click events."""
current_input = self.input_var.get()

if text == 'C': # Clear the display


self.input_var.set('') # Clear the entry field
elif text == '=': # Evaluate the expression
try:
result =
self.evaluate_expression(current_input)
self.input_var.set(result) # Display the
result
except Exception as e:
messagebox.showerror("Error", str(e))
elif text == '←': # Backspace: Remove last character
if current_input:
self.input_var.set(current_input[:-1]) #
Remove last character
elif text in ['sqrt', 'sin', 'cos', 'tan', 'exp',
'log']: # Functions that require parentheses
self.input_var.set(current_input + text + '(') #
Automatically add opening parenthesis
elif text == '!': # Factorial: Add '!' symbol and
handle it later in eval
self.input_var.set(current_input + '!')
elif text == '00': # Handle "00" button
self.input_var.set(current_input + '00')
else: # Append the clicked button text to the current
input
self.input_var.set(current_input + text)
def evaluate_expression(self, expr):
"""Evaluates the mathematical expression entered by
the user."""
try:
# Replacing mathematical symbols to match the
Calculator class
expr = expr.replace('^', '') # Replacing
exponentiation
expr = self.handle_factorial(expr) # Handling
factorial

# Replace functions with the actual methods from


the Calculator class
expr = expr.replace('sqrt',
'self.calculator.sqrt') # Use the calculator's sqrt method
expr = expr.replace('sin', 'self.calculator.sin')
# Use the calculator's sin method
expr = expr.replace('cos', 'self.calculator.cos')
# Use the calculator's cos method
expr = expr.replace('tan', 'self.calculator.tan')
# Use the calculator's tan method
expr = expr.replace('exp', 'self.calculator.exp')
# Use the calculator's exp method
expr = expr.replace('log', 'self.calculator.log')
# Use the calculator's log method

# Now safely evaluate the expression with the


correct functions
return eval(expr)
except Exception as e:
raise ValueError("Invalid input or operation: " +
str(e))

def handle_factorial(self, expr):


"""Handles the factorial in the expression."""
# Find all occurrences of the '!' symbol for factorial
and handle them
import re

# Regular expression to match the pattern: number


followed by '!'
factorial_pattern = r'(\d+)!'

# Replace the pattern 'n!' with 'math.factorial(n)'


expr = re.sub(factorial_pattern,
r'math.factorial(\1)', expr)

return expr

# Run the Tkinter Application in a thread


def run_calculator_gui():
root = tk.Tk()
app = CalculatorApp(root)
root.mainloop()

# Run Tkinter in a separate thread to avoid blocking the


notebook
threading.Thread(target=run_calculator_gui,
daemon=True).start()

import unittest
import math

# The unit tests for the Calculator class


class TestCalculator(unittest.TestCase):
def setUp(self):
"""Set up the Calculator object for testing."""
self.calculator = Calculator()

def test_add(self):
self.assertEqual(self.calculator.add(2, 3), 5)
self.assertEqual(self.calculator.add(-1, 1), 0)

def test_subtract(self):
self.assertEqual(self.calculator.subtract(5, 3), 2)
self.assertEqual(self.calculator.subtract(3, 5), -2)

def test_multiply(self):
self.assertEqual(self.calculator.multiply(3, 4), 12)
self.assertEqual(self.calculator.multiply(-3, 4), -12)

def test_divide(self):
self.assertEqual(self.calculator.divide(10, 2), 5)
with self.assertRaises(ValueError):
self.calculator.divide(10, 0) # Division by zero
should raise an error

def test_sqrt(self):
self.assertEqual(self.calculator.sqrt(16), 4)
with self.assertRaises(ValueError):
self.calculator.sqrt(-1) # Caannot take square
root of negative numbers

def test_power(self):
self.assertEqual(self.calculator.power(2, 3), 8)
self.assertEqual(self.calculator.power(5, 0), 1)

def test_percentage(self):
self.assertEqual(self.calculator.percentage(200, 10),
20)
self.assertEqual(self.calculator.percentage(100, 50),
50)

def test_factorial(self):
self.assertEqual(self.calculator.factorial(5), 120)
with self.assertRaises(ValueError):
self.calculator.factorial(-1) # Factorial is not
defined for negative numbers

def test_sin(self):
self.assertAlmostEqual(self.calculator.sin(math.pi /
2), 1)
self.assertAlmostEqual(self.calculator.sin(0), 0)

def test_cos(self):
self.assertAlmostEqual(self.calculator.cos(0), 1)
self.assertAlmostEqual(self.calculator.cos(math.pi), -
1)

def test_tan(self):
self.assertAlmostEqual(self.calculator.tan(math.pi /
4), 1)
with self.assertRaises(ValueError):
self.calculator.tan(math.pi / 2) # Tangent is
undefined at this angle

def test_exp(self):
self.assertEqual(self.calculator.exp(0), 1)
self.assertEqual(self.calculator.exp(1), math.e)

def test_log(self):
self.assertEqual(self.calculator.log(10), 1)
with self.assertRaises(ValueError):
self.calculator.log(0) # Logarithm is undefined
for zero or negative numbers

if _name_ == '_main_':
unittest.main(argv=[''], exit=False)

You might also like