SleepyTerr commited on
Commit
5fcfe1b
·
verified ·
1 Parent(s): 7818ebd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -209
app.py CHANGED
@@ -1,216 +1,135 @@
1
- import traceback
2
  import gradio as gr
3
- import pandas as pd
4
- import joblib
5
  import re
 
 
 
6
  from huggingface_hub import hf_hub_download
 
 
 
7
 
8
- # ---- CONFIG ----
9
- MODEL_REPO = "SleepyTerr/entrepreneurial_readiness"
10
- MODEL_FILENAME = "readiness_model.joblib"
11
-
12
- # ---- LOAD MODEL ----
13
- model = None
14
- model_load_error = None
15
- try:
16
- model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILENAME, repo_type="model")
17
- model = joblib.load(model_path)
18
- print("✅ Model loaded from:", model_path)
19
- except Exception as e:
20
- model_load_error = traceback.format_exc()
21
- print("⚠️ Model load error:\n", model_load_error)
22
-
23
- # ---- Parsing ----
24
- def parse_input_for_fields(text):
25
- text = text.lower()
26
- extracted = {}
27
-
28
- def grab(patterns, key, cast_float=True):
29
- if key in extracted:
30
- return
31
- for pat in patterns:
32
- m = re.search(pat, text)
33
- if m:
34
- try:
35
- extracted[key] = float(m.group(1)) if cast_float else m.group(1)
36
- except:
37
- extracted[key] = m.group(1)
38
- return
39
-
40
- # Age
41
- grab([
42
- r"\b(\d{1,2})\s*(?:yo|yrs?|years? old)\b",
43
- r"(?:i am|i'm)\s*(\d{1,2})\b",
44
- r"\bage\s*(\d{1,2})\b"
45
- ], "age")
46
-
47
- # Income
48
- grab([r"(?:income|earn|salary|make).{0,15}\$?(\d{3,6})"], "monthly_income")
49
-
50
- # Expenses
51
- grab([r"(?:expense|bill|spend).{0,15}\$?(\d{3,6})"], "monthly_expenses")
52
-
53
- # Entertainment
54
- grab([
55
- r"(?:entertainment|fun|leisure).{0,15}\$?(\d{2,5})",
56
- r"spend.{0,10}\$?(\d{2,5}).{0,10}(?:entertainment|fun|leisure)"
57
- ], "entertainment_spending")
58
-
59
- # Savings
60
- grab([r"(?:savings|saved).{0,15}\$?(\d{3,7})"], "savings_amount")
61
-
62
- # Assets
63
- grab([r"(?:asset|net worth|property).{0,15}\$?(\d{3,8})"], "assets")
64
-
65
- # Risk tolerance
66
- grab([r"(?:risk).{0,15}(\d{1,2})"], "risk_tolerance_1_10")
67
-
68
- # Sales skills
69
- grab([r"(?:sales|selling).{0,15}(\d{1,2})"], "sales_skills_1_5")
70
-
71
- # Dependents → support "no kids"/"none"
72
- if any(phrase in text for phrase in ["no kids", "none", "0 dependents"]):
73
- extracted["dependence_1_5"] = 0
74
- else:
75
- grab([r"(?:dependents?|kids|children).{0,15}(\d{1,2})"], "dependence_1_5")
76
-
77
- return extracted
78
-
79
- # ---- Compute numeric score ----
80
- def compute_readiness(row):
81
- score = 0
82
- score += row.get("risk_tolerance_1_10", 0) * 2
83
- score += row.get("sales_skills_1_5", 0) * 4
84
-
85
- disposable = row.get("monthly_income", 0) - row.get("monthly_expenses", 0)
86
- if disposable > 0:
87
- score += disposable / 200
88
- else:
89
- score += disposable / 500
90
-
91
- score += row.get("savings_amount", 0) / 2000
92
- score += row.get("assets", 0) / 20000
93
- score -= row.get("dependence_1_5", 0) * 3
94
-
95
- return min(max(score, 0), 100)
96
-
97
- # ---- Conversation state ----
98
- conversation_state = {"collected": {}}
99
-
100
- REQUIRED_FIELDS = [
101
- "age",
102
- "monthly_income",
103
- "monthly_expenses",
104
- "entertainment_spending",
105
- "savings_amount",
106
- "assets",
107
- "risk_tolerance_1_10",
108
- "sales_skills_1_5",
109
- "dependence_1_5"
110
- ]
111
-
112
- def chatbot(user_input, history):
113
  try:
114
- collected = conversation_state["collected"]
115
-
116
- # Parse free-text
117
- new_data = parse_input_for_fields(user_input)
118
- for k, v in new_data.items():
119
- if k not in collected:
120
- collected[k] = v
121
-
122
- # Check missing
123
- missing = [f for f in REQUIRED_FIELDS if f not in collected]
124
- if missing:
125
- field_map = {
126
- "age": "your age (just the number)",
127
- "monthly_income": "your monthly income ($, just numbers)",
128
- "monthly_expenses": "your monthly expenses ($)",
129
- "entertainment_spending": "your monthly entertainment spending ($)",
130
- "savings_amount": "your savings ($)",
131
- "assets": "your assets/net worth ($)",
132
- "risk_tolerance_1_10": "your risk tolerance (1–10)",
133
- "sales_skills_1_5": "your sales skills (1–5)",
134
- "dependence_1_5": "how many dependents you support (number or 'none')"
135
- }
136
- next_field = missing[0]
137
-
138
- # If user typed only a number in response
139
- if re.fullmatch(r"\d+", user_input.strip()):
140
- collected[next_field] = float(user_input.strip())
141
- missing = [f for f in REQUIRED_FIELDS if f not in collected]
142
- if not missing:
143
- # All done
144
- df = pd.DataFrame([collected])
145
- label = None
146
- try:
147
- if model:
148
- raw_pred = model.predict(df)
149
- label = raw_pred[0] if hasattr(raw_pred, "__len__") else raw_pred
150
- except Exception:
151
- label = None
152
-
153
- score = compute_readiness(collected)
154
- conversation_state["collected"] = {}
155
-
156
- response = f"📊 Your entrepreneurial readiness score is **{score:.1f}/100**."
157
- if label:
158
- response += f" The model also classified you as: **{label}**."
159
- return response
160
-
161
- return f"Hmm... I think I need a bit more info. Could you tell me {field_map[next_field]}?"
162
-
163
- # All info collected
164
- df = pd.DataFrame([collected])
165
- label = None
166
- try:
167
- if model:
168
- raw_pred = model.predict(df)
169
- label = raw_pred[0] if hasattr(raw_pred, "__len__") else raw_pred
170
- except Exception:
171
- label = None
172
-
173
- score = compute_readiness(collected)
174
- conversation_state["collected"] = {}
175
-
176
- response = f"📊 Your entrepreneurial readiness score is **{score:.1f}/100**."
177
- if label:
178
- response += f" The model also classified you as: **{label}**."
179
-
180
- return response
181
-
182
- except Exception:
183
- return "⚠️ Error in chatbot:\n" + traceback.format_exc()
184
-
185
- # ---- Gradio UI ----
186
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple", secondary_hue="purple")) as demo:
187
- gr.Markdown(
188
- """
189
- <h1 style='text-align:center; color:#D8B4FE;'>💬 Entrepreneurial Readiness Chatbot</h1>
190
- <p style='text-align:center; color:#E9D5FF; font-size:16px;'>
191
- 👋 Hello! I'm an <b>entrepreneurial readiness chatbot</b>.<br>
192
- Tell me a little about yourself (e.g., age, income, expenses, savings, etc.)<br>
193
- and I'll give you a readiness score between 0 and 100!
194
- </p>
195
- """,
196
- )
197
-
198
- chatbot_ui = gr.ChatInterface(
199
- fn=chatbot,
200
- chatbot=gr.Chatbot(
201
- height=450,
202
- bubble_full_width=False,
203
- show_copy_button=True,
204
- ),
205
- textbox=gr.Textbox(
206
- placeholder="Type your scenario here...",
207
- container=True,
208
- ),
209
- title="Entrepreneurial Readiness Chatbot",
210
- description="I’ll guide you step by step if I need more info."
211
- )
212
-
213
- if model_load_error:
214
- print("=== MODEL LOAD ERROR ===\n", model_load_error)
215
 
216
  demo.launch()
 
 
1
  import gradio as gr
 
 
2
  import re
3
+ import joblib
4
+ import csv
5
+ import os
6
  from huggingface_hub import hf_hub_download
7
+ from datasets import load_dataset, Dataset, concatenate_datasets
8
+ from huggingface_hub import HfApi, HfFolder
9
+ import pandas as pd
10
 
11
+ DATASET_REPO = "SleepyTerr/entrepreneurial_readiness_v2"
12
+
13
+ # Load model
14
+ model_repo_id = "SleepyTerr/entrepreneurial_readiness"
15
+ model_file = hf_hub_download(repo_id=model_repo_id, filename="readiness_model.joblib", repo_type="model")
16
+ model = joblib.load(model_file)
17
+
18
+ # Conversation state
19
+ expected_fields = ["age", "risk_tolerance", "sales_skills", "dependents",
20
+ "monthly_income", "monthly_expenses", "entertainment",
21
+ "savings", "assets"]
22
+
23
+ field_questions = {
24
+ "age": "How old are you?",
25
+ "risk_tolerance": "On a scale of 1-10, how much risk are you willing to take?",
26
+ "sales_skills": "On a scale of 1-10, how would you rate your sales skills?",
27
+ "dependents": "How many dependents do you take care of?",
28
+ "monthly_income": "What is your monthly income?",
29
+ "monthly_expenses": "What are your monthly expenses?",
30
+ "entertainment": "How much do you spend on entertainment each month?",
31
+ "savings": "How much do you currently have saved?",
32
+ "assets": "What is the total value of your assets?"
33
+ }
34
+
35
+ def parse_info(message):
36
+ """Extract possible numbers from free text"""
37
+ numbers = re.findall(r"\d+", message)
38
+ return [int(n) for n in numbers]
39
+
40
+ def generate_tips(user_data, score):
41
+ """Give personalized tips depending on weaknesses"""
42
+ tips = []
43
+ if user_data.get("monthly_expenses", 0) > user_data.get("monthly_income", 0) * 0.8:
44
+ tips.append("Try to lower your expenses so they don’t eat up most of your income.")
45
+ if user_data.get("savings", 0) < user_data.get("monthly_income", 0) * 2:
46
+ tips.append("Build an emergency fund with at least 2–3 months of income saved.")
47
+ if user_data.get("assets", 0) < user_data.get("monthly_income", 0) * 6:
48
+ tips.append("Work on building long-term assets to increase stability.")
49
+ if user_data.get("sales_skills", 0) < 5:
50
+ tips.append("Consider improving your sales or communication skills—they’re key for entrepreneurship.")
51
+ if user_data.get("risk_tolerance", 0) < 4:
52
+ tips.append("Think about whether you’re comfortable taking risks—entrepreneurship often involves uncertainty.")
53
+
54
+ if not tips:
55
+ tips.append("Great job! You’re on a strong path to entrepreneurship.")
56
+
57
+ return tips
58
+
59
+ def save_to_db(user_data, score):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  try:
61
+ # Convert to pandas row
62
+ row = {**user_data, "score": score}
63
+ df = pd.DataFrame([row])
64
+
65
+ # Load existing dataset
66
+ ds = load_dataset(DATASET_REPO, split="train")
67
+
68
+ # Convert new row into a Dataset
69
+ new_ds = Dataset.from_pandas(df)
70
+
71
+ # Concatenate
72
+ updated = concatenate_datasets([ds, new_ds])
73
+
74
+ # Push back to Hugging Face
75
+ updated.push_to_hub(DATASET_REPO, split="train")
76
+
77
+ print(" Response saved to Hugging Face dataset")
78
+ except Exception as e:
79
+ print("⚠️ Failed to save:", e)
80
+
81
+ def chatbot(message, history, user_data, current_field):
82
+ history = history or []
83
+ user_data = user_data or {}
84
+ current_field = current_field or expected_fields[0]
85
+
86
+ # If current field not filled, try to extract it
87
+ if current_field in expected_fields:
88
+ nums = parse_info(message)
89
+ if nums:
90
+ user_data[current_field] = nums[0]
91
+ # Move to next field
92
+ next_index = expected_fields.index(current_field) + 1
93
+ if next_index < len(expected_fields):
94
+ current_field = expected_fields[next_index]
95
+ history.append((message, field_questions[current_field]))
96
+ else:
97
+ # All info collected → make prediction
98
+ features = [user_data.get(f, 0) for f in expected_fields]
99
+ score = model.predict([features])[0]
100
+ tips = generate_tips(user_data, score)
101
+ tips_text = "\n- " + "\n- ".join(tips)
102
+
103
+ # Save to database (CSV here, but can be swapped)
104
+ save_to_db(user_data, score)
105
+
106
+ history.append((message, f"✅ Your entrepreneurial readiness score is **{score:.1f}/100**!\n\nHere are some tips to improve:\n{tips_text}"))
107
+ return history, user_data, None
108
+ else:
109
+ # Ask again in case of missing number
110
+ history.append((message, f"Please provide a number for {current_field}."))
111
+ else:
112
+ history.append((message, "Hmm... I need a bit more info. Can you clarify?"))
113
+
114
+ return history, user_data, current_field
115
+
116
+ with gr.Blocks(css="""
117
+ body {background-color: #1a002b;}
118
+ .chatbot {background-color: #2d0a45; border-radius: 12px; padding: 10px;}
119
+ .message.user {background-color: #5a2d82; color: white; border-radius: 8px; padding: 8px; margin: 5px;}
120
+ .message.bot {background-color: #3b0f58; color: #eee; border-radius: 8px; padding: 8px; margin: 5px;}
121
+ """) as demo:
122
+ gr.Markdown("<h1 style='color:white; text-align:center;'>💡 Entrepreneurial Readiness Chatbot</h1>")
123
+ gr.Markdown("<p style='color:#ddd; text-align:center;'>Hello! I'm an entrepreneurial readiness chatbot! 🧑‍💻<br>Tell me a little about yourself and I'll give you a score between 0 and 100!</p>")
124
+
125
+ chatbot_ui = gr.Chatbot(label="Chat", elem_classes="chatbot", height=400)
126
+ msg = gr.Textbox(placeholder="Type your scenario here...", label="Your Message")
127
+ state = gr.State({})
128
+ current_field = gr.State(expected_fields[0])
129
+
130
+ def respond(message, history, user_data, current_field):
131
+ return chatbot(message, history, user_data, current_field)
132
+
133
+ msg.submit(respond, [msg, chatbot_ui, state, current_field], [chatbot_ui, state, current_field])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
  demo.launch()