Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Nathan R Lapierre
advisor
Commits
19702ecc
Commit
19702ecc
authored
Jan 28, 2014
by
Daniel W Bond
Browse files
Merge branch 'master' of git.gmu.edu:srct/advisor
parents
e5bd3328
b81b048a
Changes
11
Hide whitespace changes
Inline
Side-by-side
advisor/templates/analytics.html
0 → 100644
View file @
19702ecc
{% 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 %}
advisor/templates/compare.html
View file @
19702ecc
...
...
@@ -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 %}
advisor/templates/login.html
View file @
19702ecc
...
...
@@ -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"
>
...
...
advisor/templates/student.html
View file @
19702ecc
...
...
@@ -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 %}
advisor/templates/trajectory.html
View file @
19702ecc
...
...
@@ -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 %}
...
...
advisor/trajectories/models.py
View file @
19702ecc
...
...
@@ -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
advisor/trajectories/sample-io.txt
deleted
100644 → 0
View file @
e5bd3328
### 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.
advisor/trajectories/search/search.html
0 → 100644
View file @
19702ecc
{% 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 }}&page={{ page.previous_page_number }}"
>
←
Previous
</a>
</li>
{% else %}
<li
class=
"previous disabled"
>
<a>
←
Previous
</a>
</li>
{% endif %}
{% if page.has_next %}
<li
class=
"next"
>
<a
href=
"?q={{ query }}&page={{ page.next_page_number }}"
>
Next
→
</a>
</li>
{% else %}
<li
class=
"next disabled"
>
<a>
Next
→
</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% endblock %}
advisor/trajectories/search_indexes.py
0 → 100644
View file @
19702ecc
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
()
advisor/trajectories/views.py
View file @
19702ecc
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
sign
ed
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):
readme-note.txt
0 → 100644
View file @
19702ecc
Create a branch to move things around so they're located properly.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment