G24_UnitTesting
G24_UnitTesting
Software Engineering
Group - 24
Unit Testing
Signup Function : -
This function implements the signup functionality for users. It performs the following actions:
1. Accepts and validates user input, including userName, email, and password.
2. Checks if the provided email is already in use and returns an error if so.
3. Ensures the password meets specific criteria, such as length (6-12 characters) and
complexity (must include uppercase, lowercase, number, and special character).
4. Hashes the password for security before storing it in the database.
5. Returns a success response with the user ID when a new account is created successfully.
if not
re.fullmatch(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@#$&])[A-Za-z\d@#$&]{6,}$',
password):
return jsonify({
'message': 'Password must be at least 6 characters long, contain
one uppercase letter, one lowercase letter, one number, and one special character
(@, #, $, or &).'
}), 400
# Hash the password
hashed_password = generate_password_hash(password)
newUser = Credentials(userName=userName, email=email, password=
hashed_password, date=datetime.now())
# Add the new user to the database
db.session.add(newUser)
db.session.commit()
user = Credentials.query.filter_by(email=email).first()
except Exception as e:
db.session.rollback() # Rollback if there's an error
app.logger.error(f"Error during signup: {str(e)}")
return jsonify({'message': 'Internal server error'}), 500
Result : -
Login Function : -
This function takes care of the login functionality for users. It validates the user
credentials by checking if the provided email exists in the database and if the password matches
the hashed password stored for the user. It returns an appropriate error in case of invalid
credentials or provides user details on successful login.
@app.route('/login', methods=['POST'])
def login():
data = request.json
email = data.get('email')
password = data.get('password')
# Here we find user by email from database
user = Credentials.query.filter_by(email=email).first()
def test_login(self):
# Successful
response = self.app.post('/login', json={
'email': 'hetpanchotiya@gmail.com',
'password': 'Abcd@3'
})
self.assertEqual(response.status_code, 200)
self.assertIn('Login successfully', response.json['message'])
# Wrong password
response = self.app.post('/login', json={
'email': 'testuser@example.com',
'password': 'Test1234@5'
})
self.assertEqual(response.status_code, 400)
self.assertIn('Invalid email or password', response.json['message'])
It sets up mock requests with user login details to simulate different scenarios. For a successful
login, the function tests with valid credentials, asserting that the response status is 200 and the
message "Login successfully" is returned.
For the case of an invalid password, the function simulates a login attempt with a correct email
but a wrong password. It asserts that the response status is 400 and the message "Invalid email or
password" is returned.
This test case covers both successful and unsuccessful login scenarios, as confirmed by the
results displayed in the terminal.
Result : -
@app.route('/forgotPassword', methods=['POST'])
def forgotPassword():
data = request.json
email = data.get('email')
if not email:
return jsonify({"message": "Email is required."}), 400
def test_forgotPassword(self):
# Success
response = self.app.post('/forgotPassword', json={
'email': 'testuser@example.com'
})
self.assertEqual(response.status_code, 200)
self.assertIn('Password reset email sent', response.json['message'])
# Empty Email
response = self.app.post('/forgotPassword', json={
'email': ''
})
self.assertEqual(response.status_code, 400)
self.assertIn('Email is required.', response.json['message'])
# Wrong password
response = self.app.post('/forgotPassword', json={
'email': 'testuser5@example.com'
})
self.assertEqual(response.status_code, 404)
self.assertIn('Email not found', response.json['message'])
It sets up mock requests with user email details to simulate different scenarios for the "Forgot
Password" functionality. For a successful case, the test provides a valid email and asserts that the
response status is 200 with the message "Password reset email sent".
For an empty email input, it simulates a request with a missing email and asserts that the
response status is 400, verifying that the system returns the message "Email is required.".
For a non-existent email, the function tests with an email not registered in the database. The test
asserts that the response status is 404 and the message "Email not found" is returned.
These test cases successfully validate the functionality under different conditions, as confirmed
by the results shown in the terminal.
Result : -
VerifyCode Function : -
This function takes care of the verification of the user's email using a 6-digit verification
code. It validates the input, checks for the existence of the email in the stored verification data,
and ensures the code is valid and not expired. It also handles errors such as missing inputs,
invalid or expired codes, and clears the code upon successful verification.
@app.route('/verifyCode', methods=['POST'])
def verifyCode():
data = request.get_json()
email = data.get('email')
code = data.get('verificationCode')
stored_data = verification_data[email]
stored_code = stored_data.get("code")
timestamp = stored_data.get("timestamp")
# no code given
response = self.app.post('/verifyCode', json={
'email': 'testuser5@example.com',
'verificationCode': ''
})
self.assertEqual(response.status_code, 400)
self.assertIn('Email and verification code are required.',
response.json['message'])
It sets up mock requests with user email and verification code details to simulate different
scenarios for the "Verify Code" functionality.
For an invalid or expired code, the function tests with a valid email but an incorrect or outdated
verification code. It asserts that the response status is 400 and the message "Invalid or expired
verification code." is returned.
For missing verification code input, the test simulates a request where the verification code is
empty. It asserts that the response status is 400 and verifies that the message "Email and
verification code are required." is returned.
For an email not present in the verification data, the function tests with a valid format email that
has no associated verification code. It asserts that the response status is 400 and confirms that the
message "Invalid email or verification code." is returned.
These test cases successfully validate the behavior of the verification functionality under
different conditions, as confirmed by the results shown in the terminal.
Result : -
def test_valid_token(self):
"""Test verifying a valid token."""
email = "user@example.com"
token = self.serializer.dumps(email, salt=self.salt)
result = verify_reset_token(token)
self.assertEqual(result, None)
def test_expired_token(self):
"""Test verifying an expired token."""
email = "user@example.com"
token = self.serializer.dumps(email, salt=self.salt)
def test_invalid_token(self):
"""Test verifying an invalid/corrupted token."""
token = "invalid-token-string"
result = verify_reset_token(token)
self.assertIsNone(result)
It sets up a series of tests to verify the functionality of the verify_reset_token function under
different conditions.
For the valid token case, a mock request is created with a valid token generated from a test
email. The function is called, and the test asserts that the response is as expected, confirming that
valid tokens are handled correctly.
In the expired token case, the test stubs the serializer.loads method to simulate token expiration.
The function is called with a shortened expiration time, and the test asserts that None is returned,
verifying that expired tokens are appropriately rejected.
For the invalid token, the test provides a corrupted or invalid token string. The function is
called, and the test asserts that it returns None, ensuring the function handles invalid tokens
securely.
Result : -
The function looks up the user by their email in the database. If the user is not found, it returns a
404 response with the message "User not found".
For a valid user, the function hashes the new password, updates the user's record in the database,
and commits the changes. Upon success, it returns a 200 response with the message "Password
has been reset successfully". This ensures the process is secure and user-friendly while adhering
to best practices for password management.
@app.route('/resetPassword', methods=['POST','GET'])
def resetPassword():
data = request.json
email = data.get('email')
newPassword = data.get('newPassword')
if not
re.fullmatch(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@#$&])[A-Za-z\d@#$&]{6,}$',
newPassword):
return jsonify({
'message': 'Password must be at least 6 characters long, contain
one uppercase letter, one lowercase letter, one number, and one special character
(@, #, $, or &).'
}), 400
def test_resetPassword(self):
# Successful
response = self.app.post('/resetPassword', json={
'email': 'testuser@example.com',
'newPassword': 'Test1234@'
})
self.assertEqual(response.status_code, 200)
self.assertIn('Password has been reset successfully',
response.json['message'])
It sets up mock requests to validate the functionality of the resetPassword endpoint under
different conditions.
For the successful password reset scenario, the test provides a valid email and a new password
adhering to the required complexity. The function is called, and the test asserts that res.status
returns 200, and res.json contains the message "Password has been reset successfully".
In the invalid new password case, the test supplies a valid email but an invalid password that
doesn't meet the required policy. The test asserts that res.status returns 400, and res.json includes
a message explaining the password complexity requirements.
For the user not found case, the test uses an email that does not exist in the database but with a
valid new password. It asserts that res.status returns 404, and res.json contains the message "User
not found".
This test case is successfully covered, which is confirmed with the results displayed in the
terminal as shown below.
Result : -
# if isinstance(prodCategories, list):
prodCategories = ", ".join(prodCategories)
except Exception as e:
app.logger.error(f"Error adding customer: {str(e)}")
return jsonify({'message': 'Failed to add customer information.'}), 500
def test_initForm_success(self):
sample_data = {
'companyName': 'Test Company',
'state': 'Assam',
'prodCategories': ['Electronics', 'Books']
}
response = self.app.post('/initForm?userId=12345', json=sample_data)
self.assertEqual(response.status_code, 500)
self.assertIn('Failed to add customer information.',
response.json['message'])
It sets up a mock request with customer details, including company name, state, and product
categories. The request is sent to the /initForm endpoint with a randomly generated userId to
simulate the addition of customer information. The test checks if the response status is 200 and
confirms that the success message 'Customer information added successfully!' is returned. It also
tests a failure case by using a hardcoded userId, expecting the response status to be 500 with an
error message indicating the failure to add customer information.
For the user not found case, the test uses an email that does not exist in the database but with a
valid new password. It asserts that res.status returns 404, and res.json contains the message "User
not found".
This test case is successfully covered, which is confirmed with the results displayed in the
terminal as shown below.
Result : -
Trends Function : -
This function handles the retrieval of the top 5 trending items in a specific category and
state based on sales. It first defines the get_top_5_sales function, which queries the database to
filter results by category and state, and orders them by sales in descending order. It limits the
results to the top 5 items and returns them in a list of dictionaries, containing relevant item
information such as category name, item name, state, and sales.
The /trends route accepts a JSON request with state and category, then calls get_top_5_sales to
get the relevant data. The function returns the sales data in a JSON response with a 200 status
code upon success. If an error occurs, it logs the error and returns a failure message with a 500
status code
return result
except Exception as e:
app.logger.error(f"Error finding trend: {str(e)}")
return jsonify({'message': 'Failed to find the top trending item.'}), 500
def test_trends(self):
response = self.app.post('/trends', json={
'state': 'Assam',
'catName': 'Electronics'
})
self.assertEqual(response.status_code, 200)
@patch('backend.get_top_5_sales')
def test_trends_exception(self, mock_get_top_5_sales):
mock_get_top_5_sales.side_effect = Exception("Database error")
request_data = {
'state': 'California',
'category': 'Electronics'
}
self.assertEqual(response.status_code, 500)
self.assertIn('Failed to find the top trending item',
response.json['message'])
It sets up a mock request with the required details for the /trends endpoint, such as the state and
catName. It then simulates a successful scenario where the get_top_5_sales function returns a list
of top trending items. The test asserts that the response status was called with 200, indicating that
the request was successful. The response JSON contains the top trending items, though the exact
details of the items are not verified in this test.
Additionally, another test mocks the get_top_5_sales function to simulate a database error (via
side_effect). In this case, when an exception is thrown, the test ensures that the response status is
500 and the error message includes "Failed to find the top trending item", confirming that the
error handling works correctly.
Result : -
InventoryInsert Function : -
This function handles the insertion of new inventory items into the database. It expects a
POST request with the item details provided in the request body, such as itemId, itemName,
catName, quantity, costPrice, and sellingPrice. After extracting the data, it creates a new
Inventory object and adds it to the database. If the insertion is successful, it returns a response
with a success message and a 200 status code. In case of an error, it logs the error and returns a
500 status code with a failure message.
except Exception as e:
app.logger.error(f"Entry didn't get inserted: {str(e)}")
return jsonify({"message": "Entry didn't get inserted."}), 500
def test_inventory_insert_success(self):
# Success
sample_data = {
'itemId': 'item123',
'name': 'Laptop',
'category': 'Electronics',
'quantity': 10,
'costPrice': 500,
'sellingPrice': 700
}
response = self.app.post('/inventory/insert', json=sample_data)
self.assertEqual(response.status_code, 200)
self.assertIn('Successfully entry added', response.json['message'])
Next, the test simulates a failure scenario by mocking the db.session.commit method to raise an
exception, simulating a database error. The test asserts that the response status is 500 and the
error message "Entry didn't get inserted." is returned.
Result : -
GetProductbyCategory Function : -
This function handles the product retrieval functionality by category. It checks whether a
valid category is provided in the request and returns products belonging to that category from the
database. If the category is not specified, it returns an error message. Additionally, the function
queries the database for products in the given category and returns the product details (such as
item ID, name, category, quantity, cost price, and selling price). In case of a missing category, the
function returns a 400 error indicating that the category is required. If the query is successful, it
returns a list of products with a 200 status code.
@app.route('/products', methods=['GET','POST'])
def get_products_by_category():
#category = request.args.get('category')
data = request.json
category = data.get('category')
if not category:
return jsonify({"error": "Category is required"}), 400
print(category)
if category:
products = Inventory.query.filter_by(catName=category).all()
for product in products:
print(product)
products_data = [
{
'itemId': product.itemId,
'category': product.catName,
'name': product.itemName,
'quantity': product.quantity,
'costPrice': product.costPrice,
'sellingPrice': product.sellingPrice
}
for product in products
]
print(products_data)
return jsonify(products_data), 200
def test_get_products_by_category(self):
#Success
sample_data = {
'category': 'Electronics'
}
response = self.app.post('/products', json=sample_data)
self.assertEqual(response.status_code, 200)
self.assertIsInstance(response.json, list)
#No category
sample_data = {
'category': ''
}
response = self.app.post('/products', json=sample_data)
self.assertEqual(response.status_code, 400)
self.assertIn("Category is required", response.json['error'])
sys.stdout = sys.__stdout__
devnull.close()
This test case evaluates the functionality of the get_products_by_category endpoint. It sets up a
mock request with category details and simulates a successful query for products by category.
The test checks two scenarios:
1. Success: When a valid category ("Electronics") is provided, the endpoint returns a list of
products in that category with a status code of 200.
2. No Category Provided: If the category is left empty, the endpoint returns a 400 status
code with an error message indicating that the category is required.
The test also ensures that the response is a list when the request is successful and that an
appropriate error message is returned when the category is missing
Result : -
InventoryDelete Function : -
The /inventory/delete function first checks if the itemId is provided in the request; if not,
it returns a 400 error with the message "itemId is required." It then queries the database to find an
inventory item matching the provided itemId. If the item is found, it deletes the entry from the
database and returns a success message with a 200 status. If no matching item is found, it logs a
message indicating the absence of the entry but does not perform any deletion. In case of any
exceptions (e.g., database errors), the function catches the error and returns a 500 error with a
message stating "Entry didn't get deleted."
except Exception as e:
app.logger.error(f"Entry Didn't got deleted: {str(e)}")
return jsonify({"message": "Entry didn't got deleted."}), 500
#Success
mock_entry = Inventory(itemId='item123', itemName='Laptop',
quantity=10, costPrice=500, sellingPrice=700)
mock_filter.return_value.first.return_value = mock_entry # Mock the
database query to return a mock entry
self.assertEqual(response.status_code, 200)
self.assertIn('entry deleted successfully', response.json['message'])
self.assertEqual(response.status_code, 400)
self.assertIn('itemId is required', response.json['error'])
@patch('backend.Inventory.query.filter_by')
@patch('backend.db.session.commit')
#seperate_func for 500 error
def test_inventory_delete_error(self, mock_commit, mock_filter):
"""Test the inventory delete function when there is an error."""
mock_filter.return_value.first.return_value = None
mock_commit.side_effect = Exception("DB Error")
self.assertEqual(response.status_code, 500)
self.assertIn('Entry didn\'t got deleted.', response.json['message'])
This test case verifies the behavior of the inventoryDelete function. It sets up mock
responses for database interactions using mock_commit and mock_filter. In the first scenario, it
tests the successful deletion of an inventory item by mocking the database query to return a mock
entry. The test then asserts that the response status is 200 and the message indicates the entry was
successfully deleted. In the second scenario, the test checks the case where the itemId is missing.
It ensures that the response returns a 400 status and an appropriate error message. Finally, the test
verifies the case where an error occurs during the deletion process by setting the mock_commit
to raise an exception. The test ensures the function handles the error gracefully, returning a 500
status with a relevant error message. This test is confirmed to be successful based on the terminal
results, ensuring that the inventory deletion function works as expected under both normal and
error conditions.
Result : -
InventoryModify Function : -
The inventoryModify function allows updating inventory entries based on provided data
such as itemId, category, name, quantity, costPrice, and sellingPrice. It first checks if the entry
with the given itemId exists in the database. If found, it updates the entry with the new values
and commits the changes. A success message is returned with a 200 status code. If the entry does
not exist, a message is logged, and a 404 response is returned. In case of errors, a 500 status code
is returned with an error message.
except Exception as e:
app.logger.error(f"Entry Didn't got modified: {str(e)}")
return jsonify({"message": "Entry didn't get modified."}), 500
InventoryModify Function Test : -
sample_data = {
'itemId': 'item123',
'catName': 'Electronics',
'itemName ': 'Laptop',
'quantity': '5',
'costPrice': '100',
'sellingPrice': '100'
}
response = self.app.post('/inventory/modify', json=sample_data)
self.assertEqual(response.status_code, 200)
self.assertIn('backend is ok', response.json['message'])
@patch('backend.Inventory.query.filter_by')
@patch('backend.db.session.commit')
def test_inventory_modify_commit_error(self, mock_commit, mock_filter):
"""Test 500 error when the commit operation fails."""
mock_entry = MagicMock()
mock_filter.return_value.first.return_value = mock_entry
mock_commit.side_effect = Exception("Database commit error") #
Simulate commit error
sample_data = {
'itemId': 'item123',
'category': 'Electronics',
'name': 'Laptop',
'quantity': 20,
'costPrice': 500,
'sellingPrice': 700
}
self.assertEqual(response.status_code, 500)
self.assertIn('Entry didn\'t get modified.', response.json['message'])
Result : -
Profile Function : -
The profile route fetches and returns user profile information by querying two database
tables: CustomerInfo and Credentials. The function retrieves the user's ID, name, email, mobile
number, company name, city, state, and product categories. If both entries exist, it returns the
profile data as a JSON response with a 200 status code. If an error occurs, it logs the error and
returns a 500 status with a failure message. However, there seems to be a mistake in the
exception handling; the error message in the return statement has mismatched quotation marks
("message': 'Entry didn't get deleted."). It should be corrected to "message": "Entry didn't get
deleted.".
@app.route('/profile', methods = ['POST','GET'])
def profile():
try:
# data = request.json
userId = 1
except Exception as e:
app.logger.error(f"Entry Didn't got deleted: {str(e)}")
return jsonify({"message': 'Entry didn't got deleted."}), 500
mock_customer_entry = MagicMock()
mock_customer_entry.companyName = "TechCorp"
mock_customer_entry.state = "Gujarat"
mock_customer_entry.prodCategories = "Electronics, Furniture"
mock_customer_filter.return_value.first.return_value =
mock_customer_entry
mock_credentials_entry = MagicMock()
mock_credentials_entry.userName = "JohnDoe"
mock_credentials_entry.email = "john@example.com"
mock_credentials_filter.return_value.first.return_value =
mock_credentials_entry
response = self.client.get('/profile')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, {
'userId': 1,
'userName': 'JohnDoe',
'userEmail': 'john@example.com',
'mobileNumber': 5454656546,
'companyName': 'TechCorp',
'city': 'Gandhinagar',
'state': 'Gujarat',
'categoriesSold': ['Electronics', 'Furniture']
})
The test_profile_success function mocks the database queries for CustomerInfo and
Credentials to simulate a successful retrieval of profile data. The mock_customer_filter and
mock_credentials_filter are patched to return mock entries with predefined values, such as the
user's name, email, company, state, and product categories. The test then simulates a GET
request to the /profile endpoint and checks that the response has a status code of 200. It also
validates that the returned JSON matches the expected profile data, including user details and
product categories.
Result : -
EditProfile Function : -
The editProfile function is designed to handle profile updates by modifying user
information in both the CustomerInfo and Credentials tables. Upon receiving a PUT request with
JSON data, it updates the userName, email, companyName, state, and prodCategories fields of
the respective records. The prodCategories list is converted into a string before being stored in
the database. If the updates are successful, the function commits the changes and returns a
success message with a 200 status code. In case of an error during the commit, the function rolls
back the transaction and returns an error message with a 500 status code.
@app.route('/editprofile', methods=['PUT'])
def editProfile():
data = request.json
userId = 1
entry1 = CustomerInfo.query.filter_by(userId = userId).first()
entry2 = Credentials.query.filter_by(userId=userId).first()
entry2.userName = data.get('userName')
entry2.email = data.get('userEmail')
# user.mobile_number = data.get('mobileNumber', user.mobile_number)
entry1.companyName = data.get('companyName')
# user.city = data.get('city', user.city)
entry1.state = data.get('state')
entry1.prodCategories = ", ".join(data.get('categoriesSold', [])) # Convert
list to string
try:
db.session.commit()
return jsonify({"message": "Profile updated successfully"}), 200
except Exception as e:
db.session.rollback()
return jsonify({"error": "Failed to update profile"}), 500
def test_edit_profile(self):
updated_data = {
'userName': 'JohnDoe',
'userEmail': 'john@example.com',
'companyName': 'TechCorp',
'state': 'Gujarat',
'categoriesSold': ['Electronics', 'Furniture']
}
response = self.app.put('/editprofile', json=updated_data)
self.assertEqual(response.status_code, 200)
updated_entry1 = CustomerInfo.query.filter_by(userId=1).first()
updated_entry2 = Credentials.query.filter_by(userId=1).first()
self.assertEqual(updated_entry1.companyName, 'TechCorp')
self.assertEqual(updated_entry1.state, 'Gujarat')
self.assertCountEqual(actual_categories, expected_categories)
self.assertEqual(updated_entry2.userName, 'JohnDoe')
self.assertEqual(updated_entry2.email, 'john@example.com')
@patch('backend.db.session.commit')
@patch('backend.CustomerInfo.query.filter_by')
@patch('backend.Credentials.query.filter_by')
def test_edit_profile_error(self, mock_credentials_filter,
mock_customer_filter, mock_commit):
"""Test that the edit profile route returns 500 on failure (simulate
error)."""
mock_customer_filter.return_value.first.return_value = None
mock_credentials_filter.return_value.first.return_value = None
mock_commit.side_effect = Exception("DB Error")
sample_data = {
'userName': 'newUserName',
'userEmail': 'newEmail@example.com',
'companyName': 'NewCompany',
'state': 'NewState',
'categoriesSold': ['NewCategory']
}
response = self.app.put('/editprofile', json=sample_data)
self.assertEqual(response.status_code, 500)
self.assertIn('Failed to update profile', response.json['error'])
In the first test case, test_edit_profile, the function simulates a successful profile update
by sending a PUT request with new user information. After the request is made, it checks the
response status to ensure the profile was updated successfully (status code 200). The test then
verifies that the updated user data in the CustomerInfo and Credentials tables matches the
expected values, including the company name, state, and categories.
The second test case, test_edit_profile_error, simulates an error scenario where both
customer and credentials entries are missing (simulated by mocking their queries to return
None), and the db.session.commit() is set to raise an exception. The test ensures that the route
returns a 500 status code and an appropriate error message when the commit fails due to a
database error.
Result : -
Forecast Function : -
The forecast route handles the prediction of sales based on input data provided by the
user. It expects the following data in the request body: state, itemCategory (the main product
category), subCategory (the specific product name), months (the number of months for
forecasting), and prevSale (the sales from the previous period).
Upon receiving the request, it first prints the data to verify the input. The function then calls an
external sales_prediction function, passing the input parameters to generate a sales forecast. This
forecast result, predictedSale, is then returned in the response as a JSON object.
If an error occurs during the process (for instance, an issue with the prediction function or
missing input data), the route logs the error and returns a 500 status code with a failure message.
except Exception as e:
app.logger.error(f"Error in forecasting: {str(e)}")
return jsonify({'message': 'Failed to forecast'}), 500
def test_forecast_success(self):
data = {
'state': 'Assam',
'itemCategory': 'Electronics',
'subCategory': 'Laptops',
'months': 5,
'prevSale': 1000
}
response = self.client.post('/forecast', json=data)
self.assertEqual(response.status_code, 200)
data = {
'state': 'Bihar',
'itemCategory': 'Toys',
'subCategory': 'Dolls',
'months': 1,
'prevSale': 0
}
response = self.client.post('/forecast', json=data)
self.assertEqual(response.status_code, 200)
data = {
'state': 'Invalid_state',
'itemCategory': 'Electronics',
'subCategory': 'Laptops',
'months': 5,
'prevSale': 1000
}
response = self.client.post('/forecast', json=data)
self.assertEqual(response.status_code, 500)
sys.stdout = sys.__stdout__
devnull.close()
Result : -
InventoryOptimization Function : -
The inventoryOptimization function handles the inventory optimization logic by taking
input data via a POST or GET request. The input consists of a budget, months, state, and a list of
products with details such as category, subcategory, prevSale, cost, and profit. The function uses
the maxProfit function to calculate the maximum profit and determine the best products to select
based on the given budget, state, and timeframe. It returns the maximum profit along with the
quantity of the chosen products. In case of an error, the function logs the exception and responds
with a failure message.
max_profit,chosen_products =
maxProfit(int(budget),len(products),str(state),int(months),products)
quantity = []
for (item_index,qty) in chosen_products:
quantity.append(qty)
except Exception as e:
app.logger.error(f"Error in forecasting: {str(e)}")
return jsonify({'message': 'Failed to forecast'}), 500
data = {
'budget': 100000,
'months': 6,
'state': 'Assam',
'products': [
{"category": "Electronics", "subcategory": "Laptops",
"prevSale": 50000, "cost": 200, "profit": 300},
{"category": "Electronics", "subcategory": "Smartphones",
"prevSale": 70000, "cost": 150, "profit": 200},
{"category": "Furniture", "subcategory": "Chairs", "prevSale":
20000, "cost": 50, "profit": 100}
]
}
data = {
'budget': 500,
'months': 1,
'state': 'Assam',
'products': [
{"category": "Electronics", "subcategory": "Laptops",
"prevSale": 500, "cost": 200, "profit": 300},
{"category": "Electronics", "subcategory": "Smartphones",
"prevSale": 700, "cost": 150, "profit": 200},
{"category": "Furniture", "subcategory": "Chairs", "prevSale":
200, "cost": 50, "profit": 100}
]
}
data = {
'budget': 100000,
'months': 6,
'state': 'Invalid_state',
'products': [
{"category": "Electronics", "subcategory": "Laptops",
"prevSale": 500, "cost": 200, "profit": 300},
{"category": "Electronics", "subcategory": "Smartphones",
"prevSale": 700, "cost": 150, "profit": 200},
{"category": "Furniture", "subcategory": "Chairs", "prevSale":
200, "cost": 50, "profit": 100}
]
}
data = {
'budget': 100000,
'months': 10,
'state': 'Assam',
'products': [
{"category": "Electronics", "subcategory": "Laptops",
"prevSale": 500, "cost": 200, "profit": 300},
{"category": "Electronics", "subcategory": "Smartphones",
"prevSale": 700, "cost": 150, "profit": 200},
{"category": "Furniture", "subcategory": "Chairs", "prevSale":
200, "cost": 50, "profit": 100}
]
}
Result : -