PBL Project Requirements
Total Points ___ / 4
Extra Points ___ / 1

Collections - Total ___ / 3, Grade __/1

  • Blog Python Model code and SQLite Database.
    • Show your unique collection/table in database, display rows and columns in the table of the SQLite database from VSCode using SQLite3 Editor.

    • Show your unique code that was created to initialize table and create test data from VSCode model.

Lists and Dictionaries - Total __/3, Grade __/1

  • Blog Python API code and use of List and Dictionaries.
    • Show a list as extracted from database as Python objects in VSCode using Debugger.
  • Show two distinct examples of dictionaries, show Keys/Values using debugger in VSCode.

On the left, you see variables related to a specific user instance, including details like dob (date of birth), id, name, password, and role. This part of the interface is displaying the current state of variables while the application is paused at a breakpoint during debugging.On the right, the user.py script contains code for a CRUD (Create, Read, Update, Delete) API endpoint. Specifically shown are the get(self) method under the UserAPI class which fetches and returns all users from the database as JSON, and the post(self) method in the _Security class which handles the creation of new users but seems to currently focus on handling requests for existing user authentication by checking provided user details like uid and password. If the provided details are incorrect, it returns an error message.

Same thing, but this is for the task.py, and the variables found during debugging is related to the tasks.

APIs and JSON - Total __/7, Grade __/1

  • Blog Python API code and use of Postman to request and respond with JSON.
    • Show Python API code definition for request and response using GET, POST, UPDATE methods in VSCode. Discuss algorithmic condition used to direct request to appropriate Python method based on request method.

POST:

This piece of code defines a method for handling POST requests in a Flask application. It fetches JSON data from the request, attempts to create a new task object with this data, and then saves it to the database within the application context. The inclusion of db.create_all() suggests an initialization process that might be better suited elsewhere in the application. Additionally, the placeholder for user_id signals an intention to link tasks to users, indicating a multi-user setup. Upon successful creation of the task, it reads and returns the newly created task data with an HTTP 201 status code, indicating that a new resource was created. In case of an exception, it catches it and prints out the error, which is helpful for debugging during development.

GET:

In this segment of the application, the get method defined within the TaskResource class retrieves all tasks from the database. It then reads each task’s details into a list and converts this list to JSON format, which is a standard way to respond with data in a RESTful API. The method returns the JSONified list of tasks, making it a straightforward endpoint for fetching all task data.

UPDATE:

In this part, the post method within the Update class is designed to update a user’s email. The JSON payload from the request is parsed to extract a user ID and an email address. If the user ID isn’t provided or the email doesn’t meet basic validation, it responds with an error and an HTTP 400 status code. When a valid user ID and email are supplied, it queries the database for the user and updates the email address. If the user is found and the email is successfully updated, it returns the user’s updated information in JSON format. In case of an error during the update, a JSON object with an error message and an HTTP 500 status code is returned, which suggests an unexpected condition was encountered.

  • Show algorithmic conditions used to validate data on a POST condition in VSCode.

  • Show URL request and Body requirements for GET, POST, and UPDATE methods in Postman.

GET:

POST:

UPDATE:

  • Show the JSON response for error for 400 when missing body on a POST request in Postman.

  • Show the JSON response for error for 404 when providing an unknown user ID to a UPDATE request in Postman.

Frontend - Total __/8, Grade __/1

  • Blog JavaScript API fetch code and formatting code to display JSON.
    • Show response of JSON objects from fetch of GET, POST, and UPDATE methods in Chrome inspect.

GET:

POST:

UPDATE:

  • Show a demo (GET) of obtaining an Array of JSON objects that are formatted into the browsers screen in the Chrome browser.

  • Describe fetch and method that obtained the Array of JSON objects in JavaScript code.

The JavaScript function getAllTasks is using the Fetch API to make a GET request to a specified URL (apiUrl). It sends the request with the header indicating that the content type expected is JSON, and it sets a CORS policy to allow any origin (Access-Control-Allow-Origin: ‘*’). Once the fetch promise resolves, it checks if the response was successful (response.ok). If not, it throws an error. For a successful response, it converts the response body to JSON format. This JSON is expected to be an array of task objects. After that, it logs the tasks to the console and also updates the inner HTML of an element with the ID ‘result’ on the webpage, displaying the formatted JSON data. If there’s an error at any stage, such as a network issue or a problem with the request, it catches the error and logs a failure message while also updating the ‘result’ element with a failure message. This function is set to be called when the document is fully loaded, ensuring that the task list is fetched and ready to be displayed as soon as the user can interact with the page.

  • Show code that performs iteration and formatting of data into HTML in JavaScript code.

Explanation:

  • I set up the code to handle task management efficiently. First, I implemented sorting functionality in the sortTasks function that organizes tasks based on priority. This makes it easier to see what needs to be tackled first. When a new task is added via the form, I stop the default submission with event.preventDefault(), and then check to make sure both the task name and description fields are filled out. For the task display, I create a new div element for each task, format the details into a string, and set it as the innerHTML of a child div. I also add a remove button with an event listener for task deletion. This task element is then appended to the DOM, making it visible on the page immediately. Additionally, I’ve got functions to handle API calls for fetching all tasks and updating existing tasks, updating the page content dynamically based on the API responses. This setup avoids page reloads and keeps the user interface snappy. Overall, the JavaScript I crafted manages the tasks dynamically and keeps the UI updates smooth and responsive.

    • Show a demo (POST or UPDATE) gathering and sending input and receiving a response that show update. Repeat this demo showing both success and failure in the Chrome browser.

This demonstrates a successful POST request which is intended to upload a task to the database. It returns the task object that was uploaded if it is successful

This demonstrates an unsuccessful POST request because when I leave some JSON inputs empty, the program does not allow a post request to be sent to the backend so there is no response from the backend.

  • Show and describe code that handles success. Describe how code shows success to the user in the Chrome Browser screen in JavaScript code.

The .then() method receives JSON data (data) from the API response after a successful POST request.

The success message and received data are logged to the browser’s console with console.log(“Task added:”, data);, helping to verify that the data was correctly received.

The message “Task added successfully!” is shown to the user on the web page by updating the innerHTML of an HTML element with the ID result.

The result element, likely a <div> or , displays this success message within your page’s HTML structure.

  • Show and describe code that handles failure. Describe how the code shows failure to the user in the Chrome Browser screen in JavaScript code.

Error Throwing: If the API response is not successful (!response.ok), an error is thrown with a message “Network response was not ok”.

Error Display: If any error occurs during the fetch operation or response handling, the catch block catches the error. It logs the error to the console and updates the HTML element with ID result to display “An error occurred. Please try again.” to the user in the Chrome browser. This informs the user that the request did not complete successfully.

Optional/Extra, ML Algorithm Analysis - Total __/5, Grade __/1

  • Machine Learning Algorithm Analysis
    • Show algorithms and preparation of data for analysis. This includes cleaning, encoding, and one-hot encoding.
import pandas as pd

df_cancer = pd.read_csv('breast_cancer.csv', encoding='cp1252', sep=',')

# Select specific columns to clean the data
df_final = df_cancer[['Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Normal Nucleoli', 'Mitoses']]

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression

# Assuming df_new is the DataFrame with the features for prediction
x = df_final

# Use the 'Class' column as the target variable and convert it to binary
def replace_score(score):
    return 1 if score == 4 else 0

y = df_cancer['Class'].apply(replace_score)

# Split into testing and training datasets
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# Train a logistic regression model
model = LogisticRegression(max_iter=1000)  # Increase max_iter if needed for convergence
model.fit(X_train, y_train)

# Test the model and report accuracy
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:', accuracy)
  • Show algorithms and preparation for predictions.
# Import necessary libraries
import pandas as pd  # Provides data structures and data analysis tools
import numpy as np   # Used for numerical computing

# Flask-RESTful is an extension for Flask that adds support for
# quickly building REST APIs. It is a lightweight abstraction that works with your existing ORM/libraries.
from flask_restful import Api, Resource  # Api handles the registration of the resources, Resource is what we create our endpoints from
from flask import Blueprint, request    # Blueprint is a way to organize a group of related views and other code, request is used to get data sent by the client
from joblib import load  # load is used to load a trained machine learning model from a file

# Load the ML model: replace 'cancer_model.joblib' with the path to your trained model file
model = load('./api/cancer_model.joblib')

# Initialize a Flask Blueprint. This is a way to organize your Flask app into components.
# Here, 'cancer_api' is the name of the Blueprint, and '/api/cancer' is the base URL path it will handle.
cancer_api = Blueprint('cancer_api', __name__, url_prefix='/api/cancer')
api = Api(cancer_api)  # Create an API object that will register the endpoints

# Define a class for the API endpoint. This will handle requests to predict cancer.
class cancerAPI:
    # Define a class for the prediction resource. It inherits from 'Resource' which means it can be used to handle HTTP requests.
    class _Predict(Resource):
        # Define the POST method which will be called when the API receives a POST request.
        def post(self):
            # Get JSON data sent from the frontend
            body = request.get_json()
            
            # Check if any data is received from the frontend
            if body is not None:
                # Convert the JSON data into a DataFrame which the model can understand
                data = pd.DataFrame([body])
                # Rename the columns of the DataFrame to match the model's expected input
                data = data.rename(columns={
                    "bareNuclei": "Bare Nuclei",
                    "epithelialCellSize": "Single Epithelial Cell Size",
                    "mitoses": "Mitoses",
                    "normalNucleoli": "Normal Nucleoli",
                    "clumpThickness": "Clump Thickness",
                    "cellSizeUniformity": "Uniformity of Cell Size",
                    "cellShapeUniformity": "Uniformity of Cell Shape"
                })

                # Use the model to predict the result based on the data provided and retrieve the first result from the array
                benign_proba, malignant_proba = model.predict_proba(data)[0]
                # Return the prediction score and HTTP status code 200 (OK)
                return {'benign': benign_proba, 'malignant': malignant_proba}, 200
            else:
                # If no data is provided, return a message and HTTP status code 400 (Bad Request)
                return {'message': 'No data provided'}, 400
    
    # Add the _Predict resource to the API endpoint at the URL '/predict'
    api.add_resource(_Predict, '/predict')

# Remember, to activate this API endpoint, you'll need to register the Blueprint with your Flask application object elsewhere in your code.