Streamlining Student Interaction with Tutor Controller

Welcome to the next step in our journey of building a personal tutor service with DeepSeek models. In the previous lesson, we explored the TutorService class, which acts as a bridge between managing tutoring session data and generating AI responses. Now, we will focus on the TutorController, a crucial component that manages tutoring sessions and handles student queries by interacting with both the model and service layers. The controller is responsible for orchestrating the flow of data between the student interface and the backend services, ensuring that student interactions are processed efficiently and effectively.

Implementing the TutorController Class

The TutorController class is the heart of our controller layer. It is responsible for managing tutoring sessions and processing student queries. Let's begin by examining the structure of the TutorController class in C#.

using System;
using System.Collections.Generic;
using PersonalTutor.Services;

public class TutorController
{
    private Dictionary<string, string> testSession;
    private TutorService tutorService;

    public TutorController()
    {
        testSession = new Dictionary<string, string>();
        tutorService = new TutorService();
    }
}

In this snippet, we:

  • Reference the TutorService class for managing tutoring data and processing student queries.
  • Initialize the TutorController with an instance of TutorService.
  • Create a testSession dictionary to simulate session management for testing purposes.

The testSession dictionary is used to mimic the behavior of student sessions typically managed by a web application. This allows us to focus on testing the core functionality of the TutorController without needing a full session management system. Later, a more robust session management solution can be integrated when developing a RESTful API.

Ensuring Student Session

Before creating a tutoring session, we need to ensure that a student session exists. The EnsureStudentSession method checks if a student ID is present in the testSession. If not, it generates a new student ID.

public string EnsureStudentSession()
{
    if (!testSession.ContainsKey("student_id"))
    {
        testSession["student_id"] = Guid.NewGuid().ToString();
    }
    return testSession["student_id"];
}

This method ensures that a student session is available by checking the testSession dictionary for a student_id. If it doesn't exist, a new student ID is generated using Guid.NewGuid().ToString() and stored in the session. The method then returns the student ID, either the newly created one or the existing one.

Creating a New Tutoring Session

One of the primary responsibilities of the TutorController is to create new tutoring sessions. The CreateSession method handles session creation requests.

public Dictionary<string, object> CreateSession()
{
    // Try to retrieve the student_id from the testSession dictionary
    if (!testSession.TryGetValue("student_id", out var studentId) || string.IsNullOrEmpty(studentId))
    {
        // If student_id is not found or is empty, return an error indicating session expired
        return new Dictionary<string, object>
        {
            { "error", "Session expired" }
        };
    }
    
    // Call TutorService to create a new tutoring session for the student
    string sessionId = tutorService.CreateSession(studentId!);

    // Return a dictionary with the new session_id and a success message
    return new Dictionary<string, object>
    {
        { "session_id", sessionId },
        { "message", "Tutoring session created successfully" }
    };
}

In this method, we:

  1. Retrieve the student_id: We first check the testSession for a student_id.

  2. Handle Session Expiry: If the session has expired (i.e., no student_id is found), we return an error response with an error message.

  3. Create a Tutoring Session: If the session is valid, we call the CreateSession method of the TutorService with the student ID to create a new tutoring session. We then return a dictionary containing a unique session ID and a success message.

Handling Student Queries

The SendQuery method is responsible for processing student queries and returning the tutor's response or an error message.

public Dictionary<string, object> SendQuery(string sessionId, string studentQuery)
{
    // Check if the student session is valid by retrieving the student_id
    if (!testSession.TryGetValue("student_id", out var studentId) || string.IsNullOrEmpty(studentId))
    {
        // If no student_id is found, return an error with a 401 status code
        return new Dictionary<string, object>
        {
            { "error", "Session expired" },
            { "status", 401 }
        };
    }
    
    // Validate that both sessionId and studentQuery are provided
    if (string.IsNullOrEmpty(sessionId) || string.IsNullOrEmpty(studentQuery))
    {
        // If either is missing, return an error with a 400 status code
        return new Dictionary<string, object>
        {
            { "error", "Missing session_id or query" },
            { "status", 400 }
        };
    }
        
    try
    {
        // Process the student's query using TutorService and get the tutor's response
        string tutorResponse = tutorService.ProcessQuery(studentId, sessionId, studentQuery).GetAwaiter().GetResult();

        // Return the tutor's response with a 200 status code
        return new Dictionary<string, object>
        {
            { "message", tutorResponse },
            { "status", 200 }
        };
    }
    catch (ArgumentException e)
    {
        // If an ArgumentException occurs (e.g., invalid sessionId), return a 404 error
        return new Dictionary<string, object>
        {
            { "error", e.Message },
            { "status", 404 }
        };
    }
    catch (Exception e)
    {
        // For any other exceptions, return a 500 error with the exception message
        return new Dictionary<string, object>
        {
            { "error", $"Error getting AI response: {e.Message}" },
            { "status", 500 }
        };
    }
}

In this method:

  1. We first check if the student session is valid by retrieving the student_id from the testSession. If no student_id is found, we return an error response with a 401 status code.

  2. We then validate that both sessionId and studentQuery are provided. If either is missing, we return an error response with a 400 status code.

  3. If all validations pass, we attempt to process the query using the ProcessQuery method of the TutorService. This method takes the studentId, sessionId, and studentQuery as parameters. Since ProcessQuery is asynchronous, we use .GetAwaiter().GetResult() to synchronously get the result for this context.

  4. If the query is processed successfully, we return the tutor's response in a dictionary with a status code of 200.

  5. If an ArgumentException occurs (e.g., if the session ID doesn't exist), we return an error response with a 404 status code.

  6. If any other exception occurs (e.g., if there's an issue with the AI model), we return an error response with a 500 status code.

Integrating the Tutor Controller in the Main Application

To see the TutorController in action, let's integrate it into the main application. This example demonstrates how to create a tutoring session and handle a student query, showcasing the controller's functionality.

using System;

public class Program
{
    public static void Main(string[] args)
    {
        // Initialize the TutorController
        TutorController tutorController = new TutorController();

        // Ensure a student session for testing
        string studentId = tutorController.EnsureStudentSession();

        // Create a new tutoring session
        Dictionary<string, object> sessionResponse = tutorController.CreateSession();

        // Handle session creation response
        if (sessionResponse.ContainsKey("error"))
        {
            Console.WriteLine($"Error: {sessionResponse["error"]}");
        }
        else
        {
            // Extract session_id from the response
            string sessionId = (string)sessionResponse["session_id"];
            Console.WriteLine($"Tutoring session created with session_id: {sessionId}");
            
            // Example query handling
            string studentQuery = "Can you explain the concept of inheritance in programming?";

            // Send the student query and get the response
            Dictionary<string, object> response = tutorController.SendQuery(sessionId, studentQuery);

            // Handle query response
            if (response.ContainsKey("error"))
            {
                Console.WriteLine($"Error: {response["error"]}");
            }
            else
            {
                Console.WriteLine($"Tutor Response: {response["message"]}");
            }
        }
    }
}

In this example, we first initialize the TutorController. We ensure a student session is available for testing. We then create a new tutoring session and handle the response. If successful, we simulate a student query about inheritance in programming and use the SendQuery method to process it. The response is checked for errors, and either the error message or the tutor's response is printed. This example demonstrates the flow from ensuring a student session to creating a tutoring session and handling a student query, highlighting the controller's role in managing interactions.

Summary and Next Steps

In this lesson, we explored the TutorController class and its role in managing tutoring sessions and handling student queries. We learned how to implement the controller, create tutoring sessions, and process student questions using the TutorService. The controller is a vital component of our personal tutor application, ensuring that student interactions are managed efficiently and effectively.

As you move on to the practice exercises, take the opportunity to experiment with the TutorController's functionality. This hands-on practice will reinforce the concepts covered in this lesson and prepare you for the next steps in our course. Keep up the great work, and I look forward to seeing your progress!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal