Spaces:
Sleeping
Sleeping
| import os | |
| import datetime | |
| import gradio as gr | |
| from sentence_transformers import SentenceTransformer | |
| import torch | |
| from groq import Groq | |
| financialText = "" | |
| file_names = [ | |
| "financial_literacy_text.txt", | |
| "financial_aid_text.txt" | |
| ] | |
| for path in file_names: | |
| with open(path, "r", encoding = "utf-8") as file: | |
| financialText += file.read() | |
| model = SentenceTransformer('all-MiniLM-L6-v2') | |
| def preprocessText(text): | |
| cleanedText = text.strip().split("\n") | |
| cleanedChunks = [] | |
| sectionLabels = [] | |
| currentLabel = "Knowledge Base" | |
| for chunk in cleanedText: | |
| chunk = chunk.strip() | |
| if not chunk: | |
| continue | |
| if chunk.startswith("===") and "SECTION:" in chunk: | |
| currentLabel = chunk.replace("===", "",).replace("SECTION:", "").strip() | |
| continue | |
| cleanedChunks.append(chunk) | |
| sectionLabels.append(currentLabel) | |
| return cleanedChunks, sectionLabels | |
| def createEmbeddings(textChunks): | |
| chunkEmbeddings = model.encode(textChunks, convert_to_tensor = True) | |
| return chunkEmbeddings | |
| def getTopChunks(query, chunkEmbeddings, textChunks, sectionLabels): | |
| queryEmbedding = model.encode(query, convert_to_tensor = True) | |
| queryEmbeddingNormalized = queryEmbedding / queryEmbedding.norm() | |
| chunkEmbeddingsNormalized = chunkEmbeddings / chunkEmbeddings.norm(dim = 1, keepdim = True) | |
| similarities = torch.matmul(chunkEmbeddingsNormalized, queryEmbeddingNormalized) | |
| topIndices = torch.topk(similarities, k=3).indices | |
| topChunks = [textChunks[i] for i in topIndices] | |
| topSections = [sectionLabels[i] for i in topIndices] | |
| return topChunks, topSections | |
| cleanedChunks, sectionLabels = preprocessText(financialText) | |
| chunkEmbeddings = createEmbeddings(cleanedChunks) | |
| client = Groq(api_key = os.environ.get("SF_TOKEN")) | |
| def respond(message, history): | |
| messages = [{"role": "system", | |
| "content": "You are a friendly, approachable AI assistant whose main goal is to help high school and college students to learn more about productivity, setting goals for their education, and financial literacy." | |
| "Keep responses between 200-300 words unless asked for more detail about your suggestions from the user." | |
| "Explanations should be clear with examples and always include actionable steps, following this format:" | |
| "User: What is the 50/30/20 rule when it comes to budgeting?" | |
| "AI: Great question! The 50/30/20 rule states that you should spend 50% of your income on needs, 30% of your income on wants, and 20% of your income on investing. For example, if you make $4,000 each month, you should spend $2,000 on your needs, $1,200 on your wants, and $800 on investing. That way, you can set aside money to take care of yourself while still making progress towards saving up for the things that aren't as essential."}] | |
| if history: | |
| messages.extend([{"role": h["role"], "content": h["content"]} for h in history]) | |
| # helping grok to retain message history | |
| topResults, topSections = getTopChunks(message, chunkEmbeddings, cleanedChunks, sectionLabels) | |
| context = "\n\n".join(topResults) | |
| messages.append({"role": "system", | |
| "content": context}) | |
| messages.append({"role": "user", | |
| "content": message}) | |
| response = "" | |
| responseStream = client.chat.completions.create( | |
| model = "llama-3.1-8b-instant", messages = messages, stream = True, max_tokens = 600, temperature = 0.4 | |
| ) | |
| for segment in responseStream: | |
| token = segment.choices[0].delta.content | |
| if token is not None: | |
| response += token | |
| yield response | |
| usedSections = list(dict.fromkeys(topSections)) | |
| citation = f"\n\n *📋 Sources: {usedSections}*" | |
| yield response + citation | |
| custom_css = """ | |
| body { | |
| background-color: #52528C !important; | |
| } | |
| .gradio-container { | |
| background-color: #52528C !important; | |
| } | |
| """ | |
| def budgetCalculator(income): | |
| if income is None or income <= 0: | |
| return "Please enter a monthly income value that is greater than 0." | |
| needs = income * 0.5 | |
| wants = income * 0.3 | |
| savings = income * 0.2 | |
| return ( | |
| f"### Your 50/30/20 Budget Breakdown:\n\n" | |
| f"- **Needs (50%):** ${needs:,.2f}\n" | |
| f"- **Wants (30%):** ${wants:,.2f}\n" | |
| f"- **Savings (20%):** ${savings:,.2f}\n\n" | |
| f"Based on a monthly income of ${income:,.2f}." | |
| ) | |
| def goalTracker(goal, savings, targetDate): | |
| if goal is None or savings is None or not targetDate: | |
| return "Please fill in the tracker to get started!" | |
| if goal <= 0: | |
| return "Set your goal for higher than 0!" | |
| if savings < 0: | |
| return "Savings can't be negative; start at 0 if needed!" | |
| try: | |
| target = datetime.datetime.strptime(targetDate, "%Y-%m-%d").date() | |
| except ValueError: | |
| return "Please enter the date in YYYY-MM-DD format! (ex: 2026-06-12)" | |
| today = datetime.date.today() | |
| daysLeft = (target - today).days | |
| if daysLeft <= 0: | |
| return "Try to set your goal for sometime in the future!" | |
| remaining = goal - savings | |
| if remaining <= 0: | |
| return "Congratulations on hitting your goal!" | |
| weeklyAmount = remaining / (daysLeft / 7) | |
| monthlyAmount = remaining / (daysLeft / 30.44) | |
| if daysLeft >= 28: | |
| return ( | |
| f"### Goal Tracker Results\n\n" | |
| f"- **Amount Remaining:** ${remaining:,.2f}\n" | |
| f"- **Days Remaining:** {daysLeft}\n" | |
| f"- **Save this much per week:** ${weeklyAmount:,.2f}\n" | |
| f"- **Save this much per month:** ${monthlyAmount:,.2f}\n" | |
| ) | |
| elif daysLeft >= 7: | |
| return ( | |
| f"### Goal Tracker Results\n\n" | |
| f"- **Amount Remaining:** ${remaining:,.2f}\n" | |
| f"- **Days Remaining:** {daysLeft}\n" | |
| f"- **Save this much per week:** ${weeklyAmount:,.2f}\n" | |
| ) | |
| with gr.Blocks(css=custom_css) as demo: | |
| gr.Image("banner_image.png", show_label=False, container=False) | |
| gr.HTML( | |
| """ | |
| <iframe | |
| style="border-radius:12px" | |
| src="https://open.spotify.com/embed/playlist/3WimQBublpHoOkok4Vu4Dj" | |
| width="100%" | |
| height="352" | |
| frameBorder="0" | |
| allowfullscreen="" | |
| allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" | |
| loading="lazy"> | |
| </iframe> | |
| """ | |
| ) | |
| with gr.Tabs(): | |
| with gr.Tab("Chatbot"): | |
| gr.ChatInterface( | |
| respond, | |
| title="Student Formula Bot 🔬", | |
| description='Welcome to the core component of \"The Student Formula\": the RAG chatbot! With the ability to act as a finance tutor, accountability buddy, and goal-setting partner all in one, it\'s designed to best suit your needs on the way to productivity and success. To get started, ask the chatbot a question or click on one of the examples!', | |
| examples=[ | |
| "How do I build and balance a budget?", | |
| "Why do people write SMART goals?", | |
| "What is educational investment?" | |
| ] | |
| ) | |
| with gr.Tab("Budget Calculator"): | |
| gr.Markdown("# 50/30/20 Budget Calculator 📑") | |
| gr.Markdown("Want to see what your monthly budget might look like when following financial literacy principles? Enter your monthly income to see the suggested breakdown!") | |
| incomeInput = gr.Number(label = "Monthly Income ($)", minimum = 0) | |
| budgetOutput = gr.Markdown(label = "Monthly Budget") | |
| budgetButton = gr.Button("Calculate") | |
| budgetButton.click(fn = budgetCalculator, inputs = incomeInput, outputs = budgetOutput) | |
| with gr.Tab("Goal Tracker"): | |
| gr.Markdown("# Savings Goal Tracker 🪙") | |
| gr.Markdown("Saving up to buy something special? Want to figure out how long it'll take to reach that goal? Enter your goal amount, current savings, and target date to see the suggested timeline!") | |
| goalInput = gr.Number(label = "Savings Goal ($)", minimum = 0) | |
| savingsInput = gr.Number(label = "Current Savings ($)", minimum = 0) | |
| targetInput = gr.Textbox(label = "Target Date (YYYY-MM-DD)", placeholder = "2026-12-31") | |
| goalOutput = gr.Markdown(label = "Your Savings Plan") | |
| goalButton = gr.Button("Calculate") | |
| goalButton.click(fn = goalTracker, inputs = [goalInput, savingsInput, targetInput], outputs = goalOutput) | |
| demo.launch() |