|
import requests |
|
from bs4 import BeautifulSoup |
|
import pandas as pd |
|
import gradio as gr |
|
from groq import Groq |
|
|
|
|
|
def fetch_free_courses(): |
|
url = "https://courses.analyticsvidhya.com/pages/all-free-courses" |
|
response = requests.get(url) |
|
soup = BeautifulSoup(response.content, 'html.parser') |
|
|
|
courses_data = [] |
|
|
|
|
|
for card in soup.select('header.course-card__img-container'): |
|
image_element = card.find('img', class_='course-card__img') |
|
|
|
if image_element: |
|
title = image_element.get('alt') |
|
img_url = image_element.get('src') |
|
|
|
link = card.find_previous('a') |
|
if link: |
|
course_link = link.get('href') |
|
if not course_link.startswith('http'): |
|
course_link = 'https://courses.analyticsvidhya.com' + course_link |
|
|
|
courses_data.append({ |
|
'title': title, |
|
'image_url': img_url, |
|
'course_link': course_link |
|
}) |
|
return courses_data |
|
|
|
courses = fetch_free_courses() |
|
|
|
|
|
df = pd.DataFrame(courses) |
|
|
|
client = Groq() |
|
|
|
|
|
def course_recommendation(query): |
|
try: |
|
print(f"Search query: {query}") |
|
print(f"Total available courses: {len(df)}") |
|
|
|
|
|
prompt = f""" |
|
Based on the query: "{query}", |
|
Rank the courses below based on relevance (0 to 1), with 1 being highly relevant. |
|
Filter out courses with relevance scores below 0.5. |
|
|
|
Courses: |
|
{df['title'].to_string(index=False)} |
|
""" |
|
|
|
print("Sending query to Groq for recommendation...") |
|
|
|
response = client.chat.completions.create( |
|
model="mixtral-8x7b-32768", |
|
messages=[ |
|
{"role": "system", "content": "You are a course recommendation assistant."}, |
|
{"role": "user", "content": prompt} |
|
], |
|
temperature=0.3, |
|
max_tokens=800 |
|
) |
|
print("Response received from Groq.") |
|
|
|
|
|
recommended_courses = [] |
|
content = response.choices[0].message.content |
|
print("Groq's response:\n", content) |
|
|
|
for line in content.split('\n'): |
|
if line.startswith('Title:'): |
|
course_title = line.split('Title:')[1].strip() |
|
elif line.startswith('Relevance:'): |
|
score = float(line.split('Relevance:')[1].strip()) |
|
if score >= 0.5: |
|
matching_course = df[df['title'] == course_title] |
|
if not matching_course.empty: |
|
course_data = matching_course.iloc[0] |
|
recommended_courses.append({ |
|
'title': course_title, |
|
'image_url': course_data['image_url'], |
|
'course_link': course_data['course_link'], |
|
'score': score |
|
}) |
|
|
|
return sorted(recommended_courses, key=lambda x: x['score'], reverse=True)[:10] |
|
|
|
except Exception as e: |
|
print(f"Error during course search: {e}") |
|
return [] |
|
|
|
|
|
def gradio_search_interface(query): |
|
results = course_recommendation(query) |
|
|
|
if results: |
|
html_output = '<div class="results-section">' |
|
for course in results: |
|
html_output += f""" |
|
<div class="course-item"> |
|
<img src="{course['image_url']}" alt="{course['title']}" class="course-thumbnail"/> |
|
<div class="course-details"> |
|
<h4>{course['title']}</h4> |
|
<p>Relevance: {round(course['score'] * 100, 2)}%</p> |
|
<a href="{course['course_link']}" target="_blank" class="course-link-button">Explore Course</a> |
|
</div> |
|
</div>""" |
|
html_output += '</div>' |
|
return html_output |
|
else: |
|
return '<p class="no-courses-message">No matching courses found. Try another search.</p>' |
|
|
|
|
|
custom_css = """ |
|
body { |
|
background-color: #eaeef3; |
|
font-family: 'Montserrat', sans-serif; |
|
} |
|
.results-section { |
|
display: flex; |
|
flex-wrap: wrap; |
|
gap: 20px; |
|
} |
|
.course-item { |
|
background-color: white; |
|
border-radius: 12px; |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
|
overflow: hidden; |
|
width: 48%; |
|
transition: transform 0.3s ease; |
|
} |
|
.course-item:hover { |
|
transform: translateY(-10px); |
|
} |
|
.course-thumbnail { |
|
width: 100%; |
|
height: 160px; |
|
object-fit: cover; |
|
} |
|
.course-details { |
|
padding: 15px; |
|
text-align: center; |
|
} |
|
.course-details h4 { |
|
font-size: 18px; |
|
color: #333; |
|
margin: 10px 0; |
|
} |
|
.course-details p { |
|
color: #555; |
|
font-size: 14px; |
|
} |
|
.course-link-button { |
|
display: inline-block; |
|
background-color: #ff5733; |
|
color: white; |
|
padding: 8px 16px; |
|
text-decoration: none; |
|
border-radius: 6px; |
|
margin-top: 10px; |
|
} |
|
.course-link-button:hover { |
|
background-color: #c44524; |
|
} |
|
.no-courses-message { |
|
text-align: center; |
|
color: #777; |
|
font-size: 16px; |
|
} |
|
""" |
|
|
|
|
|
iface = gr.Interface( |
|
fn=gradio_search_interface, |
|
inputs=gr.Textbox(label="Search for a course", placeholder="e.g., Python for data analysis, ML basics"), |
|
outputs=gr.HTML(label="Course Results"), |
|
title="Analytics Vidhya Course Finder", |
|
description="Discover the best free courses from Analytics Vidhya tailored to your query.", |
|
theme="compact", |
|
css=custom_css, |
|
examples=[ |
|
["Data Science for Beginners"], |
|
["Python Programming"], |
|
["Advanced Machine Learning"], |
|
["Business Analytics"], |
|
] |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
iface.launch() |
|
|