shubmrj commited on
Commit
d1fb0cc
·
verified ·
1 Parent(s): 23eb5dd

Upload 6 files

Browse files
Files changed (6) hide show
  1. FRONTEND.md +68 -0
  2. README.md +138 -3
  3. application.py +47 -0
  4. home.html +406 -0
  5. index.html +31 -0
  6. requirement.txt +4 -0
FRONTEND.md ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🏥 Frontend Architecture & UI/UX Documentation
2
+
3
+ This document outlines the design philosophy, technical implementation, and features of the **Flask-Native Frontend** for the Heart Attack Prediction application.
4
+
5
+ Unlike standard dashboards, this interface focuses on **clinical clarity**, **patient education**, and **responsive accessibility**.
6
+
7
+ ---
8
+
9
+ ## ⚡ Overview
10
+ This frontend is a server-side rendered (SSR) implementation using **Jinja2 templates**. It is designed to be lightweight, dependency-free (no Node.js/React required), and highly performant on mobile devices.
11
+
12
+ ## 🎨 Design System: "Modern Clinical Glassmorphism"
13
+ We moved away from generic Bootstrap templates to a custom design language.
14
+ * **Color Palette:** Trustworthy Medical Blue (`#2563eb`), Deep Navy (`#1e3a8a`), and Soft Slate (`#f8fafc`).
15
+ * **Visual Style:** Glass-morphism cards with backdrop filters, subtle gradients, and high-fidelity SVG animations.
16
+ * **Typography:** `Plus Jakarta Sans` for clean, modern readability.
17
+
18
+ ---
19
+
20
+ ## 🚀 Key Features
21
+
22
+ ### 1. The Intelligent Knowledge Hub 🧠
23
+ A dynamic side panel (on Desktop) or bottom-sheet (on Mobile) that acts as a real-time medical assistant.
24
+ * **Context Awareness:** As users click different fields (e.g., *Chest Pain*, *Slope*), the Hub updates instantly to explain what that medical term means.
25
+ * **Data Ranges:** Displays valid ranges (e.g., "Age: 29-77") based on the dataset.
26
+ * **Decision Support:** Provides "Healthy" vs "Risky" examples (e.g., *"0 Vessels = Blocked"* vs *"3 Vessels = Clear"*) to guide accurate data entry.
27
+
28
+ ### 2. Mobile-First Responsiveness 📱
29
+ The layout adapts aggressively to screen size:
30
+ * **Desktop:** Split-screen view. Form on the left, Knowledge Hub fixed on the right.
31
+ * **Mobile:** Single-column form. The Knowledge Hub transforms into a **Sticky Bottom Sheet**, ensuring users can read guidance *while* typing without losing context.
32
+
33
+ ### 3. Smart Risk Modals 🛡️
34
+ Instead of a simple text result, the app uses context-aware modals:
35
+ * **🔴 High Risk (Danger Mode):**
36
+ * Triggers immediate visual warnings.
37
+ * **Geolocation Integration:** Features a *"Locate Nearest Hospital"* button that uses the browser's GPS API to find cardiology centers via Google Maps.
38
+ * **Safety Fallback:** If location is denied, it presents a prioritized "To-Do List" (e.g., *Stop exertion, Sit down*).
39
+ * **🟢 Low Risk (Safe Mode):**
40
+ * Provides actionable lifestyle maintenance tips (Cardio, Diet, Hydration).
41
+
42
+ ### 4. Inclusive & Robust Inputs 🤝
43
+ * **Gender Inclusivity:** The legacy dataset (1988) strictly requires binary inputs (0/1). We added an *"Other/Non-Binary"* option that politely explains this constraint and guides the user to select the biological/hormonal match for mathematical accuracy.
44
+ * **Input Validation:** Prevents negative numbers and unrealistic values.
45
+
46
+ ---
47
+
48
+ ## 🛠️ Technical Stack
49
+
50
+ | Component | Technology |
51
+ | :--- | :--- |
52
+ | **Templating** | Jinja2 (Python/Flask) |
53
+ | **Styling** | CSS3 (Custom Properties / CSS Variables) |
54
+ | **Layout** | CSS Grid & Flexbox |
55
+ | **Interactivity** | Vanilla JavaScript (ES6+) |
56
+ | **Icons/Assets** | Inline SVGs (No external requests) |
57
+
58
+ ---
59
+
60
+ ## 📂 File Structure
61
+
62
+ ```text
63
+ /templates
64
+ ├── index.html # Landing Page (SVG ECG Animation)
65
+ └── home.html # Main App (Knowledge Hub + Modals)
66
+ /static
67
+ └── css
68
+ └── style.css # Single source of truth for all styles
README.md CHANGED
@@ -1,3 +1,138 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Heart Attack Prediction
2
+
3
+ ![Project Status](https://img.shields.io/badge/status-active-brightgreen) ![Python Version](https://img.shields.io/badge/python-3.x-blue) ![License](https://img.shields.io/badge/license-MIT-green)
4
+
5
+ ## Description
6
+ This project is a web-based application designed to predict the likelihood of a heart attack in patients based on various medical attributes. It utilizes a machine learning model to analyze the input data and provide a prediction, accessible through a user-friendly web interface.
7
+
8
+ ## Problem Statement
9
+ The primary objective of this project is to leverage machine learning to provide a quick and accessible way to assess the risk of a heart attack. By analyzing key medical indicators, the application can assist in early-stage risk assessment, complementing professional medical advice.
10
+
11
+ ## Getting Started
12
+ To get a local copy up and running, follow these simple steps.
13
+
14
+ ### Prerequisites
15
+ - Python 3.x
16
+ - pip (Python package installer)
17
+
18
+ ### Installation
19
+ 1. Clone the repo:
20
+ ```sh
21
+ git clone https://github.com/your_username/Heart-Attack-Prediction.git
22
+ ```
23
+ 2. Navigate to the project directory:
24
+ ```sh
25
+ cd Heart-Attack-Prediction
26
+ ```
27
+ 3. Install the required packages:
28
+ ```sh
29
+ pip install -r requirement.txt
30
+ ```
31
+
32
+ ### Running the Application
33
+ 1. Run the Flask application:
34
+ ```sh
35
+ python application.py
36
+ ```
37
+ 2. Open your web browser and go to `http://127.0.0.1:5000` to view the application.
38
+
39
+ ## Usage
40
+ The application provides a web form where you can input the patient's medical data. Fill in the fields and click the "Predict" button to get the heart attack risk prediction.
41
+
42
+ ## Dataset
43
+ The dataset used for training the model contains 76 attributes, but this project utilizes a subset of 14 key features for prediction. The "target" field indicates the presence of heart disease.
44
+
45
+ ### Attribute Information
46
+ - **age**: Age of the patient
47
+ - **sex**: Sex of the patient (1 = male; 0 = female)
48
+ - **cp**: Chest pain type (4 values)
49
+ - **trestbps**: Resting blood pressure (in mm Hg on admission to the hospital)
50
+ - **chol**: Serum cholestoral in mg/dl
51
+ - **fbs**: Fasting blood sugar > 120 mg/dl (1 = true; 0 = false)
52
+ - **restecg**: Resting electrocardiographic results (values 0, 1, 2)
53
+ - **thalach**: Maximum heart rate achieved
54
+ - **exang**: Exercise induced angina (1 = yes; 0 = no)
55
+ - **oldpeak**: ST depression induced by exercise relative to rest
56
+ - **slope**: The slope of the peak exercise ST segment
57
+ - **ca**: Number of major vessels (0-3) colored by flourosopy
58
+ - **thal**: 0 = normal; 1 = fixed defect; 2 = reversable defect
59
+ - **target**: 0 = less chance of heart attack; 1 = more chance of heart attack
60
+
61
+ ## Methodology
62
+ The model was developed following these steps:
63
+
64
+ 1. **Data Loading and Exploration**: The `heart.csv` dataset was loaded, and an initial exploration was performed to check for missing values and understand the data types.
65
+ 2. **Exploratory Data Analysis (EDA)**: Visualizations such as count plots, pie charts, pair plots, and a correlation heatmap were used to understand the distribution of data and the relationships between different attributes.
66
+ 3. **Data Preprocessing**: The dataset was split into training (70%) and testing (30%) sets. The features were then scaled using `StandardScaler` to ensure that all features contribute equally to the model's performance.
67
+ 4. **Model Training and Hyperparameter Tuning**: A Logistic Regression model was trained on the preprocessed data. `GridSearchCV` was used to find the optimal hyperparameters for the model, resulting in the best parameters being `{'C': 0.1, 'penalty': 'l2', 'solver': 'liblinear'}`.
68
+ 5. **Model Evaluation**: The model's performance was evaluated on the test set, achieving an accuracy of approximately 81.3%. The classification report and confusion matrix below provide a more detailed breakdown of the model's performance:
69
+
70
+ **Classification Report:**
71
+ ```
72
+ precision recall f1-score support
73
+
74
+ 0 0.78 0.80 0.79 40
75
+ 1 0.84 0.82 0.83 51
76
+
77
+ accuracy 0.81 91
78
+ macro avg 0.81 0.81 0.81 91
79
+ weighted avg 0.81 0.81 0.81 91
80
+ ```
81
+
82
+ **Confusion Matrix:**
83
+ ```
84
+ [[32 8]
85
+ [ 9 42]]
86
+ ```
87
+
88
+ ## Model
89
+ This project uses a **Logistic Regression** model. The trained `GridSearchCV` object, which includes the best estimator, is saved as `ridge.pkl` and is loaded by the Flask application to make predictions.
90
+
91
+ ## Visualization
92
+ Here is a scatter plot visualizing the relationship between age and maximum heart rate, colored by the target variable (heart attack risk).
93
+
94
+ ![Scatter Plot](Visualization%20Graph/Scatter%20Plot.png)
95
+
96
+ ### Additional Visualizations
97
+ In addition to the scatter plot, the `application.ipynb` notebook in the `Notebbook` directory contains several other visualizations that provide deeper insights into the dataset:
98
+
99
+ - **Target Class Distribution**: A bar chart showing the distribution of patients with and without a high chance of a heart attack.
100
+ - **Gender Distribution**: A pie chart illustrating the gender distribution within the dataset.
101
+ - **Correlation Heatmap**: A heatmap that displays the correlation between all the attributes in the dataset, helping to identify significant relationships.
102
+
103
+ These visualizations are crucial for understanding the data and the model's behavior. For a detailed view, please refer to the notebook.
104
+
105
+ ## Directory Structure
106
+ ```
107
+ .Heart-Attack-Prediction/
108
+ ├── Datasets/
109
+ │ └── heart.csv
110
+ ├── Models/
111
+ │ ├── ridge.pkl
112
+ │ └── scaler.pkl
113
+ ├── Notebbook/
114
+ │ └── ...
115
+ ├── templates/
116
+ │ ├── index.html
117
+ │ └── home.html
118
+ ├── Visualization Graph/
119
+ │ └── Scatter Plot.png
120
+ ├── application.py
121
+ ├── requirement.txt
122
+ └── README.md
123
+ ```
124
+
125
+ ## Dependencies
126
+ ![Flask](https://img.shields.io/badge/Flask-000000?style=for-the-badge&logo=flask&logoColor=white) ![NumPy](https://img.shields.io/badge/Numpy-777BB4?style=for-the-badge&logo=numpy&logoColor=white) ![Pandas](https://img.shields.io/badge/Pandas-2C2D72?style=for-the-badge&logo=pandas&logoColor=white) ![scikit-learn](https://img.shields.io/badge/scikit--learn-F7931E?style=for-the-badge&logo=scikit-learn&logoColor=white)
127
+
128
+ ## Contributing
129
+ Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
130
+
131
+ 1. Fork the Project
132
+ 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
133
+ 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
134
+ 4. Push to the Branch (`git push origin feature/AmazingFeature`)
135
+ 5. Open a Pull Request
136
+
137
+ ## License
138
+ Distributed under the MIT License. See `LICENSE` for more information.
application.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pickle
2
+ from flask import Flask,request,jsonify,render_template
3
+ import numpy as np
4
+ import pandas as pd
5
+ from sklearn.preprocessing import StandardScaler
6
+
7
+ application = Flask(__name__)
8
+ app=application
9
+
10
+ ## import gridsearchcv regressor and standard scaler pickle
11
+ grid_search_cv=pickle.load(open('Models/gridsearchcv.pkl','rb'))
12
+ standard_scaler=pickle.load(open('Models/scaler.pkl','rb'))
13
+
14
+ @app.route("/")
15
+ def index():
16
+ return render_template('index.html')
17
+
18
+ @app.route('/predictdata',methods=['GET','POST'])
19
+ def predict_datapoint():
20
+ if request.method=="POST":
21
+ Age=float(request.form.get('Age'))
22
+ sex = float(request.form.get('sex'))
23
+ cp = float(request.form.get('cp'))
24
+ trestbps = float(request.form.get('trestbps'))
25
+ chol = float(request.form.get('chol'))
26
+ fbs = float(request.form.get('fbs'))
27
+ restecg = float(request.form.get('restecg'))
28
+ thalach = float(request.form.get('thalach'))
29
+ exang = float(request.form.get('exang'))
30
+ oldpeak = float(request.form.get('oldpeak'))
31
+ slope = float(request.form.get('slope'))
32
+ ca = float(request.form.get('ca'))
33
+ thal = float(request.form.get('thal'))
34
+
35
+
36
+
37
+ new_data_scaled=standard_scaler.transform([[Age,sex,cp,trestbps,chol,fbs,restecg,thalach,exang,oldpeak,slope,ca,thal]])
38
+ result=grid_search_cv.predict(new_data_scaled)
39
+
40
+ return render_template('home.html',results=result[0])
41
+
42
+
43
+ else:
44
+ return render_template('home.html')
45
+
46
+ if __name__=="__main__":
47
+ app.run(host="0.0.0.0")
home.html ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Assessment Unit</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ </head>
9
+ <body>
10
+
11
+ <input type="hidden" id="risk_data" value="{{ results if results is defined else 'none' }}">
12
+
13
+ <div class="app-wrapper">
14
+
15
+ <div class="form-section">
16
+ <h2 class="section-title">Clinical Data Entry</h2>
17
+ <p class="section-subtitle">Select a field to view its clinical definitions, normal ranges, and risk benchmarks.</p>
18
+
19
+ <form action="{{ url_for('predict_datapoint')}}" method="post" autocomplete="off">
20
+ <div class="form-grid">
21
+
22
+ <div class="input-group">
23
+ <label>Age (Years)</label>
24
+ <input type="number" name="Age" min="1" max="110" required placeholder="e.g., 55" onfocus="showInfo('age')">
25
+ </div>
26
+
27
+ <div class="input-group">
28
+ <label>Sex</label>
29
+ <select name="sex" required onfocus="showInfo('sex')" onchange="checkGender(this)">
30
+ <option value="" disabled selected>Select...</option>
31
+ <option value="1">Male</option>
32
+ <option value="0">Female</option>
33
+ <option value="other">Other / Non-Binary</option>
34
+ </select>
35
+ </div>
36
+
37
+ <div class="input-group">
38
+ <label>Chest Pain Type</label>
39
+ <select name="cp" required onfocus="showInfo('cp')">
40
+ <option value="" disabled selected>Select Symptom...</option>
41
+ <option value="0">Type 0 (Typical Angina)</option>
42
+ <option value="1">Type 1 (Atypical Angina)</option>
43
+ <option value="2">Type 2 (Non-Anginal)</option>
44
+ <option value="3">Type 3 (Asymptomatic)</option>
45
+ </select>
46
+ </div>
47
+
48
+ <div class="input-group">
49
+ <label>Resting BP (mm Hg)</label>
50
+ <input type="number" name="trestbps" min="50" required placeholder="e.g. 120" onfocus="showInfo('bp')">
51
+ </div>
52
+
53
+ <div class="input-group">
54
+ <label>Cholesterol (mg/dl)</label>
55
+ <input type="number" name="chol" min="100" required placeholder="e.g. 200" onfocus="showInfo('chol')">
56
+ </div>
57
+
58
+ <div class="input-group">
59
+ <label>Fasting Blood Sugar</label>
60
+ <select name="fbs" required onfocus="showInfo('fbs')">
61
+ <option value="0">Normal (< 120)</option>
62
+ <option value="1">High (> 120)</option>
63
+ </select>
64
+ </div>
65
+
66
+ <div class="input-group">
67
+ <label>Resting ECG</label>
68
+ <select name="restecg" required onfocus="showInfo('ecg')">
69
+ <option value="0">Normal</option>
70
+ <option value="1">ST-T Abnormality</option>
71
+ <option value="2">Hypertrophy</option>
72
+ </select>
73
+ </div>
74
+
75
+ <div class="input-group">
76
+ <label>Max Heart Rate</label>
77
+ <input type="number" name="thalach" required placeholder="BPM" onfocus="showInfo('thalach')">
78
+ </div>
79
+
80
+ <div class="input-group">
81
+ <label>Exercise Induced Angina</label>
82
+ <select name="exang" required onfocus="showInfo('exang')">
83
+ <option value="0">No</option>
84
+ <option value="1">Yes</option>
85
+ </select>
86
+ </div>
87
+
88
+ <div class="input-group">
89
+ <label>ST Depression</label>
90
+ <input type="number" name="oldpeak" step="0.1" required placeholder="e.g. 1.0" onfocus="showInfo('oldpeak')">
91
+ </div>
92
+
93
+ <div class="input-group">
94
+ <label>ST Slope</label>
95
+ <select name="slope" required onfocus="showInfo('slope')">
96
+ <option value="0">Upsloping</option>
97
+ <option value="1">Flat</option>
98
+ <option value="2">Downsloping</option>
99
+ </select>
100
+ </div>
101
+
102
+ <div class="input-group">
103
+ <label>Major Vessels (0-3)</label>
104
+ <select name="ca" required onfocus="showInfo('ca')">
105
+ <option value="0">0 Vessels</option>
106
+ <option value="1">1 Vessel</option>
107
+ <option value="2">2 Vessels</option>
108
+ <option value="3">3 Vessels</option>
109
+ </select>
110
+ </div>
111
+
112
+ <div class="input-group" style="grid-column: span 2;">
113
+ <label>Thalassemia</label>
114
+ <select name="thal" required onfocus="showInfo('thal')">
115
+ <option value="0">Normal</option>
116
+ <option value="1">Fixed Defect</option>
117
+ <option value="2">Reversible Defect</option>
118
+ </select>
119
+ </div>
120
+
121
+ <button type="submit" class="btn-submit">Analyze Clinical Data</button>
122
+ </div>
123
+ </form>
124
+ </div>
125
+
126
+ <div class="hub-section">
127
+ <div id="hub-card" class="hub-card active">
128
+ <span class="hub-label">Assistant</span>
129
+ <h3 class="hub-title">Ready for Input</h3>
130
+ <p class="hub-desc">Click any field on the left. I will provide definitions, typical ranges, and good/bad examples to help you enter accurate data.</p>
131
+ </div>
132
+ </div>
133
+
134
+ </div>
135
+
136
+ <div id="dangerModal" class="modal-overlay">
137
+ <div class="modal-box">
138
+ <div class="modal-header danger">
139
+ <h3>High Risk Detected</h3>
140
+ </div>
141
+ <div class="modal-body">
142
+ <p>The model indicates a <strong>high probability</strong> of heart disease based on the provided clinical markers.</p>
143
+
144
+ <div id="danger-location-view">
145
+ <p style="margin-top:10px; font-size:0.9rem;"><strong>Recommended Action:</strong> Immediate Cardiologist Consultation.</p>
146
+ <button class="action-btn btn-danger" onclick="findHospitals()">Locate Nearest Hospital</button>
147
+ <button class="action-btn btn-secondary" onclick="showToDoList()">I cannot go right now / Cancel</button>
148
+ </div>
149
+
150
+ <div id="danger-todo-view" style="display:none;">
151
+ <strong>Immediate Safety Guidelines:</strong>
152
+ <ul class="suggestion-list">
153
+ <li>Cease all physical exertion immediately.</li>
154
+ <li>Sit in a semi-reclined position to ease breathing.</li>
155
+ <li>Loosen any tight clothing around the neck/chest.</li>
156
+ <li>If chest pain persists > 5 mins, call Emergency Services.</li>
157
+ </ul>
158
+ <button class="action-btn btn-secondary" onclick="closeModal('dangerModal')">Return to Form</button>
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </div>
163
+
164
+ <div id="safeModal" class="modal-overlay">
165
+ <div class="modal-box">
166
+ <div class="modal-header safe">
167
+ <h3>Low Risk Profile</h3>
168
+ </div>
169
+ <div class="modal-body">
170
+ <p>Great news. The clinical indicators suggest a <strong>healthy heart profile</strong>.</p>
171
+ <strong>Maintenance Recommendations:</strong>
172
+ <ul class="suggestion-list">
173
+ <li><strong>Activity:</strong> 30 mins moderate cardio (brisk walk), 5x/week.</li>
174
+ <li><strong>Diet:</strong> Limit sodium (under 2300mg) and saturated fats.</li>
175
+ <li><strong>Screening:</strong> Check BP and Cholesterol annually.</li>
176
+ </ul>
177
+ <button class="action-btn btn-safe" onclick="closeModal('safeModal')">Return to Assessment</button>
178
+ </div>
179
+ </div>
180
+ </div>
181
+
182
+ <script>
183
+ // 1. RICH KNOWLEDGE DATA
184
+ const infoData = {
185
+ age: {
186
+ title: "Age",
187
+ desc: "The dataset is trained on ages 29 to 77. Predictions for patients under 29 are possible but statistically less reliable (80/20 rule).",
188
+ range: "Dataset Range: 29 - 77 years",
189
+ good: ["Under 45 (Lower Risk)", "50 (Average)"],
190
+ bad: ["Over 65 (Higher Risk)"],
191
+ type: "numeric"
192
+ },
193
+ sex: {
194
+ title: "Biological Sex",
195
+ desc: "This model uses the 1988 dataset which strictly classifies as Male/Female. For non-binary patients, please select the biological sex assigned at birth to ensure the math works correctly.",
196
+ range: "Binary Input Required",
197
+ options: [
198
+ "1: Male (Biologically)",
199
+ "0: Female (Biologically)",
200
+ "Other: (See note above)"
201
+ ],
202
+ type: "category"
203
+ },
204
+ cp: {
205
+ title: "Chest Pain Type",
206
+ desc: "Which description fits best?",
207
+ range: "Select the closest match",
208
+ options: [
209
+ "Type 0 (Typical): Pain triggered by exercise, relieved by rest.",
210
+ "Type 1 (Atypical): Breathlessness/Fatigue (common in women).",
211
+ "Type 2 (Non-Anginal): Sharp stabbing (usually not heart).",
212
+ "Type 3 (Asymptomatic): Silent ischemia (Most Dangerous)."
213
+ ],
214
+ type: "category"
215
+ },
216
+ bp: {
217
+ title: "Resting BP",
218
+ desc: "Blood pressure level upon hospital admission.",
219
+ range: "Normal Range: 90 - 120 mm Hg",
220
+ good: ["115 (Optimal)", "120 (Normal)"],
221
+ bad: ["140 (Hypertension)", "160+ (Critical)"],
222
+ type: "numeric"
223
+ },
224
+ chol: {
225
+ title: "Cholesterol",
226
+ desc: "Total serum cholesterol level.",
227
+ range: "Ideal: Below 200 mg/dL",
228
+ good: ["180 (Healthy)", "195 (Acceptable)"],
229
+ bad: ["240 (High)", "300+ (Very High)"],
230
+ type: "numeric"
231
+ },
232
+ fbs: {
233
+ title: "Fasting Blood Sugar",
234
+ desc: "Is blood sugar > 120 mg/dl after fasting?",
235
+ range: "Binary Indicator for Diabetes Risk",
236
+ options: [
237
+ "0: No (Sugar is normal/low)",
238
+ "1: Yes (Sugar is high / Diabetic risk)"
239
+ ],
240
+ type: "category"
241
+ },
242
+ ecg: {
243
+ title: "Resting ECG",
244
+ desc: "Electrical activity of the heart at rest.",
245
+ range: "Select Result",
246
+ options: [
247
+ "0: Normal",
248
+ "1: ST Abnormality (Sign of Ischemia)",
249
+ "2: Hypertrophy (Thickened Heart Muscle)"
250
+ ],
251
+ type: "category"
252
+ },
253
+ thalach: {
254
+ title: "Max Heart Rate",
255
+ desc: "Highest rate achieved during stress exercise.",
256
+ range: "Target: Approx 220 minus Age",
257
+ good: ["160+ (Young/Fit)", "140 (Average)"],
258
+ bad: ["Under 100 (Inability to raise rate is risky)"],
259
+ type: "numeric"
260
+ },
261
+ exang: {
262
+ title: "Exercise Angina",
263
+ desc: "Example: Patient tries to run but gets chest pain and must stop walking immediately.",
264
+ range: "Binary Symptom",
265
+ options: [
266
+ "1: Yes (Pain stops you from moving)",
267
+ "0: No (No pain or random pain)"
268
+ ],
269
+ type: "category"
270
+ },
271
+ oldpeak: {
272
+ title: "ST Depression",
273
+ desc: "A dip in the ECG wave during exercise vs rest.",
274
+ range: "Normal: 0",
275
+ good: ["0.0 (Normal)", "0.5 (Minor)"],
276
+ bad: ["2.0 (Ischemia)", "4.0 (Severe Blockage)"],
277
+ type: "numeric"
278
+ },
279
+ slope: {
280
+ title: "ST Slope",
281
+ desc: "The angle of the ECG wave peak.",
282
+ range: "Diagnostic Feature",
283
+ options: [
284
+ "0: Upsloping (Healthy response)",
285
+ "1: Flat (Concerning)",
286
+ "2: Downsloping (High Risk Sign)"
287
+ ],
288
+ type: "category"
289
+ },
290
+ ca: {
291
+ title: "Major Vessels",
292
+ desc: "Number of vessels visible via Fluoroscopy dye. If a vessel lights up (colored), it is open. If it stays dark, it is blocked.",
293
+ range: "Traffic Light Logic (0 is Worst)",
294
+ options: [
295
+ "3: All vessels open (Best/Healthy)",
296
+ "2: Two vessels open",
297
+ "1: One vessel open",
298
+ "0: No vessels visible (Blocked/Risky)",
299
+ "Note: 0 is worst, 3 is best."
300
+ ],
301
+ type: "category"
302
+ },
303
+ thal: {
304
+ title: "Thalassemia",
305
+ desc: "Blood flow defect status.",
306
+ range: "Genetic/Flow Factor",
307
+ options: [
308
+ "0: Normal flow",
309
+ "1: Fixed Defect (Permanent damage)",
310
+ "2: Reversible Defect (Treatable)"
311
+ ],
312
+ type: "category"
313
+ }
314
+ };
315
+
316
+ // 2. DISPLAY LOGIC (SIDEBAR)
317
+ function showInfo(key) {
318
+ const data = infoData[key];
319
+ const card = document.getElementById('hub-card');
320
+
321
+ let contentHtml = "";
322
+
323
+ if (data.type === "numeric") {
324
+ contentHtml = `
325
+ <div class="hub-section-inner">
326
+ <p class="hub-range"><strong>${data.range}</strong></p>
327
+ <div class="example-grid">
328
+ <div class="ex-col good">
329
+ <strong>Healthy Examples:</strong>
330
+ <ul>${data.good.map(i => `<li>${i}</li>`).join('')}</ul>
331
+ </div>
332
+ <div class="ex-col bad">
333
+ <strong>Risk Indicators:</strong>
334
+ <ul>${data.bad.map(i => `<li>${i}</li>`).join('')}</ul>
335
+ </div>
336
+ </div>
337
+ </div>`;
338
+ } else {
339
+ contentHtml = `
340
+ <div class="hub-section-inner">
341
+ <p class="hub-range"><strong>${data.range}</strong></p>
342
+ <ul class="hub-list">
343
+ ${data.options.map(opt => `<li><span class="val-badge">></span> ${opt}</li>`).join('')}
344
+ </ul>
345
+ </div>`;
346
+ }
347
+
348
+ // Render
349
+ card.classList.remove('active');
350
+ setTimeout(() => {
351
+ card.innerHTML = `
352
+ <span class="hub-label">Knowledge Hub</span>
353
+ <h3 class="hub-title">${data.title}</h3>
354
+ <p class="hub-desc">${data.desc}</p>
355
+ ${contentHtml}
356
+ `;
357
+ card.classList.add('active');
358
+ }, 150);
359
+ }
360
+
361
+ // 3. GENDER EDGE CASE LOGIC
362
+ function checkGender(select) {
363
+ if (select.value === 'other') {
364
+ alert("Note on Model Constraints: Because the 1988 dataset is binary, please select the biological sex or hormonal profile that best fits the patient for this specific calculation.");
365
+ select.value = "";
366
+ }
367
+ }
368
+
369
+ // 4. MODAL LOGIC
370
+ const risk = document.getElementById('risk_data').value;
371
+
372
+ window.onload = function() {
373
+ if (risk === '1') document.getElementById('dangerModal').style.display = 'flex';
374
+ if (risk === '0') document.getElementById('safeModal').style.display = 'flex';
375
+ };
376
+
377
+ function closeModal(id) {
378
+ document.getElementById(id).style.display = 'none';
379
+ }
380
+
381
+ // 5. LOCATION / TODO LOGIC
382
+ function findHospitals() {
383
+ if (navigator.geolocation) {
384
+ navigator.geolocation.getCurrentPosition(
385
+ (pos) => {
386
+ const lat = pos.coords.latitude;
387
+ const lon = pos.coords.longitude;
388
+ window.open(`http://googleusercontent.com/maps.google.com/search?q=cardiology+hospital&center=${lat},${lon}`);
389
+ },
390
+ (err) => {
391
+ showToDoList();
392
+ }
393
+ );
394
+ } else {
395
+ showToDoList();
396
+ }
397
+ }
398
+
399
+ function showToDoList() {
400
+ document.getElementById('danger-location-view').style.display = 'none';
401
+ document.getElementById('danger-todo-view').style.display = 'block';
402
+ }
403
+ </script>
404
+
405
+ </body>
406
+ </html>
index.html ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Heart_Attack_Prediction</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ </head>
9
+ <body>
10
+
11
+ <div class="landing-container">
12
+
13
+ <svg class="pulse-graph" viewBox="0 0 600 150">
14
+ <path class="ecg-line" d="M0,75 L50,75 L60,40 L70,110 L80,20 L90,75 L150,75 L160,75 L170,50 L180,100 L190,75 L250,75 L260,30 L270,120 L280,10 L290,75 L600,75" />
15
+ </svg>
16
+
17
+ <h1 class="hero-title">Heart_Attack_Prediction</h1>
18
+
19
+ <div class="hero-desc">
20
+ <p>
21
+ <strong>CARDIOVASCULAR RISK ASSESSMENT</strong><br><br>
22
+ An open-source diagnostic tool leveraging <strong>Logistic Regression</strong> on the <strong>Cleveland Heart Disease Dataset</strong>.
23
+ We provide instant, clinically-relevant risk analysis to support early intervention strategies.
24
+ </p>
25
+ </div>
26
+
27
+ <a href="/predictdata" class="btn-start">Start Assessment</a>
28
+ </div>
29
+
30
+ </body>
31
+ </html>
requirement.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Flask
2
+ numpy
3
+ pandas
4
+ scikit-learn