Commit e5a0ea86 by Matthew Mongeau

wip

parent 9d0418ee
$(document).ready(function(){
$('section.main-content').children().hide();
$(function(){
$('.editable').inlineEdit();
$('.editable-textarea').inlineEdit({control: 'textarea'});
});
var heighest = 0;
$('.cal ol > li').each(function(){
heighest = ($(this).height() > heighest) ? $(this).height() : heighest;
});
$('.cal ol > li').css('height',heighest + 'px');
$('.add-new-section').click(function() {
return false;
});
$('.new-week .close').click( function(){
$(this).parents('.new-week').hide();
$('p.add-new-week').show();
return false;
});
$('.save-update').click(function(){
$(this).parent().parent().hide();
return false;
});
setHeight = function(){
var windowHeight = $(this).height();
var contentHeight = windowHeight - 29;
$('section.main-content > section').css('min-height', contentHeight);
$('body.content .cal').css('height', contentHeight);
$('.edit-week').click( function() {
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.week-new').show();
return false;
});
$('.cal ol li header h1 a').click( function() {
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.week-edit').show();
return false;
});
$('a.sequence-edit').click(function(){
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.sequence-edit').show();
return false;
});
}
$(document).ready(setHeight);
$(window).bind('resize', setHeight);
$('.video-new a').click(function(){
$('section.video-new').show();
return false;
});
$('a.video-edit').click(function(){
$('section.video-edit').show();
return false;
});
$('.problem-new a').click(function(){
$('section.problem-new').show();
return false;
});
$('a.problem-edit').click(function(){
$('section.problem-edit').show();
return false;
});
});
section.video-new, section.video-edit, section.problem-new, section.problem-edit {
position: absolute;
top: 72px;
right: 0;
background: #fff;
width: flex-grid(6);
@include box-shadow(0 0 6px #666);
border: 1px solid #333;
border-right: 0;
z-index: 4;
> header {
background: #666;
@include clearfix;
color: #fff;
padding: 6px;
border-bottom: 1px solid #333;
-webkit-font-smoothing: antialiased;
h2 {
float: left;
font-size: 14px;
}
a {
color: #fff;
&.save-update {
float: right;
}
&.cancel {
float: left;
}
}
}
> section {
padding: 20px;
> header {
h1 {
font-size: 24px;
margin: 12px 0;
}
section {
&.status-settings {
ul {
list-style: none;
@include border-radius(2px);
border: 1px solid #999;
@include inline-block();
li {
@include inline-block();
border-right: 1px solid #999;
padding: 6px;
&:last-child {
border-right: 0;
}
&.current {
background: #eee;
}
}
}
a.settings {
@include inline-block();
margin: 0 20px;
border: 1px solid #999;
padding: 6px;
}
select {
float: right;
}
}
&.meta {
background: #eee;
padding: 10px;
margin: 20px 0;
@include clearfix();
div {
float: left;
margin-right: 20px;
h2 {
font-size: 14px;
@include inline-block();
}
p {
@include inline-block();
}
}
}
}
}
section.notes {
margin-top: 20px;
padding: 6px;
background: #eee;
border: 1px solid #ccc;
textarea {
@include box-sizing(border-box);
display: block;
width: 100%;
}
h2 {
font-size: 14px;
margin-bottom: 6px;
}
input[type="submit"]{
margin-top: 10px;
}
}
}
}
section.problem-new, section.problem-edit {
> section {
textarea {
@include box-sizing(border-box);
display: block;
width: 100%;
}
div.preview {
background: #eee;
@include box-sizing(border-box);
height: 40px;
padding: 10px;
width: 100%;
}
a.save {
@extend .button;
@include inline-block();
margin-top: 20px;
}
}
}
section.video-new, section.video-edit {
> section {
section.upload {
padding: 6px;
margin-bottom: 10px;
border: 1px solid #ddd;
a.upload-button {
@extend .button;
@include inline-block();
}
}
section.in-use {
h2 {
font-size: 14px;
}
div {
background: #eee;
text-align: center;
padding: 6px;
}
}
a.save-update {
@extend .button;
@include inline-block();
margin-top: 20px;
}
}
}
section.week-edit,
section.week-new,
section.sequence-edit {
> header {
border-bottom: 2px solid #333;
@include clearfix();
div {
@include clearfix();
padding: 6px 20px;
h1 {
font-size: 18px;
text-transform: uppercase;
letter-spacing: 1px;
float: left;
}
p {
float: right;
}
&.week {
background: #eee;
font-size: 12px;
border-bottom: 1px solid #ccc;
h2 {
font-size: 12px;
@include inline-block();
margin-right: 20px;
}
ul {
list-style: none;
@include inline-block();
li {
@include inline-block();
margin-right: 10px;
p {
float: none;
}
}
}
}
}
section.goals {
background: #eee;
padding: 6px 20px;
border-top: 1px solid #ccc;
ul {
list-style: none;
color: #999;
li {
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
}
}
}
}
> section.content {
@include box-sizing(border-box);
padding: 20px;
section.filters {
@include clearfix;
margin-bottom: 10px;
background: #efefef;
border: 1px solid #ddd;
ul {
@include clearfix();
list-style: none;
padding: 6px;
li {
@include inline-block();
&.advanced {
float: right;
}
}
}
}
> div {
display: table;
border: 1px solid;
width: 100%;
section {
header {
background: #eee;
padding: 6px;
border-bottom: 1px solid #ccc;
@include clearfix;
h2 {
text-transform: uppercase;
letter-spacing: 1px;
font-size: 12px;
float: left;
}
}
&.modules {
@include box-sizing(border-box);
display: table-cell;
width: flex-grid(6, 9);
border-right: 1px solid #333;
&.empty {
text-align: center;
vertical-align: middle;
a {
@extend .button;
@include inline-block();
margin-top: 10px;
}
}
ol {
list-style: none;
border-bottom: 1px solid #333;
li {
border-bottom: 1px solid #333;
&:last-child{
border-bottom: 0;
}
a {
color: #000;
}
ol {
list-style: none;
li {
padding: 6px;
&:hover {
a.draggable {
opacity: 1;
}
}
a.draggable {
float: right;
opacity: .5;
}
&.group {
padding: 0;
header {
padding: 6px;
background: none;
h3 {
font-size: 14px;
}
}
ol {
border-left: 4px solid #999;
border-bottom: 0;
li {
&:last-child {
border-bottom: 0;
}
}
}
}
}
}
}
}
}
&.scratch-pad {
@include box-sizing(border-box);
display: table-cell;
width: flex-grid(3, 9) + flex-gutter(9);
vertical-align: top;
ol {
list-style: none;
border-bottom: 1px solid #999;
li {
border-bottom: 1px solid #999;
background: #f9f9f9;
&:last-child {
border-bottom: 0;
}
ul {
list-style: none;
li {
padding: 6px;
&:last-child {
border-bottom: 0;
}
&:hover {
a.draggable {
opacity: 1;
}
}
&.empty {
padding: 12px;
a {
@extend .button;
display: block;
text-align: center;
}
}
a.draggable {
float: right;
opacity: .3;
}
a {
color: #000;
}
}
}
}
}
}
}
}
}
}
<li>
<img src="http://placehold.it/300x180" alt="" /><h5>Video-file-name</h5>
</li>
<section class="caption-save">
<a href="#" class="close-box">Cancel</a>
<button class="close-box">Save changes</button>
</section>
<section class="sequence-edit">
<header>
<div class="week">
<h2><a href="">Week 1</a></h2>
<ul>
<li>
<p class="editable"><strong>Goal title:</strong> This is the goal body and is where the goal will be further explained</p>
</li>
</ul>
</div>
<div>
<h1 class="editable">Lecture sequence</h1>
<p><strong>Group type:</strong> Ordered Sequence</p>
</div>
</header>
<section class="content">
<section class="filters">
<ul>
<li>
<label for="">Sort by</label>
<select>
<option value="">Recently Modified</option>
</select>
</li>
<li>
<label for="">Display</label>
<select>
<option value="">All content</option>
</select>
</li>
<li>
<select>
<option value="">Internal Only</option>
</select>
</li>
<li class="advanced">
<a href="#">Advanced filters</a>
</li>
<li>
<input type="search" name="" id="" value="" />
</li>
</ul>
</section>
<div>
<section class="modules">
<ol>
<li>
<ol>
<li>
<a href="" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="sequence-edit">Problem Group</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="group">
<header>
<h3>
<a href="#" class="problem-edit">Problem group</a>
<a href="#" class="draggable">handle</a>
</h3>
</header>
<ol>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
</ol>
</li>
<li>
<a href="#" class="problem-edit">Problem title 13</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="sequence-edit">Problem Group</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
</ol>
</li>
<!-- <li class="new-module"> -->
<!-- <%include file="new-module.html"/> -->
<!-- </li> -->
</ol>
</section>
<section class="scratch-pad">
<ol>
<li>
<header>
<h2>Section Scratch</h2>
</header>
<ul>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 13 </a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit"> Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
</ul>
</li>
<li>
<header>
<h2>Course Scratch</h2>
</header>
<ul>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 13 </a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit"> Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
</ul>
</li>
<!-- <li class="new-module"> -->
<!-- <%include file="new-module.html"/> -->
<!-- </li> -->
</ol>
</section>
</div>
</section>
</section>
<div class="tooltip">
<ul>
<li><a href="#view" rel="leanModal">View</a></li>
<li><a href="#">Download</a></li>
<li><a href="#" class="delete-speed">Delete</a></li>
</ul>
</div>
<li class="video-box">
<div class="thumb"><img src="http://placehold.it/100x65" /></div>
<div class="meta">
<strong>video-name</strong> 236mb Uploaded 6 hours ago by <em>Anant Agrawal</em>
<p>
<ul class="speed-list">
Speed
<li class="speed">
0.75x
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">Normal
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">1.25x
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">1.5x
<%include file="speed-tooltip.html"/>
</li>
<li style="background: #eee;" ><a href="#upload" rel="leanModal" class="new-upload">+</a></li>
</ul>
</p>
<p>
<a href="#">Download All</a>
<a href="#" style="color: brown;" class="remove">Delete All</a>
<a href="#" class="edit-captions"> Edit Captions </a>
<a href="#" class="use-video">Use clip ⬆</a>
</p>
</div>
<div class="caption-box">
<%include file="captions.html"/>
<%include file="save-captions.html"/>
</div>
</li>
<li class="video-box">
<div class="thumb"><img src="http://placehold.it/155x90" /></div>
<div class="meta">
<strong>video-name</strong> 236mb
<p>Uploaded 6 hours ago by <em>Anant Agrawal</em></p>
<p>
<ul class="speed-list">
Speed
<li class="speed">
0.75x
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">Normal
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">1.25x
<%include file="speed-tooltip.html"/>
</li>
<li class="speed">1.5x
<%include file="speed-tooltip.html"/>
</li>
<li style="background: #eee;" ><a href="#upload" rel="leanModal" class="new-upload">+</a></li>
</ul>
</p>
<p>
<a href="#">Download all</a>
<a href="#" stle="color: brown;" class="remove-video">Remove ⬇ </a>
</p>
</div>
<div style="margin-top: 30px;">
<%include file="captions.html"/>
</div>
</li>
from nose.tools import assert_equals, assert_raises
from keystore import Location
from keystore.exceptions import InvalidLocationError
def check_string_roundtrip(url):
assert_equals(url, Location(url).url())
assert_equals(url, str(Location(url)))
def test_string_roundtrip():
check_string_roundtrip("tag://org/course/category/name")
check_string_roundtrip("tag://org/course/category/name/revision")
check_string_roundtrip("tag://org/course/category/name with spaces/revision")
def test_dict():
input_dict = {
'tag': 'tag',
'course': 'course',
'category': 'category',
'name': 'name',
'org': 'org'
}
assert_equals("tag://org/course/category/name", Location(input_dict).url())
assert_equals(dict(revision=None, **input_dict), Location(input_dict).dict())
input_dict['revision'] = 'revision'
assert_equals("tag://org/course/category/name/revision", Location(input_dict).url())
assert_equals(input_dict, Location(input_dict).dict())
def test_list():
input_list = ['tag', 'org', 'course', 'category', 'name']
assert_equals("tag://org/course/category/name", Location(input_list).url())
assert_equals(input_list + [None], Location(input_list).list())
input_list.append('revision')
assert_equals("tag://org/course/category/name/revision", Location(input_list).url())
assert_equals(input_list, Location(input_list).list())
def test_location():
input_list = ['tag', 'org', 'course', 'category', 'name']
assert_equals("tag://org/course/category/name", Location(Location(input_list)).url())
def test_invalid_locations():
assert_raises(InvalidLocationError, Location, "foo")
assert_raises(InvalidLocationError, Location, ["foo", "bar"])
assert_raises(InvalidLocationError, Location, ["foo", "bar", "baz", "blat", "foo/bar"])
assert_raises(InvalidLocationError, Location, None)
'''
Progress class for modules. Represents where a student is in a module.
Useful things to know:
- Use Progress.to_js_status_str() to convert a progress into a simple
status string to pass to js.
- Use Progress.to_js_detail_str() to convert a progress into a more detailed
string to pass to js.
In particular, these functions have a canonical handing of None.
For most subclassing needs, you should only need to reimplement
frac() and __str__().
'''
from collections import namedtuple
import numbers
class Progress(object):
'''Represents a progress of a/b (a out of b done)
a and b must be numeric, but not necessarily integer, with
0 <= a <= b and b > 0.
Progress can only represent Progress for modules where that makes sense. Other
modules (e.g. html) should return None from get_progress().
TODO: add tag for module type? Would allow for smarter merging.
'''
def __init__(self, a, b):
'''Construct a Progress object. a and b must be numbers, and must have
0 <= a <= b and b > 0
'''
# Want to do all checking at construction time, so explicitly check types
if not (isinstance(a, numbers.Number) and
isinstance(b, numbers.Number)):
raise TypeError('a and b must be numbers. Passed {0}/{1}'.format(a, b))
if not (0 <= a <= b and b > 0):
raise ValueError(
'fraction a/b = {0}/{1} must have 0 <= a <= b and b > 0'.format(a, b))
self._a = a
self._b = b
def frac(self):
''' Return tuple (a,b) representing progress of a/b'''
return (self._a, self._b)
def percent(self):
''' Returns a percentage progress as a float between 0 and 100.
subclassing note: implemented in terms of frac(), assumes sanity
checking is done at construction time.
'''
(a, b) = self.frac()
return 100.0 * a / b
def started(self):
''' Returns True if fractional progress is greater than 0.
subclassing note: implemented in terms of frac(), assumes sanity
checking is done at construction time.
'''
return self.frac()[0] > 0
def inprogress(self):
''' Returns True if fractional progress is strictly between 0 and 1.
subclassing note: implemented in terms of frac(), assumes sanity
checking is done at construction time.
'''
(a, b) = self.frac()
return a > 0 and a < b
def done(self):
''' Return True if this represents done.
subclassing note: implemented in terms of frac(), assumes sanity
checking is done at construction time.
'''
(a, b) = self.frac()
return a==b
def ternary_str(self):
''' Return a string version of this progress: either
"none", "in_progress", or "done".
subclassing note: implemented in terms of frac()
'''
(a, b) = self.frac()
if a == 0:
return "none"
if a < b:
return "in_progress"
return "done"
def __eq__(self, other):
''' Two Progress objects are equal if they have identical values.
Implemented in terms of frac()'''
if not isinstance(other, Progress):
return False
(a, b) = self.frac()
(a2, b2) = other.frac()
return a == a2 and b == b2
def __ne__(self, other):
''' The opposite of equal'''
return not self.__eq__(other)
def __str__(self):
''' Return a string representation of this string.
subclassing note: implemented in terms of frac().
'''
(a, b) = self.frac()
return "{0}/{1}".format(a, b)
@staticmethod
def add_counts(a, b):
'''Add two progress indicators, assuming that each represents items done:
(a / b) + (c / d) = (a + c) / (b + d).
If either is None, returns the other.
'''
if a is None:
return b
if b is None:
return a
# get numerators + denominators
(n, d) = a.frac()
(n2, d2) = b.frac()
return Progress(n + n2, d + d2)
@staticmethod
def to_js_status_str(progress):
'''
Return the "status string" version of the passed Progress
object that should be passed to js. Use this function when
sending Progress objects to js to limit dependencies.
'''
if progress is None:
return "NA"
return progress.ternary_str()
@staticmethod
def to_js_detail_str(progress):
'''
Return the "detail string" version of the passed Progress
object that should be passed to js. Use this function when
passing Progress objects to js to limit dependencies.
'''
if progress is None:
return "NA"
return str(progress)
import json
import logging
from lxml import etree
from x_module import XModule, XModuleDescriptor
from xmodule.progress import Progress
log = logging.getLogger("mitx.common.lib.seq_module")
# HACK: This shouldn't be hard-coded to two types
# OBSOLETE: This obsoletes 'type'
......@@ -37,6 +41,16 @@ class Module(XModule):
self.render()
return self.destroy_js
def get_progress(self):
''' Return the total progress, adding total done and total available.
(assumes that each submodule uses the same "units" for progress.)
'''
# TODO: Cache progress or children array?
children = self.get_children()
progresses = [child.get_progress() for child in children]
progress = reduce(Progress.add_counts, progresses)
return progress
def handle_ajax(self, dispatch, get): # TODO: bounds checking
''' get = request.POST instance '''
if dispatch=='goto_position':
......@@ -53,10 +67,15 @@ class Module(XModule):
titles = ["\n".join([i.get("name").strip() for i in e.iter() if i.get("name") is not None]) \
for e in self.xmltree]
children = self.get_children()
progresses = [child.get_progress() for child in children]
self.contents = self.rendered_children()
for contents, title in zip(self.contents, titles):
for contents, title, progress in zip(self.contents, titles, progresses):
contents['title'] = title
contents['progress_status'] = Progress.to_js_status_str(progress)
contents['progress_detail'] = Progress.to_js_detail_str(progress)
for (content, element_class) in zip(self.contents, child_classes):
new_class = 'other'
......@@ -68,16 +87,17 @@ class Module(XModule):
# Split </script> tags -- browsers handle this as end
# of script, even if it occurs mid-string. Do this after json.dumps()ing
# so that we can be sure of the quotations being used
params={'items':json.dumps(self.contents).replace('</script>', '<"+"/script>'),
'id':self.item_id,
params={'items': json.dumps(self.contents).replace('</script>', '<"+"/script>'),
'id': self.item_id,
'position': self.position,
'titles':titles,
'tag':self.xmltree.tag}
'titles': titles,
'tag': self.xmltree.tag}
if self.xmltree.tag in ['sequential', 'videosequence']:
self.content = self.system.render_template('seq_module.html', params)
if self.xmltree.tag == 'tab':
self.content = self.system.render_template('tab_module.html', params)
log.debug("rendered content: %s", content)
self.rendered = True
def __init__(self, system, xml, item_id, state=None):
......
<problem>
<script type="loncapa/python">
# from loncapa import *
x1 = 4 # lc_random(2,4,1)
y1 = 5 # lc_random(3,7,1)
x2 = 10 # lc_random(x1+1,9,1)
y2 = 20 # lc_random(y1+1,15,1)
m = (y2-y1)/(x2-x1)
b = y1 - m*x1
answer = "%s*x+%s" % (m,b)
answer = answer.replace('+-','-')
inverted_m = (x2-x1)/(y2-y1)
inverted_b = b
wrongans = "%s*x+%s" % (inverted_m,inverted_b)
wrongans = wrongans.replace('+-','-')
</script>
<text>
<p>Hints can be provided to students, based on the last response given, as well as the history of responses given. Here is an example of a hint produced by a Formula Response problem.</p>
<p>
What is the equation of the line which passess through ($x1,$y1) and
($x2,$y2)?</p>
<p>The correct answer is <tt>$answer</tt>. A common error is to invert the equation for the slope. Enter <tt>
$wrongans</tt> to see a hint.</p>
</text>
<formularesponse samples="x@-5:5#11" id="11" answer="$answer">
<responseparam description="Numerical Tolerance" type="tolerance" default="0.001" name="tol" />
<text>y = <textline size="25" /></text>
<hintgroup>
<formulahint samples="x@-5:5#11" answer="$wrongans" name="inversegrad">
</formulahint>
<hintpart on="inversegrad">
<text>You have inverted the slope in the question.</text>
</hintpart>
</hintgroup>
</formularesponse>
</problem>
<problem >
<text><h2>Example: String Response Problem</h2>
<br/>
</text>
<text>Which US state has Lansing as its capital?</text>
<stringresponse answer="Michigan" type="ci">
<textline size="20" />
<hintgroup>
<stringhint answer="wisconsin" type="cs" name="wisc">
</stringhint>
<stringhint answer="minnesota" type="cs" name="minn">
</stringhint>
<hintpart on="wisc">
<text>The state capital of Wisconsin is Madison.</text>
</hintpart>
<hintpart on="minn">
<text>The state capital of Minnesota is St. Paul.</text>
</hintpart>
<hintpart on="default">
<text>The state you are looking for is also known as the 'Great Lakes State'</text>
</hintpart>
</hintgroup>
</stringresponse>
</problem>
<problem>
<text>
<h2>Example: Symbolic Math Response Problem</h2>
<p>
A symbolic math response problem presents one or more symbolic math
input fields for input. Correctness of input is evaluated based on
the symbolic properties of the expression entered. The student enters
text, but sees a proper symbolic rendition of the entered formula, in
real time, next to the input box.
</p>
<p>This is a correct answer which may be entered below: </p>
<p><tt>cos(theta)*[[1,0],[0,1]] + i*sin(theta)*[[0,1],[1,0]]</tt></p>
<script>
from symmath import *
</script>
<text>Compute [mathjax] U = \exp\left( i \theta \left[ \begin{matrix} 0 &amp; 1 \\ 1 &amp; 0 \end{matrix} \right] \right) [/mathjax]
and give the resulting \(2 \times 2\) matrix. <br/>
Your input should be typed in as a list of lists, eg <tt>[[1,2],[3,4]]</tt>. <br/>
[mathjax]U=[/mathjax] <symbolicresponse cfn="symmath_check" answer="[[cos(theta),I*sin(theta)],[I*sin(theta),cos(theta)]]" options="matrix,imaginaryi" id="filenamedogi0VpEBOWedxsymmathresponse_1" state="unsubmitted">
<textline size="80" math="1" response_id="2" answer_id="1" id="filenamedogi0VpEBOWedxsymmathresponse_2_1"/>
</symbolicresponse>
<br/>
</text>
</text>
</problem>
import json
from x_module import XModule, XModuleDescriptor
from xmodule.progress import Progress
from lxml import etree
class ModuleDescriptor(XModuleDescriptor):
pass
class Module(XModule):
''' Layout module for laying out submodules vertically.'''
id_attribute = 'id'
def get_state(self):
return json.dumps({ })
@classmethod
def get_xml_tags(c):
return ["vertical", "problemset"]
def get_html(self):
return self.system.render_template('vert_module.html', {
'items': self.contents
})
def get_progress(self):
# TODO: Cache progress or children array?
children = self.get_children()
progresses = [child.get_progress() for child in children]
progress = reduce(Progress.add_counts, progresses)
return progress
def __init__(self, system, xml, item_id, state=None):
XModule.__init__(self, system, xml, item_id, state)
xmltree=etree.fromstring(xml)
self.contents=[(e.get("name"),self.render_function(e)) \
for e in xmltree]
import json
import logging
from lxml import etree
from x_module import XModule, XModuleDescriptor
from progress import Progress
log = logging.getLogger("mitx.courseware.modules")
class ModuleDescriptor(XModuleDescriptor):
pass
class Module(XModule):
id_attribute = 'youtube'
video_time = 0
def handle_ajax(self, dispatch, get):
'''
Handle ajax calls to this video.
TODO (vshnayder): This is not being called right now, so the position
is not being saved.
'''
log.debug(u"GET {0}".format(get))
log.debug(u"DISPATCH {0}".format(dispatch))
if dispatch == 'goto_position':
self.position = int(float(get['position']))
log.info(u"NEW POSITION {0}".format(self.position))
return json.dumps({'success':True})
raise Http404()
def get_progress(self):
''' TODO (vshnayder): Get and save duration of youtube video, then return
fraction watched.
(Be careful to notice when video link changes and update)
For now, we have no way of knowing if the video has even been watched, so
just return None.
'''
return None
def get_state(self):
log.debug(u"STATE POSITION {0}".format(self.position))
return json.dumps({ 'position': self.position })
@classmethod
def get_xml_tags(c):
'''Tags in the courseware file guaranteed to correspond to the module'''
return ["video"]
def video_list(self):
return self.youtube
def get_html(self):
return self.system.render_template('video.html', {
'streams': self.video_list(),
'id': self.item_id,
'position': self.position,
'name': self.name,
'annotations': self.annotations,
})
def __init__(self, system, xml, item_id, state=None):
XModule.__init__(self, system, xml, item_id, state)
xmltree = etree.fromstring(xml)
self.youtube = xmltree.get('youtube')
self.name = xmltree.get('name')
self.position = 0
if state is not None:
state = json.loads(state)
if 'position' in state:
self.position = int(float(state['position']))
self.annotations=[(e.get("name"),self.render_function(e)) \
for e in xmltree]
class VideoSegmentDescriptor(XModuleDescriptor):
pass
......@@ -57,6 +57,13 @@ class XModule(object):
else:
raise "We should iterate through children and find a default name"
def get_children(self):
'''
Return module instances for all the children of this module.
'''
children = [self.module_from_xml(e) for e in self.__xmltree]
return children
def rendered_children(self):
'''
Render all children.
......@@ -90,6 +97,7 @@ class XModule(object):
self.tracker = system.track_function
self.filestore = system.filestore
self.render_function = system.render_function
self.module_from_xml = system.module_from_xml
self.DEBUG = system.DEBUG
self.system = system
......@@ -118,6 +126,15 @@ class XModule(object):
'''
return "Unimplemented"
def get_progress(self):
''' Return a progress.Progress object that represents how far the student has gone
in this module. Must be implemented to get correct progress tracking behavior in
nesting modules like sequence and vertical.
If this module has no notion of progress, return None.
'''
return None
def handle_ajax(self, dispatch, get):
''' dispatch is last part of the URL.
get is a dictionary-like object '''
......@@ -187,3 +204,12 @@ class XModuleDescriptor(Plugin):
# Full ==> what we edit
# '''
# raise NotImplementedError
class DescriptorSystem(object):
def __init__(self, load_item):
"""
load_item: Takes a Location and returns and XModuleDescriptor
"""
self.load_item = load_item
......@@ -15,6 +15,7 @@ _FIELDS = ['number', # 6.002x
'instructors', # ['Anant Agarwal']
'institution', # "MIT"
'grader', # a courseware.graders.CourseGrader object
'location',
#'start', # These should be datetime fields
#'end'
......@@ -27,6 +28,7 @@ class Course(namedtuple('Course', _FIELDS)):
"""Course objects encapsulate general information about a given run of a
course. This includes things like name, grading policy, etc.
"""
@property
def id(self):
return "{0.institution},{0.number},{0.run_id}".format(self).replace(" ", "_")
......
......@@ -115,7 +115,7 @@ def make_module_from_xml_fn(user, request, student_module_cache, course, positio
return module_from_xml
def toc_for_course(user, request, course_location, active_chapter, active_section):
def toc_for_course(user, request, course, active_chapter, active_section):
'''
Create a table of contents from the module store
......@@ -131,8 +131,8 @@ def toc_for_course(user, request, course_location, active_chapter, active_sectio
chapters with name 'hidden' are skipped.
'''
student_module_cache = StudentModuleCache(user, modulestore().get_item(course_location), depth=2)
(course, _, _, _) = get_module(user, request, course_location, student_module_cache)
# student_module_cache = StudentModuleCache(user, modulestore().get_item(course_location), depth=2)
# (course, _, _, _) = get_module(user, request, course_location, student_module_cache)
chapters = list()
for chapter in course.get_display_items():
......
......@@ -65,6 +65,14 @@ def courses(request):
'csrf' : csrf_token}
return render_to_response("courses.html", context)
@ensure_csrf_cookie
def courses(request):
csrf_token = csrf(request)['csrf_token']
# TODO: Clean up how 'error' is done.
context = {'courses' : settings.COURSES,
'csrf' : csrf_token}
return render_to_response("courses.html", context)
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
def gradebook(request):
if 'course_admin' not in user_groups(request.user):
......@@ -75,8 +83,8 @@ def gradebook(request):
student_objects = User.objects.all()[:100]
student_info = []
coursename = multicourse_settings.get_coursename_from_request(request)
course_location = multicourse_settings.get_course_location(coursename)
coursename = course.name
course_location = course.path
for student in student_objects:
student_module_cache = StudentModuleCache(student, modulestore().get_item(course_location))
......@@ -133,8 +141,7 @@ def render_accordion(request, course, chapter, section):
Returns (initialization_javascript, content)'''
course_location = multicourse_settings.get_course_location(course)
toc = toc_for_course(request.user, request, course_location, chapter, section)
toc = toc_for_course(request.user, request, course, chapter, section)
active_chapter = 1
for i in range(len(toc)):
......@@ -221,7 +228,7 @@ def index(request, course=None, chapter=None, section=None,
look_for_module = chapter is not None and section is not None
if look_for_module:
course_location = multicourse_settings.get_course_location(course)
course_location = course.path #multicourse_settings.get_course_location(course)
section = get_section(course_location, chapter, section)
student_module_cache = StudentModuleCache(request.user, section)
module, _, _, _ = get_module(request.user, request, section.location, student_module_cache)
......
......@@ -20,80 +20,80 @@
# If COURSE_SETTINGS does not exist, then fallback to 6.002_Spring_2012 default,
# for now.
from django.conf import settings
# from django.conf import settings
#-----------------------------------------------------------------------------
# load course settings
if hasattr(settings,'COURSE_SETTINGS'): # in the future, this could be replaced by reading an XML file
COURSE_SETTINGS = settings.COURSE_SETTINGS
elif hasattr(settings,'COURSE_NAME'): # backward compatibility
COURSE_SETTINGS = {settings.COURSE_NAME: {'number': settings.COURSE_NUMBER,
'title': settings.COURSE_TITLE,
'location': settings.COURSE_LOCATION,
},
}
else: # default to 6.002_Spring_2012
COURSE_SETTINGS = {'6.002_Spring_2012': {'number': '6.002x',
'title': 'Circuits and Electronics',
'location': 'i4x://edx/6002xs12/course/6.002 Spring 2012',
},
}
#-----------------------------------------------------------------------------
# wrapper functions around course settings
def get_coursename_from_request(request):
if 'coursename' in request.session:
coursename = request.session['coursename']
settings.COURSE_TITLE = get_course_title(coursename) # overwrite settings.COURSE_TITLE based on this
else: coursename = None
return coursename
def get_course_settings(coursename):
if not coursename:
if hasattr(settings, 'COURSE_DEFAULT'):
coursename = settings.COURSE_DEFAULT
else:
coursename = '6.002_Spring_2012'
if coursename in COURSE_SETTINGS:
return COURSE_SETTINGS[coursename]
coursename = coursename.replace(' ', '_')
if coursename in COURSE_SETTINGS:
return COURSE_SETTINGS[coursename]
return None
def is_valid_course(coursename):
return get_course_settings(coursename) != None
def get_course_property(coursename, property):
cs = get_course_settings(coursename)
# raise exception instead?
if not cs:
return ''
if property in cs:
return cs[property]
# default
return ''
def get_course_xmlpath(coursename):
return get_course_property(coursename, 'xmlpath')
def get_course_title(coursename):
return get_course_property(coursename, 'title')
def get_course_number(coursename):
return get_course_property(coursename, 'number')
def get_course_location(coursename):
return get_course_property(coursename, 'location')
# if hasattr(settings,'COURSE_SETTINGS'): # in the future, this could be replaced by reading an XML file
# COURSE_SETTINGS = settings.COURSE_SETTINGS
#
# elif hasattr(settings,'COURSE_NAME'): # backward compatibility
# COURSE_SETTINGS = {settings.COURSE_NAME: {'number': settings.COURSE_NUMBER,
# 'title': settings.COURSE_TITLE,
# 'location': settings.COURSE_LOCATION,
# },
# }
# else: # default to 6.002_Spring_2012
# COURSE_SETTINGS = {'6.002_Spring_2012': {'number': '6.002x',
# 'title': 'Circuits and Electronics',
# 'location': 'i4x://edx/6002xs12/course/6.002 Spring 2012',
# },
# }
#
# #-----------------------------------------------------------------------------
# # wrapper functions around course settings
#
# def get_coursename_from_request(request):
# if 'coursename' in request.session:
# coursename = request.session['coursename']
# settings.COURSE_TITLE = get_course_title(coursename) # overwrite settings.COURSE_TITLE based on this
# else: coursename = None
# return coursename
#
# def get_course_settings(coursename):
# if not coursename:
# if hasattr(settings, 'COURSE_DEFAULT'):
# coursename = settings.COURSE_DEFAULT
# else:
# coursename = '6.002_Spring_2012'
# if coursename in COURSE_SETTINGS:
# return COURSE_SETTINGS[coursename]
# coursename = coursename.replace(' ', '_')
# if coursename in COURSE_SETTINGS:
# return COURSE_SETTINGS[coursename]
# return None
#
#
# def is_valid_course(coursename):
# return get_course_settings(coursename) != None
#
#
# def get_course_property(coursename, property):
# cs = get_course_settings(coursename)
#
# # raise exception instead?
# if not cs:
# return ''
#
# if property in cs:
# return cs[property]
#
# # default
# return ''
#
#
# def get_course_xmlpath(coursename):
# return get_course_property(coursename, 'xmlpath')
#
#
# def get_course_title(coursename):
# return get_course_property(coursename, 'title')
#
#
# def get_course_number(coursename):
# return get_course_property(coursename, 'number')
#
#
# def get_course_location(coursename):
# return get_course_property(coursename, 'location')
......@@ -18,7 +18,7 @@ describe 'VideoProgressSlider', ->
stop: @slider.onStop
it 'build the seek handle', ->
expect(@slider.handle).toBe '.ui-slider-handle'
expect(@slider.handle).toBe '.slider .ui-slider-handle'
expect($.fn.qtip).toHaveBeenCalledWith
content: "0:00"
position:
......
......@@ -11,7 +11,7 @@ class @VideoProgressSlider extends Subview
@buildHandle()
buildHandle: ->
@handle = @$('.ui-slider-handle')
@handle = @$('.slider .ui-slider-handle')
@handle.qtip
content: "#{Time.format(@slider.slider('value'))}"
position:
......
/*!
* jQuery Cookie Plugin
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2011, Klaus Hartl
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://www.opensource.org/licenses/mit-license.php
* http://www.opensource.org/licenses/GPL-2.0
*/
(function($) {
$.cookie = function(key, value, options) {
// key and at least value given, set cookie...
if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
options = $.extend({}, options);
if (value === null || value === undefined) {
options.expires = -1;
}
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setDate(t.getDate() + days);
}
value = String(value);
return (document.cookie = [
encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// key and possibly options given, get cookie...
options = value || {};
var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
var pairs = document.cookie.split('; ');
for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
}
return null;
};
})(jQuery);
.jobs {
margin: 60px auto 120px;
h1 + hr {
margin-bottom: 80px;
}
.message {
@include clearfix;
margin-bottom: 60px;
padding-bottom: 60px;
position: relative;
hr {
bottom: 0px;
margin: 0px;
position: absolute;
width: 100%;
}
.photo {
background: rgb(255,255,255);
border: 1px solid rgb(210,210,210);
padding: 1px;
width: flex-grid(4);
img {
background: rgb(245,245,245);
display: block;
height: 200px;
width: 100%;
}
}
&.left {
.photo {
float: left;
margin-right: flex-gutter();
}
}
&.right {
h2, p {
text-align: right;
}
.photo {
float: right;
margin-left: flex-gutter();
}
}
&:last-child {
margin-bottom: 0px;
}
}
.jobs-wrapper {
@include clearfix;
float: left;
width: flex-grid(12);
> h2 {
border-bottom: 1px solid rgb(220,220,220);
margin-bottom: 60px;
padding-bottom: 20px;
//text-align: center;
}
.jobs-sidebar {
@include box-sizing(border-box);
border-left: 1px solid rgb(220,220,220);
float: left;
padding-bottom: 20px;
padding-left: 20px;
width: flex-grid(3);
nav {
margin-bottom: 40px;
ol {
@include clearfix;
li {
float: left;
margin-right: flex-gutter();
width: flex-grid(12);
&:nth-child(4n) {
margin-right: 0px;
}
a {
display: block;
margin-left: -20px;
padding: 10px 0px 10px 20px;
position: relative;
text-transform: uppercase;
&::after {
@include background-image(linear-gradient(180deg, rgba(235,235,235, 0) 0%,
rgba(235,235,235, 1)));
bottom: 0px;
//content: "";
display: block;
height: 1px;
left: 0px;
position: absolute;
width: 100%;
}
&:hover {
background: rgb(245,245,245);
//@include background-image(linear-gradient(180deg, rgba(245,245,245, 0) 0%,
//rgba(245,245,245, 1) 80%,
//rgba(245,245,245, 1) 100%));
}
}
}
}
}
p + h2 {
margin-top: 40px;
}
}
.jobs-listing {
float: left;
margin-right: flex-gutter();
width: flex-grid(9);
.job {
border-bottom: 1px solid rgb(220,220,220);
padding: 40px 0px;
&:first-child {
padding-top: 0px;
}
&:last-child {
border: none;
padding-bottom: 0px;
}
.inner-wrapper {
}
h3 {
font-family: $sans-serif;
font-weight: bold;
margin-bottom: 15px;
}
}
}
}
}
......@@ -20,15 +20,15 @@
@import 'shared_modal';
// pages
@import "courseware/courseware", "courseware/sidebar", "courseware/video", "courseware/sequence-nav", "courseware/amplifier", "courseware/problems";
@import "textbook";
@import "info";
@import "profile";
@import "gradebook";
@import "wiki/basic-html", "wiki/sidebar", "wiki/create", "wiki/wiki", "wiki/table";
@import "help";
@import "discussion/askbot-original", "discussion/discussion","discussion/sidebar", "discussion/questions", "discussion/tags", "discussion/question-view" , "discussion/answers", "discussion/forms", "discussion/form-wmd-toolbar", "discussion/modals", "discussion/profile", "discussion/badges";
// @import "courseware/courseware", "courseware/sidebar", "courseware/video", "courseware/sequence-nav", "courseware/amplifier", "courseware/problems";
// @import "textbook";
// @import "info";
// @import "profile";
// @import "gradebook";
// @import "wiki/basic-html", "wiki/sidebar", "wiki/create", "wiki/wiki", "wiki/table";
// @import "help";
//
// @import "discussion/askbot-original", "discussion/discussion","discussion/sidebar", "discussion/questions", "discussion/tags", "discussion/question-view" , "discussion/answers", "discussion/forms", "discussion/form-wmd-toolbar", "discussion/modals", "discussion/profile", "discussion/badges";
// from prototype
@import 'index';
......
......@@ -12,11 +12,7 @@ div.course-wrapper {
@extend .table-wrapper;
ul, ol {
padding-left: lh();
li {
margin-bottom: lh(.5);
}
list-style: none;
}
section.course-content {
......@@ -36,6 +32,148 @@ div.course-wrapper {
}
}
ul {
li {
margin-bottom: lh(.5);
}
}
.problem-set {
position: relative;
@extend .clearfix;
h2 {
margin-top: 0;
margin-bottom: 15px;
width: flex-grid(2, 9);
padding-right: flex-gutter(9);
border-right: 1px dashed #ddd;
@include box-sizing(border-box);
display: table-cell;
vertical-align: top;
&.problem-header {
section.staff {
margin-top: 30px;
font-size: 80%;
}
}
@media screen and (max-width:1120px) {
display: block;
width: auto;
border-right: 0;
}
@media print {
display: block;
width: auto;
border-right: 0;
}
}
section.problem {
display: table-cell;
width: flex-grid(7, 9);
padding-left: flex-gutter(9);
@media screen and (max-width:1120px) {
display: block;
width: auto;
padding: 0;
}
@media print {
display: block;
width: auto;
padding: 0;
canvas, img {
page-break-inside: avoid;
}
}
span {
&.unanswered, &.ui-icon-bullet {
@include inline-block();
background: url('../images/unanswered-icon.png') center center no-repeat;
height: 14px;
position: relative;
top: 4px;
width: 14px;
}
&.correct, &.ui-icon-check {
@include inline-block();
background: url('../images/correct-icon.png') center center no-repeat;
height: 20px;
position: relative;
top: 6px;
width: 25px;
}
&.incorrect, &.ui-icon-close {
@include inline-block();
background: url('../images/incorrect-icon.png') center center no-repeat;
height: 20px;
width: 20px;
position: relative;
top: 6px;
}
}
}
div {
> span {
display: block;
margin-bottom: lh(.5);
&[answer] {
border-top: 1px solid #ededed;
border-bottom: 1px solid #ededed;
background: #f3f3f3;
margin: 0 (-(lh()));
padding: lh(.5) lh();
}
}
}
input[type="text"] {
display: inline-block;
width: 50%;
}
center {
display: block;
margin: lh() 0;
border: 1px solid #ccc;
padding: lh();
}
section.action {
margin-top: lh();
input[type="button"] {
padding: lh(.4) lh();
text-shadow: 0 -1px 0 #666;
}
}
}
section.problems-wrapper, div#seq_content {
@extend .problem-set;
}
section.problems-wrapper {
display: table;
width: 100%;
@media screen and (max-width:1120px) {
display: block;
width: auto;
}
}
div#seq_content {
h1 {
background: none;
......@@ -46,9 +184,6 @@ div.course-wrapper {
}
ol.vert-mod {
list-style: none;
padding-left: 0;
> li {
@extend .clearfix;
@extend .problem-set;
......@@ -86,6 +221,10 @@ div.course-wrapper {
height: 150px;
}
ul {
list-style: disc outside none;
padding-left: 1em;
}
nav.sequence-bottom {
ul {
......
<%inherit file="main.html" />
<%include file="guest_navigation.html" args="active_page='info'" />
<<<<<<< HEAD
<%namespace name='static' file='static_content.html'/>
<section class="container">
<section class="course-info">
......@@ -113,85 +112,6 @@
<section class="faq tab">
<h3>Frequently Asked Questions</h3>
=======
<section class="course-info">
<header class="course-profile">
<div class="intro-inner-wrapper">
<section class="intro">
<hgroup>
<h1>18th Century History <span class="course-number">(HC137)</span></h1>
<hr>
<h2><a href="#">HarvardX</a></h2>
</hgroup>
</section>
<section class="actions">
<a href="#" class="register">Register</a>
<section class="social-sharing">
</section>
</section>
</div>
</header>
<section class="container">
<section class="details">
<nav>
<a href="#" class="active">Overview</a>
<a href="#">FAQ</a>
<a href="#">Requirements</a>
<a href="#">Text-book</a>
<a href="#">Syllabus</a>
<a href="#">Reviews</a>
</nav>
<div class="inner-wrapper">
<section class="about">
<h2>About this course</h2>
<p>This course explores the history of the modern world since Chinggis Khan. It focuses on the connections between societies from the time of the Mongol conquests and the gradual, but accelerating ways in which connections became ties of inter-dependence. The relations between societies are what will concern us. The forces pulling the world together vary from religious to economic, political to intellectual. These forces bring the world together, but they also create new divisions. Nowadays, we call this "globalization." That term has tended to emphasize the drive to worldwide integration; the view of globalization taken in this course emphasizes disintegration as well as integration. We will tackle some very basic questions: How do we explain the staggering wealth of China in the centuries up to 1750, as well as China's recent ascent? Where did the United States come from, and where is it headed? What are the significance and legacies of empire in the world? How have world wars and revolutions shaped the international system over time? What exactly is globalization, and how does today's globalization compare with the past? How has the relationship between humans and nature changed over the centuries?</p>
<h2>Requirements</h2>
<p>In order to succeed in this course, you must have taken an AP level physics course in electricity and magnetism. You must know basic calculus and linear algebra and have some background in differential equations. Since more advanced mathematics will not show up until the second half of the course, the first half of the course will include an optional remedial differential equations component for those who need it.</p>
<p>The course web site was developed and tested primarily with Google Chrome. We support current versions of Mozilla Firefox as well. The video player is designed to work with Flash. While we provide a partial non-Flash fallback for the video, as well as partial support for Internet Explorer, other browsers, and tablets, portions of the functionality will be unavailable.</p>
</section>
<section class="course-staff">
<h2>Course staff</h3>
<article class="teacher">
<div class="teacher-image">
<img src="${static.url('images/anant.jpg')}" />
</div>
<h3>Anant Agarwal</h3>
<p>Director of MIT’s Computer Science and Artificial Intelligence Laboratory (CSAIL) and a professor of the Electrical Engineering and Computer Science department at MIT. His research focus is in parallel computer architectures and cloud software systems, and he is a founder of several successful startups, including Tilera, a company that produces scalable multicore processors. Prof. Agarwal won MIT’s Smullin and Jamieson prizes for teaching and co-authored the course textbook “Foundations of Analog and Digital Electronic Circuits.”</p>
</article>
<article class="teacher">
<div class="teacher-image">
<img src="${static.url('images/gerald.jpg')}" />
</div>
<h3>Gerald Sussman</h3>
<p>Professor of Electrical Engineering at MIT. He is a well known educator in the computer science community, perhaps best known as the author of Structure and Interpretation of Computer Programs, which is universally acknowledged as one of the top ten textbooks in computer science, and as the creator of Scheme, a popular teaching language. His research spans a range of topics, from artificial intelligence, to physics and chaotic systems, to supercomputer design.</p>
</article>
<article class="teacher">
<div class="teacher-image">
<img src="${static.url('images/piotr.jpg')}" />
</div>
<h3>Piotr Mitros</h3>
<p>Research Scientist at MIT. His research focus is in finding ways to apply techniques from control systems to optimizing the learning process. Dr. Mitros has worked as an analog designer at Texas Instruments, Talking Lights, and most recently, designed the analog front end for a novel medical imaging modality for Rhythmia Medical.</p>
</article>
</section>
<section class="syllabus">
<h2>Syllabus</h2>
</section>
<section class="textbook">
<h2>Textbook</h2>
<p>The course uses the textbook Foundations of Analog and Digital Electronic Circuits, by Anant Agarwal and Jeffrey H. Lang. Morgan Kaufmann Publishers, Elsevier, July 2005. While recommended, the book is not required: relevant sections will be provided electronically as part of the online course for personal use in connection with this course only. The copyright for the book is owned by Elsevier. The book can be purchased on <a href="http://www.amazon.com/exec/obidos/ASIN/1558607358/ref=nosim/mitopencourse-20">Amazon</a>.</p>
</section>
<section class="faq">
<h2>Frequently Asked Questions</h2>
>>>>>>> cleans up course info/profile page
<ul>
<li>What is the format of the class?
<p>The course will consist of 24 lectures, each lasting 50 minutes. There will be regular assignments consisting of map tests and short essays.</p>
......@@ -207,7 +127,6 @@
</li>
</ul>
</section>
<<<<<<< HEAD
<section class="more-info tab">
<section class="who-should-take">
......@@ -305,33 +224,5 @@
<p>Research Scientist at MIT. His research focus is in finding ways to apply techniques from control systems to optimizing the learning process. Dr. Mitros has worked as an analog designer at Texas Instruments, Talking Lights, and most recently, designed the analog front end for a novel medical imaging modality for Rhythmia Medical.</p></li>
</ul>
=======
</section>
</div>
<section class="course-sidebar">
<div class="media">
<div class="hero">
<img src="${static.url('images/history.png')}" />
</div>
</div>
<section class="dates">
<h3>Important Dates</h3>
<p>Class Starts: <span class="start-date">7/12/12</span></p>
<p>Final Exam: <span class="start-date">12/09/12</span></p>
<p>Total Length: <span class="course-length">15 weeks</span></p>
</section>
<section class="course-abstract">
<h3>Course Sumamry</h3>
<p>This course will examine the ways in which the world has grown more integrated yet more divided over the past 300 years.</p>
</section>
<section class="dates">
<p>Course Number <span class="start-date">HC137</span></p>
</section>
</section>
>>>>>>> cleans up course info/profile page
</section>
</section>
<%inherit file="main.html" />
<h1>Jobs</h1>
<section class="container jobs">
<h1>Want to change the future of education?</h1>
<hr class="horizontal-divider">
<section class="company-mission message left">
<div class="inner-wrapper">
<div class="photo">
<img src="">
</div>
<h2>Mission: Educate 1 billion people around the world</h2>
<p>“EdX represents a unique opportunity to improve education on our own campuses through online learning, while simultaneously creating a bold new educational path for millions of learners worldwide,” MIT President Susan Hockfield said.</p>
<p>Harvard President Drew Faust said, “edX gives Harvard and MIT an unprecedented opportunity to dramatically extend our collective reach by conducting groundbreaking research into effective education and by extending online access to quality higher education.”
</div>
<hr class="fade-right-hr-divider">
</section>
<section class="our-culture message right">
<div class="photo">
<img src="">
</div>
<h2>What it's like to work here</h2>
<p>“Harvard and MIT will use these new technologies and the research they will make possible to lead the direction of online learning in a way that benefits our students, our peers, and people across the nation and the globe,” Faust continued.</p>
<p>[fast-moving not-for-profit startup][institutional backing, funding, benefits, and stability][industry salaries]</p>
<hr class="fade-left-hr-divider">
</section>
<section class="benefits message left">
<div class="photo">
<img src="">
</div>
<h2>Mission: Educate 1 billion people around the world</h2>
<p>“EdX represents a unique opportunity to improve education on our own campuses through online learning, while simultaneously creating a bold new educational path for millions of learners worldwide,” MIT President Susan Hockfield said.</p>
<p>Harvard President Drew Faust said, “edX gives Harvard and MIT an unprecedented opportunity to dramatically extend our collective reach by conducting groundbreaking research into effective education and by extending online access to quality higher education.”
</section>
<section class="jobs-wrapper">
<h2>We are currently looking for</h2>
<section class="jobs-listing">
<article id="edx-fellow" class="job">
<div class="inner-wrapper">
<h3>edX Fellow</h3>
<p>The edX fellows program is intended as an alternative to the traditional academic track for candidates with a strong focus on teaching. Fellows act as contact points for departments at MIT and Harvard, and help facilitate putting together on-line courses. </p>
<p>If you're interested in this position, send an e-mail to <a href="">fellow-jobs@edxonline.org</a></p>
</div>
</article>
<article id="content-engineer" class="job">
<div class="inner-wrapper">
<h3>Content Engineer</h3>
<p>Content engineers help create the technology for specific courses. The tasks include:</p>
<ul>
<li>
<p>Development of course-specific user-facing elements, such as the circuit editor and simulator that Chris Terman and Jacob White developed for 6.002x</p>
</li>
<li>
<p>Simple integration of course materials into courses</p>
</li>
<li>
<p>Developing programs to grade rich design questions, such as the ones developed by Gerald Sussman to allow basic design problems in 6.002x.</p>
</li>
</ul>
<p>Knowledge of Python, XML, and/or JavaScript is desired. Strong interest and background in pedagogy and education is desired as well.</p>
<p>If you're interested in this position, send an e-mail to <a href="">content-engineer@edxonline.org</a></p>
</div>
</article>
<article id="technology-team" class="job">
<div class="inner-wrapper">
<h3>Technology Team</h3>
<p>[Looking for both back-end and front-end developers. Strong backgrounds in machine learning, education, user interaction design, big data, or social network analysis are desirable, but team members do wear many hats. Best candidate would be a masterful hacker who went and did startups after finishing their Ph.D. We should find a way to make some positions that parallel fellows, and can leverage MIT/Harvard prestige]</p>
<p>If you're interested in this position, send an e-mail to <a href="">content-engineer@edxonline.org</a></p>
</div>
</article>
</section>
<section class="jobs-sidebar">
<h2>Positions</h2>
<nav>
<ol>
<li>
<a href="#edx-fellow">edX Fellow</a>
</li>
<li>
<a href="#content-engineer">Content Engineer</a>
</li>
<li>
<a href="#technology-team">Technology Team</a>
</li>
</ol>
</nav>
<h2>How to Apply</h2>
<p>E-mail your resume, coverletter and any other materials to <a href="#">careers@edxonline.org</a></p>
<h2>Our Location</h2>
<p>11 Cambridge Center, Cambridge MA USA</p>
</section>
</section>
</section>
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