├── Algolyzer ├── home │ ├── __init__.py │ ├── tests.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── create_superuser.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0003_remove_userprofile_course_and_more.py │ │ ├── 0001_initial.py │ │ └── 0002_userprofile_address_userprofile_course_and_more.py │ ├── apps.py │ ├── urls.py │ ├── decorators.py │ ├── admin.py │ ├── models.py │ ├── forms.py │ ├── templates │ │ └── home │ │ │ ├── onboarding.html │ │ │ ├── dashboard.html │ │ │ └── home.html │ └── views.py ├── quiz │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_alter_useranswer_topic_and_more.py │ │ ├── 0003_topic_description_topic_difficulty.py │ │ └── 0001_initial.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── dump_quiz.py │ ├── templates │ │ └── quiz │ │ │ ├── no_questions.html │ │ │ ├── question.html │ │ │ ├── home.html │ │ │ ├── topic.html │ │ │ └── results.html │ ├── apps.py │ ├── urls.py │ ├── forms.py │ ├── admin.py │ ├── models.py │ └── views.py ├── study │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_rename_module_topic.py │ │ ├── 0003_remove_topic_category_delete_category_delete_topic.py │ │ └── 0001_initial.py │ ├── models.py │ ├── apps.py │ ├── urls.py │ ├── views.py │ └── templates │ │ └── study │ │ ├── doodle_classifier.html │ │ ├── k_means_clustering.html │ │ ├── linear_regression.html │ │ └── svm_regression.html ├── Algolyzer │ ├── __init__.py │ ├── settings │ │ ├── __init__.py │ │ ├── development.py │ │ ├── production.py │ │ └── base.py │ ├── asgi.py │ ├── wsgi.py │ └── urls.py ├── community │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ ├── tests.py │ ├── apps.py │ ├── admin.py │ ├── urls.py │ ├── templates │ │ └── community │ │ │ ├── category_list.html │ │ │ ├── post_list.html │ │ │ └── post_detail.html │ ├── models.py │ └── views.py ├── playground │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_playgroundtask_input_image.py │ │ ├── 0003_remove_playgroundtask_celery_task_id_and_more.py │ │ └── 0001_initial.py │ ├── tests.py │ ├── apps.py │ ├── admin.py │ ├── urls.py │ ├── models.py │ ├── management │ │ └── commands │ │ │ └── download_models.py │ ├── templates │ │ └── playground │ │ │ ├── sentiment_analysis.html │ │ │ ├── doodle_classifier.html │ │ │ ├── linear_regression.html │ │ │ └── kmeans_clustering.html │ └── tasks.py ├── static │ ├── algolyzer.ico │ └── input.css ├── templates │ ├── socialaccount │ │ └── snippets │ │ │ ├── login.html │ │ │ └── provider_list.html │ ├── account │ │ ├── signup.html │ │ └── login.html │ └── base.html ├── manage.py └── data │ └── quiz_data.json ├── docs ├── assets │ └── Algolyzer_homepage.png ├── setup_production.md ├── setup_development.md └── CONTRIBUTING.md ├── setup.cfg ├── run_qa_format ├── pyproject.toml ├── .github ├── ISSUE_TEMPLATE │ ├── bug-🐞.md │ └── feature---enhancement-✨.md └── workflows │ └── ci.yml ├── .pre-commit-config.yaml ├── tailwind.config.js ├── .env.sample ├── package.json ├── LICENSE ├── Dockerfile ├── README.md ├── requirements.txt └── .gitignore /Algolyzer/home/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/quiz/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/study/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/community/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/home/tests.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /Algolyzer/playground/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/home/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/home/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/quiz/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/study/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/settings/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/community/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/playground/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/home/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/quiz/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algolyzer/study/models.py: -------------------------------------------------------------------------------- 1 | # from django.db import models 2 | -------------------------------------------------------------------------------- /Algolyzer/quiz/templates/quiz/no_questions.html: -------------------------------------------------------------------------------- 1 |

No Questions in this topic!

-------------------------------------------------------------------------------- /Algolyzer/community/tests.py: -------------------------------------------------------------------------------- 1 | # from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Algolyzer/playground/tests.py: -------------------------------------------------------------------------------- 1 | # from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Algolyzer/static/algolyzer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Priyanshu-Batham/Algolyzer/HEAD/Algolyzer/static/algolyzer.ico -------------------------------------------------------------------------------- /docs/assets/Algolyzer_homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Priyanshu-Batham/Algolyzer/HEAD/docs/assets/Algolyzer_homepage.png -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 88 3 | extend-ignore = E203, W503, E501, F405, F403 4 | exclude = .git,__pycache__,.venv,build,dist,env,.env,venv 5 | -------------------------------------------------------------------------------- /Algolyzer/home/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class HomeConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "home" 7 | -------------------------------------------------------------------------------- /Algolyzer/quiz/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class QuizConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "quiz" 7 | -------------------------------------------------------------------------------- /Algolyzer/study/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class StudyConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "study" 7 | -------------------------------------------------------------------------------- /Algolyzer/community/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CommunityConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "community" 7 | -------------------------------------------------------------------------------- /Algolyzer/playground/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PlaygroundConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "playground" 7 | -------------------------------------------------------------------------------- /run_qa_format: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Running Black..." 4 | black . 5 | 6 | echo "Running isort..." 7 | isort . 8 | 9 | echo "Running Flake8..." 10 | flake8 11 | 12 | echo "Quality assurance checks completed." 13 | -------------------------------------------------------------------------------- /Algolyzer/community/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Category, Comment, Post, Vote 4 | 5 | admin.site.register(Post) 6 | admin.site.register(Comment) 7 | admin.site.register(Vote) 8 | admin.site.register(Category) 9 | -------------------------------------------------------------------------------- /Algolyzer/home/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import dashboard, home, onboarding 4 | 5 | urlpatterns = [ 6 | path("", home, name="home"), 7 | path("dashboard/", dashboard, name="dashboard"), 8 | path("onboarding/", onboarding, name="onboarding"), 9 | ] 10 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 88 3 | exclude = ''' 4 | /( 5 | env|venv # Exclude the env and venv folders 6 | )/ 7 | ''' 8 | 9 | [tool.isort] 10 | profile = "black" 11 | line_length = 88 12 | skip = [ 13 | "env", # Exclude the env folder 14 | "venv" # Exclude the venv folder 15 | ] 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-🐞.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug \U0001F41E" 3 | about: Template to use for raising issues related to bugs 4 | title: 'Bug: Title of Issue' 5 | labels: bug, enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Explanation 11 | - 12 | - 13 | Screenshot (optional) 14 | ## Reason 15 | - 16 | - 17 | ## Possible Fixes 18 | - 19 | - 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature---enhancement-✨.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature / Enhancement ✨ 3 | about: Template to use for issues related to enhancement. 4 | title: "[Feature] Title of Issue" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## What is to be done? 11 | - 12 | - 13 | ## Possible steps/resources to achieve it. 14 | - 15 | - 16 | -------------------------------------------------------------------------------- /Algolyzer/static/input.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400..700&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/settings/development.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | DEBUG = True 4 | 5 | ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",") 6 | 7 | DATABASES = { 8 | "default": { 9 | "ENGINE": "django.db.backends.sqlite3", 10 | "NAME": BASE_DIR / "db.sqlite3", 11 | } 12 | } 13 | 14 | EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: 23.9.1 # Use the latest version 4 | hooks: 5 | - id: black 6 | 7 | - repo: https://github.com/PyCQA/isort 8 | rev: 5.12.0 # Use the latest version 9 | hooks: 10 | - id: isort 11 | 12 | - repo: https://github.com/PyCQA/flake8 13 | rev: 6.1.0 # Use the latest version 14 | hooks: 15 | - id: flake8 -------------------------------------------------------------------------------- /Algolyzer/study/migrations/0002_rename_module_topic.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-13 15:10 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("study", "0001_initial"), 9 | ] 10 | 11 | operations = [ 12 | migrations.RenameModel( 13 | old_name="Module", 14 | new_name="Topic", 15 | ), 16 | ] 17 | -------------------------------------------------------------------------------- /Algolyzer/playground/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import PlaygroundTask 4 | 5 | 6 | @admin.register(PlaygroundTask) 7 | class PlaygroundTaskAdmin(admin.ModelAdmin): 8 | list_display = ("id", "user", "model_name", "status", "created_at", "completed_at") 9 | list_filter = ("status", "model_name", "created_at") 10 | search_fields = ("user__username", "model_name", "input_data") 11 | readonly_fields = ("created_at", "completed_at") 12 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for Algolyzer project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Algolyzer.settings") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for Algolyzer project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Algolyzer.settings.production") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Algolyzer/quiz/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import quiz_home, quiz_question, quiz_results, quiz_start, quiz_topic 4 | 5 | urlpatterns = [ 6 | path("", quiz_home, name="quiz_home"), 7 | path("topic//", quiz_topic, name="quiz_topic"), 8 | path("start//", quiz_start, name="quiz_start"), 9 | path("question//", quiz_question, name="quiz_question"), 10 | path("results//", quiz_results, name="quiz_results"), 11 | ] 12 | -------------------------------------------------------------------------------- /Algolyzer/home/decorators.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | from django.shortcuts import redirect 4 | from home.models import UserProfile 5 | 6 | 7 | def profile_required(view_func): 8 | @wraps(view_func) 9 | def _wrapped_view(request, *args, **kwargs): 10 | if not UserProfile.objects.filter(user=request.user).exists(): 11 | return redirect("onboarding") # Replace with your onboarding route name 12 | return view_func(request, *args, **kwargs) 13 | 14 | return _wrapped_view 15 | -------------------------------------------------------------------------------- /Algolyzer/home/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import UserProfile 4 | 5 | 6 | # Optionally, create a custom admin class to manage the model 7 | class UserProfileAdmin(admin.ModelAdmin): 8 | # Define fields to display in the list view 9 | list_display = ("user", "dob", "xp", "level") 10 | # Optionally, allow searching by the user's username 11 | search_fields = ("user__username",) 12 | 13 | 14 | # Register the UserProfile model with the admin 15 | admin.site.register(UserProfile, UserProfileAdmin) 16 | -------------------------------------------------------------------------------- /Algolyzer/playground/migrations/0002_playgroundtask_input_image.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-02-23 05:08 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ("playground", "0001_initial"), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name="playgroundtask", 15 | name="input_image", 16 | field=models.ImageField(blank=True, null=True, upload_to="doodles/"), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /Algolyzer/quiz/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | 4 | class QuizForm(forms.Form): 5 | def __init__(self, question, *args, **kwargs): 6 | super().__init__(*args, **kwargs) 7 | self.fields["answer"] = forms.ChoiceField( 8 | label=question.text, 9 | choices=[ 10 | ("a", question.option_a), 11 | ("b", question.option_b), 12 | ("c", question.option_c), 13 | ("d", question.option_d), 14 | ], 15 | widget=forms.RadioSelect, 16 | ) 17 | -------------------------------------------------------------------------------- /Algolyzer/community/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path("", views.category_list, name="category_list"), 7 | path( 8 | "category//", 9 | views.post_list_by_category, 10 | name="post_list_by_category", 11 | ), 12 | path("post//", views.post_detail, name="post_detail"), 13 | path("post//comment/", views.add_comment, name="add_comment"), 14 | path("post//vote//", views.vote_post, name="vote_post"), 15 | ] 16 | -------------------------------------------------------------------------------- /Algolyzer/home/migrations/0003_remove_userprofile_course_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-03-30 06:31 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("home", "0002_userprofile_address_userprofile_course_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.RemoveField( 13 | model_name="userprofile", 14 | name="course", 15 | ), 16 | migrations.RemoveField( 17 | model_name="userprofile", 18 | name="enrollment_date", 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /Algolyzer/templates/socialaccount/snippets/login.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load allauth %} 3 | {% load socialaccount %} 4 | {% get_providers as socialaccount_providers %} 5 | {% if socialaccount_providers %} 6 | {% comment %} {% if not SOCIALACCOUNT_ONLY %} 7 | {% element hr %} 8 | {% endelement %} 9 | {% element h2 %} 10 | {% translate "Use a third-party" %} 11 | {% endelement %} 12 | {% endif %} {% endcomment %} 13 | {% include "socialaccount/snippets/provider_list.html" with process="login" %} 14 | {% include "socialaccount/snippets/login_extra.html" %} 15 | {% endif %} 16 | -------------------------------------------------------------------------------- /Algolyzer/study/migrations/0003_remove_topic_category_delete_category_delete_topic.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-02-13 12:11 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("study", "0002_rename_module_topic"), 9 | ] 10 | 11 | operations = [ 12 | migrations.RemoveField( 13 | model_name="topic", 14 | name="category", 15 | ), 16 | migrations.DeleteModel( 17 | name="Category", 18 | ), 19 | migrations.DeleteModel( 20 | name="Topic", 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /Algolyzer/study/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path("", views.home, name="study_home"), 7 | path( 8 | "sentiment_analysis/", views.sentiment_analysis, name="sentiment_analysis_study" 9 | ), 10 | path("doodle_classifer/", views.doodle_classifier, name="doodle_classifier_study"), 11 | path("linear_regression/", views.linear_regression, name="linear_regression_study"), 12 | path( 13 | "k_means_clustering/", views.k_means_clustering, name="k_means_clustering_study" 14 | ), 15 | path("svm_regression/", views.svm_regression, name="svm_regression_study"), 16 | ] 17 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './Algolyzer/templates/**/*.html', //shared template dir at root level 5 | './Algolyzer/**/templates/**/*.html', //template dirs at app level 6 | ], 7 | theme: { 8 | extend: { 9 | fontFamily: { 10 | poppins: ['Poppins', 'sans-serif'], 11 | montserrat: ['Montserrat', 'sans-serif'], 12 | dance: ['Dancing Script', 'sans-serif'] 13 | }, 14 | }, 15 | }, 16 | plugins: [require('daisyui'),], 17 | 18 | // DaisyUI Theme setup 19 | daisyui: { 20 | themes: [ 21 | "winter", 22 | ], 23 | }, 24 | } -------------------------------------------------------------------------------- /Algolyzer/study/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | 4 | def home(request): 5 | return render(request, "study/home.html") 6 | 7 | 8 | def sentiment_analysis(request): 9 | return render(request, "study/sentiment_analysis.html") 10 | 11 | 12 | def doodle_classifier(request): 13 | return render(request, "study/doodle_classifier.html") 14 | 15 | 16 | def linear_regression(request): 17 | return render(request, "study/linear_regression.html") 18 | 19 | 20 | def k_means_clustering(request): 21 | return render(request, "study/k_means_clustering.html") 22 | 23 | 24 | def svm_regression(request): 25 | return render(request, "study/svm_regression.html") 26 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # (optional) if Google Signup needed 2 | GOOGLE_CLIENT_ID=YOUR-CLIENT-ID 3 | GOOGLE_SECRET_KEY=YOUR-SECRET-KEY 4 | 5 | # Where the app is being run 6 | ALLOWED_HOSTS=localhost,127.0.0.1,192.168.1.13,localhost,127.0.0.1,192.168.1.13,192.168.1.150 7 | CSRF_TRUSTED_ORIGINS=http://localhost,http://127.0.0.1,http://192.168.1.13,http://localhost:8000,http://127.0.0.1:8000,http://192.168.1.13:8000,http://192.168.1.150:8000 8 | 9 | # default admin credentials 10 | DJANGO_SUPERUSER_USERNAME=admin 11 | DJANGO_SUPERUSER_EMAIL=admin@gmail.com 12 | DJANGO_SUPERUSER_PASSWORD=admin 13 | 14 | # Uncomment for development 15 | #CELERY_BROKER_URL=redis://localhost:6379/0 16 | # Uncomment for production 17 | #CELERY_BROKER_URL=redis://redis:6379/0 -------------------------------------------------------------------------------- /Algolyzer/playground/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import ( 4 | doodle_classifier, 5 | kmeans_clustering, 6 | linear_regression, 7 | playground_home, 8 | sentiment_analysis, 9 | svm_regression, 10 | ) 11 | 12 | urlpatterns = [ 13 | path("", playground_home, name="playground_home"), 14 | path("linear_regression", linear_regression, name="linear_regression"), 15 | path("kmeans_clustering", kmeans_clustering, name="kmeans_clustering"), 16 | path("svm_regression", svm_regression, name="svm_regression"), 17 | path("sentiment_analysis/", sentiment_analysis, name="sentiment_analysis"), 18 | path("doodle_classifier/", doodle_classifier, name="doodle_classifier"), 19 | ] 20 | -------------------------------------------------------------------------------- /Algolyzer/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Algolyzer.settings.development") 10 | 11 | try: 12 | from django.core.management import execute_from_command_line 13 | except ImportError as exc: 14 | raise ImportError( 15 | "Couldn't import Django. Are you sure it's installed and " 16 | "available on your PYTHONPATH environment variable? Did you " 17 | "forget to activate a virtual environment?" 18 | ) from exc 19 | execute_from_command_line(sys.argv) 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /Algolyzer/playground/migrations/0003_remove_playgroundtask_celery_task_id_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-04-03 11:06 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("playground", "0002_playgroundtask_input_image"), 9 | ] 10 | 11 | operations = [ 12 | migrations.RemoveField( 13 | model_name="playgroundtask", 14 | name="celery_task_id", 15 | ), 16 | migrations.AlterField( 17 | model_name="playgroundtask", 18 | name="status", 19 | field=models.CharField( 20 | choices=[("COMPLETED", "Completed"), ("FAILED", "Failed")], 21 | default="PENDING", 22 | max_length=20, 23 | ), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /Algolyzer/community/templates/community/category_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |

Categories

6 |
7 | {% for category in categories %} 8 | 9 |
10 |

{{ category.name }}

11 |

{{ category.description }}

12 |
13 |
14 | {% endfor %} 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /Algolyzer/quiz/migrations/0002_alter_useranswer_topic_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-12 14:50 2 | 3 | import django.db.models.deletion 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | dependencies = [ 10 | ("quiz", "0001_initial"), 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name="useranswer", 17 | name="topic", 18 | field=models.ForeignKey( 19 | on_delete=django.db.models.deletion.CASCADE, to="quiz.topic" 20 | ), 21 | ), 22 | migrations.AlterUniqueTogether( 23 | name="useranswer", 24 | unique_together={("user", "topic", "question")}, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /Algolyzer/playground/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from django.db import models 3 | 4 | 5 | class PlaygroundTask(models.Model): 6 | STATUS_CHOICES = [ 7 | ("COMPLETED", "Completed"), 8 | ("FAILED", "Failed"), 9 | ] 10 | user = models.ForeignKey(User, on_delete=models.CASCADE) 11 | model_name = models.CharField(max_length=100) # Selected ML model 12 | input_data = models.TextField() # Store user input (can be JSON) 13 | input_image = models.ImageField(upload_to="doodles/", blank=True, null=True) 14 | status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="PENDING") 15 | result = models.TextField(blank=True, null=True) # ML output 16 | created_at = models.DateTimeField(auto_now_add=True) 17 | completed_at = models.DateTimeField(blank=True, null=True) 18 | 19 | def __str__(self): 20 | return f"Task {self.model_name} - {self.status}" 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algolyzer", 3 | "version": "1.0.0", 4 | "description": "A platform for learning about AI/ML models and algorithms from theoretical to executing pre-trained models all at one place.", 5 | "main": "index.js", 6 | "scripts": { 7 | "tw_build": "npx tailwindcss build -i Algolyzer/static/input.css -o Algolyzer/static/output.css", 8 | "tw_watch": "npx tailwindcss -i Algolyzer/static/input.css -o Algolyzer/static/output.css --watch" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Priyanshu-Batham/Algolyzer.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/Priyanshu-Batham/Algolyzer/issues" 19 | }, 20 | "homepage": "https://github.com/Priyanshu-Batham/Algolyzer#readme", 21 | "devDependencies": { 22 | "autoprefixer": "^10.4.20", 23 | "daisyui": "^4.12.23", 24 | "postcss": "^8.5.1", 25 | "tailwindcss": "^3.4.17" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/setup_production.md: -------------------------------------------------------------------------------- 1 | # Pre Requisites 2 | The project is built using following versions of software: 3 | 1. Docker & Docker-Compose 4 | 5 | ## Clone the Forked Repository 6 | ```bash 7 | git clone https://github.com/priyanshu-batham/Algolyzer.git 8 | cd Algolyzer 9 | ``` 10 | 11 | ## (Optional) Setting up Google OAuth service 12 | Goto [Google Developer Console](https://console.developers.google.com). Make a new OAuth Client using the following URL as the Authorized Redirect URI: 13 | ```http://localhost:8000/accounts/google/login/callback/``` 14 | 15 | ## Copy .env.sample into .env 16 | 17 | ```bash 18 | cp .env.sample .env 19 | ``` 20 | ## IMPORTANT: Read the `.env` carefully and make sure to uncomment and comment necessary `CELERY_BROKER_URL` lines in `.env` as specified there. 21 | 22 | 3. Run the docker containers 23 | ```bash 24 | docker-compose up --build 25 | ``` 26 | ## Open a web browser and goto 27 | ```bash 28 | http://localhost:8000 29 | ``` 30 | **Note - Always use `localhost:8000` instead of `127.0.0.1:8000` if you don't want access blocked from Google during development** -------------------------------------------------------------------------------- /Algolyzer/quiz/migrations/0003_topic_description_topic_difficulty.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-31 10:28 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("quiz", "0002_alter_useranswer_topic_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AddField( 13 | model_name="topic", 14 | name="description", 15 | field=models.CharField(default="No description provided.", max_length=1000), 16 | ), 17 | migrations.AddField( 18 | model_name="topic", 19 | name="difficulty", 20 | field=models.CharField( 21 | choices=[ 22 | ("Easy", "Easy"), 23 | ("Medium", "Medium"), 24 | ("Hard", "Hard"), 25 | ("Veteran", "Veteran"), 26 | ], 27 | default="Easy", 28 | help_text="Difficulty levels", 29 | max_length=7, 30 | ), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Priyanshu Batham 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Algolyzer/quiz/management/commands/dump_quiz.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.management import call_command 4 | from django.core.management.base import BaseCommand 5 | 6 | 7 | class Command(BaseCommand): 8 | help = "Dump data for quiz models (Question and Topic) into a JSON file." 9 | 10 | def add_arguments(self, parser): 11 | parser.add_argument( 12 | "--output", 13 | type=str, 14 | default="./data/quiz_data.json", 15 | help="Output file path (default: ./data/quiz_data.json)", 16 | ) 17 | 18 | def handle(self, *args, **kwargs): 19 | output_path = kwargs["output"] 20 | os.makedirs(os.path.dirname(output_path), exist_ok=True) 21 | 22 | self.stdout.write("Dumping quiz data into: {}".format(output_path)) 23 | 24 | call_command( 25 | "dumpdata", 26 | "quiz.Question", 27 | "quiz.Topic", 28 | "--natural-primary", 29 | "--natural-foreign", 30 | "--indent", 31 | "4", 32 | stdout=open(output_path, "w"), 33 | ) 34 | 35 | self.stdout.write(self.style.SUCCESS("Data dumped successfully!")) 36 | -------------------------------------------------------------------------------- /Algolyzer/home/management/commands/create_superuser.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.contrib.auth import get_user_model 4 | from django.core.management.base import BaseCommand 5 | 6 | 7 | class Command(BaseCommand): 8 | help = "Create a superuser if it doesn't exist" 9 | 10 | def handle(self, *args, **kwargs): 11 | User = get_user_model() 12 | username = os.getenv("DJANGO_SUPERUSER_USERNAME") 13 | email = os.getenv("DJANGO_SUPERUSER_EMAIL") 14 | password = os.getenv("DJANGO_SUPERUSER_PASSWORD") 15 | 16 | if username and email and password: 17 | if not User.objects.filter(username=username).exists(): 18 | User.objects.create_superuser( 19 | username=username, email=email, password=password 20 | ) 21 | self.stdout.write( 22 | self.style.SUCCESS(f"Superuser {username} created successfully.") 23 | ) 24 | else: 25 | self.stdout.write( 26 | self.style.WARNING(f"Superuser {username} already exists.") 27 | ) 28 | else: 29 | self.stdout.write( 30 | self.style.ERROR( 31 | "Superuser credentials not provided. Skipping creation." 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /Algolyzer/templates/socialaccount/snippets/provider_list.html: -------------------------------------------------------------------------------- 1 | {% load allauth socialaccount %} 2 | {% get_providers as socialaccount_providers %} 3 | {% if socialaccount_providers %} 4 | {% element provider_list %} 5 | {% for provider in socialaccount_providers %} 6 | {% if provider.id == "google" %} 7 | {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} 8 | 9 | Sign in with Google 10 | 11 | {% elif provider.id == "facebook" %} 12 | {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} 13 | 14 | Sign in with Facebook 15 | 16 | {% else %} 17 | {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} 18 | 19 | {{ provider.name }} 20 | 21 | {% endif %} 22 | {% endfor %} 23 | {% endelement %} 24 | {% endif %} 25 | 26 | -------------------------------------------------------------------------------- /Algolyzer/home/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-12 13:17 2 | 3 | import django.db.models.deletion 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | initial = True 10 | 11 | dependencies = [ 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name="UserProfile", 18 | fields=[ 19 | ( 20 | "id", 21 | models.BigAutoField( 22 | auto_created=True, 23 | primary_key=True, 24 | serialize=False, 25 | verbose_name="ID", 26 | ), 27 | ), 28 | ("dob", models.DateField()), 29 | ("xp", models.PositiveIntegerField(default=0)), 30 | ("level", models.PositiveIntegerField(default=1)), 31 | ( 32 | "user", 33 | models.OneToOneField( 34 | on_delete=django.db.models.deletion.CASCADE, 35 | to=settings.AUTH_USER_MODEL, 36 | ), 37 | ), 38 | ], 39 | ), 40 | ] 41 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Python Lint, Format, and Tests 2 | 3 | on: [push] 4 | 5 | jobs: 6 | lint-format-test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout repository 11 | uses: actions/checkout@v3 12 | 13 | - name: Set up Node.js 14 | uses: actions/setup-node@v3 15 | with: 16 | node-version: 22.13.0 17 | 18 | - name: Install Node.js dependencies 19 | run: npm install 20 | 21 | - name: Build Tailwind CSS 22 | run: npm run tw_build 23 | 24 | - name: Set up Python 25 | uses: actions/setup-python@v4 26 | with: 27 | python-version: 3.12 28 | 29 | - name: Install dependencies 30 | run: | 31 | pip install -r requirements.txt 32 | pip install black isort flake8 33 | 34 | - name: Run Black (check) 35 | run: black --check . 36 | 37 | - name: Run Isort (check) 38 | run: isort --check-only . 39 | 40 | - name: Run Flake8 41 | run: flake8 . 42 | 43 | - name: Run Django Tests 44 | run: | 45 | 46 | # Run Django tests with manage.py 47 | export PYTHONPATH=./Algolyzer:$PYTHONPATH 48 | export DJANGO_SETTINGS_MODULE=Algolyzer.settings.development 49 | cd Algolyzer 50 | python manage.py test 51 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | URL configuration for Algolyzer project. 3 | 4 | The `urlpatterns` list routes URLs to views. For more information please see: 5 | https://docs.djangoproject.com/en/5.1/topics/http/urls/ 6 | Examples: 7 | Function views 8 | 1. Add an import: from my_app import views 9 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 10 | Class-based views 11 | 1. Add an import: from other_app.views import Home 12 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 13 | Including another URLconf 14 | 1. Import the include() function: from django.urls import include, path 15 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 16 | """ 17 | 18 | from django.contrib import admin 19 | from django.urls import include, path 20 | 21 | admin.site.site_header = "Algolyzer Admin" 22 | admin.site.site_title = "Algolyzer" 23 | admin.site.index_title = "Welcome to Algolyzer" 24 | 25 | urlpatterns = [ 26 | # admin url 27 | path("admin/", admin.site.urls), 28 | # algolyzer urls 29 | path("", include("home.urls")), 30 | path("quiz/", include("quiz.urls")), 31 | path("study/", include("study.urls")), 32 | path("community/", include("community.urls")), 33 | path("playground/", include("playground.urls")), 34 | # allauth urls 35 | path("accounts/", include("allauth.urls")), 36 | ] 37 | -------------------------------------------------------------------------------- /Algolyzer/playground/management/commands/download_models.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.management.base import BaseCommand 4 | from transformers import AutoModel, AutoTokenizer 5 | 6 | # Define models to download 7 | MODELS = { 8 | "sentiment-analysis": "finiteautomata/bertweet-base-sentiment-analysis", 9 | } 10 | 11 | # Define directory for saving models 12 | MODEL_DIR = os.path.join("playground", "aiml_models") 13 | 14 | 15 | class Command(BaseCommand): 16 | help = "Download Hugging Face models for use in Django views" 17 | 18 | def handle(self, *args, **kwargs): 19 | os.makedirs(MODEL_DIR, exist_ok=True) 20 | for task, model_name in MODELS.items(): 21 | self.stdout.write( 22 | self.style.SUCCESS(f"Downloading {task} model: {model_name}...") 23 | ) 24 | 25 | # Download model and tokenizer 26 | model = AutoModel.from_pretrained(model_name) 27 | tokenizer = AutoTokenizer.from_pretrained(model_name) 28 | 29 | # Save them in the specified directory 30 | model.save_pretrained(os.path.join(MODEL_DIR, model_name.replace("/", "_"))) 31 | tokenizer.save_pretrained( 32 | os.path.join(MODEL_DIR, model_name.replace("/", "_")) 33 | ) 34 | 35 | self.stdout.write( 36 | self.style.SUCCESS(f"✔ Model {model_name} downloaded successfully!\n") 37 | ) 38 | -------------------------------------------------------------------------------- /Algolyzer/community/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.db import models 3 | 4 | 5 | class Category(models.Model): 6 | name = models.CharField(max_length=255, unique=True) 7 | description = models.TextField(blank=True) 8 | 9 | def __str__(self): 10 | return self.name 11 | 12 | 13 | class Post(models.Model): 14 | title = models.CharField(max_length=255) 15 | content = models.TextField() 16 | author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 17 | created_at = models.DateTimeField(auto_now_add=True) 18 | updated_at = models.DateTimeField(auto_now=True) 19 | category = models.ForeignKey(Category, on_delete=models.CASCADE) 20 | 21 | def __str__(self): 22 | return self.title 23 | 24 | 25 | class Comment(models.Model): 26 | post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments") 27 | author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 28 | content = models.TextField() 29 | created_at = models.DateTimeField(auto_now_add=True) 30 | 31 | def __str__(self): 32 | return f"Comment by {self.author.username} on {self.post.title}" 33 | 34 | 35 | class Vote(models.Model): 36 | VOTE_TYPES = [(1, "Upvote"), (-1, "Downvote")] 37 | post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="votes") 38 | user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 39 | vote_type = models.IntegerField(choices=VOTE_TYPES) 40 | 41 | class Meta: 42 | unique_together = ("post", "user") 43 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use Python slim image as base 2 | FROM python:3.12-slim 3 | 4 | # Set environment variables 5 | ENV PYTHONUNBUFFERED=1 6 | 7 | # Set the working directory 8 | WORKDIR /app 9 | 10 | # Install system dependencies 11 | RUN apt-get update && \ 12 | apt-get install -y --no-install-recommends \ 13 | curl \ 14 | bash \ 15 | nodejs \ 16 | npm && \ 17 | rm -rf /var/lib/apt/lists/* && \ 18 | apt-get clean 19 | 20 | # Install specific npm version 21 | RUN npm install -g npm@10.9.2 22 | 23 | # Copy requirements.txt 24 | COPY ./requirements.txt /app/ 25 | 26 | # Install Python dependencies 27 | RUN pip install --no-cache-dir -r requirements.txt gunicorn 28 | 29 | # Install Node.js dependencies (Tailwind, etc.) 30 | COPY ./package.json /app/ 31 | RUN npm install 32 | 33 | # Copy project files 34 | COPY . /app/ 35 | 36 | # Run tailwind build 37 | RUN npm run tw_build 38 | 39 | # Change working directory 40 | WORKDIR /app/Algolyzer/ 41 | 42 | # Migrate database 43 | RUN python manage.py migrate 44 | 45 | # Seed the database 46 | RUN python manage.py loaddata data/* 47 | 48 | # Collect static files 49 | RUN python manage.py collectstatic --noinput 50 | 51 | # Download aiml models (thinking of pushing models to github and everywhere directly) 52 | RUN python manage.py download_models 53 | 54 | # Expose port 8000 55 | EXPOSE 8000 56 | 57 | # Use production settings instead of default development settings 58 | ENV DJANGO_SETTINGS_MODULE=Algolyzer.settings.production 59 | 60 | # Start the application 61 | CMD (celery -A Algolyzer worker --loglevel=info &) && python manage.py create_superuser && gunicorn --bind 0.0.0.0:8000 --access-logfile - --error-logfile - Algolyzer.wsgi:application 62 | -------------------------------------------------------------------------------- /Algolyzer/home/migrations/0002_userprofile_address_userprofile_course_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-02-11 04:13 2 | 3 | import django.utils.timezone 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | dependencies = [ 9 | ("home", "0001_initial"), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name="userprofile", 15 | name="address", 16 | field=models.TextField(blank=True, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name="userprofile", 20 | name="course", 21 | field=models.CharField(default="Undecided", max_length=100), 22 | ), 23 | migrations.AddField( 24 | model_name="userprofile", 25 | name="enrollment_date", 26 | field=models.DateField(default=django.utils.timezone.now), 27 | ), 28 | migrations.AddField( 29 | model_name="userprofile", 30 | name="full_name", 31 | field=models.CharField(default="Unknown", max_length=100), 32 | preserve_default=False, 33 | ), 34 | migrations.AddField( 35 | model_name="userprofile", 36 | name="gender", 37 | field=models.CharField( 38 | blank=True, 39 | choices=[("M", "Male"), ("F", "Female"), ("O", "Other")], 40 | max_length=1, 41 | null=True, 42 | ), 43 | ), 44 | migrations.AddField( 45 | model_name="userprofile", 46 | name="phone_number", 47 | field=models.CharField(blank=True, max_length=15, null=True), 48 | ), 49 | ] 50 | -------------------------------------------------------------------------------- /Algolyzer/quiz/templates/quiz/question.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 | {% comment %} Steps {% endcomment %} 6 |
7 |
    8 | {% for i in total_array %} 9 |
  • 12 | {% endfor %} 13 |
14 |
15 | 16 |
17 | {% csrf_token %} 18 | 19 |
20 |

{{ form.answer.label }}

{# Display question text #} 21 | 22 |
23 | {% for choice in form.answer %} 24 | 28 | {% endfor %} 29 |
30 |
31 | 32 | 33 |
34 | 35 | 36 | {% comment %}

Question {{ progress.current_question|add:1 }} of {{ progress.topic.question_set.count }}

{% endcomment %} 37 |
38 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/home/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.db import models 3 | 4 | 5 | class UserProfile(models.Model): 6 | user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE) 7 | 8 | # Personal Information 9 | full_name = models.CharField(max_length=100) 10 | dob = models.DateField() 11 | phone_number = models.CharField(max_length=15, blank=True, null=True) 12 | gender = models.CharField( 13 | max_length=1, 14 | choices=[("M", "Male"), ("F", "Female"), ("O", "Other")], 15 | blank=True, 16 | null=True, 17 | ) 18 | address = models.TextField(blank=True, null=True) 19 | 20 | # Ranking System 21 | xp = models.PositiveIntegerField(default=0) 22 | level = models.PositiveIntegerField(default=1) 23 | 24 | def __str__(self): 25 | return self.user.username 26 | 27 | def add_xp(self, amount): 28 | """Add XP and check for level up""" 29 | self.xp += amount 30 | self.check_level_up() 31 | self.save() 32 | 33 | def check_level_up(self): 34 | """Update level based on XP thresholds""" 35 | level_thresholds = [0, 100, 300, 600, 1000, 1500, 2100, 2800, 3600, 4500] 36 | # If user has more exp than our thresholds itself then dynamically create new thresholds 37 | while len(level_thresholds) <= self.level: 38 | level_thresholds.append( 39 | level_thresholds[-1] + (self.level * 500) 40 | ) # Custom scaling 41 | 42 | for i, threshold in enumerate(level_thresholds): 43 | if self.xp >= threshold: 44 | self.level = i + 1 45 | 46 | def get_next_level_xp(self): 47 | """Returns XP required for the next level""" 48 | level_thresholds = [0, 100, 300, 600, 1000, 1500, 2100, 2800, 3600, 4500] 49 | if self.level < len(level_thresholds): 50 | return level_thresholds[self.level] - self.xp 51 | return None # If max level is reached 52 | -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/settings/production.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | DEBUG = True 4 | 5 | ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",") 6 | CSRF_TRUSTED_ORIGINS = os.getenv( 7 | "CSRF_TRUSTED_ORIGINS", 8 | "http://localhost,http://127.0.0.1,http://localhost:8000,http://127.0.0.1:8000", 9 | ).split(",") 10 | 11 | 12 | DATABASES = { 13 | "default": { 14 | "ENGINE": "django.db.backends.sqlite3", 15 | "NAME": BASE_DIR / "db.sqlite3", 16 | } 17 | } 18 | 19 | EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" 20 | 21 | # Using whitenoise to serve static files (should use nginx) 22 | MIDDLEWARE.insert(1, "whitenoise.middleware.WhiteNoiseMiddleware") 23 | STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" 24 | 25 | # CSRF_COOKIE_SECURE = False # Since you're using HTTP (for now) 26 | # SESSION_COOKIE_SECURE = False # Since you're using HTTP (for now) 27 | 28 | # To be done like this in future: 29 | # from .base import * 30 | 31 | # DEBUG = False 32 | 33 | # ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",") 34 | 35 | # for https: 36 | # SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") 37 | # SESSION_COOKIE_SECURE = True 38 | # CSRF_COOKIE_SECURE = True 39 | 40 | # DATABASES = { 41 | # "default": { 42 | # "ENGINE": "django.db.backends.postgresql", 43 | # "NAME": os.getenv("DB_NAME"), 44 | # "USER": os.getenv("DB_USER"), 45 | # "PASSWORD": os.getenv("DB_PASSWORD"), 46 | # "HOST": os.getenv("DB_HOST"), 47 | # "PORT": os.getenv("DB_PORT", "5432"), 48 | # } 49 | # } 50 | 51 | # SECURE_BROWSER_XSS_FILTER = True 52 | # SECURE_CONTENT_TYPE_NOSNIFF = True 53 | # SESSION_COOKIE_SECURE = True 54 | # CSRF_COOKIE_SECURE = True 55 | # X_FRAME_OPTIONS = "DENY" 56 | 57 | # EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" 58 | # EMAIL_HOST = os.getenv("EMAIL_HOST") 59 | # EMAIL_PORT = os.getenv("EMAIL_PORT") 60 | # EMAIL_USE_TLS = True 61 | # EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER") 62 | # EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD") 63 | -------------------------------------------------------------------------------- /Algolyzer/study/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-13 13:31 2 | 3 | import django.db.models.deletion 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | initial = True 9 | 10 | dependencies = [] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name="Category", 15 | fields=[ 16 | ( 17 | "id", 18 | models.BigAutoField( 19 | auto_created=True, 20 | primary_key=True, 21 | serialize=False, 22 | verbose_name="ID", 23 | ), 24 | ), 25 | ("name", models.CharField(max_length=255)), 26 | ( 27 | "parent", 28 | models.ForeignKey( 29 | blank=True, 30 | null=True, 31 | on_delete=django.db.models.deletion.CASCADE, 32 | related_name="subcategories", 33 | to="study.category", 34 | ), 35 | ), 36 | ], 37 | ), 38 | migrations.CreateModel( 39 | name="Module", 40 | fields=[ 41 | ( 42 | "id", 43 | models.BigAutoField( 44 | auto_created=True, 45 | primary_key=True, 46 | serialize=False, 47 | verbose_name="ID", 48 | ), 49 | ), 50 | ("title", models.CharField(max_length=255)), 51 | ("content", models.TextField()), 52 | ("created_at", models.DateTimeField(auto_now_add=True)), 53 | ( 54 | "category", 55 | models.ForeignKey( 56 | on_delete=django.db.models.deletion.CASCADE, to="study.category" 57 | ), 58 | ), 59 | ], 60 | ), 61 | ] 62 | -------------------------------------------------------------------------------- /Algolyzer/playground/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-02-10 16:23 2 | 3 | import django.db.models.deletion 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | initial = True 10 | 11 | dependencies = [ 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name="PlaygroundTask", 18 | fields=[ 19 | ( 20 | "id", 21 | models.BigAutoField( 22 | auto_created=True, 23 | primary_key=True, 24 | serialize=False, 25 | verbose_name="ID", 26 | ), 27 | ), 28 | ("celery_task_id", models.CharField(max_length=255, unique=True)), 29 | ("model_name", models.CharField(max_length=100)), 30 | ("input_data", models.TextField()), 31 | ( 32 | "status", 33 | models.CharField( 34 | choices=[ 35 | ("PENDING", "Pending"), 36 | ("PROCESSING", "Processing"), 37 | ("COMPLETED", "Completed"), 38 | ("FAILED", "Failed"), 39 | ], 40 | default="PENDING", 41 | max_length=20, 42 | ), 43 | ), 44 | ("result", models.TextField(blank=True, null=True)), 45 | ("created_at", models.DateTimeField(auto_now_add=True)), 46 | ("completed_at", models.DateTimeField(blank=True, null=True)), 47 | ( 48 | "user", 49 | models.ForeignKey( 50 | on_delete=django.db.models.deletion.CASCADE, 51 | to=settings.AUTH_USER_MODEL, 52 | ), 53 | ), 54 | ], 55 | ), 56 | ] 57 | -------------------------------------------------------------------------------- /Algolyzer/quiz/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Question, QuizProgress, Topic, UserAnswer 4 | 5 | 6 | # Inline for Questions 7 | class QuestionInline(admin.TabularInline): 8 | model = Question 9 | extra = 1 # Number of empty forms to display 10 | 11 | 12 | # Customize admin interface for Topic 13 | class TopicAdmin(admin.ModelAdmin): 14 | list_display = ("id", "name", "difficulty") 15 | search_fields = ("name",) 16 | list_filter = ("difficulty",) 17 | inlines = [QuestionInline] 18 | 19 | 20 | # Customize admin interface for Question 21 | class QuestionAdmin(admin.ModelAdmin): 22 | list_display = ("id", "topic", "text", "correct_answer") 23 | list_filter = ("topic", "topic__difficulty") 24 | search_fields = ("text",) 25 | fieldsets = ( 26 | (None, {"fields": ("topic", "text")}), 27 | ("Options", {"fields": ("option_a", "option_b", "option_c", "option_d")}), 28 | ("Correct Answer", {"fields": ("correct_answer",)}), 29 | ) 30 | radio_fields = { 31 | "correct_answer": admin.HORIZONTAL 32 | } # Use radio buttons for correct_answer 33 | 34 | 35 | # Customize admin interface for UserAnswer 36 | class UserAnswerAdmin(admin.ModelAdmin): 37 | list_display = ("id", "user", "question", "selected_answer", "is_correct") 38 | list_filter = ("is_correct",) 39 | search_fields = ("user__username", "question__text") 40 | readonly_fields = ("is_correct",) # Make is_correct read-only 41 | 42 | 43 | # Customize admin interface for QuizProgress 44 | class QuizProgressAdmin(admin.ModelAdmin): 45 | list_display = ("id", "user", "topic", "current_question", "completed") 46 | list_filter = ("completed",) 47 | search_fields = ("user__username", "topic__name") 48 | actions = ["mark_as_completed"] 49 | 50 | def mark_as_completed(self, request, queryset): 51 | queryset.update(completed=True) 52 | 53 | mark_as_completed.short_description = "Mark selected progress records as completed" 54 | 55 | 56 | # Register models with their respective ModelAdmin 57 | admin.site.register(Topic, TopicAdmin) 58 | admin.site.register(Question, QuestionAdmin) 59 | admin.site.register(UserAnswer, UserAnswerAdmin) 60 | admin.site.register(QuizProgress, QuizProgressAdmin) 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algolyzer - Learn AI/ML with hands on practicals. 2 | 3 | A platform for learning about AI/ML models and algorithms from theoretical to executing pre-trained models all at one place. 4 | ![Algolyzer Homepage](docs/assets/Algolyzer_homepage.png) 5 | 6 | 7 | ## Features(Planned) 8 | - Interactive Quizes 9 | - Levels and Experience points 10 | - Playground for running pre trained AIML models 11 | - Community Forums for deep discussions 12 | - Study Material offering explanations of AIML model working 13 | - Statistical Dashboard 14 | 15 | ## Status 16 | - 60-70% complete 17 | - Initial deployment at [link](http://algolyzer.servehttp.com) 18 | - Focusing on finishing the core modules of Algolyzer 19 | 20 | ## Progress 21 | - [x] Homepage 22 | - [x] Playground 23 | - [x] Community Forum 24 | - [x] Quiz 25 | - [x] Documentation 26 | - [x] Dashboard 27 | - [ ] Study Material 28 | 29 | ## How to setup Project 30 | - Development - [Setup manually](./docs/setup_development.md). 31 | - Production - [Setup with Docker](./docs/setup_production.md). 32 | ## Contribution 33 | For guidelines on how to contribute to this project, check out [Contribution Guidelines](./docs/CONTRIBUTING.md). 34 | 35 | ## Brief Description 36 | Algolyzer has the following apps: 37 | 38 | ### Quiz 39 | Learn about AI/ML models and test your knowledge by taking interesting quizzes. 40 | - Quizzes are of multiple level ranging from Easy to Veteran. 41 | - Completing a quiz gains you xp(experience). 42 | - The cumulative experience helps you unlock new models in the playground. 43 | 44 | ### Playground 45 | Run Machine Learning models and learn from experience. 46 | - Models are run on our server, reducing the need of expensive hardware. 47 | - You supply your own prompt to the model. 48 | - Output is received in the browser after processing. 49 | 50 | ### Study 51 | Learn about Machine Learning models and how to implement them yourself. 52 | - Study material is divided into modules for each type of model. 53 | - Each module contains comprehensive information about the working of the model. 54 | - The code needed to run the model yourself is included in-line. 55 | 56 | ### Community 57 | Discuss topics of interest with people all around the world using Algolyzer Community. 58 | - Get help and connect with awesome people using the platform. 59 | - Your submissions are visible to everyone, but your profile is kept private. 60 | - Forums are divided into multiple categories so you can find your niche in a few clicks. 61 | - Posts are editable, so if you need to change anything you can. 62 | - Remember to follow proper netiquette while using the community app. -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | absl-py==2.1.0 2 | amqp==5.3.1 3 | asgiref==3.8.1 4 | astunparse==1.6.3 5 | billiard==4.2.1 6 | black==24.10.0 7 | celery==5.4.0 8 | certifi==2024.12.14 9 | cffi==1.17.1 10 | cfgv==3.4.0 11 | charset-normalizer==3.4.1 12 | click==8.1.8 13 | click-didyoumean==0.3.1 14 | click-plugins==1.1.1 15 | click-repl==0.3.0 16 | colorama==0.4.6 17 | cryptography==44.0.0 18 | distlib==0.3.9 19 | Django==5.1.4 20 | django-allauth==65.3.1 21 | django-ckeditor==6.7.2 22 | django-js-asset==3.0.1 23 | filelock==3.16.1 24 | flake8==7.1.1 25 | flatbuffers==25.1.24 26 | fsspec==2025.2.0 27 | gast==0.6.0 28 | google-pasta==0.2.0 29 | grpcio==1.70.0 30 | h5py==3.12.1 31 | huggingface-hub==0.28.1 32 | identify==2.6.4 33 | idna==3.10 34 | isort==5.13.2 35 | Jinja2==3.1.5 36 | joblib==1.4.2 37 | keras==3.8.0 38 | kombu==5.4.2 39 | libclang==18.1.1 40 | Markdown==3.7 41 | markdown-it-py==3.0.0 42 | MarkupSafe==3.0.2 43 | mccabe==0.7.0 44 | mdurl==0.1.2 45 | ml-dtypes==0.4.1 46 | mpmath==1.3.0 47 | mypy-extensions==1.0.0 48 | namex==0.0.8 49 | networkx==3.4.2 50 | nodeenv==1.9.1 51 | numpy==2.0.2 52 | nvidia-cublas-cu12==12.4.5.8 53 | nvidia-cuda-cupti-cu12==12.4.127 54 | nvidia-cuda-nvrtc-cu12==12.4.127 55 | nvidia-cuda-runtime-cu12==12.4.127 56 | nvidia-cudnn-cu12==9.1.0.70 57 | nvidia-cufft-cu12==11.2.1.3 58 | nvidia-curand-cu12==10.3.5.147 59 | nvidia-cusolver-cu12==11.6.1.9 60 | nvidia-cusparse-cu12==12.3.1.170 61 | nvidia-cusparselt-cu12==0.6.2 62 | nvidia-nvjitlink-cu12==12.4.127 63 | nvidia-nvtx-cu12==12.4.127 64 | opt_einsum==3.4.0 65 | optree==0.14.0 66 | packaging==24.2 67 | pathspec==0.12.1 68 | pillow==11.1.0 69 | platformdirs==4.3.6 70 | pre_commit==4.0.1 71 | prompt_toolkit==3.0.50 72 | protobuf==5.29.3 73 | pycodestyle==2.12.1 74 | pycparser==2.22 75 | pyflakes==3.2.0 76 | Pygments==2.19.1 77 | PyJWT==2.10.1 78 | python-dateutil==2.9.0.post0 79 | python-dotenv==1.0.1 80 | PyYAML==6.0.2 81 | redis==5.2.1 82 | regex==2024.11.6 83 | requests==2.32.3 84 | rich==13.9.4 85 | safetensors==0.5.2 86 | scikit-learn==1.6.1 87 | scipy==1.15.2 88 | setuptools==75.8.0 89 | six==1.17.0 90 | sqlparse==0.5.3 91 | sympy==1.13.1 92 | tensorboard==2.18.0 93 | tensorboard-data-server==0.7.2 94 | tensorflow==2.18.0 95 | termcolor==2.5.0 96 | tf_keras==2.18.0 97 | threadpoolctl==3.6.0 98 | tokenizers==0.21.0 99 | torch==2.6.0 100 | torchaudio==2.6.0 101 | torchvision==0.21.0 102 | tqdm==4.67.1 103 | transformers==4.48.3 104 | typing_extensions==4.12.2 105 | tzdata==2025.1 106 | urllib3==2.3.0 107 | vine==5.1.0 108 | virtualenv==20.28.0 109 | wcwidth==0.2.13 110 | Werkzeug==3.1.3 111 | wheel==0.45.1 112 | whitenoise==6.8.2 113 | wrapt==1.17.2 114 | -------------------------------------------------------------------------------- /docs/setup_development.md: -------------------------------------------------------------------------------- 1 | ## Pre Requisites 2 | The project is built using following versions of software: 3 | 1. Python 3.12.3 4 | 2. pip 24.3.1 5 | 3. Node 22.13.0 6 | 4. Npm 10.9.2 7 | 5. Docker 8 | 9 | ## Clone the Forked Repository 10 | ```bash 11 | git clone https://github.com/priyanshu-batham/Algolyzer.git 12 | cd Algolyzer 13 | ``` 14 | 15 | ## Setting up Google OAuth service (Optional) 16 | Goto [Google Developer Console](https://console.developers.google.com). Make a new OAuth Client using the following URL as the Authorized Redirect URI: 17 | ```http://localhost:8000/accounts/google/login/callback/``` 18 | 19 | ## Run the following commands (Windows users just use git bash): 20 | ```bash 21 | # Create a virtual environment named 'env' 22 | python3 -m venv env 23 | 24 | # Activate the virtual environment 25 | source env/bin/activate 26 | # (For Windows) 27 | source env/Scripts/activate 28 | 29 | # Create .env file from .env.sample 30 | cp .env.sample .env 31 | 32 | # Edit the values in .env accordingly and check it 33 | cat .env 34 | 35 | # Install python dependencies 36 | pip install -r requirements.txt 37 | 38 | # Install node dependencies 39 | npm install 40 | 41 | # Install pre-commit hooks 42 | pre-commit install 43 | 44 | # Navigate into Algolyzer project 45 | cd Algolyzer 46 | 47 | # Apply migrations 48 | python manage.py migrate 49 | 50 | # Create a local administrator (make sure you specified values in .env) 51 | python manage.py create_superuser 52 | 53 | # Load default values in database 54 | python manage.py loaddata data/* 55 | 56 | # download aiml models 57 | python manage.py download_models 58 | 59 | # start redis as a docker container 60 | docker run --name redis -p 6379:6379 -d redis 61 | 62 | # start celery 63 | celery -A Algolyzer worker --loglevel=info 64 | # (For Windows) 65 | celery -A Algolyzer worker --loglevel=info --pool=threads 66 | 67 | # Now open a NEW TERMINAL and start tailwind in Algolyzer dir 68 | npm run tw_watch 69 | 70 | # Finally Open a Third terminal and Run Django server. 71 | source myenv/bin/activate 72 | # (For Windows) 73 | source env/Scripts/activate 74 | 75 | cd Algolyzer 76 | python manage.py runserver 8000 77 | ``` 78 | ## Open a web browser and goto 79 | ```bash 80 | http://localhost:8000 81 | 82 | ``` 83 | **Note - Always use `localhost:8000` instead of `127.0.0.1:8000` if you don't want access blocked from Google during development** -------------------------------------------------------------------------------- /Algolyzer/home/forms.py: -------------------------------------------------------------------------------- 1 | import re 2 | from datetime import date 3 | 4 | from django import forms 5 | from django.core.exceptions import ValidationError 6 | 7 | from .models import UserProfile 8 | 9 | 10 | class OnboardingForm(forms.ModelForm): 11 | dob = forms.DateField( 12 | widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}), 13 | label="Date of Birth", 14 | required=True, 15 | ) 16 | 17 | full_name = forms.CharField( 18 | widget=forms.TextInput(attrs={"class": "form-control"}), 19 | label="Full Name", 20 | max_length=100, 21 | required=True, 22 | ) 23 | 24 | phone_number = forms.CharField( 25 | widget=forms.TextInput( 26 | attrs={"class": "form-control", "placeholder": "+1234567890"} 27 | ), 28 | label="Phone Number", 29 | max_length=15, # Increased to accommodate country codes 30 | required=True, 31 | ) 32 | 33 | gender = forms.ChoiceField( 34 | choices=[("M", "Male"), ("F", "Female"), ("O", "Other")], 35 | widget=forms.Select(attrs={"class": "form-control"}), 36 | label="Gender", 37 | required=True, 38 | ) 39 | 40 | address = forms.CharField( 41 | widget=forms.Textarea(attrs={"class": "form-control", "rows": 3}), 42 | label="Address", 43 | required=True, 44 | ) 45 | 46 | class Meta: 47 | model = UserProfile 48 | fields = [ 49 | "full_name", 50 | "dob", 51 | "phone_number", 52 | "gender", 53 | "address", 54 | ] 55 | 56 | def clean_phone_number(self): 57 | phone_number = self.cleaned_data.get("phone_number") 58 | 59 | # Remove all non-digit characters 60 | # cleaned_number = re.sub(r'[^\d+]', '', phone_number) 61 | 62 | # Check if the number contains only digits and optional + at start 63 | if not re.match(r"^\+?\d+$", phone_number): 64 | raise ValidationError( 65 | "Phone number must contain only numbers and an optional + at the start." 66 | ) 67 | 68 | # Check minimum length (adjust according to your requirements) 69 | if len(phone_number) < 10: 70 | raise ValidationError("Phone number must be at least 10 digits long.") 71 | 72 | return phone_number 73 | 74 | def clean_dob(self): 75 | dob = self.cleaned_data.get("dob") 76 | today = date.today() 77 | 78 | # Calculate age 79 | age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day)) 80 | 81 | if age < 12: 82 | raise ValidationError("You must be at least 12 years old to register.") 83 | 84 | return dob 85 | -------------------------------------------------------------------------------- /Algolyzer/playground/templates/playground/sentiment_analysis.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |
6 |

Sentiment Analysis

7 | 8 | 9 |
10 | {% csrf_token %} 11 | 12 | 17 | 18 |
19 | 20 | 21 |
22 |

Previous Results

23 |
24 | {% for result in previous_results %} 25 |
26 | 27 |
28 | Prompt: {{ result.input_data|truncatechars:50 }} 29 |
30 |
31 |
32 |
33 |
Status
34 |
{{ result.status }}
35 |
Failed | Completed
36 |
37 | 38 |
39 |
Result
40 |
{{ result.result.label }}
41 |
Positive | Negative
42 |
43 | 44 |
45 |
Score
46 |
{{ result.result.score|truncatechars:7 }}
47 |
Between 0 to 1
48 |
49 |
50 |
51 |
52 | {% empty %} 53 |

No previous results available.

54 | {% endfor %} 55 |
56 |
57 |
58 |
59 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/Algolyzer/settings/base.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | from dotenv import load_dotenv 5 | 6 | # Load environment variables 7 | load_dotenv() 8 | 9 | BASE_DIR = Path(__file__).resolve().parent.parent.parent 10 | 11 | # Security settings (overridden in development and production) 12 | SECRET_KEY = os.getenv("SECRET_KEY", "your-default-secret-key") 13 | DEBUG = False # Will be overridden in respective settings files 14 | 15 | ALLOWED_HOSTS = [] 16 | 17 | INSTALLED_APPS = [ 18 | # default django apps 19 | "django.contrib.admin", 20 | "django.contrib.auth", 21 | "django.contrib.contenttypes", 22 | "django.contrib.sessions", 23 | "django.contrib.messages", 24 | "django.contrib.staticfiles", 25 | # allauth apps 26 | "allauth", 27 | "allauth.account", 28 | "allauth.socialaccount", 29 | "allauth.socialaccount.providers.google", 30 | # algolyzer apps 31 | "home", 32 | "quiz", 33 | "study", 34 | "community", 35 | "playground", 36 | ] 37 | 38 | MIDDLEWARE = [ 39 | "django.middleware.security.SecurityMiddleware", 40 | "django.contrib.sessions.middleware.SessionMiddleware", 41 | "django.middleware.common.CommonMiddleware", 42 | "django.middleware.csrf.CsrfViewMiddleware", 43 | "django.contrib.auth.middleware.AuthenticationMiddleware", 44 | "django.contrib.messages.middleware.MessageMiddleware", 45 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 46 | "allauth.account.middleware.AccountMiddleware", 47 | ] 48 | 49 | ROOT_URLCONF = "Algolyzer.urls" 50 | 51 | TEMPLATES = [ 52 | { 53 | "BACKEND": "django.template.backends.django.DjangoTemplates", 54 | "DIRS": [BASE_DIR / "templates"], 55 | "APP_DIRS": True, 56 | "OPTIONS": { 57 | "context_processors": [ 58 | "django.template.context_processors.debug", 59 | "django.template.context_processors.request", 60 | "django.contrib.auth.context_processors.auth", 61 | "django.contrib.messages.context_processors.messages", 62 | ], 63 | }, 64 | }, 65 | ] 66 | 67 | WSGI_APPLICATION = "Algolyzer.wsgi.application" 68 | 69 | # Authentication 70 | AUTHENTICATION_BACKENDS = [ 71 | "django.contrib.auth.backends.ModelBackend", 72 | "allauth.account.auth_backends.AuthenticationBackend", 73 | ] 74 | 75 | SOCIALACCOUNT_PROVIDERS = { 76 | "google": { 77 | "APP": { 78 | "client_id": os.getenv("GOOGLE_CLIENT_ID"), 79 | "secret": os.getenv("GOOGLE_SECRET_KEY"), 80 | } 81 | } 82 | } 83 | 84 | ACCOUNT_AUTHENTICATION_METHOD = "email" 85 | ACCOUNT_EMAIL_REQUIRED = True 86 | LOGIN_REDIRECT_URL = "/dashboard/" 87 | ACCOUNT_LOGOUT_ON_GET = False 88 | ACCOUNT_SIGNUP_REDIRECT_URL = "/onboarding/" 89 | 90 | LANGUAGE_CODE = "en-us" 91 | TIME_ZONE = "UTC" 92 | USE_I18N = True 93 | USE_TZ = True 94 | DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" 95 | 96 | STATIC_URL = "/static/" 97 | STATICFILES_DIRS = [BASE_DIR / "static"] 98 | STATIC_ROOT = BASE_DIR / "staticfiles" 99 | 100 | # AIML downloaded models directory 101 | MODEL_DIR = "/aiml_models" 102 | -------------------------------------------------------------------------------- /Algolyzer/quiz/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.db import models 3 | 4 | 5 | class Topic(models.Model): 6 | name = models.CharField(max_length=100) 7 | description = models.CharField(max_length=1000, default="No description provided.") 8 | difficulty = models.CharField( 9 | max_length=7, 10 | choices=[ 11 | ("Easy", "Easy"), 12 | ("Medium", "Medium"), 13 | ("Hard", "Hard"), 14 | ("Veteran", "Veteran"), 15 | ], 16 | default="Easy", 17 | help_text="Difficulty levels", 18 | ) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | 24 | class Question(models.Model): 25 | topic = models.ForeignKey(Topic, on_delete=models.CASCADE) 26 | text = models.TextField() # The question text 27 | option_a = models.CharField(max_length=200) # Option A 28 | option_b = models.CharField(max_length=200) # Option B 29 | option_c = models.CharField(max_length=200) # Option C 30 | option_d = models.CharField(max_length=200) # Option D 31 | correct_answer = models.CharField( 32 | max_length=1, 33 | choices=[ 34 | ("a", "Option A"), 35 | ("b", "Option B"), 36 | ("c", "Option C"), 37 | ("d", "Option D"), 38 | ], 39 | help_text="Correct answer should be 'a', 'b', 'c', or 'd'", 40 | ) 41 | 42 | def get_option_text(self, option_key): 43 | """Returns the full text of the option based on the key (a, b, c, d).""" 44 | option_mapping = { 45 | "a": self.option_a, 46 | "b": self.option_b, 47 | "c": self.option_c, 48 | "d": self.option_d, 49 | } 50 | return option_mapping.get(option_key, "Invalid Option") 51 | 52 | def __str__(self): 53 | return self.text 54 | 55 | 56 | class UserAnswer(models.Model): 57 | topic = models.ForeignKey(Topic, on_delete=models.CASCADE) 58 | user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 59 | question = models.ForeignKey(Question, on_delete=models.CASCADE) 60 | selected_answer = models.CharField( 61 | max_length=1, 62 | choices=[ 63 | ("a", "Option A"), 64 | ("b", "Option B"), 65 | ("c", "Option C"), 66 | ("d", "Option D"), 67 | ], 68 | help_text="Selected answer should be 'a', 'b', 'c', or 'd'", 69 | ) 70 | is_correct = models.BooleanField(default=False) 71 | 72 | class Meta: 73 | unique_together = ( 74 | "user", 75 | "topic", 76 | "question", 77 | ) # Ensure a user can only answer a question once in a topic 78 | 79 | def save(self, *args, **kwargs): 80 | # Automatically determine if the selected answer is correct 81 | self.is_correct = self.selected_answer == self.question.correct_answer 82 | super().save(*args, **kwargs) 83 | 84 | 85 | class QuizProgress(models.Model): 86 | user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 87 | topic = models.ForeignKey(Topic, on_delete=models.CASCADE) 88 | current_question = models.IntegerField(default=0) 89 | completed = models.BooleanField(default=False) 90 | -------------------------------------------------------------------------------- /Algolyzer/playground/tasks.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from celery import shared_task 4 | from django.conf import settings 5 | from django.utils.timezone import now 6 | from PIL import Image 7 | from transformers import AutoModelForSequenceClassification, AutoTokenizer, pipeline 8 | 9 | from .models import PlaygroundTask 10 | 11 | 12 | @shared_task(bind=True) 13 | def sentiment_analysis_task(self, task_db_id, input_data): 14 | """Celery task to process ML model input.""" 15 | try: 16 | # Fetch the task from the database 17 | task = PlaygroundTask.objects.get(id=task_db_id) 18 | task.status = "PROCESSING" 19 | task.save() 20 | 21 | MODEL_DIR = os.path.join( 22 | settings.BASE_DIR, 23 | "playground", 24 | "aiml_models", 25 | "finiteautomata_bertweet-base-sentiment-analysis", 26 | ) 27 | 28 | # Load model from saved directory 29 | tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR) 30 | model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR) 31 | sentiment_pipeline = pipeline( 32 | "sentiment-analysis", model=model, tokenizer=tokenizer 33 | ) 34 | 35 | if not model: 36 | raise ValueError( 37 | "Model 'finiteautomata_bertweet-base-sentiment-analysis' not found." 38 | ) 39 | 40 | # Process the input with the model 41 | result = sentiment_pipeline(input_data)[0] 42 | 43 | # Update the task in the database 44 | task.status = "COMPLETED" 45 | task.result = str(result) # Convert to JSON-friendly format if needed 46 | task.completed_at = now() 47 | task.save() 48 | 49 | except Exception as e: 50 | task.status = "FAILED" 51 | task.result = str(e) 52 | task.save() 53 | # raise e 54 | 55 | return task.result # Celery stores the result 56 | 57 | 58 | # Load the pre-trained MNIST model from Hugging Face 59 | mnist_classifier = pipeline( 60 | "image-classification", model="farleyknight/mnist-digit-classification-2022-09-04" 61 | ) 62 | 63 | 64 | @shared_task 65 | def doodle_classifier_task(task_id): 66 | try: 67 | # Get the task 68 | task = PlaygroundTask.objects.get(id=task_id) 69 | 70 | # Open the saved PNG image from the input_image field 71 | image = Image.open(task.input_image.path) 72 | print("image being loaded: ", image.filename) 73 | 74 | # Run inference using the pre-trained model 75 | result = mnist_classifier(image) 76 | print(str(result)) 77 | best_prediction = max(result, key=lambda x: x["score"]) 78 | best_label = best_prediction["label"] 79 | # print("Label: ", best_label, "Score: ", best_score) 80 | 81 | # Update the task with the result 82 | task.result = best_label # Convert the result to a string for storage 83 | task.status = "COMPLETED" 84 | task.save() 85 | 86 | except Exception as e: 87 | # Handle any errors that occur during processing 88 | task = PlaygroundTask.objects.get(id=task_id) 89 | task.result = str(e) # Store the error message 90 | task.status = "FAILED" 91 | task.save() 92 | 93 | return task.result 94 | -------------------------------------------------------------------------------- /Algolyzer/community/templates/community/post_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |

Posts in {{ category.name }}

6 | ← Back to Categories 7 | 8 | {% if user.is_authenticated %} 9 | 10 | 11 | 12 | 32 | 33 | {% endif %} 34 | 35 | {% for post in page_obj %} 36 | 37 |
38 |
39 |

{{ post.title }}

40 |
41 |

Votes: {{ post.total_votes|default:0 }}

42 |
43 |
44 | {% empty %} 45 |

No posts available in this category.

46 | {% endfor %} 47 | 48 | 49 |
50 | {% if page_obj.has_previous %} 51 | << 52 | < 53 | {% endif %} 54 | 55 | Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} 56 | 57 | {% if page_obj.has_next %} 58 | > 59 | >> 60 | {% endif %} 61 |
62 |
63 | {% endblock %} 64 | -------------------------------------------------------------------------------- /Algolyzer/home/templates/home/onboarding.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 | 6 |

Complete Your Profile

7 | 8 |
9 | {% csrf_token %} 10 | 11 | 12 |
13 | 14 | 16 | {% if form.full_name.errors %} 17 |

{{ form.full_name.errors.0 }}

18 | {% endif %} 19 |
20 | 21 | 22 |
23 | 24 | 26 | {% if form.dob.errors %} 27 |

{{ form.dob.errors.0 }}

28 | {% endif %} 29 |
30 | 31 | 32 |
33 | 34 | 36 | {% if form.phone_number.errors %} 37 |

{{ form.phone_number.errors.0 }}

38 | {% endif %} 39 |
40 | 41 | 42 |
43 | 44 | 50 | {% if form.gender.errors %} 51 |

{{ form.gender.errors.0 }}

52 | {% endif %} 53 |
54 | 55 | 56 |
57 | 58 | 60 | {% if form.address.errors %} 61 |

{{ form.address.errors.0 }}

62 | {% endif %} 63 |
64 | 65 | 66 |
67 | 68 |
69 |
70 | 71 |
72 | {% endblock %} 73 | -------------------------------------------------------------------------------- /Algolyzer/home/views.py: -------------------------------------------------------------------------------- 1 | from community.models import Comment, Post 2 | from django.contrib.auth.decorators import login_required 3 | from django.shortcuts import redirect, render 4 | from playground.models import PlaygroundTask 5 | from quiz.models import QuizProgress, Topic 6 | 7 | from .forms import OnboardingForm 8 | from .models import UserProfile 9 | 10 | 11 | def home(request): 12 | """Main Home Page""" 13 | return render(request, "home/home.html") 14 | 15 | 16 | @login_required 17 | def dashboard(request): 18 | """Dashboard page for logged-in users only""" 19 | # Fetch the user's profile 20 | user_profile = UserProfile.objects.filter(user=request.user).first() 21 | 22 | # Redirect to onboarding if no profile exists 23 | if not user_profile: 24 | return redirect("onboarding") 25 | 26 | # Calculate XP progress percentage 27 | next_level_xp = user_profile.get_next_level_xp() 28 | progress_percentage = ( 29 | (user_profile.xp / next_level_xp) * 100 if next_level_xp else 0 30 | ) 31 | 32 | # Fetch quiz progress data 33 | completed_quizzes = QuizProgress.objects.filter( 34 | user=request.user, completed=True 35 | ).count() 36 | total_quizzes = Topic.objects.count() 37 | recent_quizzes = QuizProgress.objects.filter( 38 | user=request.user, completed=True 39 | ).order_by("-id")[:5] 40 | 41 | # Fetch task data 42 | completed_tasks = PlaygroundTask.objects.filter( 43 | user=request.user, status="COMPLETED" 44 | ).count() 45 | pending_tasks = PlaygroundTask.objects.filter( 46 | user=request.user, status="PENDING" 47 | ).count() 48 | recent_tasks = PlaygroundTask.objects.filter(user=request.user).order_by( 49 | "-created_at" 50 | )[:5] 51 | 52 | # Fetch forum activity data 53 | total_posts = Post.objects.filter(author=request.user).count() 54 | total_comments = Comment.objects.filter(author=request.user).count() 55 | recent_posts = Post.objects.filter(author=request.user).order_by("-created_at")[:5] 56 | recent_comments = Comment.objects.filter(author=request.user).order_by( 57 | "-created_at" 58 | )[:5] 59 | 60 | # Prepare context 61 | context = { 62 | "user_profile": user_profile, 63 | "progress_percentage": progress_percentage, # XP progress percentage 64 | "completed_quizzes": completed_quizzes, # Number of completed quizzes 65 | "total_quizzes": total_quizzes, # Total number of quizzes 66 | "recent_quizzes": recent_quizzes, # Recent quizzes 67 | "completed_tasks": completed_tasks, # Number of completed tasks 68 | "pending_tasks": pending_tasks, # Number of pending tasks 69 | "recent_tasks": recent_tasks, # Recent tasks 70 | "total_posts": total_posts, # Total number of posts 71 | "total_comments": total_comments, # Total number of comments 72 | "recent_posts": recent_posts, # Recent posts 73 | "recent_comments": recent_comments, # Recent comments 74 | } 75 | 76 | return render(request, "home/dashboard.html", context=context) 77 | 78 | 79 | @login_required 80 | def onboarding(request): 81 | # Check if the UserProfile exists 82 | if UserProfile.objects.filter(user=request.user).exists(): 83 | return redirect("dashboard") # Redirect if profile exists 84 | 85 | if request.method == "POST": 86 | # If the profile doesn't exist, no instance is passed to the form 87 | form = OnboardingForm(request.POST) 88 | 89 | if form.is_valid(): 90 | # Create the UserProfile only after form validation 91 | UserProfile.objects.create(user=request.user, dob=form.cleaned_data["dob"]) 92 | return redirect("dashboard") 93 | else: 94 | # On GET request, just create an empty form (no instance) 95 | form = OnboardingForm() 96 | 97 | return render(request, "home/onboarding.html", {"form": form}) 98 | -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for considering contributing to Algolyzer! We appreciate your help in improving our project. Please follow the steps below to ensure a smooth and efficient contribution process. 4 | 5 | 1. Fork the Repository 6 | - Click the "Fork" button at the top of the repository page to create a copy in your GitHub account. 7 | 8 | 2. Clone the Forked Repository 9 | - Use the following command to clone your fork locally (replace `your-username` with your actual github username): 10 | 11 | ```bash 12 | git clone https://github.com//Algolyzer.git 13 | cd Algolyzer 14 | ``` 15 | ## Setup project 16 | [Setup for Development](./setup_development.md) 17 | 18 | ## Creating a Feature Branch 19 | 20 | 1. Create and Switch to a New Branch 21 | - Name your branch based on the contribution, e.g., feature_authentication or fix_bug_123: 22 | 23 | ```bash 24 | git checkout -b feature_branch_name 25 | ``` 26 | 27 | 2. Make Your Changes 28 | - Implement the feature, fix bugs, or update the documentation. Ensure your code adheres to the project's style and standards. 29 | 30 | # Contributing for Quiz Data 31 | 1. Goto `localhost:8000/admin` and login using your **superuser** credentials. 32 | 2. Add your Topics and Questions in the `Topics` & `Questions` models under the `Quiz` tab. 33 | 3. Open the terminal and run 34 | ```bash 35 | python manage.py dump_quiz 36 | ``` 37 | 38 | 39 | ## Running Quality Checks 40 | 41 | 1. Format the Code 42 | - Run the provided script to ensure consistent formatting: 43 | 44 | ```bash 45 | ./run_qa_format 46 | ``` 47 | 48 | 2. Run Tests 49 | - Navigate to the project directory and execute the test suite: 50 | 51 | ```bash 52 | python manage.py test 53 | ``` 54 | 55 | ## Committing and Pushing Changes 56 | 57 | 1. Stage and Commit Changes 58 | - Add your changes and commit them with a descriptive message: 59 | 60 | ```bash 61 | git add . 62 | git commit -m "Add detailed commit message here" 63 | ``` 64 | 2. Pre-Commit Hook 65 | - Note that a pre-commit hook will automatically run upon committing. If it fails, resolve the issues and commit again. 66 | 67 | 3. Push Your Branch 68 | - Push your branch to your forked repository: 69 | 70 | ```bash 71 | git push origin feature_branch_name 72 | ``` 73 | 74 | ## Create an issue on GitHub 75 | 76 | 1. Before creating a pull request, create an issue on the [original repository](https://github.com/Priyanshu-Batham/Algolyzer/issues) 77 | 2. Remember to include as much information about your addition or fix. 78 | 3. Use appropriate labels for the issue. 79 | 4. Mention the maintainer for attention. 80 | 5. Patiently wait. 81 | 6. After maintainer approval, move on to open a pull request. 82 | 83 | ## Creating a Pull Request (PR) 84 | 1. Open a PR 85 | - Navigate to the original repository and open a PR from your branch. 86 | - Use a descriptive title and message, and reference any related issues (e.g., Fixes #issue_number). 87 | - Mention the Pull Request and 88 | 89 | 2. Address CI Pipeline Failures 90 | - If the PR fails the CI pipeline, review the logs, rectify the issues, and push the changes again. 91 | 92 | 3. Await Review 93 | - Be patient while the maintainers review your PR. Respond to feedback and make the required changes if needed. 94 | 95 | 4. Merge 96 | - Once approved, your PR will be merged into the main branch. 97 | 98 | ## Cleaning Up 99 | 100 | - After a successful merge, you can clean up your local repository: 101 | 102 | ```bash 103 | git branch -D feature_branch_name 104 | git fetch --prune 105 | ``` 106 | 107 | ## Additional Tips 108 | 109 | - Modify the last commit if you need to make minor changes without creating a new commit. 110 | 111 | ```bash 112 | git commit --amend 113 | ``` 114 | 115 | - Regularly sync your fork with the upstream repository: 116 | 117 | ```bash 118 | git fetch upstream 119 | git merge upstream/main 120 | ``` -------------------------------------------------------------------------------- /Algolyzer/study/templates/study/doodle_classifier.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

6 | A Beginner's Guide to Doodle Classification 7 |

8 | 9 |

Introduction

10 |

11 | Doodle classification is a type of image classification that predicts which number (0-9) was drawn by a user. 12 | This is done using a deep learning model trained on the MNIST dataset—a famous dataset of handwritten digits. 13 |

14 |

15 | In this project, we're using a pre-trained model from Hugging Face called farleyknight/mnist-digit-classification-2022-09-04, 16 | which is specifically trained to recognize digits from rough sketches or "doodles." 17 |

18 | 19 |

How Does It Work?

20 |
    21 |
  1. The user draws a digit on a canvas in the browser.
  2. 22 |
  3. The drawing is converted to a base64 PNG image.
  4. 23 |
  5. This image is sent to the server and saved temporarily.
  6. 24 |
  7. The image is passed through a deep learning model.
  8. 25 |
  9. The model outputs the most likely digit with a confidence score.
  10. 26 |
27 | 28 |

Step-by-Step Breakdown

29 | 30 |

Step 1: Capture the Drawing

31 |

32 | We use an HTML canvas where users draw their digit. The drawing is captured as a base64-encoded image string. 33 |

34 | 35 |
36 |
image_data = request.POST.get("image_data")
37 |
38 | 39 |

Step 2: Save the Drawing as an Image

40 |

41 | The base64 string is decoded and saved as a PNG image, so that it can be read like a normal image file. 42 |

43 | 44 |
45 |
format, imgstr = image_data.split(";base64,")
46 |   ext = format.split("/")[-1]
47 |   image_file = ContentFile(base64.b64decode(imgstr), name=f"doodle.{ext}")
48 |
49 | 50 |

Step 3: Run the Image through the Classifier

51 |

52 | The image is passed into a pre-trained model that analyzes the pixel patterns and predicts which digit was drawn. 53 |

54 | 55 |
56 |
image = Image.open(task.input_image.path)
57 |   result = mnist_classifier(image)
58 |
59 | 60 |

Step 4: Get the Best Prediction

61 |

62 | The model returns a list of possible digits with scores. We choose the one with the highest score. 63 |

64 | 65 |
66 |
best_prediction = max(result, key=lambda x: x["score"])
67 |   best_label = best_prediction["label"]
68 |
69 | 70 |

Why This Model?

71 |
    72 |
  • ✅ Trained on real-world digit images from the MNIST dataset.
  • 73 |
  • ✅ Fast and lightweight — ideal for web apps and educational tools.
  • 74 |
  • ✅ Easy to integrate using Hugging Face’s pipeline interface.
  • 75 |
76 | 77 |

Try Drawing!

78 |

79 | Head over to the classifier page and draw a number to see the magic happen in real-time! 🎨 80 |

81 |
82 | {% endblock %} 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | .idea/ 169 | 170 | # For vscode users 171 | .vscode/ 172 | 173 | # PyPI configuration file 174 | .pypirc 175 | 176 | # Node.js 177 | node_modules 178 | 179 | # TailwindCSS 180 | *output.css 181 | 182 | # productions static files 183 | staticfiles 184 | 185 | # algolyzer playground aiml models 186 | aiml_models 187 | 188 | doodles -------------------------------------------------------------------------------- /Algolyzer/quiz/templates/quiz/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |

Available Quiz Topics

6 | 7 |
    8 | 9 | {% for item in data %} 10 | 11 | {% comment %} 12 | {{ topic.name }} 13 | {% endcomment %} 14 |
  • 15 | 16 | {% if not forloop.first %} 17 |
    18 | {% endif %} 19 | 20 |
    21 |
    22 | 23 |
    25 | 26 | {{ item.topic.name }} 27 | 28 |
    29 |
    31 | 32 | {% comment %} Detailed Card {% endcomment %} 33 |
    34 |
    35 |
    36 |
    Your Score
    37 | 38 |
    {{item.score}}
    39 | 40 |
    Excellent
    41 |
    42 | 43 |
    44 |
    Total Questions
    45 | 46 |
    {{item.total}}
    47 | 48 |
    ↗︎ 400 (22%)
    49 |
    50 | 51 |
    52 |
    Difficulty
    53 | 54 |
    {{item.topic.difficulty}}
    55 | 56 |
    ↘︎ 90 (14%)
    57 |
    58 |
    59 | 60 | 61 |
    62 |

    Lets Go!

    63 | 64 |

    {{item.topic.description}}

    65 | 71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 | 82 | 86 | 87 |
    88 | 89 | {% if not forloop.last %} 90 |
    91 | {% endif %} 92 | 93 |
  • 94 | 95 | {% empty %} 96 |

    No topics available at the moment. Please check back later!

    97 | {% endfor %} 98 |
99 |
100 | 101 | {% endblock content %} -------------------------------------------------------------------------------- /Algolyzer/study/templates/study/k_means_clustering.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

6 | A Beginner's Guide to K-Means Clustering 7 |

8 | 9 |

Introduction

10 |

11 | K-Means clustering is an unsupervised learning algorithm that groups data into clusters based on similarity. 12 | It finds a set of "centroids" that best represent the data points in each cluster. 13 |

14 |

15 | In this tool, you enter a list of numbers, and the algorithm will group them into up to three clusters. 16 |

17 | 18 |

How Does It Work?

19 |
    20 |
  1. You input several numbers (e.g., 2, 8, 3, 15, 6).
  2. 21 |
  3. The server reads and parses these numbers into a list.
  4. 22 |
  5. K-Means places cluster centers and assigns each number to the nearest center.
  6. 23 |
  7. The centers move to the average of their assigned points until stable.
  8. 24 |
  9. The final clusters and their labels are shown.
  10. 25 |
26 | 27 |

Step-by-Step Breakdown

28 | 29 |

Step 1: Read and Parse Input

30 |

31 | We get the raw JSON string of numbers from the form and convert it into a Python list. 32 |

33 |
34 |
import json
35 | 
36 |   values_json = request.POST.get("values", "[]")
37 |   input_values = json.loads(values_json)  # e.g., [2, 8, 3, 15, 6]
38 |
39 | 40 |

Step 2: Prepare Data for K-Means

41 |

42 | We convert the list of numbers into a NumPy array and reshape it so each number is its own data point. 43 |

44 |
45 |
import numpy as np
46 | 
47 |   X = np.array(input_values).reshape(-1, 1)  # e.g., [[2], [8], [3], [15], [6]]
48 |
49 | 50 |

Step 3: Choose Number of Clusters

51 |

52 | We allow up to 3 clusters but never more than the number of points. 53 |

54 |
55 |
from sklearn.cluster import KMeans
56 | 
57 |   n_clusters = min(len(input_values), 3)
58 |   kmeans = KMeans(n_clusters=n_clusters, random_state=42)
59 |
60 | 61 |

Step 4: Run K-Means

62 |

63 | We fit the model to our data and get a label for each point. 64 |

65 |
66 |
kmeans.fit(X)
67 |   labels = kmeans.labels_.tolist()  # e.g., [0, 1, 0, 2, 0]
68 |
69 | 70 |

Step 5: Pair Values with Cluster Labels

71 |

72 | We zip each original number with its cluster label for easy display. 73 |

74 |
75 |
classified_values = list(zip(input_values, labels))
76 |   # e.g., [(2,0), (8,1), (3,0), (15,2), (6,0)]
77 |
78 | 79 |

Why K-Means?

80 |
    81 |
  • ✅ Easy to understand and implement.
  • 82 |
  • ✅ Fast and scales well with data size.
  • 83 |
  • ✅ Good for discovering hidden groupings in your data.
  • 84 |
85 | 86 |

Try Clustering!

87 |

88 | Visit the K-Means Clustering page, input a few numbers separated by commas, and see how they group together! 🧩 89 |

90 |
91 | {% endblock %} 92 | -------------------------------------------------------------------------------- /Algolyzer/community/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-02-02 09:59 2 | 3 | import django.db.models.deletion 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | initial = True 10 | 11 | dependencies = [ 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name="Category", 18 | fields=[ 19 | ( 20 | "id", 21 | models.BigAutoField( 22 | auto_created=True, 23 | primary_key=True, 24 | serialize=False, 25 | verbose_name="ID", 26 | ), 27 | ), 28 | ("name", models.CharField(max_length=255, unique=True)), 29 | ("description", models.TextField(blank=True)), 30 | ], 31 | ), 32 | migrations.CreateModel( 33 | name="Post", 34 | fields=[ 35 | ( 36 | "id", 37 | models.BigAutoField( 38 | auto_created=True, 39 | primary_key=True, 40 | serialize=False, 41 | verbose_name="ID", 42 | ), 43 | ), 44 | ("title", models.CharField(max_length=255)), 45 | ("content", models.TextField()), 46 | ("created_at", models.DateTimeField(auto_now_add=True)), 47 | ("updated_at", models.DateTimeField(auto_now=True)), 48 | ( 49 | "author", 50 | models.ForeignKey( 51 | on_delete=django.db.models.deletion.CASCADE, 52 | to=settings.AUTH_USER_MODEL, 53 | ), 54 | ), 55 | ( 56 | "category", 57 | models.ForeignKey( 58 | on_delete=django.db.models.deletion.CASCADE, 59 | to="community.category", 60 | ), 61 | ), 62 | ], 63 | ), 64 | migrations.CreateModel( 65 | name="Comment", 66 | fields=[ 67 | ( 68 | "id", 69 | models.BigAutoField( 70 | auto_created=True, 71 | primary_key=True, 72 | serialize=False, 73 | verbose_name="ID", 74 | ), 75 | ), 76 | ("content", models.TextField()), 77 | ("created_at", models.DateTimeField(auto_now_add=True)), 78 | ( 79 | "author", 80 | models.ForeignKey( 81 | on_delete=django.db.models.deletion.CASCADE, 82 | to=settings.AUTH_USER_MODEL, 83 | ), 84 | ), 85 | ( 86 | "post", 87 | models.ForeignKey( 88 | on_delete=django.db.models.deletion.CASCADE, 89 | related_name="comments", 90 | to="community.post", 91 | ), 92 | ), 93 | ], 94 | ), 95 | migrations.CreateModel( 96 | name="Vote", 97 | fields=[ 98 | ( 99 | "id", 100 | models.BigAutoField( 101 | auto_created=True, 102 | primary_key=True, 103 | serialize=False, 104 | verbose_name="ID", 105 | ), 106 | ), 107 | ( 108 | "vote_type", 109 | models.IntegerField(choices=[(1, "Upvote"), (-1, "Downvote")]), 110 | ), 111 | ( 112 | "post", 113 | models.ForeignKey( 114 | on_delete=django.db.models.deletion.CASCADE, 115 | related_name="votes", 116 | to="community.post", 117 | ), 118 | ), 119 | ( 120 | "user", 121 | models.ForeignKey( 122 | on_delete=django.db.models.deletion.CASCADE, 123 | to=settings.AUTH_USER_MODEL, 124 | ), 125 | ), 126 | ], 127 | options={ 128 | "unique_together": {("post", "user")}, 129 | }, 130 | ), 131 | ] 132 | -------------------------------------------------------------------------------- /Algolyzer/study/templates/study/linear_regression.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends "base.html" %} 3 | 4 | {% block content %} 5 |
6 |

7 | A Beginner's Guide to Linear Regression 8 |

9 | 10 |

Introduction

11 |

12 | Linear regression is a basic machine learning method that finds a straight line (relationship) between input data and output values. 13 | In simple terms, it learns how one variable changes when another changes and uses that to make predictions. 14 |

15 |

16 | Here, we collect five numeric inputs from sliders (values 1–5) and predict a sixth value based on the trends in those inputs. 17 |

18 | 19 |

How Does It Work?

20 |
    21 |
  1. User moves five sliders to choose numbers.
  2. 22 |
  3. Values are sent to the server when the form is submitted.
  4. 23 |
  5. A straight-line model is trained on the five numbers.
  6. 24 |
  7. The model predicts the value at position 6.
  8. 25 |
  9. We display the predicted value along with the line’s equation.
  10. 26 |
27 | 28 |

Step-by-Step Breakdown

29 | 30 |

Step 1: Collect Input Data

31 |

32 | We read the slider values from the form submission using Django’s request object. 33 |

34 |
35 |
values = [
36 |     float(request.POST.get("value_1", 0)),
37 |     float(request.POST.get("value_2", 0)),
38 |     float(request.POST.get("value_3", 0)),
39 |     float(request.POST.get("value_4", 0)),
40 |     float(request.POST.get("value_5", 0)),
41 | ]
42 |
43 | 44 |

Step 2: Prepare Data for Training

45 |

46 | We create an array of positions (1–5) and another array of the slider values. This shapes the data for the model. 47 |

48 |
49 |
import numpy as np
50 | 
51 |   X = np.array(range(1, 6)).reshape(-1, 1)  # Positions 1 to 5
52 |   y = np.array(values)  # The values from sliders
53 |
54 | 55 |

Step 3: Train the Model

56 |

57 | We use scikit-learn’s LinearRegression to learn the best-fit line through our data points. 58 |

59 |
60 |
from sklearn.linear_model import LinearRegression
61 | 
62 |   model = LinearRegression()
63 |   model.fit(X, y)
64 |
65 | 66 |

Step 4: Predict the Next Value

67 |

68 | With the trained model, we predict what the value would be at position 6. 69 |

70 |
71 |
next_index = np.array([[6]])
72 |   predicted_value = model.predict(next_index)[0]
73 |
74 | 75 |

Step 5: Get the Line Equation

76 |

77 | We extract the slope (change rate) and intercept (starting point) to show the line’s formula. 78 |

79 |
80 |
slope = model.coef_[0]
81 |   intercept = model.intercept_
82 |
83 | 84 |

Why Linear Regression?

85 |
    86 |
  • ✅ Simple and interpretable — you see the actual equation.
  • 87 |
  • ✅ Fast to train and requires little data.
  • 88 |
  • ✅ Great starting point for understanding how prediction works.
  • 89 |
90 | 91 |

Try It Yourself!

92 |

93 | Go to the Linear Regression page, move the sliders, and watch your predicted point update! 📈 94 |

95 |
96 | {% endblock %} 97 | -------------------------------------------------------------------------------- /Algolyzer/community/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.core.paginator import Paginator 3 | from django.db.models import Sum 4 | from django.http import HttpResponseForbidden 5 | from django.shortcuts import get_object_or_404, redirect, render 6 | from home.decorators import profile_required 7 | 8 | from .models import Category, Comment, Post, Vote 9 | 10 | 11 | def category_list(request): 12 | """Show all categories.""" 13 | categories = Category.objects.all() 14 | return render(request, "community/category_list.html", {"categories": categories}) 15 | 16 | 17 | def post_list_by_category(request, category_id): 18 | """Show posts in a category and allow creating new posts.""" 19 | category = get_object_or_404(Category, id=category_id) 20 | 21 | if request.method == "POST" and request.user.is_authenticated: 22 | title = request.POST.get("title") 23 | content = request.POST.get("content") 24 | if title and content: 25 | Post.objects.create( 26 | title=title, content=content, author=request.user, category=category 27 | ) 28 | return redirect("post_list_by_category", category_id=category.id) 29 | 30 | # For normal get request 31 | category = get_object_or_404(Category, id=category_id) 32 | posts = ( 33 | Post.objects.filter(category=category) 34 | .annotate(total_votes=Sum("votes__vote_type")) 35 | .order_by("-total_votes", "-created_at") 36 | ) 37 | 38 | paginator = Paginator(posts, 5) # Show 5 posts per page 39 | page_number = request.GET.get("page") 40 | page_obj = paginator.get_page(page_number) 41 | 42 | return render( 43 | request, 44 | "community/post_list.html", 45 | {"category": category, "page_obj": page_obj}, 46 | ) 47 | 48 | 49 | def post_detail(request, post_id): 50 | post = get_object_or_404(Post, id=post_id) 51 | 52 | # Delete Post 53 | if ( 54 | request.method == "POST" 55 | and request.POST.get("_method") == "DELETE" 56 | and request.user.is_authenticated 57 | ): 58 | if request.user == post.author: 59 | post.delete() 60 | return redirect("post_list_by_category", category_id=post.category.id) 61 | else: 62 | return HttpResponseForbidden("You can only delete your own posts.") 63 | 64 | # Update Post 65 | if request.method == "POST" and request.user.is_authenticated: 66 | if request.user == post.author: 67 | title = request.POST.get("title") 68 | content = request.POST.get("content") 69 | if title and content: 70 | post.title = title 71 | post.content = content 72 | post.save() 73 | return redirect("post_detail", post_id=post.id) 74 | else: 75 | return HttpResponseForbidden("You can only edit your own posts.") 76 | 77 | # Read posts 78 | """Show post details along with comments and voting functionality.""" 79 | comments = post.comments.all() 80 | total_votes = post.votes.aggregate(Sum("vote_type"))["vote_type__sum"] or 0 81 | 82 | return render( 83 | request, 84 | "community/post_detail.html", 85 | {"post": post, "comments": comments, "total_votes": total_votes}, 86 | ) 87 | 88 | 89 | @login_required 90 | @profile_required 91 | def add_comment(request, post_id): 92 | """Allow users to add comments to a post.""" 93 | post = get_object_or_404(Post, id=post_id) 94 | 95 | if request.method == "POST": 96 | content = request.POST.get("content") 97 | if content: 98 | Comment.objects.create(post=post, author=request.user, content=content) 99 | 100 | return redirect("post_detail", post_id=post.id) 101 | 102 | 103 | @login_required 104 | @profile_required 105 | def vote_post(request, post_id, vote_type): 106 | post = get_object_or_404(Post, id=post_id) 107 | vote_type = int(vote_type) 108 | 109 | # Ensure vote_type is either 1 (upvote) or -1 (downvote) 110 | if vote_type not in [1, -1]: 111 | return HttpResponseForbidden("Invalid vote type.") 112 | 113 | # Check if the user has already voted on this post 114 | existing_vote = Vote.objects.filter(post=post, user=request.user).first() 115 | 116 | if existing_vote: 117 | if existing_vote.vote_type == vote_type: 118 | # If the user clicks the same vote again, remove the vote (unvote) 119 | existing_vote.delete() 120 | else: 121 | # Otherwise, update the vote 122 | existing_vote.vote_type = vote_type 123 | existing_vote.save() 124 | else: 125 | # Create a new vote if none exists 126 | Vote.objects.create(post=post, user=request.user, vote_type=vote_type) 127 | 128 | return redirect("post_detail", post_id=post.id) 129 | -------------------------------------------------------------------------------- /Algolyzer/quiz/templates/quiz/topic.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 | {% comment %} Stats Bar 7 |
8 |
9 |
10 |
11 | 16 | 21 | 22 |
23 |
Total Likes
24 |
25.6K
25 |
21% more than last month
26 |
27 | 28 |
29 |
30 | 35 | 40 | 41 |
42 |
Page Views
43 |
2.6M
44 |
21% more than last month
45 |
46 | 47 |
48 |
49 |
50 |
51 | 52 |
53 |
54 |
55 |
86%
56 |
Reach
57 |
Better than Before
58 |
59 |
60 |
{% endcomment %} 61 | 62 |
63 |
64 | {% comment %} Rules {% endcomment %} 65 |
66 |
67 |

Rules

68 |
    69 |
  • There are {{total}} No of questions in this Quiz.
  • 70 |
  • Each right answer gives 2 XP points.
  • 71 |
  • There is NO time limit so answer without hasting
  • 72 |
  • Your Score will be evaluated at the end of the Quiz
  • 73 |
74 |
75 |
76 | 77 | {% comment %} Topic Overview {% endcomment %} 78 |
79 |
80 |

Overview

81 |

Artificial Intelligence (AI) and Machine Learning (ML) are transforming the way we interact with technology, enabling systems to learn from data and make intelligent decisions. This AI-ML quiz is designed to test your understanding of fundamental concepts such as supervised and unsupervised learning, neural networks, natural language processing, and deep learning. Whether you're a beginner exploring the basics or an advanced learner diving into complex algorithms, this quiz will challenge your knowledge and help you assess your grasp of key AI-ML principles. Get ready to sharpen your skills and see how well you understand the world of intelligent machines! 🚀

82 |
83 |
84 |
85 | Start The Challenge 86 |
87 | 88 | 89 |
90 | 91 | 92 | {% endblock content %} -------------------------------------------------------------------------------- /Algolyzer/templates/account/signup.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load allauth i18n %} 3 | {% block head_title %} 4 | {% trans "Signup" %} 5 | {% endblock head_title %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |

12 | {% trans "Sign Up" %} 13 |

14 |

15 | {% blocktranslate %} 16 | Already have an account? Then please 17 | sign in. 18 | {% endblocktranslate %} 19 |

20 | 21 | {% if not SOCIALACCOUNT_ONLY %} 22 |
23 | {% csrf_token %} 24 | {% for field in form %} 25 |
26 | 34 | {% if field.name == 'password1' or field.name == 'password2' %} 35 | 46 | {% endif %} 47 |
48 | {% for error in field.errors %} 49 | {{ error }} 50 | {% endfor %} 51 | {% endfor %} 52 | {{ redirect_field }} 53 | 54 | 57 |
58 | {% endif %} 59 |
60 |
61 |
62 | {% endblock content %} 63 | 64 | {% block scripts %} 65 | 88 | {% endblock %} 89 | -------------------------------------------------------------------------------- /Algolyzer/playground/templates/playground/doodle_classifier.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |
6 |

Doodle Classifier

7 | 8 | 9 |
10 | 11 |
12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 |
21 | {% csrf_token %} 22 | 23 |
24 | 25 | 26 |
27 |

Previous Results

28 |
29 | {% for result in previous_results %} 30 |
31 | 32 |
33 | Submitted Doodle 34 |
35 |
36 | 37 |
38 |
39 |
Status
40 |
{{ result.status }}
41 |
Failed | Completed
42 |
43 | 44 |
45 |
Prediction
46 |
{{ result.result }}
47 |
Number 0 to 9
48 |
49 | 50 | 55 |
56 |
57 |
58 | {% empty %} 59 |

No previous results available.

60 | {% endfor %} 61 |
62 |
63 |
64 |
65 | 66 | 111 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/study/templates/study/svm_regression.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

6 | A Beginner's Guide to SVM Regression 7 |

8 | 9 |

Introduction

10 |

11 | Support Vector Machine (SVM) Regression is a method that finds a function 12 | to predict continuous values (like temperature or humidity) based on past data. 13 | It works well even when the relationship between inputs and outputs is complex. 14 |

15 |

16 | In this example, we use previous temperature and humidity readings 17 | to predict the next temperature and humidity values. 18 |

19 | 20 |

How Does It Work?

21 |
    22 |
  1. You input a list of temperature-humidity pairs (e.g., [[22,55], [23,60], [24,65]]).
  2. 23 |
  3. The server converts this list into a format the model understands.
  4. 24 |
  5. We train two SVM models: one to predict temperature, another for humidity.
  6. 25 |
  7. The models use all but the last pair to learn patterns.
  8. 26 |
  9. We predict the next temperature and humidity for the final pair.
  10. 27 |
28 | 29 |

Step-by-Step Breakdown

30 | 31 |

Step 1: Read the Input Values

32 |

33 | We get the JSON string of pairs from the form and convert it into a Python list. 34 |

35 |
36 |
import json
 37 | 
 38 |   values_json = request.POST.get("values", "[]")
 39 |   input_values = json.loads(values_json)  # e.g., [[22,55], [23,60], [24,65]]
40 |
41 | 42 |

Step 2: Prepare Data for SVM

43 |

44 | We convert the list to a NumPy array and split it into features and targets. 45 | Features (X) are all pairs except the last. Targets (y) are temperature and humidity separately. 46 |

47 |
48 |
import numpy as np
 49 | 
 50 |   data = np.array(input_values)  # shape: (n, 2)
 51 |   X = data[:-1]                   # all but last for training
 52 |   y_temp = data[1:, 0]            # target: next temperatures
 53 |   y_hum = data[1:, 1]             # target: next humidities
54 |
55 | 56 |

Step 3: Train SVM Models

57 |

58 | We create two SVR (Support Vector Regression) models and fit them on our training data. 59 |

60 |
61 |
from sklearn.svm import SVR
 62 | 
 63 |   svr_temp = SVR(kernel="rbf", C=100, gamma="scale")
 64 |   svr_hum = SVR(kernel="rbf", C=100, gamma="scale")
 65 |   svr_temp.fit(X, y_temp)
 66 |   svr_hum.fit(X, y_hum)
67 |
68 | 69 |

Step 4: Predict the Next Values

70 |

71 | We take the last input pair and ask both models to predict the next temperature and humidity. 72 |

73 |
74 |
last_pair = data[-1].reshape(1, -1)
 75 |   predicted_temp = svr_temp.predict(last_pair)[0]
 76 |   predicted_hum = svr_hum.predict(last_pair)[0]
77 |
78 | 79 |

Step 5: Display the Predictions

80 |

81 | We round the predictions and send them back to the template for display. 82 |

83 |
84 |
pred_temp = round(predicted_temp, 2)
 85 |   pred_hum = round(predicted_hum, 2)
86 |

87 | Then render these in the Django template 88 |

89 |
90 | 91 |

Why SVM Regression?

92 |
    93 |
  • ✅ Works well with small to medium-sized datasets.
  • 94 |
  • ✅ Can model complex, non-linear relationships.
  • 95 |
  • ✅ More robust to outliers than simple linear regression.
  • 96 |
97 | 98 |

Give It a Try!

99 |

100 | Visit the SVM Regression page, enter a JSON list of [temp, hum] pairs, and see your next prediction! 🌡️💧 101 |

102 |
103 | {% endblock %} 104 | -------------------------------------------------------------------------------- /Algolyzer/quiz/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.1.4 on 2025-01-12 13:17 2 | 3 | import django.db.models.deletion 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | initial = True 10 | 11 | dependencies = [ 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name="Topic", 18 | fields=[ 19 | ( 20 | "id", 21 | models.BigAutoField( 22 | auto_created=True, 23 | primary_key=True, 24 | serialize=False, 25 | verbose_name="ID", 26 | ), 27 | ), 28 | ("name", models.CharField(max_length=100)), 29 | ], 30 | ), 31 | migrations.CreateModel( 32 | name="QuizProgress", 33 | fields=[ 34 | ( 35 | "id", 36 | models.BigAutoField( 37 | auto_created=True, 38 | primary_key=True, 39 | serialize=False, 40 | verbose_name="ID", 41 | ), 42 | ), 43 | ("current_question", models.IntegerField(default=0)), 44 | ("completed", models.BooleanField(default=False)), 45 | ( 46 | "user", 47 | models.ForeignKey( 48 | on_delete=django.db.models.deletion.CASCADE, 49 | to=settings.AUTH_USER_MODEL, 50 | ), 51 | ), 52 | ( 53 | "topic", 54 | models.ForeignKey( 55 | on_delete=django.db.models.deletion.CASCADE, to="quiz.topic" 56 | ), 57 | ), 58 | ], 59 | ), 60 | migrations.CreateModel( 61 | name="Question", 62 | fields=[ 63 | ( 64 | "id", 65 | models.BigAutoField( 66 | auto_created=True, 67 | primary_key=True, 68 | serialize=False, 69 | verbose_name="ID", 70 | ), 71 | ), 72 | ("text", models.TextField()), 73 | ("option_a", models.CharField(max_length=200)), 74 | ("option_b", models.CharField(max_length=200)), 75 | ("option_c", models.CharField(max_length=200)), 76 | ("option_d", models.CharField(max_length=200)), 77 | ( 78 | "correct_answer", 79 | models.CharField( 80 | choices=[ 81 | ("a", "Option A"), 82 | ("b", "Option B"), 83 | ("c", "Option C"), 84 | ("d", "Option D"), 85 | ], 86 | help_text="Correct answer should be 'a', 'b', 'c', or 'd'", 87 | max_length=1, 88 | ), 89 | ), 90 | ( 91 | "topic", 92 | models.ForeignKey( 93 | on_delete=django.db.models.deletion.CASCADE, to="quiz.topic" 94 | ), 95 | ), 96 | ], 97 | ), 98 | migrations.CreateModel( 99 | name="UserAnswer", 100 | fields=[ 101 | ( 102 | "id", 103 | models.BigAutoField( 104 | auto_created=True, 105 | primary_key=True, 106 | serialize=False, 107 | verbose_name="ID", 108 | ), 109 | ), 110 | ( 111 | "selected_answer", 112 | models.CharField( 113 | choices=[ 114 | ("a", "Option A"), 115 | ("b", "Option B"), 116 | ("c", "Option C"), 117 | ("d", "Option D"), 118 | ], 119 | help_text="Selected answer should be 'a', 'b', 'c', or 'd'", 120 | max_length=1, 121 | ), 122 | ), 123 | ("is_correct", models.BooleanField(default=False)), 124 | ( 125 | "question", 126 | models.ForeignKey( 127 | on_delete=django.db.models.deletion.CASCADE, to="quiz.question" 128 | ), 129 | ), 130 | ( 131 | "topic", 132 | models.OneToOneField( 133 | on_delete=django.db.models.deletion.CASCADE, to="quiz.topic" 134 | ), 135 | ), 136 | ( 137 | "user", 138 | models.ForeignKey( 139 | on_delete=django.db.models.deletion.CASCADE, 140 | to=settings.AUTH_USER_MODEL, 141 | ), 142 | ), 143 | ], 144 | ), 145 | ] 146 | -------------------------------------------------------------------------------- /Algolyzer/playground/templates/playground/linear_regression.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block extra_head %} 4 | 5 | {% endblock %} 6 | 7 | {% block content %} 8 |
9 |
10 |

Linear Regression

11 | 12 | 13 |
14 | {% csrf_token %} 15 | 16 | 17 | {% for i in "12345" %} 18 |
19 | 23 | 32 |
33 | {% endfor %} 34 | 35 | 36 |
37 | 38 | {% if predicted_value %} 39 |
40 |
41 |

Input Values: {{ input_values|join:", " }}

42 |

Prediction: The next value is {{ predicted_value }}.

43 |
44 |
45 | {% endif %} 46 | 47 | {% if show_chart %} 48 |
49 |
50 |
51 |

Linear Regression Chart

52 | 53 |
54 |
55 |
56 | 57 | {% block scripts %} 58 | 123 | {% endblock %} 124 | {% endif %} 125 | 126 |
127 |
128 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/quiz/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.shortcuts import get_object_or_404, redirect, render 3 | from home.decorators import profile_required 4 | from home.models import UserProfile 5 | 6 | from .forms import QuizForm 7 | from .models import Question, QuizProgress, Topic, UserAnswer 8 | 9 | 10 | @login_required 11 | @profile_required 12 | def quiz_home(request): 13 | """Main QUIZ Home Page""" 14 | data = [] 15 | topics = Topic.objects.all() 16 | for topic in topics: 17 | score = 0 18 | total = Question.objects.filter(topic=topic).count() 19 | progress = QuizProgress.objects.filter(user=request.user, topic=topic).first() 20 | if progress is not None and progress.completed: 21 | answers = UserAnswer.objects.filter(user=request.user, topic=topic) 22 | score = answers.filter(is_correct=True).count() 23 | data.append( 24 | { 25 | "topic": topic, 26 | "score": score, 27 | "total": total, 28 | } 29 | ) 30 | 31 | context = {"data": data} 32 | return render(request, "quiz/home.html", context=context) 33 | 34 | 35 | @login_required 36 | @profile_required 37 | def quiz_topic(request, topic_id): 38 | topic = get_object_or_404(Topic, id=topic_id) 39 | score = 0 40 | total = 0 41 | progress = QuizProgress.objects.filter(user=request.user, topic=topic).first() 42 | if progress is not None and progress.completed: 43 | answers = UserAnswer.objects.filter(user=request.user, topic=topic) 44 | score = answers.filter(is_correct=True).count() 45 | total = Question.objects.filter(topic=topic).count() 46 | 47 | context = { 48 | "topic": topic, 49 | "score": score, 50 | "total": total, 51 | } 52 | return render(request, "quiz/topic.html", context=context) 53 | 54 | 55 | @login_required 56 | @profile_required 57 | def quiz_start(request, topic_id): 58 | """ 59 | Resets user progress to start a fresh quiz 60 | """ 61 | topic = get_object_or_404(Topic, id=topic_id) 62 | questions = Question.objects.filter(topic=topic) 63 | if not questions.exists(): 64 | return render(request, "quiz/no_questions.html") 65 | 66 | # Initialize or reset progress 67 | QuizProgress.objects.filter(user=request.user, topic=topic).delete() 68 | QuizProgress.objects.create(user=request.user, topic=topic, current_question=0) 69 | UserAnswer.objects.filter(user=request.user, topic=topic).delete() 70 | return redirect("quiz_question", topic_id=topic.id) 71 | 72 | 73 | @login_required 74 | @profile_required 75 | def quiz_question(request, topic_id): 76 | topic = get_object_or_404(Topic, id=topic_id) 77 | progress = get_object_or_404(QuizProgress, user=request.user, topic=topic) 78 | 79 | # Fetch the current question 80 | questions = Question.objects.filter(topic=topic) 81 | if progress.current_question >= len(questions): 82 | progress.completed = True 83 | progress.save() 84 | return redirect("quiz_results", topic_id=topic.id) 85 | 86 | question = questions[progress.current_question] 87 | 88 | if request.method == "POST": 89 | form = QuizForm(question, request.POST) 90 | if form.is_valid(): 91 | selected_answer = form.cleaned_data["answer"] 92 | 93 | # Save user's answer, is_correct field is managed internally in model. 94 | UserAnswer.objects.create( 95 | topic=topic, 96 | user=request.user, 97 | question=question, 98 | selected_answer=selected_answer, 99 | ) 100 | 101 | # Move to the next question 102 | progress.current_question += 1 103 | progress.save() 104 | return redirect("quiz_question", topic_id=topic.id) 105 | else: 106 | form = QuizForm(question) 107 | 108 | return render( 109 | request, 110 | "quiz/question.html", 111 | {"form": form, "progress": progress, "total_array": range(len(questions))}, 112 | ) 113 | 114 | 115 | def quiz_results(request, topic_id): 116 | topic = get_object_or_404(Topic, id=topic_id) 117 | quiz_progress = get_object_or_404(QuizProgress, topic=topic, user=request.user) 118 | if not quiz_progress.completed: 119 | return redirect("quiz_question", topic_id=topic.id) 120 | 121 | answers = UserAnswer.objects.filter(user=request.user, topic=topic) 122 | for answer in answers: 123 | # Add full option text to each answer 124 | answer.selected_option_text = answer.question.get_option_text( 125 | answer.selected_answer 126 | ) 127 | answer.correct_option_text = answer.question.get_option_text( 128 | answer.question.correct_answer 129 | ) 130 | 131 | score = answers.filter(is_correct=True).count() 132 | total = Question.objects.filter(topic=topic).count() 133 | XP_REWARDS = { 134 | "Easy": 2, 135 | "Medium": 5, 136 | "Hard": 10, 137 | "Veteran": 20, 138 | } 139 | # Add XP to the user's profile based on the topic difficulty 140 | user_profile = UserProfile.objects.get(user=request.user) 141 | xp_to_add = ( 142 | XP_REWARDS.get(topic.difficulty, 0) * score 143 | ) # Default to 0 if difficulty is not found 144 | user_profile.add_xp(xp_to_add) 145 | 146 | context = { 147 | "topic": topic, 148 | "score": score, 149 | "total": total, 150 | "answers": answers, 151 | "xp": xp_to_add, 152 | } 153 | 154 | return render(request, "quiz/results.html", context=context) 155 | -------------------------------------------------------------------------------- /Algolyzer/quiz/templates/quiz/results.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |
6 |
🎊 Congratulations! 🎊
7 |
8 |
9 |
10 |
11 |
Your Score
12 |
13 | 14 | 15 | 16 |
17 |
Experience earned: +{{ xp }}
18 |
19 |
20 |
21 | 22 | 23 |
24 | {% for answer in answers %} 25 |
26 | 27 | 35 |
36 |
37 |
38 |

39 | Your Answer: 40 | 41 | {{ answer.get_selected_answer_display }} - 42 | {{ answer.selected_option_text }} 43 | 44 |

45 | {% if not answer.is_correct %} 46 |

47 | Correct Answer: 48 | 49 | {{ answer.question.get_correct_answer_display }} - 50 | {{ answer.correct_option_text }} 51 | 52 |

53 | {% endif %} 54 |
55 |
56 |
57 |
58 | {% endfor %} 59 |
60 |
61 |
62 |
63 | {% endblock %} 64 | 65 | {% block scripts %} 66 | 111 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/playground/templates/playground/kmeans_clustering.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block extra_head %} 4 | 5 | {% endblock %} 6 | 7 | {% block content %} 8 |
9 |
10 |

K-Means Clustering

11 | 12 | 13 |
14 | {% csrf_token %} 15 |
16 | 17 |
18 | 19 | 20 |
21 |
22 |

Added Values: None

23 |
24 | 25 |
26 | 27 | 28 |
29 | 30 | {% if error %} 31 |
32 |
33 |

{{ error }}

34 |
35 |
36 | {% endif %} 37 | 38 | {% if classified_values %} 39 |
40 |
41 |

Input Values: {{ input_values|join:", " }}

42 |

Clusters:

43 |
    44 | {% for value, cluster in classified_values %} 45 |
  • Value: {{ value }} → Cluster: {{ cluster }}
  • 46 | {% endfor %} 47 |
48 |
49 |
50 | {% endif %} 51 | 52 | {% if show_chart %} 53 |
54 |
55 |
56 |

K-Means Clustering Chart

57 | 58 |
59 |
60 |
61 | {% endif %} 62 |
63 |
64 | {% endblock %} 65 | 66 | {% block scripts %} 67 | 173 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/data/quiz_data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "quiz.question", 4 | "pk": 1, 5 | "fields": { 6 | "topic": 1, 7 | "text": "What is Artificial Intelligence (AI)?", 8 | "option_a": "A branch of science focused on studying human psychology", 9 | "option_b": "The process of designing computer games", 10 | "option_c": "The simulation of human intelligence in machines", 11 | "option_d": "The development of physical robots only", 12 | "correct_answer": "c" 13 | } 14 | }, 15 | { 16 | "model": "quiz.question", 17 | "pk": 2, 18 | "fields": { 19 | "topic": 1, 20 | "text": "Which of the following is NOT a type of machine learning?", 21 | "option_a": "Supervised learning", 22 | "option_b": "Unsupervised learning", 23 | "option_c": "Reinforcement learning", 24 | "option_d": "Data modeling", 25 | "correct_answer": "d" 26 | } 27 | }, 28 | { 29 | "model": "quiz.question", 30 | "pk": 3, 31 | "fields": { 32 | "topic": 1, 33 | "text": "What distinguishes Machine Learning from traditional programming?", 34 | "option_a": "Machine Learning models rely on fixed rules defined by humans", 35 | "option_b": "Machine Learning models learn patterns from data", 36 | "option_c": "Machine Learning does not require any data", 37 | "option_d": "Traditional programming can handle image recognition better than Machine Learning", 38 | "correct_answer": "b" 39 | } 40 | }, 41 | { 42 | "model": "quiz.question", 43 | "pk": 4, 44 | "fields": { 45 | "topic": 1, 46 | "text": "Which of the following is an example of supervised learning?", 47 | "option_a": "Grouping customers based on purchasing behavior", 48 | "option_b": "Predicting house prices based on features like area and number of rooms", 49 | "option_c": "Detecting unusual transactions without labeled data", 50 | "option_d": "Training a robot to learn from rewards in a game environment", 51 | "correct_answer": "b" 52 | } 53 | }, 54 | { 55 | "model": "quiz.question", 56 | "pk": 5, 57 | "fields": { 58 | "topic": 1, 59 | "text": "What is the role of a dataset in Machine Learning?", 60 | "option_a": "To provide training and testing data for the model", 61 | "option_b": "To create a database of rules", 62 | "option_c": "To store the output of the model", 63 | "option_d": "To develop software applications", 64 | "correct_answer": "a" 65 | } 66 | }, 67 | { 68 | "model": "quiz.question", 69 | "pk": 6, 70 | "fields": { 71 | "topic": 1, 72 | "text": "What is a common application of AI in daily life?", 73 | "option_a": "Weather forecasting using random guesses", 74 | "option_b": "Spam email filtering in mail services", 75 | "option_c": "Writing code for computer programs manually", 76 | "option_d": "Developing spreadsheets for data storage", 77 | "correct_answer": "b" 78 | } 79 | }, 80 | { 81 | "model": "quiz.question", 82 | "pk": 7, 83 | "fields": { 84 | "topic": 1, 85 | "text": "What does \"unsupervised learning\" aim to do?", 86 | "option_a": "Predict a target variable using labeled data", 87 | "option_b": "Find hidden patterns in unlabeled data", 88 | "option_c": "Simulate human intelligence for logical tasks", 89 | "option_d": "Train robots to follow human instructions", 90 | "correct_answer": "b" 91 | } 92 | }, 93 | { 94 | "model": "quiz.question", 95 | "pk": 8, 96 | "fields": { 97 | "topic": 1, 98 | "text": "Which of the following is an example of reinforcement learning?", 99 | "option_a": "Clustering news articles based on their content", 100 | "option_b": "Teaching a robot to walk by rewarding it for each successful step", 101 | "option_c": "Predicting stock prices using historical data", 102 | "option_d": "Identifying spam emails based on labeled examples", 103 | "correct_answer": "b" 104 | } 105 | }, 106 | { 107 | "model": "quiz.question", 108 | "pk": 9, 109 | "fields": { 110 | "topic": 1, 111 | "text": "Which of these statements is true about deep learning?", 112 | "option_a": "It is a subset of reinforcement learning", 113 | "option_b": "It does not use neural networks", 114 | "option_c": "It requires large amounts of data to perform well", 115 | "option_d": "It is primarily used for clustering", 116 | "correct_answer": "c" 117 | } 118 | }, 119 | { 120 | "model": "quiz.question", 121 | "pk": 10, 122 | "fields": { 123 | "topic": 1, 124 | "text": "What is the primary objective of Machine Learning?", 125 | "option_a": "To make machines conscious like humans", 126 | "option_b": "To build hardware that mimics the human brain", 127 | "option_c": "To write manual code for all decision-making processes", 128 | "option_d": "To enable machines to learn from data and make decisions", 129 | "correct_answer": "d" 130 | } 131 | }, 132 | { 133 | "model": "quiz.topic", 134 | "pk": 1, 135 | "fields": { 136 | "name": "Introduction to Artificial Intelligence and Machine Learning" 137 | } 138 | }, 139 | { 140 | "model": "quiz.topic", 141 | "pk": 2, 142 | "fields": { 143 | "name": "Mathematics and Statistics for AI/ML" 144 | } 145 | }, 146 | { 147 | "model": "quiz.topic", 148 | "pk": 3, 149 | "fields": { 150 | "name": "Data Preprocessing and Feature Engineering" 151 | } 152 | }, 153 | { 154 | "model": "quiz.topic", 155 | "pk": 4, 156 | "fields": { 157 | "name": "Supervised Learning" 158 | } 159 | }, 160 | { 161 | "model": "quiz.topic", 162 | "pk": 5, 163 | "fields": { 164 | "name": "Unsupervised Learning" 165 | } 166 | }, 167 | { 168 | "model": "quiz.topic", 169 | "pk": 6, 170 | "fields": { 171 | "name": "Neural Networks and Deep Learning" 172 | } 173 | }, 174 | { 175 | "model": "quiz.topic", 176 | "pk": 7, 177 | "fields": { 178 | "name": "Reinforcement Learning" 179 | } 180 | }, 181 | { 182 | "model": "quiz.topic", 183 | "pk": 8, 184 | "fields": { 185 | "name": "Natural Language Processing (NLP)" 186 | } 187 | }, 188 | { 189 | "model": "quiz.topic", 190 | "pk": 9, 191 | "fields": { 192 | "name": "Model Deployment and Scalability" 193 | } 194 | }, 195 | { 196 | "model": "quiz.topic", 197 | "pk": 10, 198 | "fields": { 199 | "name": "Ethical AI and Advanced Topics" 200 | } 201 | } 202 | ] 203 | -------------------------------------------------------------------------------- /Algolyzer/home/templates/home/dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

6 | Welcome, {{ user_profile }} 7 |
8 | {% csrf_token %} 9 | 10 |
11 |

12 | 13 |
14 | 15 |
16 |
17 | 18 | 19 | 20 |
21 |
Your XP
22 |
{{ user_profile.xp }} XP
23 |
Level {{ user_profile.level }}
24 | 25 |
{{ user_profile.get_next_level_xp }} XP to next level
26 |
27 | 28 | 29 |
30 |
31 | 32 | 33 | 34 |
35 |
Quizzes Completed
36 |
{{ completed_quizzes }}
37 |
Out of {{ total_quizzes }} topics
38 |
39 | 40 | 41 |
42 |
43 | 44 | 45 | 46 |
47 |
Tasks
48 |
{{ completed_tasks }} Done
49 |
{{ pending_tasks }} Pending
50 |
51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 |
59 |
Forum Activity
60 |
{{ total_posts }} Posts
61 |
{{ total_comments }} Comments
62 |
63 |
64 | 65 | 66 |
67 |

Recent Activity

68 |
69 | 70 |
71 |
72 |

Recent Quizzes

73 |
    74 | {% for progress in recent_quizzes %} 75 |
  • 76 |

    {{ progress.topic.name }}

    77 |

    Completed on {{ progress.updated_at|date:"M d, Y" }}

    78 |
  • 79 | {% endfor %} 80 |
81 |
82 |
83 | 84 | 85 |
86 |
87 |

Recent Tasks

88 |
    89 | {% for task in recent_tasks %} 90 |
  • 91 |

    {{ task.model_name }}

    92 |

    93 | Status: {{ task.status }} 94 |

    95 |

    Created on {{ task.created_at|date:"M d, Y" }}

    96 |
  • 97 | {% endfor %} 98 |
99 |
100 |
101 |
102 |
103 | 104 | 105 |
106 |

Forum Activity

107 |
108 | 109 |
110 |
111 |

Recent Posts

112 |
    113 | {% for post in recent_posts %} 114 |
  • 115 |

    {{ post.title }}

    116 |

    In {{ post.category.name }}

    117 |

    Posted on {{ post.created_at|date:"M d, Y" }}

    118 |
  • 119 | {% endfor %} 120 |
121 |
122 |
123 | 124 | 125 |
126 |
127 |

Recent Comments

128 |
    129 | {% for comment in recent_comments %} 130 |
  • 131 |

    {{ comment.content|truncatechars:50 }}

    132 |

    On {{ comment.post.title }}

    133 |

    Posted on {{ comment.created_at|date:"M d, Y" }}

    134 |
  • 135 | {% endfor %} 136 |
137 |
138 |
139 |
140 |
141 |
142 | {% endblock %} -------------------------------------------------------------------------------- /Algolyzer/community/templates/community/post_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |
6 | ← Back to Posts 7 | 8 | {% if user == post.author %} 9 | 10 | 15 | 16 | 36 | 37 | {% endif %} 38 | 39 | {% if user == post.author %} 40 | 41 | 46 | 47 | 57 | 58 | {% endif %} 59 |
60 | 61 | 62 |
63 |
64 |

{{ post.title }}

65 |

By {{ post.author.username }} | {{ post.created_at|date:"F j, Y, g:i a" }}

66 | 67 | {% if post.image %} 68 | 69 | {% endif %} 70 | 71 | 72 |
73 |

{{ post.content|linebreaks }}

74 |
75 | 76 | 77 |
78 |
79 | {% csrf_token %} 80 | 85 |
86 |
87 | {% csrf_token %} 88 | 93 |
94 |

{{ total_votes }}

95 |
96 |
97 |
98 | 99 | 100 |
101 |

Comments

102 |
103 | {% for comment in comments %} 104 |
105 |

{{ comment.author.username }}: {{ comment.content }}

106 |

{{ comment.created_at|date:"F j, Y, g:i a" }}

107 |
108 | {% empty %} 109 |

No comments yet. Be the first to comment!

110 | {% endfor %} 111 |
112 | 113 | {% if user.is_authenticated %} 114 | 115 |
116 | {% csrf_token %} 117 | 118 | 119 |
120 | {% else %} 121 |

You must be logged in to comment.

122 | {% endif %} 123 |
124 |
125 | {% endblock %} 126 | -------------------------------------------------------------------------------- /Algolyzer/templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load allauth i18n %} 3 | {% block head_title %} 4 | {% trans "Sign In" %} 5 | {% endblock head_title %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |

12 | {% trans "Sign In" %} 13 |

14 | {% if not SOCIALACCOUNT_ONLY %} 15 |

16 | {% blocktranslate %} 17 | If you don't have an account, please 18 | sign up first. 19 | {% endblocktranslate %} 20 |

21 | {% endif %} 22 | 23 |
24 | {% csrf_token %} 25 | {% if form.non_field_errors %} 26 |
27 | {% for error in form.non_field_errors %} 28 | {{ error }} 29 | {% endfor %} 30 |
31 | {% endif %} 32 | 33 | 34 | {% for field in form %} 35 | {% if field.label == 'Remember Me' %} 36 |
37 | 45 | {{ field.label }} 46 |
47 | {% else %} 48 |
49 | 57 | {% if field.name == 'password' %} 58 | 69 | {% endif %} 70 |
71 | {% for error in field.errors %} 72 | {{ error }} 73 | {% endfor %} 74 | {% endif %} 75 | {% endfor %} 76 | 77 | {{ redirect_field }} 78 | 79 | 82 |
83 | 84 | {% if LOGIN_BY_CODE_ENABLED or PASSKEY_LOGIN_ENABLED %} 85 |
OR
86 |
87 | {% if PASSKEY_LOGIN_ENABLED %} 88 | 89 | {% trans "Sign in with a passkey" %} 90 | 91 | {% endif %} 92 | {% if LOGIN_BY_CODE_ENABLED %} 93 | 94 | {% trans "Mail me a sign-in code" %} 95 | 96 | {% endif %} 97 |
98 | {% endif %} 99 | 100 | {% if SOCIALACCOUNT_ENABLED %} 101 |
Or Use a Third Party App
102 |
103 | {% include "socialaccount/snippets/login.html" with page_layout="entrance" %} 104 |
105 | {% endif %} 106 |
107 |
108 |
109 | {% endblock content %} 110 | 111 | {% block extra_body %} 112 | {{ block.super }} 113 | {% if PASSKEY_LOGIN_ENABLED %} 114 | {% include "mfa/webauthn/snippets/login_script.html" with button_id="passkey_login" %} 115 | {% endif %} 116 | {% endblock extra_body %} 117 | 118 | {% block scripts %} 119 | 120 | 121 | 144 | {% endblock %} 145 | -------------------------------------------------------------------------------- /Algolyzer/home/templates/home/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block extra_head %} 4 | {% load static %} 5 | 13 | {% endblock %} 14 | 15 | {% block content %} 16 |
17 |
18 | 19 | {% comment %}

Welcome to

{% endcomment %} 20 |

Easiest way to

21 |

Learn AI-ML

22 |

Become the next Algo Expert with Algolyzer

23 | 24 |
25 | Contribute 26 | Get Started 27 |
28 |
29 |
30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /Algolyzer/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% block title %}Algolyzer{% endblock %} 8 | 9 | {% load static %} 10 | 11 | 12 | 13 | 14 | 15 | {% block extra_head %}{% endblock %} 16 | 17 | 18 | 19 | 20 | {% comment %} Loading Url tags to activate tab-active class without bugs and errors {% endcomment %} 21 | {% url 'quiz_home' as quiz_url %} 22 | {% url 'playground_home' as playground_url %} 23 | {% url 'home' as home_url %} 24 | {% url 'category_list' as community_url %} 25 | {% url 'study_home' as study_url %} 26 | 27 | 92 | 93 | 94 | 95 |
96 | {% block content %} 97 |

Welcome to my Django app!

98 | {% endblock %} 99 |
100 | 101 | 102 | 117 | 164 | 165 | 166 | {% block scripts %}{% endblock %} 167 | 168 | 169 | --------------------------------------------------------------------------------