Commit
·
1d01073
0
Parent(s):
Add coding questions, answers, and execution functionality with Streamlit interface
Browse files- .gitignore +7 -0
- README.md +22 -0
- app.py +6 -0
- data/questions/0/answer.txt +1 -0
- data/questions/0/code.py +10 -0
- data/questions/0/metadata.json +9 -0
- data/questions/0/question.txt +1 -0
- data/questions/1/answer.txt +1 -0
- data/questions/1/code.py +14 -0
- data/questions/1/metadata.json +9 -0
- data/questions/1/question.txt +1 -0
- output.jsonl +2 -0
- pages/1_All_Questions.py +21 -0
- pages/2_Execute_codes.py +50 -0
- pages/3_Add_Questions.py +73 -0
- pages/4_Edit_Questions.py +91 -0
- pages/5_Delete_Question.py +74 -0
- utils/code_services.py +23 -0
- utils/data_to_jsonl.py +47 -0
- utils/jsonl_to_data.py +26 -0
- utils/load_jsonl.py +13 -0
.gitignore
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Ignore Python cache files
|
2 |
+
__pycache__/
|
3 |
+
*.pyc
|
4 |
+
*.pyo
|
5 |
+
|
6 |
+
# Ignore CSV's present in raw_data folder
|
7 |
+
*/raw_data
|
README.md
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# VayuBuddy Question Curation
|
2 |
+
|
3 |
+
## What is VayuBuddy
|
4 |
+
|
5 |
+
## About this repo
|
6 |
+
|
7 |
+
### Folder Structure
|
8 |
+
|
9 |
+
```
|
10 |
+
VAYUBUDDY QUESTION AND ANSWER/
|
11 |
+
│── app.py # Main file (Homepage)
|
12 |
+
│── pages/ # Folder containing additional pages
|
13 |
+
│ ├── questions.py # First page
|
14 |
+
│ ├── execute.py # Second page
|
15 |
+
│── utils/ # Folder containing functions needed while adding and editing questions
|
16 |
+
│ ├── questions.py # First page
|
17 |
+
│ ├── execute.py # Second page
|
18 |
+
│── output.jsonl # Your data file
|
19 |
+
```
|
20 |
+
|
21 |
+
|
22 |
+
## How to use this repo
|
app.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
st.set_page_config(page_title="Coding Questions App", layout="wide")
|
4 |
+
st.title("Welcome to the Coding Questions App!")
|
5 |
+
|
6 |
+
st.write("Use the sidebar to navigate between pages.")
|
data/questions/0/answer.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Delhi
|
data/questions/0/code.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def true_code():
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
df = pd.read_csv('data/raw_data/Data.csv', sep=",")
|
5 |
+
|
6 |
+
data = df.groupby(['state','station'])['PM2.5'].mean()
|
7 |
+
ans = data.idxmax()[0]
|
8 |
+
print(ans)
|
9 |
+
|
10 |
+
true_code()
|
data/questions/0/metadata.json
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"question_id": 0,
|
3 |
+
"category": "spatial",
|
4 |
+
"answer_category": "single",
|
5 |
+
"plot": false,
|
6 |
+
"libraries": [
|
7 |
+
"pandas"
|
8 |
+
]
|
9 |
+
}
|
data/questions/0/question.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Which state has the highest average PM2.5 concentration across all stations?
|
data/questions/1/answer.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Lal Bahadur Shastri Nagar, Kalaburagi
|
data/questions/1/code.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def true_code():
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
df = pd.read_csv('data/raw_data/Data.csv', sep=",")
|
5 |
+
|
6 |
+
df['Timestamp'] = pd.to_datetime(df['Timestamp'])
|
7 |
+
|
8 |
+
df['Year'] = df['Timestamp'].dt.year
|
9 |
+
df['Month'] = df['Timestamp'].dt.month
|
10 |
+
data = df[(df['Year'] == 2020) & (df['Month'] == 8)]
|
11 |
+
ans = data.groupby('station')['PM2.5'].max().idxmax()
|
12 |
+
print(ans)
|
13 |
+
|
14 |
+
true_code()
|
data/questions/1/metadata.json
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"question_id": 2,
|
3 |
+
"category": "temporal",
|
4 |
+
"answer_category": "double",
|
5 |
+
"plot": false,
|
6 |
+
"libraries": [
|
7 |
+
"pandas"
|
8 |
+
]
|
9 |
+
}
|
data/questions/1/question.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Report the station that recorded the highest value of PM 2.5 for the month Aug of 2020
|
output.jsonl
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
{"folder": "0", "question": "Which state has the highest average PM2.5 concentration across all stations?", "answer": "Delhi", "code": "def true_code():\n import pandas as pd\n \n df = pd.read_csv('data/raw_data/Data.csv', sep=\",\")\n \n data = df.groupby(['state','station'])['PM2.5'].mean()\n ans = data.idxmax()[0]\n print(ans)\n\ntrue_code()", "metadata": {"question_id": 0, "category": "spatial", "answer_category": "single", "plot": false, "libraries": ["pandas"]}}
|
2 |
+
{"folder": "1", "question": "Report the station that recorded the highest value of PM 2.5 for the month Aug of 2020", "answer": "Lal Bahadur Shastri Nagar, Kalaburagi ", "code": "def true_code():\n import pandas as pd\n \n df = pd.read_csv('data/raw_data/Data.csv', sep=\",\")\n \n df['Timestamp'] = pd.to_datetime(df['Timestamp'])\n \n df['Year'] = df['Timestamp'].dt.year\n df['Month'] = df['Timestamp'].dt.month\n data = df[(df['Year'] == 2020) & (df['Month'] == 8)]\n ans = data.groupby('station')['PM2.5'].max().idxmax()\n print(ans)\n\ntrue_code()", "metadata": {"question_id": 2, "category": "temporal", "answer_category": "double", "plot": false, "libraries": ["pandas"]}}
|
pages/1_All_Questions.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from utils.load_jsonl import load_data
|
3 |
+
|
4 |
+
# Load Data
|
5 |
+
data_file = "output.jsonl"
|
6 |
+
data = load_data(data_file)
|
7 |
+
|
8 |
+
# Create category-wise dictionary
|
9 |
+
category_dict = {}
|
10 |
+
for entry in data:
|
11 |
+
category = entry["metadata"].get("category", "Uncategorized")
|
12 |
+
if category not in category_dict:
|
13 |
+
category_dict[category] = []
|
14 |
+
category_dict[category].append(entry)
|
15 |
+
|
16 |
+
st.title("Questions by Category")
|
17 |
+
|
18 |
+
for category, questions in category_dict.items():
|
19 |
+
st.subheader(category)
|
20 |
+
for q in questions:
|
21 |
+
st.write(f"🔹 {q['question']}")
|
pages/2_Execute_codes.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import subprocess
|
2 |
+
import streamlit as st
|
3 |
+
from utils.load_jsonl import load_data
|
4 |
+
|
5 |
+
# Load Data
|
6 |
+
data_file = "output.jsonl"
|
7 |
+
data = load_data(data_file)
|
8 |
+
|
9 |
+
# Create category-wise dictionary
|
10 |
+
category_dict = {}
|
11 |
+
for entry in data:
|
12 |
+
category = entry["metadata"].get("category", "Uncategorized")
|
13 |
+
if category not in category_dict:
|
14 |
+
category_dict[category] = []
|
15 |
+
category_dict[category].append(entry)
|
16 |
+
|
17 |
+
st.title("Code Execution")
|
18 |
+
|
19 |
+
# Select Category
|
20 |
+
category_selected = st.selectbox("Select Category", list(category_dict.keys()))
|
21 |
+
|
22 |
+
# Select Question
|
23 |
+
question_dict = {q["question"]: {"code": q["code"], "folder": q["folder"]} for q in category_dict[category_selected]}
|
24 |
+
question_selected = st.selectbox("Select Question", list(question_dict.keys()))
|
25 |
+
|
26 |
+
# Get folder name and code snippet
|
27 |
+
selected_entry = question_dict[question_selected]
|
28 |
+
folder_name = selected_entry["folder"]
|
29 |
+
code_snippet = selected_entry["code"]
|
30 |
+
|
31 |
+
# Show Code Snippet
|
32 |
+
st.code(code_snippet, language="python")
|
33 |
+
|
34 |
+
# Execute Button
|
35 |
+
if st.button("Execute"):
|
36 |
+
# Path to the selected code.py file
|
37 |
+
# code_path = script_dir.parent / "data/questions" / folder_name / "code.py"
|
38 |
+
code_path = f"data/questions/{folder_name}/code.py"
|
39 |
+
|
40 |
+
try:
|
41 |
+
# Execute the Python script and capture the output
|
42 |
+
result = subprocess.check_output(["python", str(code_path)], text=True, stderr=subprocess.STDOUT)
|
43 |
+
|
44 |
+
# Display the execution output
|
45 |
+
st.subheader("Execution Output:")
|
46 |
+
st.success(result)
|
47 |
+
|
48 |
+
except subprocess.CalledProcessError as e:
|
49 |
+
# Display any errors if execution fails
|
50 |
+
st.error(f"Error executing script:\n{e.output}")
|
pages/3_Add_Questions.py
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import json
|
3 |
+
from pathlib import Path
|
4 |
+
from utils.code_services import format_code, execute_code
|
5 |
+
|
6 |
+
QUESTIONS_DIR = Path("data/questions")
|
7 |
+
QUESTIONS_DIR.mkdir(parents=True, exist_ok=True)
|
8 |
+
|
9 |
+
def get_next_question_id():
|
10 |
+
existing_ids = [int(folder.name) for folder in QUESTIONS_DIR.iterdir() if folder.is_dir() and folder.name.isdigit()]
|
11 |
+
return max(existing_ids, default=-1) + 1
|
12 |
+
|
13 |
+
st.title("📝 Add a New Question")
|
14 |
+
|
15 |
+
question_text = st.text_area("Enter Question", placeholder="Type the question here...", height=80)
|
16 |
+
answer_text = st.text_area("Enter Answer", placeholder="Type the answer here...", height=80)
|
17 |
+
user_code = st.text_area("Enter Code", placeholder="Write your Python solution here...", height=300)
|
18 |
+
|
19 |
+
category = st.text_input("Category", placeholder="e.g. spatial")
|
20 |
+
answer_category = st.text_input("#### Answer Category", placeholder="e.g. signal")
|
21 |
+
plot = st.checkbox("## Does this require a plot?")
|
22 |
+
libraries = st.text_input("Libraries (comma-separated)", placeholder="e.g. pandas, numpy")
|
23 |
+
|
24 |
+
if st.button("Save Question"):
|
25 |
+
if not all([question_text.strip(), answer_text.strip(), user_code.strip(), category.strip(), answer_category.strip()]):
|
26 |
+
st.error("❌ All fields are required. Please fill them out.")
|
27 |
+
else:
|
28 |
+
formatted_code = format_code(user_code)
|
29 |
+
output, error = execute_code(formatted_code)
|
30 |
+
|
31 |
+
if error:
|
32 |
+
st.error("❌ Code execution failed! Fix the following error before saving:")
|
33 |
+
st.code(error, language="plaintext")
|
34 |
+
else:
|
35 |
+
question_id = get_next_question_id()
|
36 |
+
question_dir = QUESTIONS_DIR / str(question_id)
|
37 |
+
question_dir.mkdir(parents=True, exist_ok=True)
|
38 |
+
|
39 |
+
(question_dir / "question.txt").write_text(question_text, encoding="utf-8")
|
40 |
+
|
41 |
+
(question_dir / "answer.txt").write_text(answer_text, encoding="utf-8")
|
42 |
+
|
43 |
+
(question_dir / "code.py").write_text(formatted_code, encoding="utf-8")
|
44 |
+
|
45 |
+
metadata = {
|
46 |
+
"question_id": question_id,
|
47 |
+
"category": category.strip().lower(),
|
48 |
+
"answer_category": answer_category.strip(),
|
49 |
+
"plot": plot,
|
50 |
+
"libraries": [lib.strip() for lib in libraries.split(",")] if libraries else []
|
51 |
+
}
|
52 |
+
with open(question_dir / "metadata.json", "w", encoding="utf-8") as f:
|
53 |
+
json.dump(metadata, f, indent=4)
|
54 |
+
|
55 |
+
st.success(f"✅ Question saved successfully! (ID: {question_id})")
|
56 |
+
st.info("refresh in-order to see the applied changes")
|
57 |
+
if st.button("refresh") :
|
58 |
+
st.rerun()
|
59 |
+
|
60 |
+
if user_code:
|
61 |
+
st.subheader("💻 Test Your Code Before Saving")
|
62 |
+
formatted_test_code = format_code(user_code)
|
63 |
+
st.code(formatted_test_code, language="python")
|
64 |
+
|
65 |
+
if st.button("Execute Code"):
|
66 |
+
output, error = execute_code(formatted_test_code)
|
67 |
+
|
68 |
+
if error:
|
69 |
+
st.error("❌ Code execution failed! Fix the following error:")
|
70 |
+
st.error(error)
|
71 |
+
else:
|
72 |
+
st.success("✅ Code executed successfully!")
|
73 |
+
st.success(f"Execution Output : {output}")
|
pages/4_Edit_Questions.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import streamlit as st
|
3 |
+
from pathlib import Path
|
4 |
+
from utils.load_jsonl import load_data
|
5 |
+
from utils.code_services import format_code, execute_code
|
6 |
+
|
7 |
+
DATA_DIR = Path("data/questions")
|
8 |
+
JSONL_FILE = "output.jsonl"
|
9 |
+
|
10 |
+
questions_data = load_data(JSONL_FILE)
|
11 |
+
|
12 |
+
categories = sorted(set(q["metadata"]["category"] for q in questions_data))
|
13 |
+
|
14 |
+
st.title("✏️ Edit a Question")
|
15 |
+
|
16 |
+
if not categories:
|
17 |
+
st.warning("No categories available.")
|
18 |
+
st.stop()
|
19 |
+
|
20 |
+
selected_category = st.selectbox("Select a Category", categories)
|
21 |
+
|
22 |
+
filtered_questions = {int(q["folder"]): q["question"][:50] + "..." for q in questions_data if q["metadata"]["category"] == selected_category}
|
23 |
+
|
24 |
+
if not filtered_questions:
|
25 |
+
st.warning("No questions found in this category.")
|
26 |
+
st.stop()
|
27 |
+
|
28 |
+
selected_question_id = st.selectbox("Select Question to Edit", list(filtered_questions.keys()), format_func=lambda x: f"ID {x}: {filtered_questions[x]}")
|
29 |
+
|
30 |
+
selected_question = next((q for q in questions_data if int(q["folder"]) == selected_question_id), None)
|
31 |
+
|
32 |
+
if selected_question:
|
33 |
+
question_input = st.text_area("Edit Question", value=selected_question["question"])
|
34 |
+
answer_input = st.text_area("Edit Answer", value=selected_question["answer"])
|
35 |
+
code_input = st.text_area("Edit Code", value=selected_question["code"])
|
36 |
+
|
37 |
+
metadata = selected_question["metadata"]
|
38 |
+
category_input = st.text_input("Category", value=metadata["category"])
|
39 |
+
answer_category_input = st.text_input("Answer Category", value=metadata["answer_category"])
|
40 |
+
plot_input = st.checkbox("Does this require a plot?", value=metadata["plot"])
|
41 |
+
libraries_input = st.text_input("Libraries (comma-separated)", value=", ".join(metadata["libraries"]))
|
42 |
+
|
43 |
+
if st.button("Save Changes"):
|
44 |
+
if not all([question_input.strip(), answer_input.strip(), code_input.strip(), category_input.strip(), answer_category_input.strip()]):
|
45 |
+
st.error("❌ All fields are required. Please fill them out.")
|
46 |
+
else:
|
47 |
+
formatted_code = format_code(code_input)
|
48 |
+
output, error = execute_code(formatted_code)
|
49 |
+
|
50 |
+
if error:
|
51 |
+
st.error("❌ Code execution failed! Fix the following error before saving:")
|
52 |
+
st.code(error, language="plaintext")
|
53 |
+
else:
|
54 |
+
question_dir = DATA_DIR / str(selected_question_id)
|
55 |
+
|
56 |
+
(question_dir / "question.txt").write_text(question_input, encoding="utf-8")
|
57 |
+
(question_dir / "answer.txt").write_text(answer_input, encoding="utf-8")
|
58 |
+
(question_dir / "code.py").write_text(formatted_code, encoding="utf-8")
|
59 |
+
|
60 |
+
updated_metadata = {
|
61 |
+
"question_id": selected_question_id,
|
62 |
+
"category": category_input.strip(),
|
63 |
+
"answer_category": answer_category_input.strip(),
|
64 |
+
"plot": plot_input,
|
65 |
+
"libraries": [lib.strip() for lib in libraries_input.split(",")] if libraries_input else []
|
66 |
+
}
|
67 |
+
with open(question_dir / "metadata.json", "w", encoding="utf-8") as f:
|
68 |
+
json.dump(updated_metadata, f, indent=4)
|
69 |
+
|
70 |
+
st.success(f"✅ Question ID {selected_question_id} updated successfully!")
|
71 |
+
st.info("Refresh to see the applied changes")
|
72 |
+
if st.button("Refresh"):
|
73 |
+
st.rerun()
|
74 |
+
|
75 |
+
else:
|
76 |
+
st.error("❌ Failed to load question data.")
|
77 |
+
|
78 |
+
if code_input:
|
79 |
+
st.subheader("💻 Test Your Code Before Saving")
|
80 |
+
formatted_test_code = format_code(code_input)
|
81 |
+
st.code(formatted_test_code, language="python")
|
82 |
+
|
83 |
+
if st.button("Execute Code"):
|
84 |
+
output, error = execute_code(formatted_test_code)
|
85 |
+
|
86 |
+
if error:
|
87 |
+
st.error("❌ Code execution failed! Fix the following error:")
|
88 |
+
st.error(error)
|
89 |
+
else:
|
90 |
+
st.success("✅ Code executed successfully!")
|
91 |
+
st.success(f"Execution Output: {output}")
|
pages/5_Delete_Question.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
import shutil
|
4 |
+
from pathlib import Path
|
5 |
+
from utils.load_jsonl import load_data
|
6 |
+
|
7 |
+
DATA_DIR = Path("data/questions")
|
8 |
+
JSONL_FILE = "output.jsonl"
|
9 |
+
|
10 |
+
questions_data = load_data(JSONL_FILE)
|
11 |
+
|
12 |
+
categories = sorted(set(q["metadata"]["category"] for q in questions_data))
|
13 |
+
|
14 |
+
st.title("🗑️ Delete a Question")
|
15 |
+
|
16 |
+
if not categories:
|
17 |
+
st.warning("No categories available.")
|
18 |
+
st.stop()
|
19 |
+
|
20 |
+
selected_category = st.selectbox("Select a Category", categories)
|
21 |
+
|
22 |
+
filtered_questions = {int(q["folder"]): q["question"][:50] + "..." for q in questions_data if q["metadata"]["category"] == selected_category}
|
23 |
+
|
24 |
+
if not filtered_questions:
|
25 |
+
st.warning("No questions found in this category.")
|
26 |
+
st.stop()
|
27 |
+
|
28 |
+
selected_question_id = st.selectbox("Select Question to Delete", list(filtered_questions.keys()), format_func=lambda x: f"ID {x}: {filtered_questions[x]}")
|
29 |
+
|
30 |
+
selected_question = next((q for q in questions_data if int(q["folder"]) == selected_question_id), None)
|
31 |
+
|
32 |
+
if selected_question:
|
33 |
+
st.subheader("Question Details")
|
34 |
+
st.text_area("Question", value=selected_question["question"], disabled=True, height=70)
|
35 |
+
st.text_area("Answer", value=selected_question["answer"], disabled=True, height=70)
|
36 |
+
|
37 |
+
st.subheader("Code")
|
38 |
+
st.code(selected_question["code"], language="python")
|
39 |
+
|
40 |
+
metadata = selected_question["metadata"]
|
41 |
+
st.subheader("Meta data")
|
42 |
+
st.write(f"Category : **{metadata['category']}**")
|
43 |
+
st.write(f"Answer Category : **{metadata['answer_category']}**")
|
44 |
+
st.write(f"Plot Required : **{'Yes' if metadata['plot'] else 'No'}**")
|
45 |
+
st.write(f"Libraries : **{', '.join(metadata['libraries']) if metadata['libraries'] else 'None'}**")
|
46 |
+
|
47 |
+
def rename_folders(deleted_id):
|
48 |
+
"""Renames folders after deleting one to maintain continuous numbering."""
|
49 |
+
all_folders = sorted([int(f) for f in os.listdir(DATA_DIR) if f.isdigit()])
|
50 |
+
|
51 |
+
for folder_id in all_folders:
|
52 |
+
if folder_id > deleted_id:
|
53 |
+
old_path = DATA_DIR / str(folder_id)
|
54 |
+
new_path = DATA_DIR / str(folder_id - 1)
|
55 |
+
shutil.move(old_path, new_path)
|
56 |
+
|
57 |
+
st.info("Need to check the box in-order to delete the question")
|
58 |
+
confirm = st.checkbox("Confirm Deletion")
|
59 |
+
|
60 |
+
if st.button("🚨 Delete This Question"):
|
61 |
+
if confirm:
|
62 |
+
question_folder = DATA_DIR / str(selected_question_id)
|
63 |
+
if question_folder.exists():
|
64 |
+
shutil.rmtree(question_folder)
|
65 |
+
rename_folders(selected_question_id)
|
66 |
+
st.success(f"✅ Question ID {selected_question_id} deleted successfully!")
|
67 |
+
st.info("Refresh to see the applied changes")
|
68 |
+
if st.button("Refresh"):
|
69 |
+
st.rerun()
|
70 |
+
else:
|
71 |
+
st.warning("⚠️ Please check 'Confirm Deletion' before proceeding.")
|
72 |
+
|
73 |
+
else:
|
74 |
+
st.error("❌ Failed to load question data.")
|
utils/code_services.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pathlib import Path
|
2 |
+
import os
|
3 |
+
import subprocess
|
4 |
+
|
5 |
+
def execute_code(code_content):
|
6 |
+
"""Executes the given Python code and returns output/errors."""
|
7 |
+
temp_path = "temp_code.py"
|
8 |
+
Path(temp_path).write_text(code_content, encoding="utf-8")
|
9 |
+
|
10 |
+
try:
|
11 |
+
output = subprocess.check_output(["python", temp_path], stderr=subprocess.STDOUT, text=True)
|
12 |
+
os.remove(temp_path)
|
13 |
+
return output, None
|
14 |
+
except subprocess.CalledProcessError as e:
|
15 |
+
os.remove(temp_path)
|
16 |
+
return None, e.output
|
17 |
+
|
18 |
+
|
19 |
+
def format_code(user_code):
|
20 |
+
if user_code.strip().startswith("def true_code()"):
|
21 |
+
return user_code
|
22 |
+
else:
|
23 |
+
return f"def true_code():\n " + "\n ".join(user_code.splitlines()) + "\n\ntrue_code()" # Wrap in function
|
utils/data_to_jsonl.py
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
def data_to_jsonl(input_dir, output_file):
|
6 |
+
"""Reads data from folders inside input_dir and writes to a JSONL file."""
|
7 |
+
data = []
|
8 |
+
|
9 |
+
for folder_name in sorted(os.listdir(input_dir), key=lambda x: int(x)): # Sort numerically
|
10 |
+
folder_path = os.path.join(input_dir, folder_name)
|
11 |
+
if os.path.isdir(folder_path): # Ensure it's a folder
|
12 |
+
|
13 |
+
try:
|
14 |
+
with open(os.path.join(folder_path, "question.txt"), "r", encoding="utf-8") as f:
|
15 |
+
question = f.read()
|
16 |
+
|
17 |
+
with open(os.path.join(folder_path, "answer.txt"), "r", encoding="utf-8") as f:
|
18 |
+
answer = f.read()
|
19 |
+
|
20 |
+
with open(os.path.join(folder_path, "code.py"), "r", encoding="utf-8") as f:
|
21 |
+
code = f.read()
|
22 |
+
|
23 |
+
with open(os.path.join(folder_path, "metadata.json"), "r", encoding="utf-8") as f:
|
24 |
+
metadata = json.load(f)
|
25 |
+
|
26 |
+
data.append({
|
27 |
+
"folder": folder_name,
|
28 |
+
"question": question,
|
29 |
+
"answer": answer,
|
30 |
+
"code": code,
|
31 |
+
"metadata": metadata
|
32 |
+
})
|
33 |
+
except FileNotFoundError as e:
|
34 |
+
print(f"Skipping {folder_name} due to missing file: {e}")
|
35 |
+
|
36 |
+
with open(output_file, "w", encoding="utf-8") as f:
|
37 |
+
for entry in data:
|
38 |
+
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
|
39 |
+
|
40 |
+
print(f"Data successfully written to {output_file}")
|
41 |
+
|
42 |
+
if __name__ == "__main__":
|
43 |
+
outputfile = input('Enter the name of file without .jsonl : ')
|
44 |
+
|
45 |
+
script_dir = Path(__file__).parent
|
46 |
+
input_dir = script_dir.parent / "data/questions"
|
47 |
+
data_to_jsonl(input_dir, f'{outputfile}.jsonl')
|
utils/jsonl_to_data.py
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
|
4 |
+
def jsonl_to_data(input_file, output_dir):
|
5 |
+
"""Reads a JSONL file and reconstructs the original folder structure."""
|
6 |
+
os.makedirs(output_dir, exist_ok=True)
|
7 |
+
|
8 |
+
with open(input_file, "r", encoding="utf-8") as f:
|
9 |
+
for line in f:
|
10 |
+
entry = json.loads(line)
|
11 |
+
folder_path = os.path.join(output_dir, entry["folder"])
|
12 |
+
os.makedirs(folder_path, exist_ok=True)
|
13 |
+
|
14 |
+
with open(os.path.join(folder_path, "question.txt"), "w", encoding="utf-8") as f_q:
|
15 |
+
f_q.write(entry["question"])
|
16 |
+
|
17 |
+
with open(os.path.join(folder_path, "answer.txt"), "w", encoding="utf-8") as f_a:
|
18 |
+
f_a.write(entry["answer"])
|
19 |
+
|
20 |
+
with open(os.path.join(folder_path, "code.py"), "w", encoding="utf-8") as f_c:
|
21 |
+
f_c.write(entry["code"])
|
22 |
+
|
23 |
+
with open(os.path.join(folder_path, "meta_data.json"), "w", encoding="utf-8") as f_m:
|
24 |
+
json.dump(entry["meta_data"], f_m, indent=4)
|
25 |
+
|
26 |
+
print(f"Data successfully reconstructed in {output_dir}")
|
utils/load_jsonl.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
from pathlib import Path
|
3 |
+
from utils.data_to_jsonl import data_to_jsonl
|
4 |
+
|
5 |
+
def load_data(jsonl_file):
|
6 |
+
data = []
|
7 |
+
script_dir = Path(__file__).parent
|
8 |
+
input_dir = script_dir.parent / "data/questions"
|
9 |
+
data_to_jsonl(input_dir, jsonl_file)
|
10 |
+
with open(jsonl_file, "r", encoding="utf-8") as f:
|
11 |
+
for line in f:
|
12 |
+
data.append(json.loads(line))
|
13 |
+
return data
|