Commit 38e93730 authored by GI's avatar GI

Fixed HTML errors wrote grade check CGI form

parent 880c97fc
teaching/2018-19/269-vector-analysis
\ No newline at end of file
# Shibboleth header
AuthType Shibboleth
ShibRequireSession On
ShibApplicationId default
ShibExportAssertion On
# For any authenticated user. (Need not be a CMU member)
#Require Shibboleth
# Specific user id
#require user gi1242@andrew.cmu.edu
# Groups.
#require shib-attr affiliation Faculty@andrew.cmu.edu
#require shib-attr affiliation Staff@andrew.cmu.edu
#require shib-attr affiliation Member@andrew.cmu.edu
require shib-user ~ ^.+@andrew\.cmu\.edu$
title: test
## CGI Output
<pre id='form-output'></pre>
<script>
window.addEventListener('DOMContentLoaded', function() {
$.get( "{{get_link('/cgi-bin/auth/test.py')}}",
'{{dirname}}/grades.csv',
function(data) {
$('#form-output').text(data);
}
);
});
</script>
...@@ -213,6 +213,7 @@ The status message should tell you what files are conflicted, and what you shoul ...@@ -213,6 +213,7 @@ The status message should tell you what files are conflicted, and what you shoul
You can fix these conflicts by opening these files in your editor, and searching for the conflict markers `<<<<<<<`, `=======`, `>>>>>>>`. You can fix these conflicts by opening these files in your editor, and searching for the conflict markers `<<<<<<<`, `=======`, `>>>>>>>`.
Here's what it will typically look like: Here's what it will typically look like:
<pre class='codehilite'> <pre class='codehilite'>
In 1875, Galton and Watson~\cite{WatsonGalton75} took up an investigation into the phenomenon In 1875, Galton and Watson~\cite{WatsonGalton75} took up an investigation into the phenomenon
of ``the decay of the families of men who occupied conspicuous positions in past times.'' of ``the decay of the families of men who occupied conspicuous positions in past times.''
......
...@@ -25,7 +25,7 @@ LaTeX can be used between `$` signs: ...@@ -25,7 +25,7 @@ LaTeX can be used between `$` signs:
## WikiLinks ## WikiLinks
* `[[file]]` generates a link to `file`. * `[[file]]` generates a link to `file`.
* To specify the link text use `[[/index.html|Test]]`, which links to `/index.html` and says `Test`. * To specify the link text use `[[/index.md|Test]]`, which links to `/index.html` and says `Test`.
This renders like this: [[/index.html|Test]] This renders like this: [[/index.html|Test]]
* For `markdown` files, an extension of `.md` is replaced with `.html`. * For `markdown` files, an extension of `.md` is replaced with `.html`.
Also, if the link text is omitted the title of the linked file is used instead. Also, if the link text is omitted the title of the linked file is used instead.
......
...@@ -4,7 +4,7 @@ breadcrumb: /{{dirname}}.md ...@@ -4,7 +4,7 @@ breadcrumb: /{{dirname}}.md
<div class='alert alert-info' role='alert' markdown="1"> <div class='alert alert-info' role='alert' markdown="1">
This markdown cheat cheat sheet is taken from [gist jonschlinkert/5854601](https://gist.github.com/jonschlinkert/5854601), and is used as a test of markdown rendering on this site. This markdown cheat cheat sheet is taken from [gist jonschlinkert/5854601](https://gist.github.com/jonschlinkert/5854601), and is used as a test of markdown rendering on this site.
Site specific extensions are [[README.md|here]]. Site specific extensions are [[local-extensions.md|here]].
</div> </div>
......
page: 20140129-wordpress.md
subject: Good post
name: Venkat
email: venkannababugadde@gmail.com
avatar: http://cdn.libravatar.org/avatar/083d67aa888df13b1c6e1e6c0003d943
date: 2019-01-28 06:11:12 EST
ip: 49.207.228.182
referer: http://www.math.cmu.edu/~gautam/sj/blog/20140129-wordpress.html
Thanks for sharing your valuable information. This is a very useful and informative post.
...@@ -8,4 +8,4 @@ As an alternative to the SOCKS proxy, you could set up an [SSH tunnel](http://ma ...@@ -8,4 +8,4 @@ As an alternative to the SOCKS proxy, you could set up an [SSH tunnel](http://ma
`ssh you@campus.machine.edu -L <port>:paywalledjournal.com:<port>` `ssh you@campus.machine.edu -L <port>:paywalledjournal.com:<port>`
(With <port> for HTTP access usually being 80.) (With `<port>` for HTTP access usually being 80.)
Options -Indexes
# Shibboleth header
AuthType Shibboleth
ShibRequireSession On
ShibApplicationId default
ShibExportAssertion On
# For any authenticated user. (Need not be a CMU member)
#Require Shibboleth
# Specific user id
#require user gi1242@andrew.cmu.edu
# Groups.
#require shib-attr affiliation Faculty@andrew.cmu.edu
#require shib-attr affiliation Staff@andrew.cmu.edu
#require shib-attr affiliation Member@andrew.cmu.edu
require shib-user ~ ^.+@andrew\.cmu\.edu$
#! /usr/bin/python3
#import cgitb; cgitb.enable()
import cgi, os, sys, csv, json, statistics
def tofloat(x):
try: return float(x)
except: return 0
print( "Content-type: application/json;\n" )
docroot = os.environ.get( 'CONTEXT_DOCUMENT_ROOT',
os.environ.get('PWD') )
fname = os.path.join( docroot, '{{path_prefix}}',
os.environ.get('QUERY_STRING') )
user = os.environ.get( 'eppn', '' )[:-len('@andrew.cmu.edu')]
{% if dev_env == 'local' %}
# No authentication; just impersonate someone for testing
user = 'afogelso'
{% endif %}
data = {}
try:
with open(fname) as f:
reader = csv.reader( f )
header = next( reader )
lname = header.index('Last Name')
fname = header.index('Preferred/First Name')
mi = header.index('MI')
andrewid = header.index('Andrew ID')
scores_start = max( lname, fname, mi, andrewid ) + 1
scores_end = len( header )
scores = [ [] for s in range(scores_start, scores_end) ]
# Put assignment titles in rows
data['rows'] = header[ scores_start:scores_end ]
# Put assignment scores, and statistics in columns
data['cols'] = []
for row in reader:
# Check for users score
if user == row[andrewid]:
data['cols'].append( ['Your Score']
+ row[scores_start:] + ['']*(scores_end - len(row)) )
data['name'] = row[fname] + ' ' + row[lname]
# Get non-zero HW scores in scores to compute statistics
if row[lname] and row[fname] and row[andrewid]:
for i, s in enumerate( row[scores_start:] ):
sf = tofloat(s)
if sf > 0: scores[i].append(sf)
# Check for total points
if row[lname] == '' and row[fname] == '':
# print( 'getgrades.py:', row, file=sys.stderr )
rf = map( tofloat, row[scores_start:scores_end] )
if all( s != 0 for s in rf ):
data['cols'].append( ['Out of']
+ row[scores_start:scores_end] )
# This is the last row we care about
break
data['cols'].append( ['# Submissions']
+ [len(s) for s in scores] )
data['cols'].append( ['Max']
+ [max(s) for s in scores] )
#data['cols'].append( ['Min']
# + [min(s) for s in scores] )
data['cols'].append( ['Median']
+ [round(statistics.median(s), 1) for s in scores] )
data['cols'].append( ['Mean']
+ [round(statistics.mean(s), 1) for s in scores] )
#data['cols'].append( ['Std. Dev']
# + [round(statistics.stdev(s), 2) for s in scores] )
#data['rows'] = [row for row in reader]
#data['scores'] = scores
except Exception as e:
data['error'] = str(e)
print( json.JSONEncoder().encode( data ) )
#! /usr/bin/python3
import cgitb; cgitb.enable()
import cgi, os, sys, csv
print( "Content-type: text/plain;\n" )
# Print values
print( 'Query: {}\n\n'.format( os.environ.get( 'QUERY_STRING', 'None' ) ) )
print( 'CGI Fields:' )
form = cgi.FieldStorage()
for k in form.keys():
print( '{}: {}'.format( k, form.getvalue(k) ) )
# Print environment (text)
print( '\n\nEnvironment:' )
for k, v in os.environ.items():
print( '{}: {}'.format(k, v) )
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
{%- macro course_info_table(c) -%} {%- macro course_info_table(c) -%}
{#- Import this using "with context", so all the variables are inherited #} {#- Import this using "with context", so all the variables are inherited #}
<table class='table' summary='Logistical Information'> <table class='table'>
<thead><tr><td colspan='2'></td></tr></thead> <thead><tr><td colspan='2'></td></tr></thead>
<tbody>{# Instructor, lectures {{{ #} <tbody>{# Instructor, lectures {{{ #}
<tr> <tr>
...@@ -153,6 +153,26 @@ ...@@ -153,6 +153,26 @@
{%- endif -%} {%- endif -%}
</td> </td>
</tr> </tr>
{%- if ta.name2 %}
<tr>
<th scope='row'>TA</th>
<td>
{%- if ta.url2 -%}
<a href='{{ta.url2}}'>{{ta.name2}}</a>.
{%- else -%}
{{ta.name2 | default('TBA')}}.
{%- endif -%}
{%- if ta.office2 -%}
&emsp;
{{ room( ta.office2.bldg, ta.office2.room ) }}
{%- endif -%}
{%- if ta.email2 -%}
&emsp;
{{ email( ta.email2 ) }}
{%- endif -%}
</td>
</tr>
{%- endif %}
{%- if ta.office_hours -%} {%- if ta.office_hours -%}
<tr> <tr>
<th scope='row'>Office Hours (TA)</th> <th scope='row'>Office Hours (TA)</th>
...@@ -215,11 +235,13 @@ ...@@ -215,11 +235,13 @@
{%- endfor -%} {%- endfor -%}
</tbody> </tbody>
{%- endif -%}{# }}} #} {%- endif -%}{# }}} #}
{%- if c.mailing_list or c.anonymous_list or c.blackboard or c.mediasite or c.links or c.canvas -%}{# Mailing list {{{ #} {#- Mailing list {{{ #}
{%- if c.mailing_list or c.anonymous_list or c.blackboard
or c.mediasite or c.links or c.discourse or c.canvas %}
<tbody> <tbody>
{%- if c.mailing_list -%} {%- if c.mailing_list -%}
<tr> <tr>
<th scope='row'>Mailing list</td> <th scope='row'>Mailing list</th>
<td> <td>
<a href='{{c.mailing_list.url}}'>{{c.mailing_list.name}}</a> <a href='{{c.mailing_list.url}}'>{{c.mailing_list.name}}</a>
<span class='small'> <span class='small'>
...@@ -236,6 +258,14 @@ ...@@ -236,6 +258,14 @@
</td> </td>
</tr> </tr>
{%- endif -%} {%- endif -%}
{%- if c.discourse -%}
<tr>
<th scope='row'>Discourse</th>
<td>
Class discussion board <a href="{{c.discourse}}">here</a>.
</td>
</tr>
{%- endif -%}
{%- if c.blackboard -%} {%- if c.blackboard -%}
<tr> <tr>
<th scope='row'>Blackboard</th> <th scope='row'>Blackboard</th>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
{% extends "layouts/md-nav-right-affix.j2" -%} {% extends "layouts/md-nav-right-affix.j2" -%}
{% block comments_block -%} {% block comments_block -%}
{% if comments != 'disabled' -%} {% if comments != 'disabled' -%}
<br /> <br>
<h3> <h3>
{{ glyph( 'comment' ) }}&emsp;Comments {{ glyph( 'comment' ) }}&emsp;Comments
</h3> </h3>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
<div class='media-body'> <div class='media-body'>
<h4 class='media-heading'> <h4 class='media-heading'>
{{meta.subject}} {{meta.subject}}
<br /> <br>
<small>{{meta.name|default('Anonymous')}} ({{meta.date}})</small> <small>{{meta.name|default('Anonymous')}} ({{meta.date}})</small>
</h4> </h4>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
</div> </div>
</li> </li>
</ul> </ul>
<br /> <br>
{% endfor -%} {% endfor -%}
<h4> <h4>
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
{% block nav_after_toc -%} {% block nav_after_toc -%}
{{ super() }} {{ super() }}
<br /> <br>
<h4>{{glyph( 'bullhorn' )}}&emsp;Recent posts</h4> <h4>{{glyph( 'bullhorn' )}}&emsp;Recent posts</h4>
{% set files = glob( '/blog/[0-9]*.md' ) | sort( reverse=True ) -%} {% set files = glob( '/blog/[0-9]*.md' ) | sort( reverse=True ) -%}
<ol class='list-unstyled'> <ol class='list-unstyled'>
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
{% set active = 'teaching' -%} {% set active = 'teaching' -%}
{%- if path_exists( 'course_info.j2' ) -%} {%- if path_exists( 'course_info.j2' ) -%}
{%- from get_file('course_info.j2') import course -%} {%- from get_file('course_info.j2') import course -%}
{%- if not title %}{% set title = course.title %}{% endif -%} {%- if not title %}
{%- set title = course.title %}
{%- if course.semester %}{% set subtitle = course.semester %}{% endif %}
{%- endif -%}
{% set page_email = course.email -%} {% set page_email = course.email -%}
{# Set breadcrumb for level 1 pages -#} {# Set breadcrumb for level 1 pages -#}
{% if not breadcrumb and basename != 'index.md' -%} {% if not breadcrumb and basename != 'index.md' -%}
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
{% if title -%} {% if title -%}
<h1> <h1>
{{title}} {{title}}
{% if post_date(basename) -%} {% if subtitle or post_date(basename) -%}
<br /> <br>
<small>{{post_date(basename)}}</small> <small>{{subtitle | default(post_date(basename))}}</small>
{% endif -%} {% endif -%}
</h1> </h1>
{% endif -%} {% endif -%}
......
'use strict';
$(document).ready( function() { $(document).ready( function() {
/* Easy Bootstrap affix. Simply do: /* Easy Bootstrap affix. Simply do:
* *
...@@ -12,65 +14,64 @@ $(document).ready( function() { ...@@ -12,65 +14,64 @@ $(document).ready( function() {
* CSS to disable: .affix, .affix-bottom { position: static; } * CSS to disable: .affix, .affix-bottom { position: static; }
*/ */
$('[data-affix-after]').each( function() { $('[data-affix-after]').each( function() {
var elem = $(this); var elem = $(this);
var parent_panel = elem.parent(); var parent_panel = elem.parent();
var prev = $( elem.data('affix-after') ); var prev = $( elem.data('affix-after') );
if( prev.length != 1 ) { function resizeFn() {
/* Create a new element immediately before. */ /* Set the width to it's natural width in the parent. */
prev = elem.before( '<div></div>' ).prev(); var sideBarNavWidth = parent_panel.width()
} - parseInt(elem.css('paddingLeft'))
- parseInt(elem.css('paddingRight'))
- parseInt(elem.css('marginLeft'))
- parseInt(elem.css('marginRight'))
- parseInt(elem.css('borderLeftWidth'))
- parseInt(elem.css('borderRightWidth'));
elem.css('width', sideBarNavWidth);
var resizeFn = function() { elem.affix({
/* Set the width to it's natural width in the parent. */ offset: {
var sideBarNavWidth = parent_panel.width() top: prev.offset().top + prev.outerHeight(true),
- parseInt(elem.css('paddingLeft')) bottom: $('body>footer').outerHeight(true)
- parseInt(elem.css('paddingRight')) }
- parseInt(elem.css('marginLeft')) });
- parseInt(elem.css('marginRight'))
- parseInt(elem.css('borderLeftWidth'))
- parseInt(elem.css('borderRightWidth'));
elem.css('width', sideBarNavWidth);
elem.affix({
offset: {
top: prev.offset().top + prev.outerHeight(true),
bottom: $('body>footer').outerHeight(true)
}
});
elem.affix( 'checkPosition' ); elem.affix( 'checkPosition' );
}; }
resizeFn(); if( prev.length != 1 )
$(window).resize(resizeFn); /* Create a new element immediately before. */
prev = elem.before( '<div></div>' ).prev();
$('[data-spy~="scroll"]').each( function() { resizeFn();
$(this).on('activate.bs.scrollspy', function() { $(window).resize(resizeFn);
elem.affix( 'checkPosition' );
});
});
});
$('[data-spy~="scroll"]').each( function() {
$(this).on('activate.bs.scrollspy', function() {
elem.affix( 'checkPosition' );
});
});
}); /* end $('[data-affix-after]') */
}); /* end ready */ }); /* end ready */
function submit_comment() { function submit_comment() {
$('#comment-failed,#comment-form,#comment-success').addClass('hidden'); function failfn(data) {
$('#comment-sending').removeClass( 'hidden' );
var failfn = function(data) {
$('#comment-form,#comment-sending').addClass('hidden'); $('#comment-form,#comment-sending').addClass('hidden');
$('#comment-failed,#comment-form').removeClass( 'hidden' ); $('#comment-failed,#comment-form').removeClass( 'hidden' );
{% if dev_env == 'local' %} {% if dev_env == 'local' %}
$('#comment-failed').append('<pre>' + data + '</pre>'); $('#comment-failed').append('<pre>' + data + '</pre>');
{% endif %} {% endif %}
}; }
$('#comment-failed,#comment-form,#comment-success').addClass('hidden');
$('#comment-sending').removeClass( 'hidden' );
$.post( "{{get_link('/cgi-bin/comment.py')}}", $.post( "{{get_link('/cgi-bin/comment.py')}}",
$('#comment-form > form').serializeArray() ) $('#comment-form > form').serializeArray() )
.done( function( data ) { .done( function( data ) {
if( data.trim() == "OK" ) { if( data.trim() == "OK" ) {
$('#comment-failed,#comment-form,#comment-sending').addClass('hidden'); $('#comment-failed,#comment-form,#comment-sending')
.addClass('hidden');
$('#comment-success').removeClass( 'hidden' ); $('#comment-success').removeClass( 'hidden' );
} }
else failfn(data); else failfn(data);
...@@ -78,3 +79,62 @@ function submit_comment() { ...@@ -78,3 +79,62 @@ function submit_comment() {
) )
.fail( failfn ); .fail( failfn );
} }
function get_grades(fname) {
function failfn( msg ) {
$('#status')
.attr( 'class', 'alert alert-danger' )
.text( 'Sorry, an error occurred.' );
{%- if dev_env == 'local' %}
$('#status').append( ' Error: ' +
(typeof(msg) === 'object' && msg.hasOwnProperty('statusText') ?
msg.statusText : msg ));
/* For debugging */
get_grades.errMsg = msg;
{%- endif -%}
}
$.getJSON( "{{get_link('/cgi-bin/auth/getgrades.py')}}",
fname, function(data) {
var table = $('#scores');
var thead = table.children('thead').children();
var tbody = table.children('tbody');
{% if dev_env == 'local' -%}
/* Save for debugging */
get_grades.data = data;
{% endif -%}
if( data.hasOwnProperty('error') )
failfn( data.error );
else {
$('#status').addClass( 'hidden' );
if( data.name )
$('#student-name').text(data.name).wrap('<strong></strong>');
else
$('#status')
.attr( 'class', 'alert alert-warning' )
.text( 'Your scores were not found!' );
// for( let c of data.cols ) throws an error in IE
for ( let i=0; i < data.cols.length; i++ ) {
thead.append( '<th>' + data.cols[i][0] + '</th>' );
/* console.log( '<td>' + c[0] + '</td>' ); */
};
for ( let i=0; i < data.rows.length; i++ ) {
let tr = $('<tr></tr>').appendTo(tbody);
tr.append('<th>' + data.rows[i] + '</th>' );
for( let j=0; j < data.cols.length; j++ )
tr.append( '<td>' + data.cols[j][i+1] + '</td>' );
}
/* $('#form-output').text(JSON.stringify(data, null, 2)); */
}
}
) /* getJSON */
.fail(failfn)
;
}
{% set course = { {% set course = {
'title' : 'Math 268: Multidimensional Calculus', 'title' : 'Math 268: Multidimensional Calculus',
'semester' : 'Fall 2015',
'email' : 'gi1242+268@cmu.edu', 'email' : 'gi1242+268@cmu.edu',
'lectures' : { 'lectures' : {
'time' : 'MWF 3:30--4:20', 'time' : 'MWF 3:30--4:20',
......
...@@ -33,7 +33,7 @@ Students will be expected to write proofs; however, some of the deeper results w ...@@ -33,7 +33,7 @@ Students will be expected to write proofs; however, some of the deeper results w
### Homework ### Homework
* Homework must be turned in **at the beginning of class** on the due date. * Homework must be turned in **at the beginning of class** on the due date.
* <span markdown='1' class='text-danger lead'>Late homework will **NEVER** be accepted. Really!</span> * <span class='text-danger lead'>Late homework will **NEVER** be accepted. Really!</span>
* To account for unusual circumstances, the bottom 20% of your homework will not count towards your grade. * To account for unusual circumstances, the bottom 20% of your homework will not count towards your grade.
* Working in groups is encouraged, but solutions must be written up on your own. * Working in groups is encouraged, but solutions must be written up on your own.
* Nearly perfect student solutions may be scanned and hosted here, with your identifying information removed. If you don't want any part of your solutions used, please make a note of it in the margin of your assignment. * Nearly perfect student solutions may be scanned and hosted here, with your identifying information removed. If you don't want any part of your solutions used, please make a note of it in the margin of your assignment.
......
{% set course = { {% set course = {
'title' : "Math 272: Introduction to PDE's", 'title' : "Math 272: Introduction to PDE's",
'semester' : 'Fall 2015',
'email' : 'gi1242+272@cmu.edu', 'email' : 'gi1242+272@cmu.edu',
'lectures' : { 'lectures' : {
'time' : 'MWF 2:30-3:20', 'time' : 'MWF 2:30-3:20',
......
{% set course = { {% set course = {
'title' : 'Math 269: Vector Analysis', 'title' : 'Math 269: Vector Analysis',
'semester' : 'Spring 2017',
'email' : 'gi1242+269@cmu.edu', 'email' : 'gi1242+269@cmu.edu',
'lectures' : { 'lectures' : {
'time' : 'MWF 11:30-12:20', 'time' : 'MWF 11:30-12:20',
......
{% set course = { {% set course = {
'title' : "46-944: Stochastic Calculus for Finance 1", 'title' : "46-944: Stochastic Calculus for Finance 1",
'semester' : 'Spring 2017',
'email' : 'gi1242+944@cmu.edu', 'email' : 'gi1242+944@cmu.edu',
'lectures' : [ 'lectures' : [
'MW 1:30--3:00 in POS 145 (Pittsburgh), telecast in TPR NY1 (New York)', 'MW 1:30--3:00 in POS 145 (Pittsburgh), telecast in TPR NY1 (New York)',
......
title: Working Group: Mathematical Fluid Dynamics title: Working Group: Mathematical Fluid Dynamics
subtitle: Fall 2016
## Logistical Information ## Logistical Information
...@@ -19,10 +20,6 @@ title: Working Group: Mathematical Fluid Dynamics ...@@ -19,10 +20,6 @@ title: Working Group: Mathematical Fluid Dynamics
<th scope='row'>Mailing List</th> <th scope='row'>Mailing List</th>
<td><a href='https://lists.andrew.cmu.edu/mailman/listinfo/fluids-wg'>lists.andrew/mailman/listinfo/fluids-wg</a></td> <td><a href='https://lists.andrew.cmu.edu/mailman/listinfo/fluids-wg'>lists.andrew/mailman/listinfo/fluids-wg</a></td>
</tr> </tr>
<tr>
<th scope='row'>Semester</th>
<td>Fall, 2016</td>
</tr>
</table> </table>
## Topics and References ## Topics and References
......
{% set course = { {% set course = {
'title' : 'Math 268: Multidimensional Calculus', 'title' : 'Math 268: Multidimensional Calculus',
'semester' : 'Spring 2018',
'email' : 'gi1242+268@cmu.edu', 'email' : 'gi1242+268@cmu.edu',
'lectures' : { 'lectures' : {
'time' : 'MWF 9:30-10:20', 'time' : 'MWF 9:30-10:20',
......
{% set course = { {% set course = {
'title' : "46-944: Stochastic Calculus for Finance 1", 'title' : "46-944: Stochastic Calculus for Finance 1",
'semester' : 'Fall 2017',
'email' : 'gi1242+944@cmu.edu', 'email' : 'gi1242+944@cmu.edu',
'lectures' : [ 'lectures' : [
'MW 2:45--4:15 in POS 145 (Pittsburgh), telecast in TPR NY1 (New York)', 'MW 2:45--4:15 in POS 145 (Pittsburgh), telecast in TPR NY1 (New York)',
......
title: Working Group: Stochastic PDEs title: Working Group: Stochastic PDEs
subtitle: Spring 2018
## Logistical Information ## Logistical Information