Commit 19702ecc authored by Daniel W Bond's avatar Daniel W Bond

Merge branch 'master' of git.gmu.edu:srct/advisor

parents e5bd3328 b81b048a
{% extends 'layouts/base.html' %}
{% block title %}
GMU Advisor | Analytics
{% endblock %}
{% block content %}
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1>Analytics</h1>
<p class="lead">Some information we've discovered from our users.</p>
</div>
</div>
</div>
<div class="row well">
<legend>Popularity</legend>
<p>Most popular classes</p>
<p>Most popular program</p>
<p>Most popular department</p>
<p>Popularity over time</p>
<p>Percentage BS majors | Percentage BA majors</p>
<p>Percentage with minors</p>
<p>Most popular program combinations</p>
</div>
<!-- Our users versus GMU official statistics. -->
<div class="row well">
<legend>You vs. Your Peers</legend>
<div class="col-md-6">
<h3>In your year</h3>
<!-- Similar information as above -->
</div>
<div class="col-md-6">
<h3>With Your Same Major</h3>
<!-- Similar information as above -->
</div>
{% endblock %}
......@@ -15,8 +15,8 @@ GMU Advisor | Compare
</div>
<div class="row well">
<legend>Choose up to three</legend>
<div class="col-md-12">
<legend>Choose up to three</legend>
<form class="form-vertical" action="" method="post" role="form" enctype="multipart/form-data">
<!-- learn what enctype does when you have internet -->
<div class="form-group">
......@@ -109,9 +109,27 @@ to be loaded on submit with JavaScript ;_; </p>
</div>
<div class="row well">
<legend>Automatic comparisons of your selected trajectories.</legend>
<div class="col-md-12">
<legend>Automatic comparisons of your selected trajectories.</legend>
<p>Trajectory one will take longer to complete.</p>
<p>Trajectory two has fewer higher-level classes.</p>
<p>Trajectory one has the lightest average courseload.</p>
</div>
<div class="col-md-12">
<p>Common courses between trajectories include:</p>
</div>
<div class="col-md-6">
<p>Additional electives (courses not required for the completion of your
selected program) for trajectory one include:</p>
</div>
<div class="col-md-6">
<p>Additional electives (courses not required for the completion of your
selected program) for trajectory two include:</p>
</div>
</div>
{% endblock %}
......@@ -15,6 +15,9 @@ GMU Advisor | Login
</div>
</div>
<!-- this will be the landing page for people who haven't yet logged in
should put a bit more information about the service here -->
<div class="row">
<div class="col-lg-6 col-lg-offset-3">
<div class="well">
......
......@@ -6,12 +6,18 @@ GMU Advisor | {{ student.user.first_name }} {{ student.user.last_name }}
{% block content %}
{% load gravatar %}
<div class="row">
<div class="col-md-5">
<div class="col-md-6">
<h3>{{ student.user.first_name }} {{ student.user.last_name }}</h3>
</div>
<div class="col-md-6">
<img class="img-circle img-responsive center-block" src="{% gravatar url 'daniel@dbond.cc' 200 %}">
<!-- don't have a gravatar? make one here! -->
</div>
<h4><strong>My Trajectories</strong></h4>
{% for trajectory in topTrajectories %}
......@@ -35,6 +41,7 @@ GMU Advisor | {{ student.user.first_name }} {{ student.user.last_name }}
</div>
{% endfor %}
<!-- How does one edit the courses that they've already completed? -->
<!-- potential issue with naming new trajectories: there will have to be
a way to rename whenever a new branch off is created ->
{% endblock %}
......@@ -16,11 +16,13 @@ GMU Advisor | Trajectory Name
</div>
<div class="row">
<div class="col-md-12">
<legend>Trajectories</legend>
{% for trajectory in trajectories %}
<div class="col-md-12">
<!-- the semester -->
{% for course in trajectory %}
<div class="col-md-4">
{{ course.name }}
</div>
{% endfor %}
......
......@@ -13,6 +13,7 @@ class BaseModel(models.Model):
class Course(BaseModel):
name = models.CharField(max_length = 150)
slug = models.SlugField(max_length = 50, unique=True)
# ordering
prerequisites = models.ManyToManyField('Course', related_name = 'prereqField', null=True)
......@@ -74,6 +75,7 @@ class CourseCollection(BaseModel):
class Program(BaseModel):
name = models.CharField(max_length = 150)
# slug = models.SlugField(max_length = 50, unique = True)
# courseCollections
courseReqs = models.ManyToManyField('CourseCollection',)
......@@ -99,11 +101,17 @@ class Program(BaseModel):
def __unicode__(self):
return self.name
# def get_absolute_url(self):
# return 'my-trajectories/%s/' % self.slug
# should inherit from the standard Django User Model
class Student(models.Model):
user = models.OneToOneField(User)
# does User have a slug field?
alreadyTaken = models.ManyToManyField('Course', null=True)
# all of the student's trajectories
trajectory = models.ManyToManyField('Trajectory', null=True)
......@@ -129,19 +137,21 @@ post_save.connect(create_user_profile, sender=User)
class Trajectory(BaseModel):
name = models.CharField(max_length = 150)
slug = models.SlugField(max_length = 50, unique = True)
# Takes courses
previousCourses = models.ManyToManyField('Trajectory',)
# def getPreviousTrajectory(Trajectory):
# return Trajectory
# the program(s) that this trajectory is completing
# CHECK VIEWS, MAKE SURE I DIDN'T ALREADY SOMEHOW ACCOUNT FOR THIS
forPrograms = models.ManyToManyField('Program',)
whichPrograms = models.ManyToManyField('Program',)
# whether or not the trajectory can be seen by others
isPublic = models.BooleanField()
# this isn't exactly done correctly-- ideally courses should be elements
# of a list, not one created for each and every semester
# semesters since entering college
semester = models.IntegerField()
class Meta:
......@@ -150,5 +160,3 @@ class Trajectory(BaseModel):
def get_absolute_url(self):
return 'my-trajectories/%s/' % self.slug
return '/%s/' % self.slug
### in which we write pseudocodey algorithms and musings before they are used
### transferred to the views
# all of the courses that have that course as a prereq or coreq
# I think that the recursive issue is fixed-- it doesn't matter if there
# are prereqs of prereqs because the class has already been taken
# furthermore, you're not going to have to worry about whether or not
# a course is
Information that is passed in from the initial request
separate the input into two list for ease
this is also better because you can mandate how many of each is required
(programList, maxProgramNumber)
programs [list]
minors [list]
boolean isHonors
--> getGenEds
def maxProgramsAllowed(programList, maxProgramNumber):
OTHER THOUGHTS
#############################################
NO WAY TO CHECK ACCURACY OF USER INPUT
this is important for modifying trajectories-- see below
once a user has selected the courses they want to take for the subsequent semester,
this is saved as a trajectory
I take it then that each semester is its own trajectory?
how does one tell that things are broken when a trajectory is fucked up?
users can modify their trajectories, or particularly in comparisons
"do you have the prereqs and coreqs for everything now?"
or will it kill off an entire line of the courses
should only rewrite the trajectory of the furthest semester considered... then you
can not fuck up the other ones?
and then they should be able to share their trajectories so that it can be compared
with other students... --will need to implement later
should be able to point out "by permission of instructor"
also, what if the user input is wrong? answer: this system just assumes that it's right
needs to limit the number of programs that can be selected-- there already is one, implicitly
from a BA or BS selection, and then Honors?
UX
#############################################
User arrives on homepage, selects program, (Honors College?) and is prompted to select
already-completed courses.
User then is then displayed a list of courses for their major that they are able to take next.
Also displayed is are rectangles indicating whether or not each of the gen-ed requirements
have been completed.
If a gen-ed has not been completed, then they can select that button, which will retrieve all of
the gen-eds that they could concievably take for that particular instance.
The user then selects the classes that they intend to take for that semester.
This is then completed for each subsequent semester, until there are no more classes to select.
The user can save this trajectory.
What if a user wants to modify their trajectory? They can select to go back to any semester, but
it will delete their progress thus far for something.
{% extends 'layouts/base.html' %}
{% block title %}
GMU Advisor | Search
{% endblock %}
{% block content %}
<div class="page-header" id="banner">
<div class="row">
<div class="col-lg-12 text-center">
<h1>Search</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<form class="form-horizontal" role="form" method="get">
<div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-search"></span>
</span>
{{ form.q }}
</div>
</form>
</div>
</div>
{% if query %}
<hr />
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
{% if page.object_list %}
<h3 class="text-center">Search Results</h3>
<div class="list-group">
{% endif %}
{% for result in page.object_list %}
<a class="list-group-item" href="{{ result.object.get_absolute_url }}">
<strong>{{ result.object }}</strong>
</a>
{% empty %}
<h3 class="text-center">No results found.</h3>
{% endfor %}
{% if page.object_list %}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-lg-5 col-lg-offset-3">
<ul class="pager">
{% if page.has_previous %}
<li class="previous">
<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">
&larr; Previous
</a>
</li>
{% else %}
<li class="previous disabled">
<a>
&larr; Previous
</a>
</li>
{% endif %}
{% if page.has_next %}
<li class="next">
<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">
Next &rarr;
</a>
</li>
{% else %}
<li class="next disabled">
<a>
Next &rarr;
</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% endblock %}
from haystack import indexes
from django.utils import timezone # required for when the indexes were last updated
from trajectories.models import Course
class CourseIndex(indexes.SearchIndex, indexes.Indexable):
# search result
# there can only be one document=True per model
text = indexes.CharField( document=True, use_template=True )
# search filtering
name = indexes.CharField( model_attr = 'name' )
contents = indexes.CharField( model_attr = 'courseDescription' )
department = indexes.CharField( model_attr = 'department' )
departmentAbbr = indexes.CharField( model_attr = 'departmentAbbr' )
courseNumber = indexes.CharField( model_attr = 'courseNumber' )
def get_model(self):
return Course
def index_queryset(self, using=None):
return self.get_model().objects.all()
from django.shortcuts import render, render_to_response
from django.shortcuts import render, render_to_response, get_object_or_404
from trajectories.models import Course, CourseCollection, Program, Student, Trajectory
from django.db.models import Max
# other functions
# processing functions
# run on each coursecollection
def remainingReqCourses(requiredCourses, coursesTaken):
""" returns remaining courses for program """
remainingReqCourses = []
......@@ -23,6 +24,7 @@ def allPrereqCoreq(course, remainingReqCourses):
allPrereqCoreq.append(coreq)
return allPreqCoreq
# run on each coursecollection
def nextCourses(coursesTaken, remainingReqCourses):
""" returns the courses student can take given what's been taken """
nextCourses = []
......@@ -102,13 +104,12 @@ def enoughCourses(coursesTaken):
else:
return False
### IMPORTANT OUTSTANDING ISSUE ###
# how does one deal with "you have to take the coreq at the same time?"
# note: coreq requirements are fulfilled through onpage javascript, not here
# page render functions
# homepage, sign in to save or compare multiple options
#@login_required -- not sure how this part works
# this is where all users not signed in are redirected
#@login_required
def index(request):
courses = [] # student's courses
return render(request, 'index.html', {
......@@ -116,61 +117,38 @@ def index(request):
},
)
def login(request):
return render(request, 'login.html', {
},
)
# SRCT, how to contribute information
def about(request):
# "homepage", create a new trajectory
#@login_required
def index(request):
return render(request, 'about.html', {
return render(request, 'index.html', {
},
)
# student creates trajectory
# def create(request, slug):
# student selects the classes for their trajectories
# @login_required
# def create(request, slug): slug is the user's
def create(request):
# needs to get list of programs from user
programs = []
#
return render(request, 'create.html', {
},
)
# just displays a page for the course
def course(request, slug):
return render(request, 'course.html', {
},
)
def trajectory(request, slug):
# actually needs more than one slug
return render(request, 'trajectory.html', {
},
)
# student's page; shows saved trajectories
#@login_required
# @login_required
def student(request, slug):
student = get_object_or_404(Student, user__username=username)
trajectories = Trajectory.objects.filter(student__user__username=username)
topTrajectories = topTrajectories(trajectories)
return render(request, 'student.html', {
'student' : student,
'topTrajectories' : topTrajectories,
'student' : student,
'topTrajectories' : topTrajectories,
},
)
......@@ -180,11 +158,54 @@ def student(request, slug):
# def compare(request, slug):
def compare(request):
# this is gonna be hella slow; I need to learn how ajax works and what
# it will actually need
trajectories = Trajectory.objects.all()
return render(request, 'compare.html', {
'trajectories' : trajectories,
},
)
# simply displays a page for the course
def course(request, slug):
course = get_object_or_404(Course, slug=slug)
return render(request, 'course.html', {
'course' : course,
},
)
# simply returns a page showing a program
# def program (request, slug):
# program = get_object_or_404(Program, slug=slug)
# return render(request, 'program.html, {
# 'program' : program,
# },
# )
# simply displays a page for an individual trajectory, (along with edit links)
# @login_required
def trajectory(request, slug):
# actually needs more than one slug, the one for the user
trajectory = get_object_or_404(Trajectory, slug=slug)
return render(request, 'trajectory.html', {
'trajectory' : trajectory,
},
)
# page like one for courses, except for programs? >_>
# search
# # # # # STATIC PAGES # # # # #
# SRCT, how to contribute information, how Advisor works
def about(request):
return render(request, 'about.html', {
},
)
#search for courses or programs view
# def privacy(request):
Create a branch to move things around so they're located properly.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment