File size: 6,704 Bytes
3a3744e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import random

def generate_problem(operation, min_value, max_value):
    """
    Generates a random math problem based on the selected operation and range.
    """
    # Ensure min_value is less than or equal to max_value
    if min_value > max_value:
        min_value, max_value = max_value, min_value

    num1 = random.randint(int(min_value), int(max_value))
    num2 = random.randint(int(min_value), int(max_value))
    # Avoid division by zero
    if operation == 'Divide':
        while num2 == 0:
            num2 = random.randint(int(min_value), int(max_value))
    return num1, num2

def update_question(operation, min_value, max_value):
    """
    Updates the question text and generates new random numbers.
    """
    num1, num2 = generate_problem(operation, min_value, max_value)
    op_symbol = {'Add': '+', 'Subtract': '-', 'Multiply': '*', 'Divide': '/'}[operation]
    question = f"What is {num1} {op_symbol} {num2}?"
    return question, num1, num2

def check_answer(operation, user_answer, num1, num2, min_value, max_value, correct_tally, incorrect_tally):
    """
    Checks the user's answer, updates tallies, and returns the result message and a new question.
    """
    # Calculate the correct answer
    if operation == 'Add':
        correct_answer = num1 + num2
    elif operation == 'Subtract':
        correct_answer = num1 - num2
    elif operation == 'Multiply':
        correct_answer = num1 * num2
    elif operation == 'Divide':
        correct_answer = num1 / num2

    # Check if the user's answer is correct
    if user_answer == correct_answer:
        result = "Correct!"
        correct_tally += 1
    else:
        result = f"Incorrect. The correct answer is {correct_answer}."
        incorrect_tally += 1

    # Generate a new question for the next round
    question_new, num1_new, num2_new = update_question(operation, min_value, max_value)

    # Prepare the tally message
    tally_message = f"Correct Answers: {correct_tally}\nIncorrect Answers: {incorrect_tally}"

    # Return all updated values
    return result, question_new, num1_new, num2_new, correct_tally, incorrect_tally, tally_message

def reset_tallies(correct_tally, incorrect_tally):
    """
    Resets the correct and incorrect tallies to zero and updates the tally display.
    """
    correct_tally = 0
    incorrect_tally = 0
    tally_message = f"Correct Answers: {correct_tally}\nIncorrect Answers: {incorrect_tally}"
    return correct_tally, incorrect_tally, tally_message

with gr.Blocks() as demo:
    gr.Markdown("## Math Quiz\nSelect an operation, set the range, solve the problem, and enter your answer.")

    with gr.Row():
        # Operation selection
        operation = gr.Radio(['Add', 'Subtract', 'Multiply', 'Divide'], label='Select Operation', value='Add')

        # Range inputs
        min_value = gr.Number(label='Minimum Value', value=-100)
        max_value = gr.Number(label='Maximum Value', value=100)

    # Question display
    question_text = gr.Textbox(label='Question', interactive=False)

    # User's answer input
    answer = gr.Number(label='Your Answer')

    # Result display
    result = gr.Textbox(label='Result', interactive=False)

    # Tally display
    tally_display = gr.Textbox(label='Tally', value="Correct Answers: 0\nIncorrect Answers: 0", interactive=False)

    with gr.Row():
        # Button to check the answer
        check_button = gr.Button('Check Answer')

        # Button to reset tallies
        reset_button = gr.Button('Reset Tallies')

    # Hidden states to store the current numbers and tallies
    num1_state = gr.State()
    num2_state = gr.State()
    correct_tally = gr.State(0)
    incorrect_tally = gr.State(0)

    # Initialize the interface with the first question and tallies
    def init_interface():
        question, num1, num2 = update_question(operation.value, min_value.value, max_value.value)
        tally_message = f"Correct Answers: {correct_tally.value}\nIncorrect Answers: {incorrect_tally.value}"
        return question, num1, num2, tally_message

    # Set initial values for the question, numbers, and tally
    init_question, init_num1, init_num2, init_tally_message = init_interface()
    question_text.value = init_question
    num1_state.value = init_num1
    num2_state.value = init_num2
    tally_display.value = init_tally_message

    # Update the question when the operation or range changes
    def on_operation_or_range_change(op, min_val, max_val, correct_tally, incorrect_tally):
        question, num1, num2 = update_question(op, min_val, max_val)
        tally_message = f"Correct Answers: {correct_tally}\nIncorrect Answers: {incorrect_tally}"
        return question, num1, num2, tally_message

    operation.change(
        fn=on_operation_or_range_change,
        inputs=[operation, min_value, max_value, correct_tally, incorrect_tally],
        outputs=[question_text, num1_state, num2_state, tally_display]
    )

    min_value.change(
        fn=on_operation_or_range_change,
        inputs=[operation, min_value, max_value, correct_tally, incorrect_tally],
        outputs=[question_text, num1_state, num2_state, tally_display]
    )

    max_value.change(
        fn=on_operation_or_range_change,
        inputs=[operation, min_value, max_value, correct_tally, incorrect_tally],
        outputs=[question_text, num1_state, num2_state, tally_display]
    )

    # Check the user's answer when the button is clicked
    def on_check_answer(operation, user_answer, num1, num2, min_value, max_value, correct_tally, incorrect_tally):
        result_text, question_new, num1_new, num2_new, correct_tally_new, incorrect_tally_new, tally_message = check_answer(
            operation, user_answer, num1, num2, min_value, max_value, correct_tally, incorrect_tally)
        return result_text, question_new, num1_new, num2_new, correct_tally_new, incorrect_tally_new, tally_message

    check_button.click(
        fn=on_check_answer,
        inputs=[operation, answer, num1_state, num2_state, min_value, max_value, correct_tally, incorrect_tally],
        outputs=[result, question_text, num1_state, num2_state, correct_tally, incorrect_tally, tally_display]
    )

    # Reset the tallies when the reset button is clicked
    def on_reset_tallies(correct_tally, incorrect_tally):
        correct_tally_new, incorrect_tally_new, tally_message = reset_tallies(correct_tally, incorrect_tally)
        return correct_tally_new, incorrect_tally_new, tally_message

    reset_button.click(
        fn=on_reset_tallies,
        inputs=[correct_tally, incorrect_tally],
        outputs=[correct_tally, incorrect_tally, tally_display]
    )

demo.launch(share=True)