From 9d487b368f3bd75fd3323662d03be8a7f8521922 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 25 Nov 2015 21:57:55 -0800 Subject: [PATCH 1/5] Work on basic UI of test bank --- .../migrations/0003_auto_20151007_2244.py | 33 ------------------- website/templates/website/header_footer.html | 1 + website/urls.py | 1 + website/views.py | 3 ++ 4 files changed, 5 insertions(+), 33 deletions(-) delete mode 100644 upe_calendar/migrations/0003_auto_20151007_2244.py diff --git a/upe_calendar/migrations/0003_auto_20151007_2244.py b/upe_calendar/migrations/0003_auto_20151007_2244.py deleted file mode 100644 index e1af2fd..0000000 --- a/upe_calendar/migrations/0003_auto_20151007_2244.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('upe_calendar', '0002_auto_20150328_1856'), - ] - - operations = [ - migrations.RemoveField( - model_name='event', - name='end_time', - ), - migrations.RemoveField( - model_name='event', - name='thumbnail', - ), - migrations.AddField( - model_name='event', - name='facebookid', - field=models.BigIntegerField(default=0), - preserve_default=True, - ), - migrations.AlterField( - model_name='event', - name='banner', - field=models.CharField(max_length=4096), - ), - ] diff --git a/website/templates/website/header_footer.html b/website/templates/website/header_footer.html index 1c9144b..b07452a 100644 --- a/website/templates/website/header_footer.html +++ b/website/templates/website/header_footer.html @@ -45,6 +45,7 @@ Student Services
  • diff --git a/website/urls.py b/website/urls.py index 8662211..a33ca73 100644 --- a/website/urls.py +++ b/website/urls.py @@ -10,4 +10,5 @@ url(r'^$', 'website.views.index', name='index'), url(r'^oh/$', 'website.views.oh', name='oh'), + url(r'^interview/$', 'website.views.interview', name='interview') ) diff --git a/website/views.py b/website/views.py index f59d48f..f6a6585 100644 --- a/website/views.py +++ b/website/views.py @@ -21,3 +21,6 @@ def index(request): def oh(request): return render(request, 'website/oh.html', {}) + +def interview(request): + return render(request, 'website/interview.html', {}) From 2614a373ea8e06bcb2290a6bb92c6798d8f9fbb9 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 27 Nov 2015 09:03:35 -0800 Subject: [PATCH 2/5] Continue working on question bank UI --- website/static/website/css/interview.css | 19 +++++++ website/templates/website/interview.html | 63 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 website/static/website/css/interview.css create mode 100644 website/templates/website/interview.html diff --git a/website/static/website/css/interview.css b/website/static/website/css/interview.css new file mode 100644 index 0000000..548aef4 --- /dev/null +++ b/website/static/website/css/interview.css @@ -0,0 +1,19 @@ +#questions-sidebar { + height: 600px; + border: 1px solid black; + overflow: auto; +} +#questions-table { + cursor: pointer; +} +#targ-question { + height: 600px; + overflow: auto; +} +#question-soln { + margin-top: 10px; +} +#nav-questions { + margin-top: 10px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/website/templates/website/interview.html b/website/templates/website/interview.html new file mode 100644 index 0000000..30dd0fa --- /dev/null +++ b/website/templates/website/interview.html @@ -0,0 +1,63 @@ +{% extends "website/header_footer.html" %} +{% load staticfiles %} +{% block javascript %} + + + + + + + + + + + + + + + +{% endblock %} +{% block content %} +
    +
    +
    +

    Questions

    + + + + + + + + + + + +
    Arrays
    Array 1
    Array 2
    Array 3
    Linked Lists
    LL 1
    LL 2
    LL 3
    Trees
    Bitwise Ops
    +
    +
    +

    Sample Question Title

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +

    +
    + +
    +
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    +
    +
    + +
    +
    +
    + +{% endblock %} \ No newline at end of file From ac812e96361820e490da0d92f4334880f3851818 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 27 Nov 2015 16:45:01 -0800 Subject: [PATCH 3/5] Add question models --- website/models.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/website/models.py b/website/models.py index beeb308..526d9cb 100644 --- a/website/models.py +++ b/website/models.py @@ -1,2 +1,23 @@ from django.db import models +class QuestionCategory(models.Model): + category_title = models.CharField(max_length=100) + +class Question(models.Model): + question_category = models.ForeignKey(QuestionCategory) + question_title = models.CharField(max_length=100) + question_text = models.CharField(max_length=1000) + question_soln = models.CharField(max_length=1000) + question_difficulty = models.PositiveSmallIntegerField() + +class QuestionImage(models.Model): + question = models.ForeignKey(Question) + img = models.ImageField(upload_to='question_images', null=True) + for_soln = models.BooleanField(default=False) # whether this image is for the soln of the question + + + + + + + From 1e725d213f54667ae5d3a2c5b029f1da0da0b31e Mon Sep 17 00:00:00 2001 From: Jack Thakar Date: Sat, 12 Dec 2015 01:53:32 -0800 Subject: [PATCH 4/5] add markdown and mathjax support, link frontend to backend --- requirements.txt | 2 ++ upe/settings.py | 13 +++++++ upe/urls.py | 2 +- website/admin.py | 4 +++ website/models.py | 28 +++++++++------ website/static/website/css/interview.css | 10 ++++-- website/templates/website/interview.html | 36 ++++++++----------- .../templates/website/interview_question.html | 33 +++++++++++++++++ website/urls.py | 3 +- website/views.py | 8 ++++- 10 files changed, 102 insertions(+), 37 deletions(-) create mode 100644 website/templates/website/interview_question.html diff --git a/requirements.txt b/requirements.txt index 6fcd3b9..902d47f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ Django==1.7 Pillow==2.4.0 psycopg2==2.5.3 pystache==0.5.4 +django-markdown==0.8.4 +django-mathjax==0.0.5 diff --git a/upe/settings.py b/upe/settings.py index cadd573..046ffad 100644 --- a/upe/settings.py +++ b/upe/settings.py @@ -37,6 +37,8 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django_markdown', + 'django_mathjax', 'website', 'upe_calendar', 'users' @@ -105,3 +107,14 @@ EMAIL_USE_TLS = False DEFAULT_FROM_EMAIL = 'Do-Not-Reply ' +MATHJAX_ENABLED=True + +MATHJAX_CONFIG_DATA = { + "tex2jax": { + "inlineMath": + [ + ['\\(','\\)'] + ] + } +} + diff --git a/upe/urls.py b/upe/urls.py index 597c46a..cd59d19 100644 --- a/upe/urls.py +++ b/upe/urls.py @@ -38,5 +38,5 @@ url(r'^static/(?P.*)$', 'django.views.static.serve', { 'document_root': settings.STATIC_ROOT, }), - + url('^markdown/', include( 'django_markdown.urls')), ) diff --git a/website/admin.py b/website/admin.py index 694323f..69aa5ff 100644 --- a/website/admin.py +++ b/website/admin.py @@ -1 +1,5 @@ from django.contrib import admin +from website.models import * + +admin.site.register(QuestionTag) +admin.site.register(Question) \ No newline at end of file diff --git a/website/models.py b/website/models.py index 526d9cb..8ea99a2 100644 --- a/website/models.py +++ b/website/models.py @@ -1,19 +1,27 @@ from django.db import models +from django_markdown.models import MarkdownField -class QuestionCategory(models.Model): - category_title = models.CharField(max_length=100) +class QuestionTag(models.Model): + tag = models.CharField(max_length=100) + def __str__(self): + return self.tag class Question(models.Model): - question_category = models.ForeignKey(QuestionCategory) - question_title = models.CharField(max_length=100) - question_text = models.CharField(max_length=1000) - question_soln = models.CharField(max_length=1000) - question_difficulty = models.PositiveSmallIntegerField() + tags = models.ManyToManyField(QuestionTag) + title = models.CharField(max_length=100) + text = MarkdownField() + solution = MarkdownField() + difficulty = models.PositiveSmallIntegerField() + + def __str__(self): + return self.title + class QuestionImage(models.Model): - question = models.ForeignKey(Question) - img = models.ImageField(upload_to='question_images', null=True) - for_soln = models.BooleanField(default=False) # whether this image is for the soln of the question + question = models.ForeignKey(Question) + img = models.ImageField(upload_to='question_images', null=True) + for_soln = models.BooleanField(default=False) # whether this image is for the soln of the question + diff --git a/website/static/website/css/interview.css b/website/static/website/css/interview.css index 548aef4..cc4a9ae 100644 --- a/website/static/website/css/interview.css +++ b/website/static/website/css/interview.css @@ -1,15 +1,21 @@ #questions-sidebar { height: 600px; - border: 1px solid black; overflow: auto; } #questions-table { cursor: pointer; } #targ-question { - height: 600px; + height: 800px; overflow: auto; } + +#targ-question iframe { + height: 100%; + width: 100%; +} + + #question-soln { margin-top: 10px; } diff --git a/website/templates/website/interview.html b/website/templates/website/interview.html index 30dd0fa..443b170 100644 --- a/website/templates/website/interview.html +++ b/website/templates/website/interview.html @@ -21,9 +21,8 @@
    -

    Questions

    - + + {% for q in questions %} + + {% endfor %}
    Arrays
    {{q.title}}
    -
    -

    Sample Question Title

    -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    -

    -
    - -
    -
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    -
    -
    - +
    +
    {% endblock %} \ No newline at end of file diff --git a/website/templates/website/interview_question.html b/website/templates/website/interview_question.html new file mode 100644 index 0000000..925c498 --- /dev/null +++ b/website/templates/website/interview_question.html @@ -0,0 +1,33 @@ +{% load staticfiles %} +{% load mathjax %} +{% load django_markdown %} +{% block javascript %} + + + + + + + + + + + + + + {% mathjax_scripts %} +{% endblock %} +

    {{question.title}}

    +

    {{question.text|markdown}}

    +
    + +
    +
    {{question.solution|markdown}}
    +
    +
    + + \ No newline at end of file diff --git a/website/urls.py b/website/urls.py index a33ca73..c99f0b8 100644 --- a/website/urls.py +++ b/website/urls.py @@ -10,5 +10,6 @@ url(r'^$', 'website.views.index', name='index'), url(r'^oh/$', 'website.views.oh', name='oh'), - url(r'^interview/$', 'website.views.interview', name='interview') + url(r'^interview/$', 'website.views.interview', name='interview'), + url(r'^interview/question/(?P\d+)/$', 'website.views.interview_question', name='interview_question') ) diff --git a/website/views.py b/website/views.py index f6a6585..d3b3385 100644 --- a/website/views.py +++ b/website/views.py @@ -8,6 +8,7 @@ from django.core.serializers.json import DjangoJSONEncoder import json, re from users.models import * +from website.models import * def index(request): template = loader.get_template('website/index.html') @@ -23,4 +24,9 @@ def oh(request): return render(request, 'website/oh.html', {}) def interview(request): - return render(request, 'website/interview.html', {}) + questions = Question.objects.order_by('difficulty') + return render(request, 'website/interview.html', { 'questions': questions}) + +def interview_question(request, ident): + question = Question.objects.get(id=int(ident)) + return render(request, 'website/interview_question.html', {'question': question}) From 952f422014a55c6a5f95947797996d5b0af47050 Mon Sep 17 00:00:00 2001 From: Jack Thakar Date: Sat, 12 Dec 2015 10:33:58 -0800 Subject: [PATCH 5/5] add tag filtering; improve UI --- upe/settings.py | 2 ++ website/models.py | 6 ---- website/static/website/css/interview.css | 33 +++++++++++++++--- website/templates/website/interview.html | 34 ++++++++++--------- .../templates/website/interview_question.html | 6 +++- website/urls.py | 3 +- website/views.py | 5 +++ 7 files changed, 61 insertions(+), 28 deletions(-) diff --git a/upe/settings.py b/upe/settings.py index 046ffad..9731d4b 100644 --- a/upe/settings.py +++ b/upe/settings.py @@ -118,3 +118,5 @@ } } +MARKDOWN_EXTENSIONS = ['extra'] + diff --git a/website/models.py b/website/models.py index 8ea99a2..d467244 100644 --- a/website/models.py +++ b/website/models.py @@ -17,12 +17,6 @@ def __str__(self): return self.title -class QuestionImage(models.Model): - question = models.ForeignKey(Question) - img = models.ImageField(upload_to='question_images', null=True) - for_soln = models.BooleanField(default=False) # whether this image is for the soln of the question - - diff --git a/website/static/website/css/interview.css b/website/static/website/css/interview.css index cc4a9ae..6b44210 100644 --- a/website/static/website/css/interview.css +++ b/website/static/website/css/interview.css @@ -1,18 +1,24 @@ #questions-sidebar { - height: 600px; + height: 700px; overflow: auto; + padding: 0; + margin: 0; } #questions-table { cursor: pointer; } #targ-question { - height: 800px; - overflow: auto; + height: 700px; + padding: 0; + margin: 0; + position: relative; } #targ-question iframe { - height: 100%; + height: 700px; width: 100%; + padding: 0; + margin: 0; } @@ -22,4 +28,23 @@ #nav-questions { margin-top: 10px; margin-bottom: 20px; +} + +#question-wrapper { + padding-left: 16px; + padding-right: 16px; +} + +.tag { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background: #43ACC5; + margin-right: .2em; } \ No newline at end of file diff --git a/website/templates/website/interview.html b/website/templates/website/interview.html index 443b170..8f6c3c7 100644 --- a/website/templates/website/interview.html +++ b/website/templates/website/interview.html @@ -20,36 +20,38 @@ {% block content %}
    -
    +
    - {% for q in questions %} - + {% endfor %}
    {{q.title}}
    + {{q.title}}
    + {% for tag in q.tags.all %} + {{tag}} + {% endfor %} +
    -
    - +
    +
    {% endblock %} \ No newline at end of file diff --git a/website/templates/website/interview_question.html b/website/templates/website/interview_question.html index 925c498..77f202a 100644 --- a/website/templates/website/interview_question.html +++ b/website/templates/website/interview_question.html @@ -17,6 +17,7 @@ {% mathjax_scripts %} {% endblock %} +

    {{question.title}}

    {{question.text|markdown}}

    @@ -25,9 +26,12 @@

    {{question.title}}

    {{question.solution|markdown}}
    +
    + \ No newline at end of file diff --git a/website/urls.py b/website/urls.py index c99f0b8..7d95b52 100644 --- a/website/urls.py +++ b/website/urls.py @@ -11,5 +11,6 @@ url(r'^$', 'website.views.index', name='index'), url(r'^oh/$', 'website.views.oh', name='oh'), url(r'^interview/$', 'website.views.interview', name='interview'), - url(r'^interview/question/(?P\d+)/$', 'website.views.interview_question', name='interview_question') + url(r'^interview/question/(?P\d+)/$', 'website.views.interview_question', name='interview_question'), + url(r'^interview/tagged/(?P.+)/$', 'website.views.interview_tagged', name='interview_tagged') ) diff --git a/website/views.py b/website/views.py index d3b3385..99e882b 100644 --- a/website/views.py +++ b/website/views.py @@ -30,3 +30,8 @@ def interview(request): def interview_question(request, ident): question = Question.objects.get(id=int(ident)) return render(request, 'website/interview_question.html', {'question': question}) + +def interview_tagged(request, tag): + tagObj = QuestionTag.objects.get(tag=tag) + questions = Question.objects.filter(tags=tagObj).order_by('difficulty') + return render(request, 'website/interview.html', {'questions': questions})