File size: 5,454 Bytes
f4fbd3f
0fc8113
f4fbd3f
 
0fc8113
 
2bcbe6e
fc208c7
f4fbd3f
 
2bcbe6e
fc208c7
0fc8113
 
 
fc208c7
ae6caeb
f4fbd3f
 
 
ae6caeb
 
 
fc208c7
 
 
 
ae6caeb
 
 
 
 
 
 
 
fc208c7
ae6caeb
 
 
fc208c7
 
 
 
 
 
 
 
2bcbe6e
 
 
fc208c7
 
 
2bcbe6e
fc208c7
2bcbe6e
fc208c7
 
 
 
 
 
2bcbe6e
 
fc208c7
 
 
 
 
2bcbe6e
 
ae6caeb
fc208c7
 
 
 
 
 
 
2bcbe6e
fc208c7
f4fbd3f
 
 
fc208c7
 
 
f4fbd3f
 
 
 
2bcbe6e
f4fbd3f
 
 
fc208c7
2bcbe6e
f4fbd3f
 
0fc8113
 
f4fbd3f
0fc8113
f4fbd3f
ae6caeb
fc208c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0fc8113
f4fbd3f
0fc8113
ae6caeb
fc208c7
f4fbd3f
 
0fc8113
 
 
2bcbe6e
0fc8113
 
fc208c7
0fc8113
ae6caeb
 
 
f4fbd3f
ae6caeb
 
fc208c7
ae6caeb
fc208c7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import json
import requests
import os
import streamlit as st
import pandas as pd
import openpyxl
import faiss
import torch
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from sentence_transformers import SentenceTransformer
from transformers import AutoModelForCausalLM, AutoTokenizer

# βœ… Streamlit UI Setup
st.set_page_config(page_title="AI-Powered Timetable", layout="wide")
st.markdown("<h1 style='text-align: center; color: #4CAF50;'>πŸ“… AI-Powered Timetable</h1>", unsafe_allow_html=True)

# βœ… API Key Input
st.sidebar.markdown("## πŸ”‘ Enter Hugging Face API Key")
hf_api_key = st.sidebar.text_input("API Key", type="password")

# βœ… File Upload Section
st.sidebar.markdown("## πŸ“‚ Upload Your Timetable Files")
uploaded_master = st.sidebar.file_uploader("Upload Master Timetable", type=["xlsx"])
uploaded_lab = st.sidebar.file_uploader("Upload Lab Timetable", type=["xlsx"])
uploaded_classroom = st.sidebar.file_uploader("Upload Classroom Timetable", type=["xlsx"])
uploaded_individual = st.sidebar.file_uploader("Upload Individual Timetable", type=["xlsx"])

uploaded_files = {
    "Master Timetable": uploaded_master,
    "Lab Timetable": uploaded_lab,
    "Classroom Timetable": uploaded_classroom,
    "Individual Timetable": uploaded_individual,
}

# βœ… Load Timetable Data (Directly from Uploaded File)
def load_timetable(file):
    if not file:
        return None
    wb = openpyxl.load_workbook(file)
    sheet = wb.active
    return [row for row in sheet.iter_rows(values_only=True)]

# βœ… Initialize Sentence Transformer for Embeddings
embedder = SentenceTransformer("all-MiniLM-L6-v2")

# βœ… Process Uploaded Files and Create RAG Index
rag_data = {}
for name, file in uploaded_files.items():
    if file:
        timetable_data = load_timetable(file)
        if timetable_data:
            rag_data[name] = timetable_data

# βœ… Convert timetable data to text format
data_texts = ["\n".join(map(str, data)) for data in rag_data.values() if data]

if not data_texts:
    st.error("Error: No extracted timetable content available for AI processing.")
    st.stop()

# βœ… Generate FAISS Embeddings
data_embeddings = embedder.encode(data_texts, convert_to_tensor=True)

if len(data_embeddings) == 0:
    st.error("Error: No valid embeddings created. Check your timetable files.")
    st.stop()

dimension = data_embeddings.shape[1]  # FIXED ERROR: Ensuring valid shape
index = faiss.IndexFlatL2(dimension)
index.add(data_embeddings.cpu().numpy())

# βœ… Function to Retrieve Relevant Data from FAISS
def retrieve_relevant_text(query, top_k=2):
    query_embedding = embedder.encode([query], convert_to_tensor=True).cpu().numpy()
    distances, indices = index.search(query_embedding, top_k)
    
    retrieved_texts = [data_texts[idx] for idx in indices[0] if idx < len(data_texts)]
    return "\n".join(retrieved_texts)

# βœ… Ask LLaMA-3 AI via API
def ask_llama_api(query):
    if not hf_api_key:
        return "Error: Please enter your API key."

    retrieved_text = retrieve_relevant_text(query)
    context = f"Relevant timetable data:\n{retrieved_text}\n\nUser Query: {query}"

    url = "https://api-inference.huggingface.co/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {hf_api_key}",
        "Content-Type": "application/json"
    }
    payload = {
        "model": "meta-llama/Meta-Llama-3-8B",
        "messages": [{"role": "user", "content": context}],
        "max_tokens": 500
    }

    response = requests.post(url, headers=headers, json=payload)
    if response.status_code == 200:
        return response.json()["choices"][0]["message"]["content"]
    else:
        return f"API Error: {response.status_code} - {response.text}"

# βœ… Auto-Schedule Missing Slots
def auto_schedule(file):
    if not file:
        return "No timetable uploaded."

    wb = openpyxl.load_workbook(file)
    sheet = wb.active

    empty_slots = []
    for row_idx, row in enumerate(sheet.iter_rows(min_row=2, values_only=True), start=2):
        if None in row or "" in row:
            empty_slots.append(row_idx)

    for row_idx in empty_slots:
        query = f"Suggest a subject and faculty for the empty slot in row {row_idx}."
        suggestion = ask_llama_api(query)

        try:
            subject, faculty = suggestion.split(", Faculty: ")
            sheet.cell(row=row_idx, column=4, value=subject.strip())
            sheet.cell(row=row_idx, column=5, value=faculty.strip())
        except:
            continue  

    return f"Auto-scheduling completed for {len(empty_slots)} slots."

# βœ… AI Query Section
st.markdown("## πŸ€– Ask LLaMA-3 AI About Your Timetable")
user_query = st.text_input("Type your question here (e.g., 'Who is free at 10 AM on Monday?')")

if st.button("Ask AI via API"):
    ai_response = ask_llama_api(user_query)
    st.write("🧠 **LLaMA-3 AI Suggests:**", ai_response)

# βœ… Auto-Schedule Feature
st.markdown("## πŸ“… Auto-Schedule Missing Timetable Slots")
selected_file = st.selectbox("Choose a timetable file to auto-fill missing slots:", list(uploaded_files.keys()))

if st.button("Auto-Schedule"):
    result = auto_schedule(uploaded_files[selected_file])
    st.write("βœ…", result)

# βœ… Display Uploaded Timetables
st.markdown("## πŸ“œ View Uploaded Timetables")

for name, file in uploaded_files.items():
    if file:
        df = pd.read_excel(file)
        st.markdown(f"### {name}")
        st.dataframe(df)