mechanical_test / app.py
barcegab's picture
Update app.py
2f4041b verified
Raw
History Blame Contribute Delete
3.54 kB
import gradio as gr
import json
import bisect
# Define the questions with a single image for options
with open('mechanical/questions.json', 'r') as q_file:
questions = json.load(q_file)
with open('mechanical/answers.json', 'r') as a_file:
answers = json.load(a_file)
with open('mechanical/distribution.json', 'r') as file:
distribution_data = json.load(file)
def calculate_percentile(correct_answers, distribution):
# Sort the distribution by the number of correct answers
distribution.sort(key=lambda x: x[0])
# Separate the correct answers and percentiles into two lists
scores = [item[0] for item in distribution]
percentiles = [item[1] for item in distribution]
# Find the index where the given correct_answers should be inserted
index = bisect.bisect_left(scores, correct_answers)
# If the exact score is found in the distribution
if index < len(scores) and scores[index] == correct_answers:
return percentiles[index]
# If the score is beyond the highest score in the distribution
if index == len(scores):
return 100.0
# If the score is between two values in the distribution, interpolate
if index > 0:
lower_score, lower_percentile = scores[index-1], percentiles[index-1]
upper_score, upper_percentile = scores[index], percentiles[index]
# Linear interpolation
slope = (upper_percentile - lower_percentile) / (upper_score - lower_score)
interpolated_percentile = lower_percentile + slope * (correct_answers - lower_score)
return round(interpolated_percentile, 2)
# If the score is below the lowest score in the distribution
return 0.0
# Function to evaluate the answer
def evaluate_answer(*responses):
score = 0
distribution = [(item['correct_answers'], item['percentile']) for item in distribution_data]
if any(response is None for response in responses):
indices = [index for index, value in enumerate(responses) if value is None]
indices = [value + 1 for value in indices]
raise gr.Error(f"No se puede quedar ningun valor en 0. Preguntas sin respuesta:{indices}")
for i, response in enumerate(responses):
response_parsed = response.split('.')[0]
if response_parsed == answers[str(i)]:
score += 1
percentile = calculate_percentile(score, distribution)
return f"Your score: {percentile}: correct answers: {score}"
# Create a Gradio interface
with gr.Blocks() as demo:
results = []
for question in questions:
with gr.Row():
with gr.Column():
gr.Image(type="filepath",
value=question["image"],
show_download_button=False,
mirror_webcam=False,
sources=['clipboard'],
interactive=False)
with gr.Column():
if len(question['options']) == 0:
options = ["A", "B", "C"]
else:
options = question['options']
radio = gr.Radio(choices=options,
label=question['question'])
results.append(radio)
submit = gr.Button("Submit")
output = gr.Textbox(label="Results")
submit.click(evaluate_answer, inputs=results, outputs=output)
# Launch the interface
if __name__ == "__main__":
#app = create_interface()
demo.launch()