QuantumChecker 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/PKG-INFO +1 -1
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/main.py +15 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/powerbi_evaluator.py +16 -2
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/python_evaluator.py +8 -1
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/sql_evaluator.py +20 -3
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/ssis_evaluator.py +14 -3
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumChecker.egg-info/PKG-INFO +1 -1
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumChecker.egg-info/SOURCES.txt +0 -1
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/setup.py +1 -1
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/tests/test2.py +5 -5
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/__init__.py +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumCheck/prompts.py +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumChecker.egg-info/dependency_links.txt +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumChecker.egg-info/requires.txt +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/QuantumChecker.egg-info/top_level.txt +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/README.md +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/setup.cfg +0 -0
- {quantumchecker-0.4.0 → quantumchecker-0.5.0}/tests/test.py +0 -0
|
@@ -20,12 +20,27 @@ class HomeworkEvaluator:
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
EXTENSION_TO_TYPE = {
|
|
23
|
+
#Python
|
|
23
24
|
".py": "python",
|
|
25
|
+
".ipynb": "python",
|
|
26
|
+
".pyw": "python",
|
|
27
|
+
".pyi": "python",
|
|
28
|
+
".pyx": "python",
|
|
29
|
+
".pxd": "python",
|
|
30
|
+
".pyd": "python",
|
|
31
|
+
".so": "python",
|
|
32
|
+
|
|
33
|
+
#SQL
|
|
24
34
|
".sql": "sql",
|
|
35
|
+
|
|
36
|
+
#Power BI
|
|
25
37
|
".pbit": "powerbi",
|
|
26
38
|
".pdf": "powerbi",
|
|
39
|
+
|
|
40
|
+
#SSIS
|
|
27
41
|
".dtsx": "ssis",
|
|
28
42
|
".DTSX": "ssis",
|
|
43
|
+
|
|
29
44
|
".txt": "text",
|
|
30
45
|
".md": "text"
|
|
31
46
|
}
|
|
@@ -188,8 +188,22 @@ class PowerBIProcessor:
|
|
|
188
188
|
schema_path = os.path.join(export_path, "DataModelSchema")
|
|
189
189
|
txt_path = os.path.join(export_path, "DataModelSchema.txt")
|
|
190
190
|
os.rename(schema_path, txt_path)
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
try:
|
|
192
|
+
with open(txt_path, "r", encoding="utf-16-le") as file:
|
|
193
|
+
data = file.read()
|
|
194
|
+
except UnicodeDecodeError:
|
|
195
|
+
with open(txt_path, "r", encoding="utf-16-le", errors="ignore") as file:
|
|
196
|
+
data = file.read()
|
|
197
|
+
|
|
198
|
+
# normalize curly quotes and similar unicode chars
|
|
199
|
+
data = (
|
|
200
|
+
data.replace("’", "'")
|
|
201
|
+
.replace("‘", "'")
|
|
202
|
+
.replace("“", '"')
|
|
203
|
+
.replace("”", '"')
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
return json.loads(data)
|
|
193
207
|
except UnicodeDecodeError as e:
|
|
194
208
|
logger.error("Failed to decode DataModelSchema: %s", str(e))
|
|
195
209
|
raise ProcessingError(f"Invalid encoding in DataModelSchema: {e}")
|
|
@@ -102,6 +102,7 @@ class GeminiFlashModel:
|
|
|
102
102
|
class PythonAnswerParser:
|
|
103
103
|
@staticmethod
|
|
104
104
|
def parse_single_file(content: str) -> List[str]:
|
|
105
|
+
content = content.replace("’", "'").replace("‘", "'")
|
|
105
106
|
answers = [a.strip() for a in content.strip().split("\n\n") if a.strip()]
|
|
106
107
|
if not answers:
|
|
107
108
|
logger.warning("No valid answers found in single file")
|
|
@@ -128,7 +129,11 @@ class PythonAnswerParser:
|
|
|
128
129
|
zip_ref.extractall(temp_dir)
|
|
129
130
|
|
|
130
131
|
python_files = sorted(
|
|
131
|
-
[
|
|
132
|
+
[
|
|
133
|
+
f
|
|
134
|
+
for f in os.listdir(temp_dir)
|
|
135
|
+
if f.endswith((".py", ".ipynb", ".pyw", ".pyi", ".pyx", ".pxd", ".pyd", ".so"))
|
|
136
|
+
]
|
|
132
137
|
)
|
|
133
138
|
|
|
134
139
|
if not python_files:
|
|
@@ -140,8 +145,10 @@ class PythonAnswerParser:
|
|
|
140
145
|
os.path.join(temp_dir, python_file),
|
|
141
146
|
"r",
|
|
142
147
|
encoding="utf-8",
|
|
148
|
+
errors="ignore",
|
|
143
149
|
) as f:
|
|
144
150
|
content = f.read().strip()
|
|
151
|
+
content = content.replace("’", "'").replace("‘", "'")
|
|
145
152
|
if content:
|
|
146
153
|
combined_content.append(content)
|
|
147
154
|
|
|
@@ -102,6 +102,7 @@ class GeminiFlashModel:
|
|
|
102
102
|
class SQLAnswerParser:
|
|
103
103
|
@staticmethod
|
|
104
104
|
def parse_single_file(content: str) -> List[str]:
|
|
105
|
+
content = content.replace("’", "'").replace("‘", "'")
|
|
105
106
|
answers = [a.strip() for a in content.strip().split("\n\n") if a.strip()]
|
|
106
107
|
if not answers:
|
|
107
108
|
logger.warning("No valid answers found in single file")
|
|
@@ -140,8 +141,10 @@ class SQLAnswerParser:
|
|
|
140
141
|
os.path.join(temp_dir, sql_file),
|
|
141
142
|
"r",
|
|
142
143
|
encoding="utf-8",
|
|
144
|
+
errors="ignore",
|
|
143
145
|
) as f:
|
|
144
146
|
content = f.read().strip()
|
|
147
|
+
content = content.replace("’", "'").replace("‘", "'")
|
|
145
148
|
if content:
|
|
146
149
|
combined_content.append(content)
|
|
147
150
|
|
|
@@ -183,12 +186,26 @@ class SQLEvaluator:
|
|
|
183
186
|
"""
|
|
184
187
|
try:
|
|
185
188
|
if answer_path.endswith(".zip"):
|
|
186
|
-
# Use provided temp_dir or generate a default one
|
|
187
189
|
temp_dir = temp_dir or f"temp_sql_extract_{os.getpid()}"
|
|
188
190
|
answers = SQLAnswerParser.parse_zip_file(answer_path, temp_dir)
|
|
189
191
|
else:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
try:
|
|
193
|
+
with open(answer_path, "r", encoding="utf-8") as file:
|
|
194
|
+
content = file.read()
|
|
195
|
+
except UnicodeDecodeError:
|
|
196
|
+
try:
|
|
197
|
+
with open(answer_path, "r", encoding="cp1252") as file:
|
|
198
|
+
content = file.read()
|
|
199
|
+
except UnicodeDecodeError:
|
|
200
|
+
with open(answer_path, "r", encoding="utf-8", errors="ignore") as file:
|
|
201
|
+
content = file.read()
|
|
202
|
+
|
|
203
|
+
content = (
|
|
204
|
+
content.replace("’", "'")
|
|
205
|
+
.replace("‘", "'")
|
|
206
|
+
.replace("“", '"')
|
|
207
|
+
.replace("”", '"')
|
|
208
|
+
)
|
|
192
209
|
answers = SQLAnswerParser.parse_single_file(content)
|
|
193
210
|
|
|
194
211
|
logger.info(
|
|
@@ -262,9 +262,20 @@ class SSISAnswerParser:
|
|
|
262
262
|
|
|
263
263
|
for dtsx_file in dtsx_files:
|
|
264
264
|
file_path = os.path.join(temp_dir, dtsx_file)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
try:
|
|
266
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
267
|
+
content = f.read()
|
|
268
|
+
except UnicodeDecodeError:
|
|
269
|
+
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
270
|
+
content = f.read()
|
|
271
|
+
|
|
272
|
+
content = (
|
|
273
|
+
content.replace("’", "'")
|
|
274
|
+
.replace("‘", "'")
|
|
275
|
+
.replace("“", '"')
|
|
276
|
+
.replace("”", '"')
|
|
277
|
+
).strip()
|
|
278
|
+
if content:
|
|
268
279
|
parsed_data = SSISAnswerParser.parse_single_file(content)
|
|
269
280
|
combined_answers.extend(parsed_data.get("text_answers", []))
|
|
270
281
|
# Merge structured data
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="QuantumChecker",
|
|
5
|
-
version="0.
|
|
5
|
+
version="0.5.0",
|
|
6
6
|
author="Qobiljon",
|
|
7
7
|
author_email="qobiljonkhayrullayev@gmail.com",
|
|
8
8
|
description="A package to evaluate homework submissions in Python, SQL, PowerBI, and SSIS.",
|
|
@@ -2,10 +2,10 @@ import asyncio
|
|
|
2
2
|
from pprint import pprint
|
|
3
3
|
from QuantumCheck import HomeworkEvaluator
|
|
4
4
|
|
|
5
|
-
API_KEY = "
|
|
5
|
+
API_KEY = "AIzaSyDuFmw1Z6qHsQicYsb1XVV7EXPtCj7Kzro"
|
|
6
6
|
|
|
7
|
-
question = "
|
|
8
|
-
answer_path = "../tests/
|
|
7
|
+
question = "Mark the answers below"
|
|
8
|
+
answer_path = "../tests/answers/sample_notebook.ipynb"
|
|
9
9
|
|
|
10
10
|
async def main():
|
|
11
11
|
evaluator = HomeworkEvaluator()
|
|
@@ -13,10 +13,10 @@ async def main():
|
|
|
13
13
|
question_content=question,
|
|
14
14
|
answer_path=answer_path,
|
|
15
15
|
api_key=API_KEY,
|
|
16
|
-
question_type="
|
|
16
|
+
question_type="python"
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
print(f"
|
|
19
|
+
print(f" | {answer_path}")
|
|
20
20
|
print("✅ Evaluation result:")
|
|
21
21
|
pprint(evaluation)
|
|
22
22
|
print("-" * 40)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|