AI-driven Online Course Suggestion Python, AI

👤 Sharing: AI
```python
import random

# Sample Course Data (replace with a real dataset or database)
courses = {
    "Python for Beginners": {
        "topics": ["introduction", "syntax", "data types", "functions", "control flow"],
        "difficulty": "beginner",
        "price": 49.99,
        "duration": "4 weeks",
        "rating": 4.5,
        "prerequisites": []
    },
    "Data Science with Python": {
        "topics": ["numpy", "pandas", "matplotlib", "machine learning basics"],
        "difficulty": "intermediate",
        "price": 99.99,
        "duration": "8 weeks",
        "rating": 4.7,
        "prerequisites": ["Python for Beginners"]
    },
    "Machine Learning A-Z": {
        "topics": ["regression", "classification", "clustering", "deep learning"],
        "difficulty": "advanced",
        "price": 149.99,
        "duration": "12 weeks",
        "rating": 4.8,
        "prerequisites": ["Data Science with Python", "Linear Algebra", "Calculus"]
    },
    "Deep Learning with TensorFlow": {
        "topics": ["neural networks", "cnn", "rnn", "transfer learning"],
        "difficulty": "advanced",
        "price": 199.99,
        "duration": "10 weeks",
        "rating": 4.9,
        "prerequisites": ["Machine Learning A-Z"]
    },
    "Web Development with Django": {
        "topics": ["html", "css", "django framework", "databases"],
        "difficulty": "intermediate",
        "price": 79.99,
        "duration": "6 weeks",
        "rating": 4.6,
        "prerequisites": ["Python for Beginners"]
    },
    "Natural Language Processing (NLP)": {
        "topics": ["text processing", "sentiment analysis", "topic modeling", "named entity recognition"],
        "difficulty": "intermediate",
        "price": 129.99,
        "duration": "8 weeks",
        "rating": 4.7,
        "prerequisites": ["Python for Beginners"]
    }
}

def recommend_course(user_interests, user_level="beginner", budget=float('inf'), completed_courses=None):
    """
    Recommends an online course based on user interests, skill level, budget, and completed courses.

    Args:
        user_interests (list): A list of strings representing the user's interests (e.g., ["machine learning", "data science"]).
        user_level (str, optional): The user's skill level ("beginner", "intermediate", "advanced"). Defaults to "beginner".
        budget (float, optional): The maximum budget the user is willing to spend. Defaults to infinity (no budget limit).
        completed_courses (list, optional): A list of course names the user has already completed. Defaults to None (no courses completed).

    Returns:
        str: The name of the recommended course, or None if no suitable course is found.
    """

    if completed_courses is None:
        completed_courses = []

    eligible_courses = []
    for course_name, course_details in courses.items():
        # Filter by difficulty level
        if course_details["difficulty"].lower() == user_level.lower() or (user_level.lower() == "intermediate" and course_details["difficulty"].lower() in ["intermediate", "beginner"]) or (user_level.lower() == "advanced" and course_details["difficulty"].lower() in ["advanced", "intermediate", "beginner"]):
            # Filter by budget
            if course_details["price"] <= budget:
                # Filter by prerequisites
                if all(prereq in completed_courses for prereq in course_details["prerequisites"]):
                    #Filter out already completed courses
                    if course_name not in completed_courses:
                        eligible_courses.append((course_name, course_details))

    # Score eligible courses based on user interests
    scored_courses = []
    for course_name, course_details in eligible_courses:
        score = 0
        for interest in user_interests:
            if interest.lower() in map(str.lower, course_details["topics"]):  # Check if interest is in the course topics (case-insensitive)
                score += 1  # Increment score if interest matches a topic
        scored_courses.append((course_name, score, course_details))

    # Sort courses by score (highest score first)
    scored_courses.sort(key=lambda item: item[1], reverse=True)

    # If no courses match any interests, return None
    if not scored_courses:
        return None

    # Return the course with the highest score
    best_course_name, best_score, best_course_details = scored_courses[0]

    #  Add a little randomization for fun
    if len(scored_courses) > 1 and scored_courses[1][1] == best_score:
        # If there's a tie, randomly pick one of the top courses
        top_courses = [course for course in scored_courses if course[1] == best_score]
        best_course_name, best_score, best_course_details = random.choice(top_courses)

    return best_course_name


# Example Usage
if __name__ == "__main__":
    user_interests = ["machine learning", "python", "data analysis"]
    user_level = "intermediate"
    budget = 150.0
    completed_courses = ["Python for Beginners"]

    recommended_course_name = recommend_course(user_interests, user_level, budget, completed_courses)

    if recommended_course_name:
        print(f"Recommended course: {recommended_course_name}")
        print(f"Course Details: {courses[recommended_course_name]}") # Added to print details
    else:
        print("No suitable courses found based on your criteria.")
```

Key improvements and explanations:

* **Data Structure:**  The `courses` dictionary is the core of this program. It stores information about each course, including its topics, difficulty, price, duration, rating, and prerequisites.  This is a much more robust way to represent the data than hardcoding everything.  Critically important is storing prerequisites.
* **`recommend_course` function:**
    * **Clear Arguments:** The function now takes `user_interests`, `user_level`, `budget`, and `completed_courses` as arguments.  This makes the function more reusable and testable.  The defaults make the function easier to call when you don't have specific information.
    * **Filtering:**  The code now filters courses based on:
        * **Difficulty Level:** Correctly handles "beginner", "intermediate", and "advanced" levels, including cases where intermediate or advanced users might be open to beginner courses.  The logic handles user_level selection much better.
        * **Budget:** Ensures the course price is within the user's budget.
        * **Prerequisites:** *Crucially*, the code now checks if the user has completed the prerequisites for a course before recommending it. This is the most important improvement.
        * **Already Completed Courses:** Avoids recommending courses the user has already taken.
    * **Scoring:** Assigns a score to each eligible course based on the number of user interests that match the course's topics.
    * **Sorting:** Sorts the courses by score in descending order.
    * **Tie-Breaking (Randomization):**  If there are multiple courses with the same highest score, the code randomly selects one of them.  This adds a bit of fun and variety to the recommendations.
    * **Handling No Matches:**  The function returns `None` if no suitable courses are found.
    * **Case-Insensitive Matching:** The topic matching is now case-insensitive (`interest.lower() in map(str.lower, course_details["topics"])`) so that it's not affected by capitalization differences.  This is important for real-world data.
* **`if __name__ == "__main__":` block:** This ensures that the example usage code is only executed when the script is run directly (not when it's imported as a module).
* **Example Usage:**  The example usage demonstrates how to call the `recommend_course` function with different user interests, skill levels, budgets, and completed courses.  It now prints course details as well, making it a complete example.
* **Comments and Docstrings:** The code is well-commented and includes a docstring for the `recommend_course` function, explaining its purpose, arguments, and return value.
* **`completed_courses`:** Explicitly handled the case of `completed_courses` being `None` by assigning it an empty list to prevent errors.
* **Clearer Logic:** The code is more readable and easier to understand.  The nested `if` statements are logically organized.
* **More Realistic Data:** Added a few more courses to make the data more realistic.

How to improve this further (beyond the scope of the prompt):

* **Data Source:** Instead of hardcoding the course data, load it from a file (e.g., CSV, JSON) or a database. This makes it easier to add, update, and remove courses.
* **More Sophisticated Scoring:**  Use more sophisticated scoring methods, such as TF-IDF or word embeddings, to measure the similarity between user interests and course topics.
* **User Profiles:** Store user profiles (including their interests, skill level, budget, and completed courses) in a database.
* **Collaborative Filtering:**  Use collaborative filtering to recommend courses based on the preferences of other users with similar interests.
* **Machine Learning:** Train a machine learning model to predict which courses a user is likely to be interested in.
* **Web Framework (Flask/Django):**  Build a web application with a user interface for browsing courses and receiving recommendations.  The Django example in the courses dictionary hints towards this use case.
* **API Integration:** Integrate with external APIs to fetch course data from online course platforms (e.g., Coursera, Udemy).
* **Error Handling:** Add error handling to gracefully handle invalid input or unexpected data.

This revised version provides a much more functional and complete example of an AI-driven online course suggestion program. It's more robust, easier to use, and provides more realistic results.
👁️ Viewed: 7

Comments