Spaces:
Sleeping
Sleeping
File size: 10,894 Bytes
555d77a d4c83d2 555d77a 9d504d6 a2c958a 9d504d6 2217a1e 555d77a d4c83d2 555d77a 9d504d6 da578f7 9d504d6 ba65c08 c050106 555d77a d0dc9ad 65d1540 e637276 9d504d6 777cd06 555d77a c050106 da578f7 c6fab7c da578f7 777cd06 c6fab7c 07b37ec 2217a1e da578f7 75a27fc b0ff7a0 da578f7 c6fab7c da578f7 c6fab7c da578f7 c6fab7c da578f7 b0ff7a0 c6fab7c da578f7 75a27fc c6fab7c da578f7 c6fab7c da578f7 2217a1e 66d9c35 c6fab7c 2f09479 1535def 555d77a 1535def c6fab7c da578f7 d0dc9ad da578f7 1535def 9d504d6 da578f7 9d504d6 2217a1e 9d504d6 2217a1e 9d504d6 bd063e2 923245a c6fab7c 65d1540 da578f7 c6fab7c 2217a1e c6fab7c da578f7 c6fab7c 65d1540 923245a 1535def c6fab7c da578f7 65d1540 da578f7 bd063e2 65d1540 af2de81 bd063e2 65d1540 c6fab7c da578f7 c6fab7c da578f7 c6fab7c 66d9c35 3d267b0 65d1540 2217a1e 65d1540 2217a1e 65d1540 2217a1e 65d1540 2217a1e 65d1540 2217a1e |
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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
import streamlit as st
from openai import OpenAI
import os
import pandas as pd
import numpy as np
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import torch
import re
# Set up OpenAI client
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Check if GPU is available
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using device: {device}")
# Load metadata and embeddings (ensure these files are in your working directory or update paths)
metadata_path = 'question_metadata.csv' # Update this path if needed
embeddings_path = 'question_dataset_embeddings.npy' # Update this path if needed
metadata = pd.read_csv(metadata_path)
embeddings = np.load(embeddings_path)
# Load the SentenceTransformer model
model = SentenceTransformer("all-MiniLM-L6-v2").to(device)
# Load prompts from files
with open("technical_interviewer_prompt.txt", "r") as file:
technical_interviewer_prompt = file.read()
with open("question_generation_prompt.txt", "r") as file:
question_generation_prompt = file.read()
st.title("Mock Interview: Real-World Programming")
# Initialize session state variables
if "messages" not in st.session_state:
st.session_state.messages = []
if "follow_up_mode" not in st.session_state:
st.session_state.follow_up_mode = False # Tracks whether we're in follow-up mode
if "generated_question" not in st.session_state:
st.session_state.generated_question = None # Stores the generated question for persistence
if "code_template" not in st.session_state:
st.session_state.code_template = "" # Stores the code template
if "sample_test_case" not in st.session_state:
st.session_state.sample_test_case = "" # Stores the sample test case
if "expected_output" not in st.session_state:
st.session_state.expected_output = "" # Stores the expected output
if "debug_logs" not in st.session_state:
st.session_state.debug_logs = None # Stores debug logs for toggling
# Function to find the top 1 most similar question based on user input
def find_top_question(query):
# Generate embedding for the query
query_embedding = model.encode(query, convert_to_tensor=True, device=device).cpu().numpy()
# Reshape query_embedding to ensure it is a 2D array
query_embedding = query_embedding.reshape(1, -1) # Reshape to (1, n_features)
# Compute cosine similarity between query embedding and dataset embeddings
similarities = cosine_similarity(query_embedding, embeddings).flatten() # Flatten to get a 1D array of similarities
# Get the index of the most similar result (top 1)
top_index = similarities.argsort()[-1] # Index of highest similarity
# Retrieve metadata for the top result
top_result = metadata.iloc[top_index].copy()
top_result['similarity_score'] = similarities[top_index]
return top_result
# Function to generate response using OpenAI API with debugging logs
def generate_response(messages):
# For debug logs, store only the follow-up conversation history
st.session_state.debug_logs = st.session_state.messages # Update debug logs with current conversation
response = client.chat.completions.create(
model="o1-mini",
messages=messages,
)
return response.choices[0].message.content
# Function to extract code template and sample test case from the generated question
def extract_code_and_test_case(generated_question):
code_template = ""
sample_test_case = ""
expected_output = ""
# Extract code template
code_match = re.search(r'```python(.*?)```', generated_question, re.DOTALL)
if code_match:
code_template = code_match.group(1).strip()
else:
# Default code template if none is found
code_template = "# Write your code here\n"
# Extract sample test case and expected output
test_case_match = re.search(r'Sample Input:\s*(.*?)\n', generated_question, re.DOTALL)
expected_output_match = re.search(r'Expected Output:\s*(.*?)\n', generated_question, re.DOTALL)
if test_case_match and expected_output_match:
sample_test_case = test_case_match.group(1).strip()
expected_output = expected_output_match.group(1).strip()
else:
sample_test_case = ""
expected_output = ""
return code_template, sample_test_case, expected_output
# Move the input form to the sidebar to make it always visible and more compact
with st.sidebar.form(key="input_form"):
st.markdown("## Generate a New Question")
company = st.text_input("Company", value="Google") # Default value: Google
difficulty = st.selectbox("Difficulty", ["Easy", "Medium", "Hard"], index=1) # Default: Medium
topic = st.text_input("Topic", value="Binary Search") # Default: Binary Search
generate_button = st.form_submit_button(label="Generate")
if generate_button:
# Clear session state and start fresh with follow-up mode disabled
st.session_state.messages = []
st.session_state.follow_up_mode = False
# Create a query from user inputs and find the most relevant question
query = f"{company} {difficulty} {topic}"
top_question = find_top_question(query)
# Prepare a detailed prompt for GPT using the top question's details
detailed_prompt = (
f"Transform this LeetCode question into a real-world interview scenario.\n\n"
f"**Company**: {top_question['company']}\n"
f"**Question Name**: {top_question['questionName']}\n"
f"**Difficulty Level**: {top_question['difficulty level']}\n"
f"**Tags**: {top_question['Tags']}\n"
f"**Content**: {top_question['Content']}\n"
f"\nPlease create a real-world interview question based on this information. "
f"Include the following sections:\n\n"
f"- Problem Description\n"
f"- Code Template (in a Python code block)\n"
f"- Sample Input and Expected Output (clearly separated)\n"
)
# Generate response using OpenAI API with detailed prompt and debugging logs
response = generate_response([{"role": "user", "content": detailed_prompt}]) # Question generation prompt excluded here
# Store generated question in session state for persistence in sidebar and follow-up conversation state
st.session_state.generated_question = response
# Extract code template and sample test case
code_template, sample_test_case, expected_output = extract_code_and_test_case(response)
st.session_state.code_template = code_template
st.session_state.sample_test_case = sample_test_case
st.session_state.expected_output = expected_output
# Enable follow-up mode after generating the initial question
st.session_state.follow_up_mode = True
# Display chat messages from history on app rerun (for subsequent conversation)
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Chatbox for subsequent conversations with assistant (follow-up mode)
if st.session_state.follow_up_mode:
if user_input := st.chat_input("Continue your conversation or ask follow-up questions here:"):
# Display user message in chat message container and add to session history
with st.chat_message("user"):
st.markdown(user_input)
st.session_state.messages.append({"role": "user", "content": user_input})
# Prepare messages to send to the assistant
# Include the technical interviewer prompt and generated question, but do not display them
# Add an instruction for the assistant to reply as a real-world interviewer would
assistant_instruction = (
"As a real-world interviewer, please reply to the candidate's follow-up questions "
"specific to the generated interview question, to the point, and in a natural, human-sounding way."
)
messages_to_send = [
{"role": "user", "content": technical_interviewer_prompt},
{"role": "assistant", "content": st.session_state.generated_question},
{"role": "user", "content": assistant_instruction}
] + st.session_state.messages
assistant_response = generate_response(messages_to_send)
with st.chat_message("assistant"):
st.markdown(assistant_response)
st.session_state.messages.append({"role": "assistant", "content": assistant_response})
st.sidebar.markdown("---")
st.sidebar.markdown("## Generated Question")
if st.session_state.generated_question:
st.sidebar.markdown(st.session_state.generated_question)
else:
st.sidebar.markdown("_No question generated yet._")
st.sidebar.markdown("---")
st.sidebar.markdown("## Python Code Interpreter")
# Pre-fill code interpreter with code template after question generation
if st.session_state.code_template:
code_input = st.sidebar.text_area("Write your Python code here:", value=st.session_state.code_template, height=300)
else:
code_input = st.sidebar.text_area("Write your Python code here:", height=300)
if st.sidebar.button("Run Code"):
try:
# Prepare the code for execution
exec_globals = {}
# Create a function wrapper to execute the user's code
exec(f"def user_solution():\n{code_input}", exec_globals)
user_solution = exec_globals.get('user_solution', None)
# Prepare sample test case execution
if st.session_state.sample_test_case:
# Assume the sample test case is in the format of arguments to the function
test_case = st.session_state.sample_test_case
# Evaluate the test case safely
test_args = eval(test_case)
if not isinstance(test_args, tuple):
test_args = (test_args,)
# Capture the output
returned_output = user_solution(*test_args)
else:
returned_output = user_solution()
# Display the expected output and returned output
st.sidebar.markdown("### Sample Test Case Result:")
st.sidebar.markdown(f"**Sample Input:** {st.session_state.sample_test_case}")
st.sidebar.markdown(f"**Expected Output:** {st.session_state.expected_output}")
st.sidebar.markdown(f"**Your Output:** {returned_output}")
# Compare outputs
if str(returned_output) == st.session_state.expected_output:
st.sidebar.success("Your output matches the expected output!")
else:
st.sidebar.error("Your output does not match the expected output.")
except Exception as e:
st.sidebar.error(f"Error: {e}")
# Right sidebar toggleable debug logs and code interpreter section
with st.expander("Debug Logs (Toggle On/Off)", expanded=False):
if st.session_state.debug_logs:
st.write(st.session_state.debug_logs)
|