File size: 5,642 Bytes
217abc3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from typing import List
from openai import OpenAI
from models import BaseLearningObjective, LearningObjective, TEMPERATURE_UNAVAILABLE
from prompts.incorrect_answers import INCORRECT_ANSWER_EXAMPLES_WITH_EXPLANATION

def generate_incorrect_answer_options(client: OpenAI, model: str, temperature: float, file_contents: List[str], base_objectives: List[BaseLearningObjective], model_override: str = None) -> List[LearningObjective]:
    """
    Generate incorrect answer options for each base learning objective.
    
    Args:
        file_contents: List of file contents with source tags
        base_objectives: List of base learning objectives to enhance
        
    Returns:
        List of learning objectives with incorrect answer suggestions
    """
    print(f"Generating incorrect answer options for {len(base_objectives)} learning objectives")
    
    # Create combined content for context
    combined_content = "\n\n".join(file_contents)
    enhanced_objectives = []
    
    for i, objective in enumerate(base_objectives):
        print(f"Processing objective {i+1}/{len(base_objectives)}: {objective.learning_objective[:50]}...")
        print(f"Learning objective: {objective.learning_objective}")
        print(f"Correct answer: {objective.correct_answer}")
    #     # Create the prompt for generating incorrect answer options
        prompt = f"""
Based on the learning objective and correct answer provided below.

Learning Objective: {objective.learning_objective}
Correct Answer: {objective.correct_answer}


Generate 3 incorrect answer options.


Use the examples with explanations below to guide you in generating incorrect answer options:
<examples_with_explanation>
    {INCORRECT_ANSWER_EXAMPLES_WITH_EXPLANATION}
</examples_with_explanation>



    Here's the course content that the student has been exposed to:
    <course_content>
    {combined_content}
    </course_content>

    Here's the learning objective that was identified:

    <learning_objective>
    "id": {objective.id},
    "learning_objective": "{objective.learning_objective}",
    "source_reference": "{objective.source_reference}",
    "correct_answer": "{objective.correct_answer}"
    </learning_objective>

        When creating incorrect answers, refer to the correct answer <correct_answer>{objective.correct_answer}</correct_answer>.
    Make sure incorrect answers match the correct answer in terms of length, complexity, phrasing, style, and subject matter.
    Incorrect answers should be of approximate equal length to the correct answer, preferably one sentence and 20 words long. Pay attention to the
    example in <examples_with_explanation> about avoiding unnecessary length.
    """




        
        try:
            model_to_use = model_override if model_override else model

            # Use OpenAI beta API for structured output
 

            system_prompt = "You are an expert in designing effective multiple-choice questions that assess higher-order thinking skills while following established educational best practices."
            params = {
                "model": model_to_use,
                "messages": [
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": prompt}
                ],
                "response_format": LearningObjective
            }
            if not TEMPERATURE_UNAVAILABLE.get(model_to_use, True):
                params["temperature"] = temperature # Use higher temperature for creative misconceptions
            
            print(f"DEBUG - Using model {model_to_use} for incorrect answer options with temperature {params.get('temperature', 'N/A')}")

            completion = client.beta.chat.completions.parse(**params)
            enhanced_obj = completion.choices[0].message.parsed
            # Simple debugging for incorrect answer suggestions
            if enhanced_obj.incorrect_answer_options:
                print(f"  → Got {len(enhanced_obj.incorrect_answer_options)} incorrect answers")
                print(f"  → First option: {enhanced_obj.incorrect_answer_options[0][:100]}..." if len(enhanced_obj.incorrect_answer_options[0]) > 100 else enhanced_obj.incorrect_answer_options[0])
            else:
                print("  → No incorrect answer options received!")
            
            # Preserve grouping metadata from the original objective
            enhanced_obj.in_group = getattr(objective, 'in_group', None)
            enhanced_obj.group_members = getattr(objective, 'group_members', None)
            enhanced_obj.best_in_group = getattr(objective, 'best_in_group', None)
            
            enhanced_objectives.append(enhanced_obj)
            
        except Exception as e:
            print(f"Error generating incorrect answer options for objective {objective.id}: {e}")
            # If there's an error, create a learning objective without suggestions
            enhanced_obj = LearningObjective(
                id=objective.id,
                learning_objective=objective.learning_objective,
                source_reference=objective.source_reference,
                correct_answer=objective.correct_answer,
                incorrect_answer_options=None,
                in_group=getattr(objective, 'in_group', None),
                group_members=getattr(objective, 'group_members', None),
                best_in_group=getattr(objective, 'best_in_group', None)
            )
            enhanced_objectives.append(enhanced_obj)
    
    print(f"Generated incorrect answer options for {len(enhanced_objectives)} learning objectives")
    return enhanced_objectives