Map the below elements from MiraCosta course description using your CPT project.

  • This must be unique to your portion of the integrated project.
  • This is a pre-requisite prior to answering the college board questions that have been posted to AP Classroom.

Collections

Blog Python Model code and SQLite Database. From VSCode using SQLite3 Editor, show your unique collection/table in database, display rows and columns in the table of the SQLite database. From VSCode model, show your unique code that was created to initialize table and create test data.

from __init__ import app, db
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
import os
from sqlalchemy.orm import relationship
from sqlalchemy.exc import IntegrityError
import pandas as pd


class House(db.Model, UserMixin):
    __tablename__ = 'houses'

    id = db.Column(db.Integer, primary_key=True)
    address = db.Column(db.String(256), index=True)
    city = db.Column(db.String(64), index=True, nullable=True)
    state = db.Column(db.String(8), index=True, nullable=True)
    zip = db.Column(db.Integer, index=True, nullable=True)
    latitude = db.Column(db.Float, index=True, nullable=True)
    longitude = db.Column(db.Float, index=True, nullable=True)
    price = db.Column(db.Integer, index=True, nullable=True)
    bathrooms = db.Column(db.Float, index=True, nullable=True)
    bedrooms = db.Column(db.Integer, index=True, nullable=True)
    livingarea = db.Column(db.Integer, index=True, nullable=True)
    homeType = db.Column(db.String(64), index=True, nullable=True)
    priceEstimate = db.Column(db.Integer, index=True, nullable=True)
    rentEstimate = db.Column(db.Integer, index=True, nullable=True)
    imgSRC = db.Column(db.String, index=True, nullable=True)
    favorites = db.relationship('Favorite', backref='House', uselist=True, lazy='dynamic')

    def __init__(self, address, city, state, zip, latitude, longitude, price, bathrooms, bedrooms, livingarea, homeType, priceEstimate, rentEstimate, imgSRC):
        self.address = address
        self.city = city
        self.state = state
        self.zip = zip
        self.latitude = latitude
        self.longitude = longitude
        self.price = price
        self.bathrooms = bathrooms
        self.bedrooms = bedrooms
        self.livingarea = livingarea
        self.homeType = homeType
        self.priceEstimate = priceEstimate
        self.rentEstimate = rentEstimate
        self.imgSRC = imgSRC

    def all_details(self):
        return {
            'id': self.id,
            'address': self.address,
            'city': self.city,
            'state': self.state,
            'zip': self.zip,
            'latitude': self.latitude,
            'longitude': self.longitude,
            'price': self.price,
            'bathrooms': self.bathrooms,
            'bedrooms': self.bedrooms,
            'livingarea': self.livingarea,
            'homeType': self.homeType,
            'priceEstimate': self.priceEstimate,
            'rentEstimate': self.rentEstimate,
            'imgSRC': self.imgSRC
        }

    def few_details(self):
        return {
            'id': self.id,
            'address': self.address,
            'price': self.price,
            'livingarea': self.livingarea,
            'bathrooms': self.bathrooms,
            'bedrooms': self.bedrooms,
            'imgSRC': self.imgSRC
        }


class Favorite(db.Model):
    __tablename__ = 'favorites'
    id = db.Column(db.Integer, primary_key=True)
    account_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    house_id = db.Column(db.Integer, db.ForeignKey('houses.id'))

    def __init__(self, account_id, house_id):
        self.account_id = account_id
        self.house_id = house_id


def initHouses():
    with app.app_context():
        """Create database and tables"""
        db.create_all()
        house_count = db.session.query(House).count()
        if house_count > 0:
            return
        
        basedir = os.path.abspath(os.path.dirname(__file__))
        # Specify the file path
        file_path = basedir + "/../static/data/RealEstateData.csv"
        # Load the CSV file into a DataFrame
        df = pd.read_csv(file_path)

        for index, row in df.iterrows():
            try:
                house = House(
                    address=row['address'] if pd.notna(row['address']) else None,
                    city=row['city'] if pd.notna(row['city']) else None,
                    state=row['state'] if pd.notna(row['state']) else None,
                    zip=row['zipcode'] if pd.notna(row['zipcode']) else None,
                    latitude=row['latitude'] if pd.notna(row['latitude']) else None,
                    longitude=row['longitude'] if pd.notna(row['longitude']) else None,
                    price=row['price'] if pd.notna(row['price']) else None,
                    bathrooms=row['bathrooms'] if pd.notna(row['bathrooms']) else None,
                    bedrooms=row['bedrooms'] if pd.notna(row['bedrooms']) else None,
                    livingarea=row['livingArea'] if pd.notna(row['livingArea']) else None,
                    homeType=row['homeType'] if pd.notna(row['homeType']) else None,
                    priceEstimate=row['PriceEstimate'] if pd.notna(row['PriceEstimate']) else None,
                    rentEstimate=row['RentEstimate'] if pd.notna(row['RentEstimate']) else None,
                    imgSRC=row['imgSrc'] if pd.notna(row['imgSrc']) else None
                )
                db.session.add(house)
                db.session.commit()
            except IntegrityError:
                '''fails with bad or duplicate data'''
                db.session.remove()
                print(f"Records exist, duplicate house, or error: {house.name}")
            except Exception as e_inner:
                print(f"Error adding house at index {index}: {str(e_inner)}")

This code intializes the database for the houses and the database for favorites. The favorites database contains a foreignkey for user.id and houses.id
alt text This is the houses database

alt text This is the users database

alt text This is the favorites database

Lists and Dictionaries

Blog Python API code and use of List and Dictionaries.

class _getHouses(Resource):
        def get(self):
            houses = db.session.query(House).all()
            print("Hi")
            return jsonify([house.few_details() for house in houses])

This code returns all the houses in a JSON

In VSCode using Debugger, show a list as extracted from database as Python objects. alt text

This is the houses object in debugger.

In VSCode use Debugger and list, show two distinct example examples of dictionaries, show Keys/Values using debugger. alt text

This is the favorites object in debugger.

APIs and JSON

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

 class _getHouses(Resource):
        def get(self):
            houses = db.session.query(House).all()
            print("Hi")
            return jsonify([house.few_details() for house in houses])
        
    class _gethousedetails(Resource):
        def get(self):
            house = db.session.query(House).filter(House.id == int(request.args.get("id"))).first()
            return jsonify(house.all_details())
    
    def post(self): # Create method
            ''' Read data for json body '''
            body = request.get_json()
            
            ''' Avoid garbage in, error checking '''
            # validate name
            name = body.get('name')
            if name is None or len(name) < 2:
                return {'message': f'Name is missing, or is less than 2 characters'}, 400
            # validate uid
            uid = body.get('uid')
            if uid is None or len(uid) < 2:
                return {'message': f'User ID is missing, or is less than 2 characters'}, 400
            # look for password and dob
            password = body.get('password')
            dob = body.get('dob')

            ''' #1: Key code block, setup USER OBJECT '''
            uo = User(name=name, 
                      uid=uid)
            
            ''' Additional garbage error checking '''
            # set password if provided
            if password is not None:
                uo.set_password(password)
            # convert to date type
            if dob is not None:
                try:
                    uo.dob = datetime.strptime(dob, '%Y-%m-%d').date()
                except:
                    return {'message': f'Date of birth format error {dob}, must be mm-dd-yyyy'}, 400
            
            ''' #2: Key Code block to add user to database '''
            # create user in database
            user = uo.create()
            # success returns json of user
            if user:
                return jsonify(user.read())
            # failure returns error
            return {'message': f'Processed {name}, either a format error or User ID {uid} is duplicate'}, 400

The first api method returns all the houses in a JSON The second api method returns the details of a specific house in a JSON The third api method creates a new user in the database

In VSCode, show algorithmic conditions used to validate data on a POST condition. alt text

This code checks if name is missing, user id is missing, password is missing, and date of birth is missing. If any of these are missing, it returns an error message.

In Postman, show URL request and Body requirements for GET, POST, and UPDATE methods.

alt text

URL for GET method to get favorites for a specific user

alt text

URL and body for POST method to create a authenticate a user

In Postman, show the JSON response data for 200 success conditions on GET, POST, and UPDATE methods. alt text

This is the response for the GET method to get all the houses. It shows the JSON of all the houses.

alt text

This is the response for the POST method to authenticate a user. It shows the authentication success message.

In Postman, show the JSON response for error for 400 when missing body on a POST request. alt text

This is the response for the POST method to authenticate a user. It shows the error message for missing body.

In Postman, show the JSON response for error for 404 when providing an unknown user ID to a UPDATE request. alt text

This is the response for the UPDATE method to update a user. It shows the error message for unknown user ID.

Frontend

Blog JavaScript API fetch code and formatting code to display JSON. In Chrome inspect, show response of JSON objects from fetch of GET, POST, and UPDATE methods. alt text

This image shows the JSON response from the GET method to get all the houses. It shows a few rows of the table created for the JSON of the houses.

In JavaScript code, describe fetch and method that obtained the Array of JSON objects.

<script type="module">
    import { uri, options } from '/student/assets/js/api/config.js';

    // Function to get the JWT token from cookies
    function getJwtToken() {
        return document.cookie.split(';').find(cookie => cookie.trim().startsWith('jwt='));
    }

    // Function to redirect to the login page if the JWT token does not exist
    function redirectToLogin() {
        window.location.href = "/student/login"; // Adjust the login page URL as needed
    }

    // Check for the existence of the JWT token when the page loads
    window.addEventListener('load', function() {
        const jwtToken = getJwtToken();

        // If the JWT token does not exist, redirect to the login page
        if (!jwtToken) {
            redirectToLogin();
        }
    });

    // Your existing JavaScript code for fetching and rendering houses data
    document.addEventListener('DOMContentLoaded', () => {
        // Your existing JavaScript code for fetching and rendering houses data
    });

    document.addEventListener('DOMContentLoaded', () => {
        const houseCardsContainer = document.getElementById('house-cards');
        const searchBar = document.getElementById('search-bar');
        const placeholderImageUrl = 'https://www.avantistones.com/images/noImage.png';
        let housesData = [];

        // Define getHouseDetailsLink function
        function getHouseDetailsLink(houseId) {
            return `/houses/house_details?id=${houseId}`;
        }

        async function fetchData() {
            try {
                const url = uri + '/api/house/houses';
                const response = await fetch(url);
                const data = await response.json();
                housesData = data;
                renderHouses(housesData);
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        }

        function renderHouses(houses) {
            houseCardsContainer.innerHTML = '';
            houses.forEach(house => {
                const houseCard = document.createElement('div');
                houseCard.classList.add('col-lg-4', 'col-md-6', 'mb-4');
                houseCard.innerHTML = `
                    <div class="card">
                        <img src="${house.imgSRC || placeholderImageUrl}" class="card-img-top" alt="${house.address}">
                        <div class="card-body">
                            <h5 class="card-title">${house.address}</h5>
                            <h5 class="card-title">Price: $${house.price}</h5>
                            ${house.livingarea ? `<p class="card-text">${house.livingarea} sqft</p>` : ''}
                            ${house.bedrooms ? `<p class="card-text">Bedrooms: ${house.bedrooms}</p>` : ''}
                            ${house.bathrooms ? `<p class="card-text">Bathrooms: ${house.bathrooms}</p>` : ''}
                            ${house.id ? `<a href="${getHouseDetailsLink(house.id)}" class="btn btn-primary view-details-btn">View Details</a>` : ''}
                        </div>
                    </div>
                `;
                houseCardsContainer.appendChild(houseCard);
            });

            const detailsButtons = document.querySelectorAll('.view-details-btn');
            detailsButtons.forEach(btn => {
                btn.addEventListener('click', (e) => {
                    const houseId = e.target.getAttribute('data-house-id');
                    let baseUrl;
                    if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
                        baseUrl = "/houses/";
                    } else {
                        baseUrl = "https://real-estate-analyzation.github.io/RealEstateFrontend/houses/";
                    }
                    console.log(`${baseUrl}house_details?id=${houseId}`)
                    location.href = `${baseUrl}house_details?id=${houseId}`;
                });
            });
        }

        function filterHouses() {
            const searchTerm = searchBar.value.toLowerCase();
            const filteredHouses = housesData.filter(house => {
                const houseAddress = house.address.toLowerCase();
                return houseAddress.includes(searchTerm);
            });
            renderHouses(filteredHouses);
        }

        fetchData();
        searchBar.addEventListener('input', filterHouses);
    });
</script>

In this JavaScript code, the fetch function is used to get the data from the API. The data is then rendered into the browser screen using the renderHouses function. The renderHouses function creates a card for each house in the data and appends it to the houseCardsContainer. The card contains the address, price, living area, bedrooms, bathrooms, and a button to view details. The view details button redirects the user to the house details page.

In JavaScript code, show code that performs iteration and formatting of data into HTML.

function renderHouses(houses) {
            houseCardsContainer.innerHTML = '';
            houses.forEach(house => {
                const houseCard = document.createElement('div');
                houseCard.classList.add('col-lg-4', 'col-md-6', 'mb-4');
                houseCard.innerHTML = `
                    <div class="card">
                        <img src="${house.imgSRC || placeholderImageUrl}" class="card-img-top" alt="${house.address}">
                        <div class="card-body">
                            <h5 class="card-title">${house.address}</h5>
                            <h5 class="card-title">Price: $${house.price}</h5>
                            ${house.livingarea ? `<p class="card-text">${house.livingarea} sqft</p>` : ''}
                            ${house.bedrooms ? `<p class="card-text">Bedrooms: ${house.bedrooms}</p>` : ''}
                            ${house.bathrooms ? `<p class="card-text">Bathrooms: ${house.bathrooms}</p>` : ''}
                            ${house.id ? `<a href="${getHouseDetailsLink(house.id)}" class="btn btn-primary view-details-btn">View Details</a>` : ''}
                        </div>
                    </div>
                `;
                houseCardsContainer.appendChild(houseCard);
            });

In this JavaScript code, the renderHouses uses a forEach loop to iterate through the houses data and create a card for each house. The card contains the address, price, living area, bedrooms, bathrooms, and a button to view details. The card is then appended to the houseCardsContainer.

In JavaScript code, show and describe code that handles success. Describe how code shows success to the user in the Chrome Browser screen. alt text

In this Javacript code, the fetch function has a condition that checks if response is ok, and if not, gives an error. It also catches errors and outputs the errors in the console.

In JavaScript code, show and describe code that handles failure. Describe how the code shows failure to the user in the Chrome Browser screen. alt text

The code checks if the response is ok, and if not, gives an error. It also catches errors and outputs the errors in the console. The error is returned into console.

Optional/Extra, Algorithm Analysis

In the ML projects, there is a great deal of algorithm analysis. Think about preparing data and predictions. Show algorithms and preparation of data for analysis. This includes cleaning, encoding, and one-hot encoding.

from flask import Flask, request, jsonify
from flask import Blueprint
from flask_restful import Api, Resource
import seaborn as sns
import pandas as pd
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
import numpy as np
import pandas as pd
import os
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics


class RecEngine:
    
    regressor = None

    def __init__(self):
        self.buildModel()
        
    def buildModel(self):
        basedir = os.path.abspath(os.path.dirname(__file__))

        # Specify the file path
        file_path = basedir + "/../static/data/RealEstateData.csv"

        data = pd.read_csv(file_path)
        data = data.dropna()
        #print(data)

        self.regressor = LinearRegression()
        X = data.drop(['price', 'address', 'city', 'state', 'zipcode', 'latitude', 'longitude', 'homeType', 'imgSrc', 'PriceEstimate'], axis=1)
        Y = data['price']
        
        X_Train, X_Test, Y_Train, Y_Test = train_test_split(X, Y, test_size=0.2, random_state=0)
        self.regressor.fit(X_Train, Y_Train)

        Y_Prediction = self.regressor.predict(X_Test)

        df = pd.DataFrame({'Actual ': Y_Test, 'Predicted': Y_Prediction})
        # print(df)

        mae = metrics.mean_absolute_error(Y_Test, Y_Prediction)
        r2 = metrics.r2_score(Y_Test, Y_Prediction)
        
        # print("The model performance for testing set")
        # print("-------------------------------------")
        # print('MAE is {}'.format(mae))
        # print('R2 score is {}'.format(r2))

    def predictPrice(self, bathrooms, bedrooms, livingArea, RentEstimate):
        predicion = self.regressor.predict([[bathrooms, bedrooms, livingArea, RentEstimate]])
        return predicion[0]

This code initializes the model for the real estate data. It reads the data from the CSV file, drops any null values, and creates a linear regression model. It then trains the model and makes predictions on the test data. The mean absolute error and R2 score are calculated to evaluate the model’s performance. The predictPrice method takes the input features and returns the predicted price of the house. Cleaning is displayed in this code by dropping null values. Encoding is displayed in this code by dropping columns that are not needed for the model. One-hot encoding is not needed in this code because the data is already numerical.

from flask import Flask, request, jsonify
from flask import Blueprint
from flask_restful import Api, Resource
import seaborn as sns
import pandas as pd
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
import numpy as np
import pandas as pd
import os
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics


class SalaryRecEngine:
    
    regressor = None

    def __init__(self):
        self.buildModel()
        
    def buildModel(self):
        basedir = os.path.abspath(os.path.dirname(__file__))

        # Specify the file path
        file_path = basedir + "/../static/data/RealEstateData.csv"

        data = pd.read_csv(file_path)
        data = data.dropna()
        #print(data)

        self.regressor = LinearRegression()
        X = data.drop(['price', 'address', 'city', 'state', 'zipcode', 'latitude', 'longitude', 'homeType', 'imgSrc', 'PriceEstimate', 'bathrooms', 'bedrooms', 'livingArea', 'RentEstimate'], axis=1)
        Y = data['price']
        
        X_Train, X_Test, Y_Train, Y_Test = train_test_split(X, Y, test_size=0.2, random_state=0)
        self.regressor.fit(X_Train, Y_Train)

        Y_Prediction = self.regressor.predict(X_Test)

        df = pd.DataFrame({'Actual ': Y_Test, 'Predicted': Y_Prediction})
        # print(df)

        mae = metrics.mean_absolute_error(Y_Test, Y_Prediction)
        r2 = metrics.r2_score(Y_Test, Y_Prediction)
        
        # print("The model performance for testing set")
        # print("-------------------------------------")
        # print('MAE is {}'.format(mae))
        # print('R2 score is {}'.format(r2))

    def predictPrice(self, JobSalary):
        predicion = self.regressor.predict([[JobSalary]])
        return predicion[0]


# Instantiate the RecEngine class
rec_engine = SalaryRecEngine()
print(rec_engine.predictPrice(1800000))

Show algorithms and preparation for predictions.

self.regressor = LinearRegression()
        X = data.drop(['price', 'address', 'city', 'state', 'zipcode', 'latitude', 'longitude', 'homeType', 'imgSrc', 'PriceEstimate', 'bathrooms', 'bedrooms', 'livingArea', 'RentEstimate'], axis=1)
        Y = data['price']
        
        X_Train, X_Test, Y_Train, Y_Test = train_test_split(X, Y, test_size=0.2, random_state=0)
        self.regressor.fit(X_Train, Y_Train)

        Y_Prediction = self.regressor.predict(X_Test)

This code drops the columns that are not needed for the model and creates a linear regression model. It then trains the model and makes predictions on the test data.

Discuss concepts and understanding of Linear Regression algorithms.

Linear Regression algorithms are used to model the relationship between a dependent variable and one or more independent variables. The algorithm finds the best-fitting line that represents the relationship between the variables. The line is represented by the equation y = mx + b, where y is the dependent variable, x is the independent variable, m is the slope of the line, and b is the y-intercept. The algorithm minimizes the sum of the squared differences between the actual and predicted values to find the best-fitting line. The model can then be used to make predictions on new data.

Discuss concepts and understanding of Decision Tree analysis algorithms.

Decision Tree analysis algorithms are used to model the relationship between a dependent variable and one or more independent variables. The algorithm creates a tree-like structure of decisions based on the features of the data. The tree is built by splitting the data into subsets based on the values of the features. The algorithm selects the best feature to split the data at each node to maximize the information gain. The tree is built recursively until a stopping criterion is met. The model can then be used to make predictions on new data by traversing the tree based on the features of the data.