").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+ // Otherwise use the full result
+ responseText );
+
+ }).complete( callback && function( jqXHR, status ) {
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+ });
+ }
+
+ return this;
+};
+
+
+
+
+jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+};
+
+
+
+
+
+var docElem = window.document.documentElement;
+
+/**
+ * Gets a window from an element
+ */
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+jQuery.offset = {
+ setOffset: function( elem, options, i ) {
+ var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+ position = jQuery.css( elem, "position" ),
+ curElem = jQuery( elem ),
+ props = {};
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ curOffset = curElem.offset();
+ curCSSTop = jQuery.css( elem, "top" );
+ curCSSLeft = jQuery.css( elem, "left" );
+ calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+ jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+jQuery.fn.extend({
+ offset: function( options ) {
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ var docElem, win,
+ box = { top: 0, left: 0 },
+ elem = this[ 0 ],
+ doc = elem && elem.ownerDocument;
+
+ if ( !doc ) {
+ return;
+ }
+
+ docElem = doc.documentElement;
+
+ // Make sure it's not a disconnected DOM node
+ if ( !jQuery.contains( docElem, elem ) ) {
+ return box;
+ }
+
+ // If we don't have gBCR, just use 0,0 rather than error
+ // BlackBerry 5, iOS 3 (original iPhone)
+ if ( typeof elem.getBoundingClientRect !== strundefined ) {
+ box = elem.getBoundingClientRect();
+ }
+ win = getWindow( doc );
+ return {
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+ };
+ },
+
+ position: function() {
+ if ( !this[ 0 ] ) {
+ return;
+ }
+
+ var offsetParent, offset,
+ parentOffset = { top: 0, left: 0 },
+ elem = this[ 0 ];
+
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
+ // we assume that getBoundingClientRect is available when computed position is fixed
+ offset = elem.getBoundingClientRect();
+ } else {
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+ parentOffset = offsetParent.offset();
+ }
+
+ // Add offsetParent borders
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+ }
+
+ // Subtract parent offsets and element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ return {
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || docElem;
+
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent || docElem;
+ });
+ }
+});
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+ var top = /Y/.test( prop );
+
+ jQuery.fn[ method ] = function( val ) {
+ return access( this, function( elem, method, val ) {
+ var win = getWindow( elem );
+
+ if ( val === undefined ) {
+ return win ? (prop in win) ? win[ prop ] :
+ win.document.documentElement[ method ] :
+ elem[ method ];
+ }
+
+ if ( win ) {
+ win.scrollTo(
+ !top ? val : jQuery( win ).scrollLeft(),
+ top ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ elem[ method ] = val;
+ }
+ }, method, val, arguments.length, null );
+ };
+});
+
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// getComputedStyle returns percent when specified for top/left/bottom/right
+// rather than make the css module depend on the offset module, we just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+ jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+ function( elem, computed ) {
+ if ( computed ) {
+ computed = curCSS( elem, prop );
+ // if curCSS returns percentage, fallback to offset
+ return rnumnonpx.test( computed ) ?
+ jQuery( elem ).position()[ prop ] + "px" :
+ computed;
+ }
+ }
+ );
+});
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+ // margin is only for outerHeight, outerWidth
+ jQuery.fn[ funcName ] = function( margin, value ) {
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+ return access( this, function( elem, type, value ) {
+ var doc;
+
+ if ( jQuery.isWindow( elem ) ) {
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
+ // https://github.com/jquery/jquery/pull/764
+ return elem.document.documentElement[ "client" + name ];
+ }
+
+ // Get document width or height
+ if ( elem.nodeType === 9 ) {
+ doc = elem.documentElement;
+
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+ return Math.max(
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ }
+
+ return value === undefined ?
+ // Get width or height on the element, requesting but not forcing parseFloat
+ jQuery.css( elem, type, extra ) :
+
+ // Set width or height on the element
+ jQuery.style( elem, type, value, extra );
+ }, type, chainable ? margin : undefined, chainable, null );
+ };
+ });
+});
+
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+ return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+ define( "jquery", [], function() {
+ return jQuery;
+ });
+}
+
+
+
+
+var
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in
+// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( typeof noGlobal === strundefined ) {
+ window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+
+}));
diff --git a/_static/jquery.js b/_static/jquery.js
new file mode 100644
index 0000000..ab28a24
--- /dev/null
+++ b/_static/jquery.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="
",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d
b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/_static/js/modernizr.min.js b/_static/js/modernizr.min.js
new file mode 100644
index 0000000..f65d479
--- /dev/null
+++ b/_static/js/modernizr.min.js
@@ -0,0 +1,4 @@
+/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
+ */
+;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML=" ",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f
");
+
+ // Add expand links to all parents of nested ul
+ $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
+ var link = $(this);
+ expand = $(' ');
+ expand.on('click', function (ev) {
+ self.toggleCurrent(link);
+ ev.stopPropagation();
+ return false;
+ });
+ link.prepend(expand);
+ });
+ };
+
+ nav.reset = function () {
+ // Get anchor from URL and open up nested nav
+ var anchor = encodeURI(window.location.hash);
+ if (anchor) {
+ try {
+ var link = $('.wy-menu-vertical')
+ .find('[href="' + anchor + '"]');
+ $('.wy-menu-vertical li.toctree-l1 li.current')
+ .removeClass('current');
+ link.closest('li.toctree-l2').addClass('current');
+ link.closest('li.toctree-l3').addClass('current');
+ link.closest('li.toctree-l4').addClass('current');
+ }
+ catch (err) {
+ console.log("Error expanding nav for anchor", err);
+ }
+ }
+ };
+
+ nav.onScroll = function () {
+ this.winScroll = false;
+ var newWinPosition = this.win.scrollTop(),
+ winBottom = newWinPosition + this.winHeight,
+ navPosition = this.navBar.scrollTop(),
+ newNavPosition = navPosition + (newWinPosition - this.winPosition);
+ if (newWinPosition < 0 || winBottom > this.docHeight) {
+ return;
+ }
+ this.navBar.scrollTop(newNavPosition);
+ this.winPosition = newWinPosition;
+ };
+
+ nav.onResize = function () {
+ this.winResize = false;
+ this.winHeight = this.win.height();
+ this.docHeight = $(document).height();
+ };
+
+ nav.hashChange = function () {
+ this.linkScroll = true;
+ this.win.one('hashchange', function () {
+ this.linkScroll = false;
+ });
+ };
+
+ nav.toggleCurrent = function (elem) {
+ var parent_li = elem.closest('li');
+ parent_li.siblings('li.current').removeClass('current');
+ parent_li.siblings().find('li.current').removeClass('current');
+ parent_li.find('> ul li.current').removeClass('current');
+ parent_li.toggleClass('current');
+ }
+
+ return nav;
+};
+
+module.exports.ThemeNav = ThemeNav();
+
+if (typeof(window) != 'undefined') {
+ window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
+}
+
+},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);
diff --git a/_static/minus.png b/_static/minus.png
new file mode 100644
index 0000000..0f22b16
Binary files /dev/null and b/_static/minus.png differ
diff --git a/_static/pc_menu.png b/_static/pc_menu.png
new file mode 100644
index 0000000..1621fb6
Binary files /dev/null and b/_static/pc_menu.png differ
diff --git a/_static/phd101212s.gif b/_static/phd101212s.gif
new file mode 100644
index 0000000..721323e
Binary files /dev/null and b/_static/phd101212s.gif differ
diff --git a/_static/plugin_list.png b/_static/plugin_list.png
new file mode 100644
index 0000000..5b206bb
Binary files /dev/null and b/_static/plugin_list.png differ
diff --git a/_static/plus.png b/_static/plus.png
new file mode 100644
index 0000000..0cfe084
Binary files /dev/null and b/_static/plus.png differ
diff --git a/_static/pygments.css b/_static/pygments.css
new file mode 100644
index 0000000..b67900d
--- /dev/null
+++ b/_static/pygments.css
@@ -0,0 +1,63 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #ffffff; }
+.highlight .c { color: #888888 } /* Comment */
+.highlight .err { color: #FF0000; background-color: #FFAAAA } /* Error */
+.highlight .k { color: #008800; font-weight: bold } /* Keyword */
+.highlight .o { color: #333333 } /* Operator */
+.highlight .cm { color: #888888 } /* Comment.Multiline */
+.highlight .cp { color: #557799 } /* Comment.Preproc */
+.highlight .c1 { color: #888888 } /* Comment.Single */
+.highlight .cs { color: #cc0000; font-weight: bold } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #003388; font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #333399; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #6600EE; font-weight: bold } /* Literal.Number */
+.highlight .s { background-color: #fff0f0 } /* Literal.String */
+.highlight .na { color: #0000CC } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #BB0066; font-weight: bold } /* Name.Class */
+.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #880000; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #FF0000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #0066BB; font-weight: bold } /* Name.Function */
+.highlight .nl { color: #997700; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #007700 } /* Name.Tag */
+.highlight .nv { color: #996633 } /* Name.Variable */
+.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #6600EE; font-weight: bold } /* Literal.Number.Bin */
+.highlight .mf { color: #6600EE; font-weight: bold } /* Literal.Number.Float */
+.highlight .mh { color: #005588; font-weight: bold } /* Literal.Number.Hex */
+.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
+.highlight .mo { color: #4400EE; font-weight: bold } /* Literal.Number.Oct */
+.highlight .sb { background-color: #fff0f0 } /* Literal.String.Backtick */
+.highlight .sc { color: #0044DD } /* Literal.String.Char */
+.highlight .sd { color: #DD4422 } /* Literal.String.Doc */
+.highlight .s2 { background-color: #fff0f0 } /* Literal.String.Double */
+.highlight .se { color: #666666; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */
+.highlight .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */
+.highlight .si { background-color: #eeeeee } /* Literal.String.Interpol */
+.highlight .sx { color: #DD2200; background-color: #fff0f0 } /* Literal.String.Other */
+.highlight .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */
+.highlight .s1 { background-color: #fff0f0 } /* Literal.String.Single */
+.highlight .ss { color: #AA6600 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #336699 } /* Name.Variable.Class */
+.highlight .vg { color: #dd7700; font-weight: bold } /* Name.Variable.Global */
+.highlight .vi { color: #3333BB } /* Name.Variable.Instance */
+.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/_static/python.png b/_static/python.png
new file mode 100644
index 0000000..23a4c6e
Binary files /dev/null and b/_static/python.png differ
diff --git a/_static/remotes_clone.png b/_static/remotes_clone.png
new file mode 100644
index 0000000..8003dce
Binary files /dev/null and b/_static/remotes_clone.png differ
diff --git a/_static/remotes_fork.png b/_static/remotes_fork.png
new file mode 100644
index 0000000..e494696
Binary files /dev/null and b/_static/remotes_fork.png differ
diff --git a/_static/remotes_start.png b/_static/remotes_start.png
new file mode 100644
index 0000000..aa4839d
Binary files /dev/null and b/_static/remotes_start.png differ
diff --git a/_static/remotes_upstream.png b/_static/remotes_upstream.png
new file mode 100644
index 0000000..de03659
Binary files /dev/null and b/_static/remotes_upstream.png differ
diff --git a/_static/searchtools.js b/_static/searchtools.js
new file mode 100644
index 0000000..efec3c4
--- /dev/null
+++ b/_static/searchtools.js
@@ -0,0 +1,651 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+
+/* Non-minified version JS is _stemmer.js if file is provided */
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
+ };
+
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
+
+
+/**
+ * Simple result scoring code.
+ */
+var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [filename, title, anchor, descr, score]
+ // and returns the new score.
+ /*
+ score: function(result) {
+ return result[4];
+ },
+ */
+
+ // query matches the full name of an object
+ objNameMatch: 11,
+ // or matches in the last dotted part of the object name
+ objPartialMatch: 6,
+ // Additive scores depending on the priority of the object
+ objPrio: {0: 15, // used to be importantResults
+ 1: 5, // used to be objectResults
+ 2: -5}, // used to be unimportantResults
+ // Used when the priority is not in the mapping.
+ objPrioDefault: 0,
+
+ // query found in title
+ title: 15,
+ // query found in terms
+ term: 5
+};
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+ _index : null,
+ _queued_query : null,
+ _pulse_status : -1,
+
+ init : function() {
+ var params = $.getQueryParameters();
+ if (params.q) {
+ var query = params.q[0];
+ $('input[name="q"]')[0].value = query;
+ this.performSearch(query);
+ }
+ },
+
+ loadIndex : function(url) {
+ $.ajax({type: "GET", url: url, data: null,
+ dataType: "script", cache: true,
+ complete: function(jqxhr, textstatus) {
+ if (textstatus != "success") {
+ document.getElementById("searchindexloader").src = url;
+ }
+ }});
+ },
+
+ setIndex : function(index) {
+ var q;
+ this._index = index;
+ if ((q = this._queued_query) !== null) {
+ this._queued_query = null;
+ Search.query(q);
+ }
+ },
+
+ hasIndex : function() {
+ return this._index !== null;
+ },
+
+ deferQuery : function(query) {
+ this._queued_query = query;
+ },
+
+ stopPulse : function() {
+ this._pulse_status = 0;
+ },
+
+ startPulse : function() {
+ if (this._pulse_status >= 0)
+ return;
+ function pulse() {
+ var i;
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ var dotString = '';
+ for (i = 0; i < Search._pulse_status; i++)
+ dotString += '.';
+ Search.dots.text(dotString);
+ if (Search._pulse_status > -1)
+ window.setTimeout(pulse, 500);
+ }
+ pulse();
+ },
+
+ /**
+ * perform a search for something (or wait until index is loaded)
+ */
+ performSearch : function(query) {
+ // create the required interface elements
+ this.out = $('#search-results');
+ this.title = $('' + _('Searching') + ' ').appendTo(this.out);
+ this.dots = $(' ').appendTo(this.title);
+ this.status = $('
').appendTo(this.out);
+ this.output = $('').appendTo(this.out);
+
+ $('#search-progress').text(_('Preparing search...'));
+ this.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (this.hasIndex())
+ this.query(query);
+ else
+ this.deferQuery(query);
+ },
+
+ /**
+ * execute search (requires search index to be loaded)
+ */
+ query : function(query) {
+ var i;
+ var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
+
+ // stem the searchterms and add them to the correct list
+ var stemmer = new Stemmer();
+ var searchterms = [];
+ var excluded = [];
+ var hlterms = [];
+ var tmp = query.split(/\s+/);
+ var objectterms = [];
+ for (i = 0; i < tmp.length; i++) {
+ if (tmp[i] !== "") {
+ objectterms.push(tmp[i].toLowerCase());
+ }
+
+ if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
+ tmp[i] === "") {
+ // skip this "word"
+ continue;
+ }
+ // stem the word
+ var word = stemmer.stemWord(tmp[i].toLowerCase());
+ var toAppend;
+ // select the correct list
+ if (word[0] == '-') {
+ toAppend = excluded;
+ word = word.substr(1);
+ }
+ else {
+ toAppend = searchterms;
+ hlterms.push(tmp[i].toLowerCase());
+ }
+ // only add if not already in the list
+ if (!$u.contains(toAppend, word))
+ toAppend.push(word);
+ }
+ var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+ // console.debug('SEARCH: searching for:');
+ // console.info('required: ', searchterms);
+ // console.info('excluded: ', excluded);
+
+ // prepare search
+ var terms = this._index.terms;
+ var titleterms = this._index.titleterms;
+
+ // array of [filename, title, anchor, descr, score]
+ var results = [];
+ $('#search-progress').empty();
+
+ // lookup as object
+ for (i = 0; i < objectterms.length; i++) {
+ var others = [].concat(objectterms.slice(0, i),
+ objectterms.slice(i+1, objectterms.length));
+ results = results.concat(this.performObjectSearch(objectterms[i], others));
+ }
+
+ // lookup as search terms in fulltext
+ results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
+
+ // let the scorer override scores with a custom scoring function
+ if (Scorer.score) {
+ for (i = 0; i < results.length; i++)
+ results[i][4] = Scorer.score(results[i]);
+ }
+
+ // now sort the results by score (in opposite order of appearance, since the
+ // display function below uses pop() to retrieve items) and then
+ // alphabetically
+ results.sort(function(a, b) {
+ var left = a[4];
+ var right = b[4];
+ if (left > right) {
+ return 1;
+ } else if (left < right) {
+ return -1;
+ } else {
+ // same score: sort alphabetically
+ left = a[1].toLowerCase();
+ right = b[1].toLowerCase();
+ return (left > right) ? -1 : ((left < right) ? 1 : 0);
+ }
+ });
+
+ // for debugging
+ //Search.lastresults = results.slice(); // a copy
+ //console.info('search results:', Search.lastresults);
+
+ // print the results
+ var resultCount = results.length;
+ function displayNextItem() {
+ // results left, load the summary and display it
+ if (results.length) {
+ var item = results.pop();
+ var listItem = $(' ');
+ if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
+ // dirhtml builder
+ var dirname = item[0] + '/';
+ if (dirname.match(/\/index\/$/)) {
+ dirname = dirname.substring(0, dirname.length-6);
+ } else if (dirname == 'index/') {
+ dirname = '';
+ }
+ listItem.append($(' ').attr('href',
+ DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+ highlightstring + item[2]).html(item[1]));
+ } else {
+ // normal html builders
+ listItem.append($(' ').attr('href',
+ item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+ highlightstring + item[2]).html(item[1]));
+ }
+ if (item[3]) {
+ listItem.append($(' (' + item[3] + ') '));
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+ $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
+ dataType: "text",
+ complete: function(jqxhr, textstatus) {
+ var data = jqxhr.responseText;
+ if (data !== '' && data !== undefined) {
+ listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
+ }
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }});
+ } else {
+ // no source available, just display title
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }
+ }
+ // search finished, update title and status message
+ else {
+ Search.stopPulse();
+ Search.title.text(_('Search Results'));
+ if (!resultCount)
+ Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+ else
+ Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+ Search.status.fadeIn(500);
+ }
+ }
+ displayNextItem();
+ },
+
+ /**
+ * search for object names
+ */
+ performObjectSearch : function(object, otherterms) {
+ var filenames = this._index.filenames;
+ var objects = this._index.objects;
+ var objnames = this._index.objnames;
+ var titles = this._index.titles;
+
+ var i;
+ var results = [];
+
+ for (var prefix in objects) {
+ for (var name in objects[prefix]) {
+ var fullname = (prefix ? prefix + '.' : '') + name;
+ if (fullname.toLowerCase().indexOf(object) > -1) {
+ var score = 0;
+ var parts = fullname.split('.');
+ // check for different match types: exact matches of full name or
+ // "last name" (i.e. last dotted part)
+ if (fullname == object || parts[parts.length - 1] == object) {
+ score += Scorer.objNameMatch;
+ // matches in last name
+ } else if (parts[parts.length - 1].indexOf(object) > -1) {
+ score += Scorer.objPartialMatch;
+ }
+ var match = objects[prefix][name];
+ var objname = objnames[match[1]][2];
+ var title = titles[match[0]];
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ if (otherterms.length > 0) {
+ var haystack = (prefix + ' ' + name + ' ' +
+ objname + ' ' + title).toLowerCase();
+ var allfound = true;
+ for (i = 0; i < otherterms.length; i++) {
+ if (haystack.indexOf(otherterms[i]) == -1) {
+ allfound = false;
+ break;
+ }
+ }
+ if (!allfound) {
+ continue;
+ }
+ }
+ var descr = objname + _(', in ') + title;
+
+ var anchor = match[3];
+ if (anchor === '')
+ anchor = fullname;
+ else if (anchor == '-')
+ anchor = objnames[match[1]][1] + '-' + fullname;
+ // add custom score for some objects according to scorer
+ if (Scorer.objPrio.hasOwnProperty(match[2])) {
+ score += Scorer.objPrio[match[2]];
+ } else {
+ score += Scorer.objPrioDefault;
+ }
+ results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
+ }
+ }
+ }
+
+ return results;
+ },
+
+ /**
+ * search for full-text terms in the index
+ */
+ performTermsSearch : function(searchterms, excluded, terms, titleterms) {
+ var filenames = this._index.filenames;
+ var titles = this._index.titles;
+
+ var i, j, file;
+ var fileMap = {};
+ var scoreMap = {};
+ var results = [];
+
+ // perform the search on the required terms
+ for (i = 0; i < searchterms.length; i++) {
+ var word = searchterms[i];
+ var files = [];
+ var _o = [
+ {files: terms[word], score: Scorer.term},
+ {files: titleterms[word], score: Scorer.title}
+ ];
+
+ // no match but word was a required one
+ if ($u.every(_o, function(o){return o.files === undefined;})) {
+ break;
+ }
+ // found search word in contents
+ $u.each(_o, function(o) {
+ var _files = o.files;
+ if (_files === undefined)
+ return
+
+ if (_files.length === undefined)
+ _files = [_files];
+ files = files.concat(_files);
+
+ // set score for the word in each file to Scorer.term
+ for (j = 0; j < _files.length; j++) {
+ file = _files[j];
+ if (!(file in scoreMap))
+ scoreMap[file] = {}
+ scoreMap[file][word] = o.score;
+ }
+ });
+
+ // create the mapping
+ for (j = 0; j < files.length; j++) {
+ file = files[j];
+ if (file in fileMap)
+ fileMap[file].push(word);
+ else
+ fileMap[file] = [word];
+ }
+ }
+
+ // now check if the files don't contain excluded terms
+ for (file in fileMap) {
+ var valid = true;
+
+ // check if all requirements are matched
+ if (fileMap[file].length != searchterms.length)
+ continue;
+
+ // ensure that none of the excluded terms is in the search result
+ for (i = 0; i < excluded.length; i++) {
+ if (terms[excluded[i]] == file ||
+ titleterms[excluded[i]] == file ||
+ $u.contains(terms[excluded[i]] || [], file) ||
+ $u.contains(titleterms[excluded[i]] || [], file)) {
+ valid = false;
+ break;
+ }
+ }
+
+ // if we have still a valid result we can add it to the result list
+ if (valid) {
+ // select one (max) score for the file.
+ // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
+ var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
+ results.push([filenames[file], titles[file], '', null, score]);
+ }
+ }
+ return results;
+ },
+
+ /**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+ makeSearchSummary : function(text, keywords, hlwords) {
+ var textLower = text.toLowerCase();
+ var start = 0;
+ $.each(keywords, function() {
+ var i = textLower.indexOf(this.toLowerCase());
+ if (i > -1)
+ start = i;
+ });
+ start = Math.max(start - 120, 0);
+ var excerpt = ((start > 0) ? '...' : '') +
+ $.trim(text.substr(start, 240)) +
+ ((start + 240 - text.length) ? '...' : '');
+ var rv = $('
').text(excerpt);
+ $.each(hlwords, function() {
+ rv = rv.highlightText(this, 'highlighted');
+ });
+ return rv;
+ }
+};
+
+$(document).ready(function() {
+ Search.init();
+});
\ No newline at end of file
diff --git a/_static/simple_prompt.png b/_static/simple_prompt.png
new file mode 100644
index 0000000..db8b9d4
Binary files /dev/null and b/_static/simple_prompt.png differ
diff --git a/_static/tab_completion.png b/_static/tab_completion.png
new file mode 100644
index 0000000..92cf8aa
Binary files /dev/null and b/_static/tab_completion.png differ
diff --git a/_static/transmogrifier.jpg b/_static/transmogrifier.jpg
new file mode 100644
index 0000000..73363de
Binary files /dev/null and b/_static/transmogrifier.jpg differ
diff --git a/_static/two_line_prompt.png b/_static/two_line_prompt.png
new file mode 100644
index 0000000..23d9cac
Binary files /dev/null and b/_static/two_line_prompt.png differ
diff --git a/_static/underscore-1.3.1.js b/_static/underscore-1.3.1.js
new file mode 100644
index 0000000..208d4cd
--- /dev/null
+++ b/_static/underscore-1.3.1.js
@@ -0,0 +1,999 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var slice = ArrayProto.slice,
+ unshift = ArrayProto.unshift,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) { return new wrapper(obj); };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root['_'] = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.3.1';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (_.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = _.collect = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results[results.length] = iterator.call(context, value, index, list);
+ });
+ if (obj.length === +obj.length) results.length = obj.length;
+ return results;
+ };
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError('Reduce of empty array with no initial value');
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var reversed = _.toArray(obj).reverse();
+ if (context && !initial) iterator = _.bind(iterator, context);
+ return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ each(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ each(obj, function(value, index, list) {
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ });
+ return result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ each(obj, function(value, index, list) {
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if a given value is included in the array or object using `===`.
+ // Aliased as `contains`.
+ _.include = _.contains = function(obj, target) {
+ var found = false;
+ if (obj == null) return found;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ found = any(obj, function(value) {
+ return value === target;
+ });
+ return found;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ return _.map(obj, function(value) {
+ return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, function(value){ return value[key]; });
+ };
+
+ // Return the maximum element or (element-based computation).
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
+ var result = {computed : -Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed >= result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
+ if (!iterator && _.isEmpty(obj)) return Infinity;
+ var result = {computed : Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed < result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Shuffle an array.
+ _.shuffle = function(obj) {
+ var shuffled = [], rand;
+ each(obj, function(value, index, list) {
+ if (index == 0) {
+ shuffled[0] = value;
+ } else {
+ rand = Math.floor(Math.random() * (index + 1));
+ shuffled[index] = shuffled[rand];
+ shuffled[rand] = value;
+ }
+ });
+ return shuffled;
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, iterator, context) {
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value : value,
+ criteria : iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }), 'value');
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = function(obj, val) {
+ var result = {};
+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+ each(obj, function(value, index) {
+ var key = iterator(value, index);
+ (result[key] || (result[key] = [])).push(value);
+ });
+ return result;
+ };
+
+ // Use a comparator function to figure out at what index an object should
+ // be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator) {
+ iterator || (iterator = _.identity);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >> 1;
+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely convert anything iterable into a real, live array.
+ _.toArray = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ if (_.isArray(iterable)) return slice.call(iterable);
+ if (_.isArguments(iterable)) return slice.call(iterable);
+ return _.values(iterable);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ return _.toArray(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
+ // with `_.map`.
+ _.first = _.head = function(array, n, guard) {
+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ };
+
+ // Returns everything but the last entry of the array. Especcialy useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if ((n != null) && !guard) {
+ return slice.call(array, Math.max(array.length - n, 0));
+ } else {
+ return array[array.length - 1];
+ }
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail`.
+ // Especially useful on the arguments object. Passing an **index** will return
+ // the rest of the values in the array from that index onward. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = function(array, index, guard) {
+ return slice.call(array, (index == null) || guard ? 1 : index);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, function(value){ return !!value; });
+ };
+
+ // Return a completely flattened version of an array.
+ _.flatten = function(array, shallow) {
+ return _.reduce(array, function(memo, value) {
+ if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
+ memo[memo.length] = value;
+ return memo;
+ }, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iterator) {
+ var initial = iterator ? _.map(array, iterator) : array;
+ var result = [];
+ _.reduce(initial, function(memo, el, i) {
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
+ memo[memo.length] = el;
+ result[result.length] = array[i];
+ }
+ return memo;
+ }, []);
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays. (Aliased as "intersect" for back-compat.)
+ _.intersection = _.intersect = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.indexOf(other, item) >= 0;
+ });
+ });
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = _.flatten(slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.include(rest, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var args = slice.call(arguments);
+ var length = _.max(_.pluck(args, 'length'));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+ return results;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i, l;
+ if (isSorted) {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+ for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item) {
+ if (array == null) return -1;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+ var i = array.length;
+ while (i--) if (i in array && array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(len);
+
+ while(idx < len) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Binding with arguments is also known as `curry`.
+ // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+ // We check for `func.bind` first, to fail fast when `func` is undefined.
+ _.bind = function bind(func, context) {
+ var bound, args;
+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
+ };
+ };
+
+ // Bind all of an object's methods to that object. Useful for ensuring that
+ // all callbacks defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length == 0) funcs = _.functions(obj);
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time.
+ _.throttle = function(func, wait) {
+ var context, args, timeout, throttling, more;
+ var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
+ return function() {
+ context = this; args = arguments;
+ var later = function() {
+ timeout = null;
+ if (more) func.apply(context, args);
+ whenDone();
+ };
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (throttling) {
+ more = true;
+ } else {
+ func.apply(context, args);
+ }
+ whenDone();
+ throttling = true;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds.
+ _.debounce = function(func, wait) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ func.apply(context, args);
+ };
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ return memo = func.apply(this, arguments);
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return function() {
+ var args = [func].concat(slice.call(arguments, 0));
+ return wrapper.apply(this, args);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = arguments;
+ return function() {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ if (times <= 0) return func();
+ return function() {
+ if (--times < 1) { return func.apply(this, arguments); }
+ };
+ };
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = nativeKeys || function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ return _.map(obj, _.identity);
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function.
+ function eq(a, b, stack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a._chain) a = a._wrapped;
+ if (b._chain) b = b._wrapped;
+ // Invoke a custom `isEqual` method if one is provided.
+ if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
+ if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = stack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (stack[length] == a) return true;
+ }
+ // Add the first object to the stack of traversed objects.
+ stack.push(a);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ // Ensure commutative equality for sparse arrays.
+ if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+ }
+ }
+ } else {
+ // Objects with different constructors are not equivalent.
+ if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ stack.pop();
+ return result;
+ }
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType == 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) == '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Is a given variable an arguments object?
+ _.isArguments = function(obj) {
+ return toString.call(obj) == '[object Arguments]';
+ };
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Is a given value a function?
+ _.isFunction = function(obj) {
+ return toString.call(obj) == '[object Function]';
+ };
+
+ // Is a given value a string?
+ _.isString = function(obj) {
+ return toString.call(obj) == '[object String]';
+ };
+
+ // Is a given value a number?
+ _.isNumber = function(obj) {
+ return toString.call(obj) == '[object Number]';
+ };
+
+ // Is the given value `NaN`?
+ _.isNaN = function(obj) {
+ // `NaN` is the only value for which `===` is not reflexive.
+ return obj !== obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+ };
+
+ // Is a given value a date?
+ _.isDate = function(obj) {
+ return toString.call(obj) == '[object Date]';
+ };
+
+ // Is the given value a regular expression?
+ _.isRegExp = function(obj) {
+ return toString.call(obj) == '[object RegExp]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Has own property?
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Run a function **n** times.
+ _.times = function (n, iterator, context) {
+ for (var i = 0; i < n; i++) iterator.call(context, i);
+ };
+
+ // Escape a string for HTML interpolation.
+ _.escape = function(string) {
+ return (''+string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
+ };
+
+ // Add your own custom functions to the Underscore object, ensuring that
+ // they're correctly added to the OOP wrapper as well.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name){
+ addToWrapper(name, _[name] = obj[name]);
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = idCounter++;
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /.^/;
+
+ // Within an interpolation, evaluation, or escaping, remove HTML escaping
+ // that had been previously added.
+ var unescape = function(code) {
+ return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(str, data) {
+ var c = _.templateSettings;
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+ 'with(obj||{}){__p.push(\'' +
+ str.replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+ .replace(c.escape || noMatch, function(match, code) {
+ return "',_.escape(" + unescape(code) + "),'";
+ })
+ .replace(c.interpolate || noMatch, function(match, code) {
+ return "'," + unescape(code) + ",'";
+ })
+ .replace(c.evaluate || noMatch, function(match, code) {
+ return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
+ })
+ .replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ + "');}return __p.join('');";
+ var func = new Function('obj', '_', tmpl);
+ if (data) return func(data, _);
+ return function(data) {
+ return func.call(this, data, _);
+ };
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // The OOP Wrapper
+ // ---------------
+
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+ var wrapper = function(obj) { this._wrapped = obj; };
+
+ // Expose `wrapper.prototype` as `_.prototype`
+ _.prototype = wrapper.prototype;
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj, chain) {
+ return chain ? _(obj).chain() : obj;
+ };
+
+ // A method to easily add functions to the OOP wrapper.
+ var addToWrapper = function(name, func) {
+ wrapper.prototype[name] = function() {
+ var args = slice.call(arguments);
+ unshift.call(args, this._wrapped);
+ return result(func.apply(_, args), this._chain);
+ };
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ var wrapped = this._wrapped;
+ method.apply(wrapped, arguments);
+ var length = wrapped.length;
+ if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
+ return result(wrapped, this._chain);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ return result(method.apply(this._wrapped, arguments), this._chain);
+ };
+ });
+
+ // Start chaining a wrapped Underscore object.
+ wrapper.prototype.chain = function() {
+ this._chain = true;
+ return this;
+ };
+
+ // Extracts the result from a wrapped and chained object.
+ wrapper.prototype.value = function() {
+ return this._wrapped;
+ };
+
+}).call(this);
diff --git a/_static/underscore.js b/_static/underscore.js
new file mode 100644
index 0000000..5b55f32
--- /dev/null
+++ b/_static/underscore.js
@@ -0,0 +1,31 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
+h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
+b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==
+null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
+function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
+e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
+c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};
+b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
+1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
+b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
+b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
+function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
+u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
+function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
+true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
diff --git a/_static/up-pressed.png b/_static/up-pressed.png
new file mode 100644
index 0000000..99e7210
Binary files /dev/null and b/_static/up-pressed.png differ
diff --git a/_static/up.png b/_static/up.png
new file mode 100644
index 0000000..26de002
Binary files /dev/null and b/_static/up.png differ
diff --git a/_static/virtualenv_prompt.png b/_static/virtualenv_prompt.png
new file mode 100644
index 0000000..68902a6
Binary files /dev/null and b/_static/virtualenv_prompt.png differ
diff --git a/_static/websupport.js b/_static/websupport.js
new file mode 100644
index 0000000..28d65db
--- /dev/null
+++ b/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+ $.fn.autogrow = function() {
+ return this.each(function() {
+ var textarea = this;
+
+ $.fn.autogrow.resize(textarea);
+
+ $(textarea)
+ .focus(function() {
+ textarea.interval = setInterval(function() {
+ $.fn.autogrow.resize(textarea);
+ }, 500);
+ })
+ .blur(function() {
+ clearInterval(textarea.interval);
+ });
+ });
+ };
+
+ $.fn.autogrow.resize = function(textarea) {
+ var lineHeight = parseInt($(textarea).css('line-height'), 10);
+ var lines = textarea.value.split('\n');
+ var columns = textarea.cols;
+ var lineCount = 0;
+ $.each(lines, function() {
+ lineCount += Math.ceil(this.length / columns) || 1;
+ });
+ var height = lineHeight * (lineCount + 1);
+ $(textarea).css('height', height);
+ };
+})(jQuery);
+
+(function($) {
+ var comp, by;
+
+ function init() {
+ initEvents();
+ initComparator();
+ }
+
+ function initEvents() {
+ $(document).on("click", 'a.comment-close', function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.vote', function(event) {
+ event.preventDefault();
+ handleVote($(this));
+ });
+ $(document).on("click", 'a.reply', function(event) {
+ event.preventDefault();
+ openReply($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.close-reply', function(event) {
+ event.preventDefault();
+ closeReply($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.sort-option', function(event) {
+ event.preventDefault();
+ handleReSort($(this));
+ });
+ $(document).on("click", 'a.show-proposal', function(event) {
+ event.preventDefault();
+ showProposal($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.hide-proposal', function(event) {
+ event.preventDefault();
+ hideProposal($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.show-propose-change', function(event) {
+ event.preventDefault();
+ showProposeChange($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.hide-propose-change', function(event) {
+ event.preventDefault();
+ hideProposeChange($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.accept-comment', function(event) {
+ event.preventDefault();
+ acceptComment($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.delete-comment', function(event) {
+ event.preventDefault();
+ deleteComment($(this).attr('id').substring(2));
+ });
+ $(document).on("click", 'a.comment-markup', function(event) {
+ event.preventDefault();
+ toggleCommentMarkupBox($(this).attr('id').substring(2));
+ });
+ }
+
+ /**
+ * Set comp, which is a comparator function used for sorting and
+ * inserting comments into the list.
+ */
+ function setComparator() {
+ // If the first three letters are "asc", sort in ascending order
+ // and remove the prefix.
+ if (by.substring(0,3) == 'asc') {
+ var i = by.substring(3);
+ comp = function(a, b) { return a[i] - b[i]; };
+ } else {
+ // Otherwise sort in descending order.
+ comp = function(a, b) { return b[by] - a[by]; };
+ }
+
+ // Reset link styles and format the selected sort option.
+ $('a.sel').attr('href', '#').removeClass('sel');
+ $('a.by' + by).removeAttr('href').addClass('sel');
+ }
+
+ /**
+ * Create a comp function. If the user has preferences stored in
+ * the sortBy cookie, use those, otherwise use the default.
+ */
+ function initComparator() {
+ by = 'rating'; // Default to sort by rating.
+ // If the sortBy cookie is set, use that instead.
+ if (document.cookie.length > 0) {
+ var start = document.cookie.indexOf('sortBy=');
+ if (start != -1) {
+ start = start + 7;
+ var end = document.cookie.indexOf(";", start);
+ if (end == -1) {
+ end = document.cookie.length;
+ by = unescape(document.cookie.substring(start, end));
+ }
+ }
+ }
+ setComparator();
+ }
+
+ /**
+ * Show a comment div.
+ */
+ function show(id) {
+ $('#ao' + id).hide();
+ $('#ah' + id).show();
+ var context = $.extend({id: id}, opts);
+ var popup = $(renderTemplate(popupTemplate, context)).hide();
+ popup.find('textarea[name="proposal"]').hide();
+ popup.find('a.by' + by).addClass('sel');
+ var form = popup.find('#cf' + id);
+ form.submit(function(event) {
+ event.preventDefault();
+ addComment(form);
+ });
+ $('#s' + id).after(popup);
+ popup.slideDown('fast', function() {
+ getComments(id);
+ });
+ }
+
+ /**
+ * Hide a comment div.
+ */
+ function hide(id) {
+ $('#ah' + id).hide();
+ $('#ao' + id).show();
+ var div = $('#sc' + id);
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ }
+
+ /**
+ * Perform an ajax request to get comments for a node
+ * and insert the comments into the comments tree.
+ */
+ function getComments(id) {
+ $.ajax({
+ type: 'GET',
+ url: opts.getCommentsURL,
+ data: {node: id},
+ success: function(data, textStatus, request) {
+ var ul = $('#cl' + id);
+ var speed = 100;
+ $('#cf' + id)
+ .find('textarea[name="proposal"]')
+ .data('source', data.source);
+
+ if (data.comments.length === 0) {
+ ul.html('No comments yet. ');
+ ul.data('empty', true);
+ } else {
+ // If there are comments, sort them and put them in the list.
+ var comments = sortComments(data.comments);
+ speed = data.comments.length * 100;
+ appendComments(comments, ul);
+ ul.data('empty', false);
+ }
+ $('#cn' + id).slideUp(speed + 200);
+ ul.slideDown(speed);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem retrieving the comments.');
+ },
+ dataType: 'json'
+ });
+ }
+
+ /**
+ * Add a comment via ajax and insert the comment into the comment tree.
+ */
+ function addComment(form) {
+ var node_id = form.find('input[name="node"]').val();
+ var parent_id = form.find('input[name="parent"]').val();
+ var text = form.find('textarea[name="comment"]').val();
+ var proposal = form.find('textarea[name="proposal"]').val();
+
+ if (text == '') {
+ showError('Please enter a comment.');
+ return;
+ }
+
+ // Disable the form that is being submitted.
+ form.find('textarea,input').attr('disabled', 'disabled');
+
+ // Send the comment to the server.
+ $.ajax({
+ type: "POST",
+ url: opts.addCommentURL,
+ dataType: 'json',
+ data: {
+ node: node_id,
+ parent: parent_id,
+ text: text,
+ proposal: proposal
+ },
+ success: function(data, textStatus, error) {
+ // Reset the form.
+ if (node_id) {
+ hideProposeChange(node_id);
+ }
+ form.find('textarea')
+ .val('')
+ .add(form.find('input'))
+ .removeAttr('disabled');
+ var ul = $('#cl' + (node_id || parent_id));
+ if (ul.data('empty')) {
+ $(ul).empty();
+ ul.data('empty', false);
+ }
+ insertComment(data.comment);
+ var ao = $('#ao' + node_id);
+ ao.find('img').attr({'src': opts.commentBrightImage});
+ if (node_id) {
+ // if this was a "root" comment, remove the commenting box
+ // (the user can get it back by reopening the comment popup)
+ $('#ca' + node_id).slideUp();
+ }
+ },
+ error: function(request, textStatus, error) {
+ form.find('textarea,input').removeAttr('disabled');
+ showError('Oops, there was a problem adding the comment.');
+ }
+ });
+ }
+
+ /**
+ * Recursively append comments to the main comment list and children
+ * lists, creating the comment tree.
+ */
+ function appendComments(comments, ul) {
+ $.each(comments, function() {
+ var div = createCommentDiv(this);
+ ul.append($(document.createElement('li')).html(div));
+ appendComments(this.children, div.find('ul.comment-children'));
+ // To avoid stagnating data, don't store the comments children in data.
+ this.children = null;
+ div.data('comment', this);
+ });
+ }
+
+ /**
+ * After adding a new comment, it must be inserted in the correct
+ * location in the comment tree.
+ */
+ function insertComment(comment) {
+ var div = createCommentDiv(comment);
+
+ // To avoid stagnating data, don't store the comments children in data.
+ comment.children = null;
+ div.data('comment', comment);
+
+ var ul = $('#cl' + (comment.node || comment.parent));
+ var siblings = getChildren(ul);
+
+ var li = $(document.createElement('li'));
+ li.hide();
+
+ // Determine where in the parents children list to insert this comment.
+ for(i=0; i < siblings.length; i++) {
+ if (comp(comment, siblings[i]) <= 0) {
+ $('#cd' + siblings[i].id)
+ .parent()
+ .before(li.html(div));
+ li.slideDown('fast');
+ return;
+ }
+ }
+
+ // If we get here, this comment rates lower than all the others,
+ // or it is the only comment in the list.
+ ul.append(li.html(div));
+ li.slideDown('fast');
+ }
+
+ function acceptComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.acceptCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ $('#cm' + id).fadeOut('fast');
+ $('#cd' + id).removeClass('moderate');
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem accepting the comment.');
+ }
+ });
+ }
+
+ function deleteComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.deleteCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ var div = $('#cd' + id);
+ if (data == 'delete') {
+ // Moderator mode: remove the comment and all children immediately
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ return;
+ }
+ // User mode: only mark the comment as deleted
+ div
+ .find('span.user-id:first')
+ .text('[deleted]').end()
+ .find('div.comment-text:first')
+ .text('[deleted]').end()
+ .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+ ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+ .remove();
+ var comment = div.data('comment');
+ comment.username = '[deleted]';
+ comment.text = '[deleted]';
+ div.data('comment', comment);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem deleting the comment.');
+ }
+ });
+ }
+
+ function showProposal(id) {
+ $('#sp' + id).hide();
+ $('#hp' + id).show();
+ $('#pr' + id).slideDown('fast');
+ }
+
+ function hideProposal(id) {
+ $('#hp' + id).hide();
+ $('#sp' + id).show();
+ $('#pr' + id).slideUp('fast');
+ }
+
+ function showProposeChange(id) {
+ $('#pc' + id).hide();
+ $('#hc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val(textarea.data('source'));
+ $.fn.autogrow.resize(textarea[0]);
+ textarea.slideDown('fast');
+ }
+
+ function hideProposeChange(id) {
+ $('#hc' + id).hide();
+ $('#pc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val('').removeAttr('disabled');
+ textarea.slideUp('fast');
+ }
+
+ function toggleCommentMarkupBox(id) {
+ $('#mb' + id).toggle();
+ }
+
+ /** Handle when the user clicks on a sort by link. */
+ function handleReSort(link) {
+ var classes = link.attr('class').split(/\s+/);
+ for (var i=0; iThank you! Your comment will show up '
+ + 'once it is has been approved by a moderator.');
+ }
+ // Prettify the comment rating.
+ comment.pretty_rating = comment.rating + ' point' +
+ (comment.rating == 1 ? '' : 's');
+ // Make a class (for displaying not yet moderated comments differently)
+ comment.css_class = comment.displayed ? '' : ' moderate';
+ // Create a div for this comment.
+ var context = $.extend({}, opts, comment);
+ var div = $(renderTemplate(commentTemplate, context));
+
+ // If the user has voted on this comment, highlight the correct arrow.
+ if (comment.vote) {
+ var direction = (comment.vote == 1) ? 'u' : 'd';
+ div.find('#' + direction + 'v' + comment.id).hide();
+ div.find('#' + direction + 'u' + comment.id).show();
+ }
+
+ if (opts.moderator || comment.text != '[deleted]') {
+ div.find('a.reply').show();
+ if (comment.proposal_diff)
+ div.find('#sp' + comment.id).show();
+ if (opts.moderator && !comment.displayed)
+ div.find('#cm' + comment.id).show();
+ if (opts.moderator || (opts.username == comment.username))
+ div.find('#dc' + comment.id).show();
+ }
+ return div;
+ }
+
+ /**
+ * A simple template renderer. Placeholders such as <%id%> are replaced
+ * by context['id'] with items being escaped. Placeholders such as <#id#>
+ * are not escaped.
+ */
+ function renderTemplate(template, context) {
+ var esc = $(document.createElement('div'));
+
+ function handle(ph, escape) {
+ var cur = context;
+ $.each(ph.split('.'), function() {
+ cur = cur[this];
+ });
+ return escape ? esc.text(cur || "").html() : cur;
+ }
+
+ return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+ return handle(arguments[2], arguments[1] == '%' ? true : false);
+ });
+ }
+
+ /** Flash an error message briefly. */
+ function showError(message) {
+ $(document.createElement('div')).attr({'class': 'popup-error'})
+ .append($(document.createElement('div'))
+ .attr({'class': 'error-message'}).text(message))
+ .appendTo('body')
+ .fadeIn("slow")
+ .delay(2000)
+ .fadeOut("slow");
+ }
+
+ /** Add a link the user uses to open the comments popup. */
+ $.fn.comment = function() {
+ return this.each(function() {
+ var id = $(this).attr('id').substring(1);
+ var count = COMMENT_METADATA[id];
+ var title = count + ' comment' + (count == 1 ? '' : 's');
+ var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+ var addcls = count == 0 ? ' nocomment' : '';
+ $(this)
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-open' + addcls,
+ id: 'ao' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: image,
+ alt: 'comment',
+ title: title
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ show($(this).attr('id').substring(2));
+ })
+ )
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-close hidden',
+ id: 'ah' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: opts.closeCommentImage,
+ alt: 'close',
+ title: 'close'
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ })
+ );
+ });
+ };
+
+ var opts = {
+ processVoteURL: '/_process_vote',
+ addCommentURL: '/_add_comment',
+ getCommentsURL: '/_get_comments',
+ acceptCommentURL: '/_accept_comment',
+ deleteCommentURL: '/_delete_comment',
+ commentImage: '/static/_static/comment.png',
+ closeCommentImage: '/static/_static/comment-close.png',
+ loadingImage: '/static/_static/ajax-loader.gif',
+ commentBrightImage: '/static/_static/comment-bright.png',
+ upArrow: '/static/_static/up.png',
+ downArrow: '/static/_static/down.png',
+ upArrowPressed: '/static/_static/up-pressed.png',
+ downArrowPressed: '/static/_static/down-pressed.png',
+ voting: false,
+ moderator: false
+ };
+
+ if (typeof COMMENT_OPTIONS != "undefined") {
+ opts = jQuery.extend(opts, COMMENT_OPTIONS);
+ }
+
+ var popupTemplate = '\
+ ';
+
+ var commentTemplate = '\
+ \
+ ';
+
+ var replyTemplate = '\
+ \
+ \
+ \
+
\
+ ';
+
+ $(document).ready(function() {
+ init();
+ });
+})(jQuery);
+
+$(document).ready(function() {
+ // add comment anchors for all paragraphs that are commentable
+ $('.sphinx-has-comment').comment();
+
+ // highlight search words in search results
+ $("div.context").each(function() {
+ var params = $.getQueryParameters();
+ var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+ var result = $(this);
+ $.each(terms, function() {
+ result.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ });
+
+ // directly open comment window if requested
+ var anchor = document.location.hash;
+ if (anchor.substring(0, 9) == '#comment-') {
+ $('#ao' + anchor.substring(9)).click();
+ document.location.hash = '#s' + anchor.substring(9);
+ }
+});
diff --git a/exercises/circle_class.html b/exercises/circle_class.html
new file mode 100644
index 0000000..8c6a670
--- /dev/null
+++ b/exercises/circle_class.html
@@ -0,0 +1,433 @@
+
+
+
+
+
+
+
+
+
+
+ Circle Class Excercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Circle Class Excercise
+
+
Circle Class
+
+
Goal:
+
The goal is to create a class that represents a simple circle.
+
A Circle can be defined by either specifying the radius or the diameter,
+and the user can query the circle for either its radius or diameter.
+
Other abilities of a Circle instance:
+
+
+Compute the circle’s area
+Print the circle and get something nice
+Be able to add two circles together
+Be able to compare two circles to see which is bigger
+Be able to compare to see if there are equal
+(follows from above) be able to put them in a list and sort them
+
+
+
You will use:
+
+
+properties
+a classmethod
+a define a bunch of “special methods”
+
+
+
+
+
General Instructions:
+
+For each step, write a couple of unit tests that test the new features.
+Run these tests (and they will fail the first time)
+Add the code required for your tests to pass.
+
+
+
+
Step 1:
+
create class called Circle – it’s signature should look like:
+
+
The radius is a required parameter (can’t have a circle without one!)
+
the resulting circle should have a attribute for the radius:
+
+
So you can do:
+
>> c = Circle ( 4 )
+>> print c . radius
+4
+
+
+
Remember: tests first!
+
+
+
Step 2:
+
Add a “diameter” property, so the user can get the diameter of the circle:
+
>> c = Circle ( 4 )
+>> print c . diameter
+8
+
+
+
+
+
Step 3:
+
Set up the diameter property so that the user can set the diameter of the circle:
+
>> c = Circle ( 4 )
+>> c . diameter = 2
+>> print c . diameter
+2
+>> print c . radius
+1
+
+
+
NOTE that the radius has changed!
+
+
+
Step 4:
+
Add an area property so the user can get the area of the circle:
+
>> c = Circle ( 2 )
+>> print c . area
+12.566370
+
+
+
(pi can be found in the math module)
+
The user should not be able to set the area:
+
>> c = Circle ( 2 )
+>> c . area = 42
+AttributeError
+
+
+
+
+
Step 5:
+
Add an “alternate constructor” that lets the user create a Circle directly
+with the diameter:
+
>> c = Circle . from_diameter ( 8 )
+>> print c . diameter
+8
+>> print c . radius
+4
+
+
+
+
+
Step 6:
+
Add __str__ and __repr__ methods to your Circle class.
+
Now you can print it:
+
In [2]: c = Circle ( 4 )
+
+In [3]: print c
+Circle with radius: 4.000000
+
+In [4]: repr ( c )
+Out[4]: 'Circle(4)'
+
+In [5]: d = eval ( repr ( c ))
+
+In [6]: d
+Out[6]: Circle(4)
+
+
+
+
+
Step 7:
+
Add some of the numeric protocol to your Circle:
+
You should be able to add two circles:
+
In [7]: c1 = Circle ( 2 )
+
+In [8]: c2 = Circle ( 4 )
+
+In [9]: c1 + c2
+Out[9]: Circle(6)
+
+
+
and multiply one times a number:
+
In [16]: c2 * 3
+Out[16]: Circle(12)
+
+
+
(what happens with 3 * c2 ? – can you fix that?)
+
+
+
Step 8:
+
add the ability to compare two circles:
+
In [10]: c1 > c2
+Out[10]: False
+
+In [11]: c1 < c2
+Out[11]: True
+
+In [12]: c1 == c2
+Out[12]: False
+
+In [13]: c3 = Circle ( 4 )
+
+In [14]: c2 == c3
+Out[14]: True
+
+
+
Once the comparing is done, you should be able to sort a list of circles:
+
In [18]: print circles
+[Circle(6), Circle(7), Circle(8), Circle(4), Circle(0), Circle(2), Circle(3), Circle(5), Circle(9), Circle(1)]
+
+In [19]: circl
+circle circle.py circle.pyc circles
+
+In [19]: circles . sort ()
+
+In [20]: print circles
+[Circle(0), Circle(1), Circle(2), Circle(3), Circle(4), Circle(5), Circle(6), Circle(7), Circle(8), Circle(9)]
+
+
+
NOTE: make sure to write unit tests for all of this! Ideally before writing the code.
+
+
+
Step 8: Optional Features:
+
+See if you can make “reflected” numerics do the right thing:
+
+
a_circle * 3 == 3 * a_circle
+
+
+
+What else makes sense: division? others?
+Add the “augmented assignment” operators, where they make sense:
+
+
a_circle += another_circle
+
+a_circle *= 2
+
+
+
+look through all the “magic methods” and see what makes sense for circles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/comprehensions_lab.html b/exercises/comprehensions_lab.html
new file mode 100644
index 0000000..700db92
--- /dev/null
+++ b/exercises/comprehensions_lab.html
@@ -0,0 +1,423 @@
+
+
+
+
+
+
+
+
+
+
+ Comprehensions Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Comprehensions Lab
+
+
Playing with Comprehensions
+
Goal:
+
Getting Familiar with list, set and dict comprehensions
+
+
List comprehensions
+
Note: this is a bit of a “backwards” exercise –
+we show you code, you figure out what it does.
+
As a result, not much to submit – don’t worry about it – you’ll have
+a chance to use these in other exercises.
+
>>> feast = [ 'lambs' , 'sloths' , 'orangutans' ,
+ 'breakfast cereals', 'fruit bats']
+
+>>> comprehension = [ delicacy . capitalize () for delicacy in feast ]
+
+
+
What is the output of:
+
>>> comprehension [ 0 ]
+???
+
+>>> comprehension [ 2 ]
+???
+
+
+
(figure it out before you try it)
+
+
+
Filtering lists with list comprehensions
+
>>> feast = [ 'spam' , 'sloths' , 'orangutans' , 'breakfast cereals' ,
+ 'fruit bats']
+
+>>> comp = [ delicacy for delicacy in feast if len ( delicacy ) > 6 ]
+
+
+
What is the output of:
+
>>> len ( feast )
+???
+
+>>> len ( comp )
+???
+
+
+
(figure it out first!)
+
+
+
Unpacking tuples in list comprehensions
+
>>> list_of_tuples = [( 1 , 'lumberjack' ), ( 2 , 'inquisition' ), ( 4 , 'spam' )]
+
+>>> comprehension = [ skit * number for number , skit in list_of_tuples ]
+
+
+
What is the output of:
+
>>> comprehension [ 0 ]
+???
+
+>>> len ( comprehension [ 2 ])
+???
+
+
+
+
+
Double list comprehensions
+
>>> eggs = [ 'poached egg' , 'fried egg' ]
+
+>>> meats = [ 'lite spam' , 'ham spam' , 'fried spam' ]
+
+>>> comprehension = \
+[ '{0} and {1}'.format(egg, meat) for egg in eggs for meat in meats]
+
+
+
What is the output of:
+
>>> len ( comprehension )
+???
+
+>>> comprehension [ 0 ]
+???
+
+
+
+
+
Set comprehensions
+
>>> comprehension = { x for x in 'aabbbcccc' }
+
+
+
What is the output of:
+
+
+
+
Dictionary comprehensions
+
>>> dict_of_weapons = { 'first' : 'fear' ,
+ 'second': 'surprise',
+ 'third':'ruthless efficiency',
+ 'forth':'fanatical devotion',
+ 'fifth': None}
+>>> dict_comprehension = \
+{ k.upper(): weapon for k, weapon in dict_of_weapons.iteritems() if weapon}
+
+
+
What is the output of:
+
>>> 'first' in dict_comprehension
+???
+>>> 'FIRST' in dict_comprehension
+???
+>>> len ( dict_of_weapons )
+???
+>>> len ( dict_comprehension )
+???
+
+
+
+
+
+
Count Even Numbers
+
Use test-driven development!
+
This is from CodingBat “count_evens” (http://codingbat.com/prob/p189616 )
+
Using a list comprehension , return the number of even integers in the given array.
+
Note: the % “mod” operator computes the remainder, e.g. 5 % 2 is 1.
+
count_evens ([ 2 , 1 , 2 , 3 , 4 ]) == 3
+
+count_evens ([ 2 , 2 , 0 ]) == 3
+
+count_evens ([ 1 , 3 , 5 ]) == 0
+
+
+
def count_evens ( nums ):
+ one_line_comprehension_here
+
+
+
+
+
dict and set comprehensions
+
Let’s revisiting the dict/set lab – see how much you can do with
+comprehensions instead.
+
(Dictionary and Set Lab )
+
Specifically, look at these:
+
First a slightly bigger, more interesting (or at least bigger..) dict:
+
food_prefs = { "name" : "Chris" ,
+ "city" : "Seattle" ,
+ "cake" : "chocolate" ,
+ "fruit" : "mango" ,
+ "salad" : "greek" ,
+ "pasta" : "lasagna" }
+
+
+
1. Print the dict by passing it to a string format method, so that you
+get something like:
+
+
+“Chris is from Seattle, and he likes chocolate cake, mango fruit,
+greek salad, and lasagna pasta”
+
+
+
2. Using a list comprehension, build a dictionary of numbers from zero
+to fifteen and the hexadecimal equivalent (string is fine).
+(the hex() function gives you the hexidecimal representation of a number.)
+
+Do the previous entirely with a dict comprehension – should be a one-liner
+
+
4. Using the dictionary from item 1: Make a dictionary using the same
+keys but with the number of ‘a’s in each value. You can do this either
+by editing the dict in place, or making a new one. If you edit in place,
+make a copy first!
+
5. Create sets s2, s3 and s4 that contain numbers from zero through twenty,
+divisible 2, 3 and 4.
+
+
+Do this with one set comprehension for each set.
+What if you had a lot more than 3? – Don’t Repeat Yourself (DRY)
+create a sequence that holds all three sets
+loop through that sequence to build the sets up – so no repeated code.
+
+
+Extra credit: do it all as a one-liner by nesting a set comprehension
+inside a list comprehension. (OK, that may be getting carried away!)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/dict_lab.html b/exercises/dict_lab.html
new file mode 100644
index 0000000..e8e6873
--- /dev/null
+++ b/exercises/dict_lab.html
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+
+
+
+
+ Dictionary and Set Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Dictionary and Set Lab
+
+
Learning about dictionaries and sets
+
+
Goal:
+
Learn the basic ins and outs of Python dictionaries and sets.
+
+
+
Procedure
+
In your student dir in the IntroPython2015 repo, create a session04 dir and put in a new dict_lab.py file.
+
The file should be an executable python script. That is to say that one
+should be able to run the script directly like so:
+
+
(At least on OS-X and Linux)
+
– you do that with this command:
+
+
(The +x means make this executable)
+
Add the file to your clone of the repository and commit changes frequently
+while working on the following tasks. When you are done, push your changes to
+GitHub and issue a pull request.
+
(if you are struggling with git – just write the code for now)
+
When the script is run, it should accomplish the following four series of
+actions:
+
+Create a dictionary containing “name”, “city”, and “cake” for “Chris” from “Seattle” who likes “Chocolate”.
+Display the dictionary.
+Delete the entry for “cake”.
+Display the dictionary.
+Add an entry for “fruit” with “Mango” and display the dictionary.
+Display the dictionary keys.
+Display the dictionary values.
+Display whether or not “cake” is a key in the dictionary (i.e. False) (now).
+Display whether or not “Mango” is a value in the dictionary (i.e. True).
+
+
+
+
+Using the dictionary from item 1: Make a dictionary using the same keys but
+with the number of ‘t’s in each value.
+
+
+Create sets s2, s3 and s4 that contain numbers from zero through twenty,
+divisible 2, 3 and 4.
+Display the sets.
+Display if s3 is a subset of s2 (False)
+and if s4 is a subset of s2 (True).
+
+
+Create a set with the letters in ‘Python’ and add ‘i’ to the set.
+Create a frozenset with the letters in ‘marathon’
+display the union and intersection of the two sets.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/exceptions_lab.html b/exercises/exceptions_lab.html
new file mode 100644
index 0000000..c16bf6e
--- /dev/null
+++ b/exercises/exceptions_lab.html
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+
+
+
+ Exceptions Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Exceptions Lab
+
+
Learning Exceptions
+
Just a little bit for the basics.
+
+
Exceptions Lab
+
Improving input
+
+The input() function can generate two exceptions: EOFError or KeyboardInterrupt on end-of-file(EOF) or canceled input.
+Create a wrapper function, perhaps safe_input() that returns None rather rather than raising these exceptions, when the user enters ^C for Keyboard Interrupt, or ^D (^Z on Windows) for End Of File.
+Update your mailroom program to use exceptions to handle malformed numeric input.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/fib_and_lucas.html b/exercises/fib_and_lucas.html
new file mode 100644
index 0000000..71264b6
--- /dev/null
+++ b/exercises/fib_and_lucas.html
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+
+
+
+
+ Fibonacci Series Exercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fibonacci Series Exercise
+
+
Computing the Fibonacci and Lucas Series
+
+
Goal:
+
The Fibonacci Series is a numeric series starting with the integers 0 and 1.
+
In this series, the next integer is determined by summing the previous two.
+
This gives us:
+
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , ...
+
+
+
We will write a function that computes this series – then generalize it.
+
+
+
Step 1
+
+Create a new module series.py in the session02 folder in your student folder.
+In it, add a function called fibonacci .
+The function should have one parameter n .
+The function should return the nth value in the fibonacci series.
+
+
+Ensure that your function has a well-formed docstring
+
+
Note that the fibinacci series is naturally recusive – the value is
+defined by previous values:
+
fib(n) = fib(n-2) + fib(n-1)
+
+
+
Lucas Numbers
+
The Lucas Numbers are a related series of integers that start with the
+values 2 and 1 rather than 0 and 1. The resulting series looks like this:
+
2 , 1 , 3 , 4 , 7 , 11 , 18 , 29 , ...
+
+
+
In your series.py module, add a new function lucas that returns the
+nth value in the lucas numbers series.
+
Ensure that your function has a well-formed docstring
+
+
+
Generalizing
+
Both the fibonacci series and the lucas numbers are based on an identical
+formula.
+
Add a third function called sum_series with one required parameter and two
+optional parameters. The required parameter will determine which element in the
+series to print. The two optional parameters will have default values of 0 and
+1 and will determine the first two values for the series to be produced.
+
Calling this function with no optional parameters will produce numbers from the
+fibonacci series . Calling it with the optional arguments 2 and 1 will
+produce values from the lucas numbers . Other values for the optional
+parameters will produce other series.
+
Ensure that your function has a well-formed docstring
+
+
+
Tests...
+
Add a block of code to the end of your series.py
+module. Use the block to write a series of assert statements that
+demonstrate that your three functions work properly.
+
Use comments in this block to inform the observer what your tests do.
+
Add your new module to your git clone and commit frequently while working on
+your implementation. Include good commit messages that explain concisely both
+what you are doing and why .
+
When you are finished, push your changes to your fork of the class repository
+in GitHub and make a pull request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/fizz_buzz.html b/exercises/fizz_buzz.html
new file mode 100644
index 0000000..6e0db32
--- /dev/null
+++ b/exercises/fizz_buzz.html
@@ -0,0 +1,290 @@
+
+
+
+
+
+
+
+
+
+
+ Fizz Buzz Exercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fizz Buzz Exercise
+
+
The Classic Fizz Buzz Problem
+
Fizz Buzz is a classic simple problem in computer science.
+
Often used as an exercise in interviews for programmers.
+
Apparently a LOT of people applying for jobs as profesional developers can’t do this in an interview:
+
(http://c2.com/cgi/wiki?FizzBuzzTest )
+
Now that I’ve psyched you out – it’s really pretty straightforward.
+
+
Goal:
+
+Write a program that prints the numbers from 1 to 100 inclusive.
+But for multiples of three print “Fizz” instead of the number
+For the multiples of five print “Buzz”.
+For numbers which are multiples of both three and five print “FizzBuzz” instead.
+
+
+
+
Hint:
+
+Look up the % operator. What do these do?
+10 % 7 == 3
+14 % 7 == 0
+
+
+
+
(try that in iPython)
+
+Do try to write it without looking it up – there are a million nifty solutions posted on the web.
+
+
+
+
Results:
+
Running your code should result in something like:
+
1
+2
+Fizz
+4
+Buzz
+Fizz
+7
+8
+Fizz
+Buzz
+11
+Fizz
+13
+14
+FizzBuzz
+16
+....
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/functions_as_args.html b/exercises/functions_as_args.html
new file mode 100644
index 0000000..e451bf2
--- /dev/null
+++ b/exercises/functions_as_args.html
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+ Passing functions to functions — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Passing functions to functions
+
+
Goal
+
Practice passing functions as arguments to other functions
+
+
+
Scenario
+
You are a game designer working on a scoring system. You have several different categories of weapons: hand weapons, guns, and flower power weapons. In each of these categories of weapon there is a small, a medium and a large weapon. Your task is to write a scoring function that takes two arguments and returns an integer which represets the score value of the specified size of the specified weapon.
+
The first argument to the scoring function is itself a function that represents the cagetory of weapon, be it a hand weapon, a gun or a weapon of the dreaded flower power variety.
+
The second argument to the scoring function is one of three strings: small, medium or large.
+
The score for weapons across the various categories follow the fibonacci scale such that acceptance tests for the scoring function follow the following pattern. Keep in mind that you need not do any math to get the tests to pass.
+
def test_scoring ():
+ assert score ( hand_weapon , 'small' ) == 1
+ assert score ( hand_weapon , 'medium' ) == 2
+ assert score ( hand_weapon , 'large' ) == 3
+ assert score ( gun , 'small' ) == 5
+ assert score ( gun , 'medium' ) == 8
+ assert score ( gun , 'large' ) == 13
+ assert score ( flower_power , 'small' ) == 21
+ assert score ( flower_power , 'medium' ) == 34
+ assert score ( flower_power , 'large' ) == 55
+
+
+
Your task is to fill out the following functions.
+
def hand_weapon ():
+ pass
+
+def gun ():
+ pass
+
+def flower_power ():
+ pass
+
+def score ( weapon_type , weapon_size ):
+ pass
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/grid_printer.html b/exercises/grid_printer.html
new file mode 100644
index 0000000..89ca160
--- /dev/null
+++ b/exercises/grid_printer.html
@@ -0,0 +1,407 @@
+
+
+
+
+
+
+
+
+
+
+ Grid Printer Exercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Grid Printer Exercise
+
+
Printing a Grid
+
(adapted from Downey, “Think Python”, ex. 3.5)
+
+
Goal:
+
Write a function that draws a grid like the following:
+
+ - - - - + - - - - +
+| | |
+| | |
+| | |
+| | |
++ - - - - + - - - - +
+| | |
+| | |
+| | |
+| | |
++ - - - - + - - - - +
+
+
+
+
+
hints
+
A couple features to get you started...
+
+
+
printing
+
To print more than one value on a line, you can pass multiple names into the print function:
+
+
If you don’t want a newline after something is printed, you tell python what you want the print to end with like so:
+
print ( '+' , end = ' ' )
+print ( '-' )
+
+
+
The output of these statements is '+ -' .
+
(that end parameter defaults to a newline...)
+
A print function with no arguments ends the current line and goes to the next line:
+
+
+
+
Simple string manipulation:
+
You can put two strings together with the plus operator:
+
In [20]: "this" + "that"
+Out[20]: 'thisthat
+
+
+
Particularly useful if they have been assigned names:
+
In [21]: plus = '+'
+
+In [22]: minus = '-'
+
+In [23]: plus + minus + plus
+Out[23]: '+-+'
+
+
+
Note that you can string any number of operations together in an expression.
+
You can also multiply strings:
+
In [24]: '+' * 10
+Out[24]: '++++++++++'
+
+
+
And combine that with plus in a complex expression:
+
In [29]: first_name = 'Chris'
+
+In [30]: last_name = 'Barker'
+
+In [31]: 5 * '*' + first_name + ' ' + last_name + 5 * '*'
+Out[31]: '*****Chris Barker*****'
+
+
+
Note that there are better ways to build up complex strings – we’ll get to that later.
+
Now you’ve got what you need to print that grid...
+
+
+
+
Part 2
+
Making it more general
+
+
Make it a function
+
One of the points of writing functions is so you can write code that does similar things, but customized to input parameters. So what if we want to be able to print that grid at an arbitrary size?
+
Write a function print_grid(n) that takes one integer argument
+and prints a grid just like before, BUT the size of the
+grid is given by the argument.
+
For example, print_grid(11) prints the grid in the above picture.
+
print_grid(3) would print a smaller grid:
+
+ - + - +
+| | |
++ - + - +
+| | |
++ - + - +
+
+
+
print_grid(15) prints a larger grid:
+
+ - - - - - - - + - - - - - - - +
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
++ - - - - - - - + - - - - - - - +
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
+| | |
++ - - - - - - - + - - - - - - - +
+
+
+
This problem is underspecified. Do something reasonable.
+
+
+
+
Part 3:
+
Even more general...
+
+
A function with two parameters
+
Write a function that draws a similar grid with a specified number of rows and three columns.
+
for example, print_grid2(3,4) results in:
+
+ - - - - + - - - - + - - - - +
+| | | |
+| | | |
+| | | |
+| | | |
++ - - - - + - - - - + - - - - +
+| | | |
+| | | |
+| | | |
+| | | |
++ - - - - + - - - - + - - - - +
+| | | |
+| | | |
+| | | |
+| | | |
++ - - - - + - - - - + - - - - +
+
+
+
What to do about rounding? – you decide.
+
Another example: print_grid2(5,3) :
+
+ - - - + - - - + - - - + - - - + - - - +
+| | | | | |
+| | | | | |
+| | | | | |
++ - - - + - - - + - - - + - - - + - - - +
+| | | | | |
+| | | | | |
+| | | | | |
++ - - - + - - - + - - - + - - - + - - - +
+| | | | | |
+| | | | | |
+| | | | | |
++ - - - + - - - + - - - + - - - + - - - +
+| | | | | |
+| | | | | |
+| | | | | |
++ - - - + - - - + - - - + - - - + - - - +
+| | | | | |
+| | | | | |
+| | | | | |
++ - - - + - - - + - - - + - - - + - - - +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/html_renderer.html b/exercises/html_renderer.html
new file mode 100644
index 0000000..b7ccf03
--- /dev/null
+++ b/exercises/html_renderer.html
@@ -0,0 +1,572 @@
+
+
+
+
+
+
+
+
+
+
+ HTML Renderer Exercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
HTML Renderer Exercise
+
+
HTML Renderer
+
Ever need to generate some HTML?
+
And not want to write all those tags yourself?
+
+
Goal:
+
The goal is to create a set of classes to render html pages – in a “pretty printed” way.
+
i.e. nicely indented and human readable.
+
We’ll try to get to all the features required to render:
+
sample_html.html
+
Take a look at it with “view source” in your browser – or open in a text editor – it’s also in the Examples dir.
+
If you don’t know html – just look at the example and copy that....
+
The exercise is broken down into a number of steps – each requiring a few more OO concepts in Python.
+
+
+
General Instructions:
+
For each step, add the required functionality. There is example code to run your code for each step in: Examples\session07\run_html_render.py
+
Name your file: html_render.py – so it can be imported by run_html_render.py
+
You should be able to run that code at each step, uncommenting each new step in run_html_render.py as you go.
+
It builds up an html tree, and then calls the render() method of your element to render the page.
+
It uses a cStringIO object (like a file, but in memory) to render to memory, then dumps it to the console, and writes a file. Take a look at the code at the end to make sure you understand it.
+
The html generated at each step will be in the files: test_html_ouput?.html
+
At each step, your results should look similar that those (maybe not identical...)
+
+
+
Unit tests
+
Use “test driven development”:
+
In addition to checking if the output is what you expect with the running script – you should also write unit tests as you go.
+
Each new line of code should have a test that will run it – before you write that code.
+
That is:
+
+
+write a test that exercises the next step in your process
+run the tests – the new test will fail
+write your code...
+run the tests. If it still fails, go back to step 3...
+
+
+
+
+
Step 1:
+
Create an Element class for rendering an html element (xml element).
+
It should have class attributes for the tag name (“html” first) and the indentation (spaces to indent for pretty printing)
+
The initializer signature should look like
+
+
where content is expected to be a string
+
It should have an append method that can add another string to the content.
+
So your class will need a way to store the content in a way that you can keep adding more to it.
+
It should have a render(file_out, ind = "") method that renders the tag and the strings in the content.
+
file_out could be any file-like object ( i.e. have a write() method ).
+
ind is a string with the indentation level in it: the amount that the tag should be indented for pretty printing.
+
+
+This is a little tricky: ind will be the amount that this element should be indented already. It will be from zero (an empty string) to a lot of spaces, depending on how deep it is in the tree.
+
+
+
The amount of each level of indentation should be set by the class attribute: indent
+
NOTE: don’t worry too much about indentation at this stage – the primary goal is to get proper, compliant html. i.e. the opening and closing tags rendered correctly. Worry about cleaning up the indentation once you’ve got that working.
+
So this render() method takes a file-like object, and calls its write() method, writing the html for a tag. Something like:
+
<html>
+ Some content. Some more content.
+<\html>
+
+
+
You should now be able to render an html tag with text in it as contents.
+
See: step 1. in run_html_render.py
+
+
+
Step 2:
+
Create a couple subclasses of Element , for each of <html> , <body> , and <p> tags. All you should have to do is override the tag class attribute (you may need to add a tag class attribute to the Element class first, if you haven’t already).
+
Now you can render a few different types of element.
+
Extend the Element.render() method so that it can render other elements inside the tag in addition to strings. Simple recursion should do it. i.e. it can call the render() method of the elements it contains. You’ll need to be smart about setting the ind optional parameter – so that the nested elements get indented correctly. (again, this is a secondary concern...)
+
Figure out a way to deal with the fact that the contained elements could be either simple strings or Element s with render methods (there are a few ways to handle that...). Think about “Duck Typing” and EAFP. See the section ‘Notes on handling “duck typing”’ and the end of the Exercise for more.
+
You should now be able to render a basic web page with an <html> tag around the whole thing, a <body> tag inside, and multiple <p> tags inside that, with text inside that. And all indented nicely.
+
See test_html_output2.html
+
NOTE: when you run step 2 in run_html_render.py , you will want to comment out step 1 – that way you’ll only get one set of output.
+
+
+
Step 3:
+
Create a <head> element – a simple subclass.
+
Create a OneLineTag subclass of Element :
+
+
Create a Title subclass of OneLineTag class for the title.
+
You should now be able to render an html doc with a head element, with a
+title element in that, and a body element with some <P> elements and some text.
+
See test_html_output3.html
+
+
+
Step 4:
+
Extend the Element class to accept a set of attributes as keywords to the
+constructor, e.g. run_html_render.py
+
Element ( "some text content" , id = "TheList" , style = "line-height:200%" )
+
+
+
html elements can take essentially any attributes – so you can’t hard-code these particular ones. ( remember **kwargs ? )
+
The render method will need to be extended to render the attributes properly.
+
You can now render some <p> tags (and others) with attributes
+
See test_html_output4.html
+
+
+
Step 5:
+
Create a SelfClosingTag subclass of Element, to render tags like:
+
<hr /> and <br /> (horizontal rule and line break).
+
+
+
You will need to override the render method to render just the one tag and
+attributes, if any.
+
Create a couple subclasses of SelfClosingTag for and <hr /> and <br />
+
Note that you now have a couple render methods – is there repeated code in them?
+
Can you refactor the common parts into a separate method that all the render methods can call?
+
See test_html_output5.html
+
+
+
Step 6:
+
Create an A class for an anchor (link) element. Its constructor should look like:
+
+
where link is the link, and content is what you see. It can be called like so:
+
A ( "http://google.com" , "link to google" )
+
+
+
You should be able to subclass from Element , and only override the __init__ — Calling the Element __init__ from the A __init__
+
You can now add a link to your web page.
+
See test_html_output6.html
+
+
+
Step 7:
+
Create Ul class for an unordered list (really simple subclass of Element )
+
Create Li class for an element in a list (also really simple)
+
Add a list to your web page.
+
Create a Header class – this one should take an integer argument for the
+header level. i.e <h1>, <h2>, <h3>, called like
+
H ( 2 , "The text of the header" )
+
+
+
for an <h2> header
+
It can subclass from OneLineTag – overriding the __init__ , then calling the superclass __init__
+
See test_html_output7.html
+
+
+
Step 8:
+
Update the Html element class to render the “<!DOCTYPE html>” tag at the head of the page, before the html element.
+
You can do this by subclassing Element , overriding render() , but then calling the Element render from the new render.
+
Create a subclass of SelfClosingTag for <meta charset="UTF-8" /> (like for <hr /> and <br /> and add the meta element to the beginning of the head element to give your document an encoding.
+
The doctype and encoding are HTML 5 and you can check this at: http://validator.w3.org .
+
You now have a pretty full-featured html renderer – play with it, add some
+new tags, etc....
+
See test_html_output8.html
+
+
+
+
Notes on handling “duck typing”
+
In this exercise, we need to deal with the fact that XML (and thus HTML) allows either plain text or other tags to be the content of a tag. Our code also needs to handle the fact that there are two possible types that we need to be able to render.
+
There are two primary ways to address this (and multiple ways to actually write the code for each of these).
+
+Make sure that the content only has renderable objects in it.
+Make sure the render() method can handle either type on the fly
+
+
The difference is where you handle the multiple types – in the render method itself, or ahead of time.
+
+
The ahead of time option:
+
You can handle it ahead of time by creating a simple object that wraps a string and gives it a render method. As simple as:
+
class TextWrapper :
+ """
+ A simple wrapper that creates a class with a render method
+ for simple text
+ """
+ def __init__ ( self , text ):
+ self . text = text
+
+ def render ( self , file_out , current_ind = "" ):
+ file_out . write ( current_ind + self . text )
+
+
+
You could require your users to use the wrapper, so instead of just appending a string, they would do:
+
an_element . append ( TextWRapper ( "the string they want to add" ))
+
+
+
But this is not very Pythonic style – it’s OO heavy. Strings for text are so common you want to be able to simply use them:
+
an_element . append ( "the string they want to add" )
+
+
+
So much easier.
+
To accomplish this, you can update the append() method to put this wrapper around plain strings when somethign new is added.
+
+
+
Checking if it’s the right type
+
How do you decide if the wrapper is required?
+
Checking it it’s an instance of Element:
+
You could check and see if the object being appended is an Element:
+
if isinstance ( content , Element ):
+ self . content . append ( content )
+else :
+ self . content . append ( TextWrapper ( content ))
+
+
+
This would work well, but closes the door to using any other type that may not be a strict subclsss of Element, but can render itself. Not too bad in this case, but in general, frowned upon in Python.
+
Alternatively, you could check for the string type:
+
if isinstance ( content , str ):
+ self . content . append ( TextWrapper ( content ))
+else :
+ self . content . append ( content )
+
+
+
I think this is a little better – strings are a pretty core type in python, it’s not likely that anyone is going to need to use a “string-like” object.
+
+
+
Duck Typing
+
The Python model of duck typing is if quacks like a duck, then treat it like a duck.
+
But in this case, we’re not actually rendering the object at this stage, so calling the method isn’t appropriate.
+
Checking for an attribute
+
Instead of calling the method, see if it’s there:
+
You can check if the passed-in object has a render() attribute:
+
if hasattr ( content , 'render' ):
+ self . content . append ( content )
+else :
+ self . content . append ( TextWrapper ( content ))
+
+
+
This is my favorite. html_render_wrap.py in Solutions demonstrates with method.
+
+
+
Duck Typing on the Fly
+
The other option is to simply put both elements and text in the content list, and figure out what to do in the render() method.
+
Again, you could type check – but I prefer the duck typing approach, and EAFP:
+
try :
+ content . render ( out_file )
+except AttributeError :
+ outfile . write ( content )
+
+
+
If content is a simple string then it won’t have a render method, and an AttributeError will be raised.
+
You can catch that, and simply write the content.
+
You may want to turn it into a string, first:
+
outfile . write ( str ( content ))
+
+
+
Then you could write just about anything – numbers, etc.
+
+
+
Where did the Exception come from?
+
Caution
+
If the object doesn’t have a render method, then an AttributeError will be raised. But what if it does have a render method, but that method is broken?
+
Depending on what’s broken, it could raise any number of exceptions. Most will not get caught by the except clause, and will halt the program.
+
But if, just by bad luck, it has an bug that raises an AttributeError – then this could with catch it, and try to simply write it out instead. So you may get somethign like: <html_render.H object at 0x103604400> in the middle of your html.
+
The beauty of testing
+
If you have a unit test that calls every render method in your code – then it should catch that error, and it wil be clear where it is coming from.
+
+
+
+
HTML Primer
+
The very least you need to know about html to do this assigment.
+
If you are familar with html, then this will all make sense to you. If you have never seen html before, this might be a bit intimidating, but you really don’t need to know much to do this assignment.
+
First of all, sample output from each step is provided. So all you really need to do is look at that, and make your code do the same thing. But it does help to know a little bit about what you are doing.
+
+
HTML
+
HTML is “Hyper Text Markup Language”. Hypertext, because it can contain links
+to other pages, and markup language means that text is “marked up” with
+instructions about how to format the text, etc.
+
Here is a good basic intro:
+
http://www.w3schools.com/html/html_basic.asp
+
And there are countless others online.
+
As html is XML – the XML intro is a good source of the XML syntax, too:
+
http://www.w3schools.com/xml/default.asp
+
But here is a tiny intro of just what you need to know for this project.
+
+
+
Elements
+
Modern HTML is a particular dialect of XML (eXtensible Markup Language),
+which is itself a special case of SGML (Standard Generalized Markup Language)
+
It inherits from SGML a basic structure: each piece of the document is an element. each element is described by a “tag”. Each tag has a different meaning, but they all have the same structure:
+
<some_tag> some content </some_tag>
+
+
+
that is, the tag name is surrounded by < and >, which marks the beginning of
+the element, and the end of the element is indicated by the same tag with a slash.
+
The real power is that these elements can be nested arbitrarily deep. In order to keep that all readable, we often want to indent the content inside the tags, so it’s clear what belongs with what. That is one of the tricky bits of this assignment.
+
+
+
+
Attributes:
+
In addition to the tag name and the content, extra attributes can be attached to a tag. These are added to the “opening tag”, with name=”something”, another_name=”somethign else” format:
+
<p style= "text-align: center; font-style: oblique;" >
+
+
+
There can be all sorts of stuff stored in attributes – some required for specific tags, some extra, like font sizes and colors. Note that since tags can essentially have any attributes, your code will need to support that – doesn’t it kind of look like a dict? And keyword arguments?
+
+
+
Special Elements
+
The general structure is everything in between the opening and closing tag. But some elements don’t really have content – just attributes. So the slash goes at the end of the tag, after the attributes. We can call these self-closing tags:
+
<meta charset= "UTF-8" />
+
+
+
To make a link, you use an “anchor” tag: <a> . It requires attributes to indicate what the link is:
+
<a href= "http://google.com" > link </a>
+
+
+
The href attribute is the link (hyper reference).
+
To make a bulleted list, you use a <ul> tag (unordered list), and inside that, you put individual list elements <li>:
+
<ul style= "line-height:200%" id= "TheList" >
+ <li>
+ The first item in a list
+ </li>
+ <li style= "color: red" >
+ This is the second item
+ </li>
+</ul>
+
+
+
Note that the list itself, and the list items can both take various attributes (all tags can...)
+
Section Headers are created with “h” tags: <h1> is the biggest (highest level), and there is <h2>, <h3>, etc. for sections, sub sections, subsub sections...
+
<h2> PythonClass - Class 7 example</h2>
+
+
+
I think that’s all you need to know!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/index.html b/exercises/index.html
new file mode 100644
index 0000000..95f2269
--- /dev/null
+++ b/exercises/index.html
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+
+
+
+ Exercises — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Exercises
+
+
Contents:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/kata_fourteen.html b/exercises/kata_fourteen.html
new file mode 100644
index 0000000..38aeb1b
--- /dev/null
+++ b/exercises/kata_fourteen.html
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+ Kata Fourteen: Tom Swift Under Milk Wood — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Kata Fourteen: Tom Swift Under Milk Wood
+
Adapted from Dave Thomas’s work:
+
http://codekata.com/kata/kata14-tom-swift-under-the-milkwood/
+
+
Trigrams
+
Trigrams can be used to mutate text into new, surreal, forms. But what
+heuristics do we apply to get a reasonable result?
+
+
The Problem
+
As a boy, one of my treats was go to the shops on a Saturday and spend part
+of my allowance on books; for a nine-year old, I had quite a collection of
+Tom Swift and Hardy Boys. Wouldn’t it be great to be able to create
+more and more of these classic books, to be able to generate a new Tom
+Swift adventure on demand?
+
OK, perhaps not. But that won’t stop us trying. I coded up a quick
+program to generate some swash-buckling scientific adventure on demand. It
+came up with:
+
+... it was in the wind that was what he thought was his companion. I
+think would be a good one and accordingly the ship their situation
+improved. Slowly so slowly that it beat the band! You’d think no one
+was a low voice. “Don’t take any of the elements and the
+inventors of the little Frenchman in the enclosed car or cabin completely
+fitted up in front of the gas in the house and wringing her hands.
+“I’m sure they’ll fall!”
+
She looked up at them. He dug a mass of black vapor which it had
+refused to accept any. As for Mr. Swift as if it goes too high I’ll
+warn you and you can and swallow frequently. That will make the airship was
+shooting upward again and just before the raid wouldn’t have been
+instrumental in capturing the scoundrels right out of jail.”
+
+
Stylistically, it’s Victor Appleton meets Dylan Thomas. Technically,
+it’s all done with trigrams.
+
Trigram analysis is very simple. Look at each set of three adjacent words
+in a document. Use the first two words of the set as a key, and remember
+the fact that the third word followed that key. Once you’ve finished,
+you know the list of individual words that can follow each two word
+sequence in the document. For example, given the input:
+
I wish I may I wish I might
+
+
+
You might generate:
+
"I wish" => ["I", "I"]
+"wish I" => ["may", "might"]
+"may I" => ["wish"]
+"I may" => ["I"]
+
+
+
This says that the words “I wish” are twice followed by the word
+“I”, the words “wish I” are followed once by
+“may” and once by “might” and so on.
+
To generate new text from this analysis, choose an arbitrary word pair as a
+starting point. Use these to look up a random next word (using the table
+above) and append this new word to the text so far. This now gives you a
+new word pair at the end of the text, so look up a potential next word
+based on these. Add this to the list, and so on. In the previous example,
+we could start with “I may”. The only possible next word is
+“I”, so now we have:
+
+
The last two words are “may I”, so the next word is
+“wish”. We then look up “I wish”, and find our choice
+is constrained to another “I”.:
+
+
Now we look up “wish I”, and find we have a choice. Let’s
+choose “may”:
+
+
Now we’re back where we started from, with “I may.”
+Following the same sequence, but choosing “might” this time, we
+get:
+
I may I wish I may I wish I might
+
+
+
At this point we stop, as no sequence starts “I might.”
+
Given a short input text, the algorithm isn’t too interesting. Feed
+it a book, however, and you give it more options, so the resulting output
+can be surprising.
+
For this kata, try implementing a trigram algorithm that generates a couple
+of hundred words of text using a book-sized file as input.
+Project Gutenberg is a good source of online
+books (Tom Swift and His Airship is here .)
+
Be warned that these files have DOS line endings (carriage return followed by
+newline).
+
There is a copy of sherlock holmes right here:
+
sherlock.txt .
+
And a shorter copy for testing:
+
sherlock_small.txt .
+
+
+
Objectives
+
Kata’s are about trying something many times. In this one, what
+we’re experimenting with is not just the code, but the heuristics of
+processing the text. What do we do with punctuation? Paragraphs? Do we have
+to implement backtracking if we chose a next word that turns out to be a
+dead end?
+
I’ll fire the signal and the fun will commence...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/lambda_magic.html b/exercises/lambda_magic.html
new file mode 100644
index 0000000..47390a3
--- /dev/null
+++ b/exercises/lambda_magic.html
@@ -0,0 +1,278 @@
+
+
+
+
+
+
+
+
+
+
+ lambda and keyword Magic — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
lambda and keyword Magic
+
+
Goals
+
+A bit of lambda
+functions as objects
+keyword evaluation
+
+
+
Task
+
Write a function that returns a list of n functions,
+such that each one, when called, will return the input value,
+incremented by an increasing number.
+
Use a for loop, lambda , and a keyword argument
+
( Extra credit ):
+
Do it with a list comprehension, instead of a for loop
+
Not clear? here’s what you should get...
+
+
+
Example calling code
+
In [96]: the_list = function_builder ( 4 )
+### so the_list should contain n functions (callables)
+In [97]: the_list [ 0 ]( 2 )
+Out[97]: 2
+## the zeroth element of the list is a function that add 0
+## to the input, hence called with 2, returns 2
+In [98]: the_list [ 1 ]( 2 )
+Out[98]: 3
+## the 1st element of the list is a function that adds 1
+## to the input value, thus called with 2, returns 3
+In [100]: for f in the_list :
+ print(f(5))
+ .....:
+5
+6
+7
+8
+### If you loop through them all, and call them, each one adds one more
+to the input, 5... i.e. the nth function in the list adds n to the input.
+
+
+
See the test code in Examples/Session06
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/list_lab.html b/exercises/list_lab.html
new file mode 100644
index 0000000..73d48bb
--- /dev/null
+++ b/exercises/list_lab.html
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+ List Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
List Lab
+
+
Learning about lists
+
After:
+
http://www.upriss.org.uk/python/session5.html
+
+
Goal:
+
Learn the basic ins and outs of Python lists.
+
+
+
hint
+
to query the user for info at the command line, you use:
+
response = input ( "a prompt for the user > " )
+
+
+
response will be a string of whatever the user types (until a <return>).
+
+
+
Procedure
+
In your student dir in the repo, create a directory for today’s session and put in a new list_lab.py file.
+
The file should be an executable python script. That is to say that one
+should be able to run the script directly like so:
+
+
(At least on OS-X and Linux)
+
– you do that with this command:
+
+
(The +x means make this executable)
+
Add the file to your clone of the repository and commit changes frequently
+while working on the following tasks. When you are done, push your changes to
+GitHub and issue a pull request.
+
(if you are struggling with git – just write the code for now)
+
When the script is run, it should accomplish the following four series of
+actions:
+
+Create a list that contains “Apples”, “Pears”, “Oranges” and “Peaches”.
+Display the list.
+Ask the user for another fruit and add it to the end of the list.
+Display the list.
+Ask the user for a number and display the number back to the user and the
+fruit corresponding to that number (on a 1-is-first basis).
+Add another fruit to the beginning of the list using “+” and display the
+list.
+Add another fruit to the beginning of the list using insert() and display the list.
+Display all the fruits that begin with “P”, using a for loop.
+
+
Using the list created in series 1 above:
+
+Display the list.
+Remove the last fruit from the list.
+Display the list.
+Ask the user for a fruit to delete and find it and delete it.
+(Bonus: Multiply the list times two. Keep asking until a match is found. Once found, delete all occurrences.)
+
+
Again, using the list from series 1:
+
+Ask the user for input displaying a line like “Do you like apples?”
+for each fruit in the list (making the fruit all lowercase).
+For each “no”, delete that fruit from the list.
+For any answer that is not “yes” or “no”, prompt the user to answer with one
+of those two values (a while loop is good here):
+Display the list.
+
+
Once more, using the list from series 1:
+
+Make a copy of the list and reverse the letters in each fruit in the copy.
+Delete the last item of the original list. Display the original list and the
+copy.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/mailroom.html b/exercises/mailroom.html
new file mode 100644
index 0000000..94ccd36
--- /dev/null
+++ b/exercises/mailroom.html
@@ -0,0 +1,311 @@
+
+
+
+
+
+
+
+
+
+
+ Mailroom — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mailroom
+
+
A complete program
+
Using basic data types and logic for a full program
+
+
Goal:
+
You work in the mail room at a local charity. Part of your job is to write
+incredibly boring, repetitive emails thanking your donors for their generous
+gifts. You are tired of doing this over an over again, so yo’ve decided to
+let Python help you out of a jam.
+
+
+
The program
+
Write a small command-line script called mailroom.py . This script should be executable. The script should accomplish the following goals:
+
+It should have a data structure that holds a list of your donors and a
+history of the amounts they have donated. This structure should be populated
+at first with at least five donors, with between 1 and 3 donations each
+The script should prompt the user (you) to choose from a menu of 2 actions:
+‘Send a Thank You’ or ‘Create a Report’.
+
+
+
+
Sending a Thank You
+
+If the user (you) selects ‘Send a Thank You’, prompt for a Full Name.
+If the user types ‘list’, show them a list of the donor names and re-prompt
+If the user types a name not in the list, add that name to the data structure and use it.
+If the user types a name in the list, use it.
+Once a name has been selected, prompt for a donation amount.
+Verify that the amount is in fact a number, and re-prompt if it isn’t.
+Once an amount has been given, add that amount to the donation history of
+the selected user.
+Finally, use string formatting to compose an email thanking the donor for
+their generous donation. Print the email to the terminal and return to the
+original prompt.
+
+
+
+
It is fine to forget new donors once the script quits running.
+
+
+
Creating a Report
+
+If the user (you) selected ‘Create a Report’ Print a list of your donors,
+sorted by total historical donation amount.
+Include Donor Name, total donated, number of donations and average donation amount as values in each row.
+Using string formatting, format the output rows as nicely as possible. The end result should be tabular (values in each column should align with those above and below)
+After printing this report, return to the original prompt.
+
+
+At any point, the user should be able to quit their current task and return
+to the original prompt.
+From the original prompt, the user should be able to quit the script cleanly
+
+
+
+
Guidelines
+
First, factor your script into separate functions. Each of the above
+tasks can be accomplished by a series of steps. Write discreet functions
+that accomplish individual steps and call them.
+
Second, use loops to control the logical flow of your program. Interactive
+programs are a classic use-case for the while loop.
+
Of course, input() will be useful here.
+
Put the functions you write into the script at the top.
+
Put your main interaction into an if __name__ == '__main__' block.
+
Finally, use only functions and the basic Python data types you’ve learned
+about so far. There is no need to go any farther than that for this assignment.
+
+
+
Submission
+
As always, put the new file in your student directory and git add it to your repo early. Make frequent commits with good, clear messages about what you are doing and why. When you are done, push your changes and make a pull request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/rot13.html b/exercises/rot13.html
new file mode 100644
index 0000000..a5fd5c5
--- /dev/null
+++ b/exercises/rot13.html
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+ ROT13 — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ROT13
+
+
Goal
+
Get used to working with the number values for characters
+
Get a bit of practice with string methods and string processing
+
+
+
ROT13 encryption
+
The ROT13 encryption scheme is a simple substitution cypher where each letter
+in a text is replace by the letter 13 away from it (imagine the alphabet as a
+circle, so it wraps around).
+
+
+
The task
+
Add a python module named rot13.py to the session03 dir in your student dir. This module should provide at least one function called rot13 that takes any amount of text and returns that same text encrypted by ROT13.
+
This function should preserve whitespace, punctuation and capitalization.
+
Your module should include an if __name__ == '__main__': block with tests (asserts) that demonstrate that your rot13 function and any helper functions you add work properly.
+
There is a “short-cut” available that will help you accomplish this task. Some
+spelunking in the documentation for strings should help you to find it. If
+you do find it, using it is completely fair game.
+
As usual, add your new file to your local clone right away. Make commits
+early and often and include commit messages that are descriptive and concise.
+
When you are done, if you want me to review it, push your changes to github
+and issue a pull request.
+
try decrypting this:
+
“Zntargvp sebz bhgfvqr arne pbeare”
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/slicing.html b/exercises/slicing.html
new file mode 100644
index 0000000..9533ada
--- /dev/null
+++ b/exercises/slicing.html
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+ Slicing Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Slicing Lab
+
+
Goal
+
Get the basics of sequence slicing down
+
+
Tasks
+
Write some functions that:
+
+return a sequence with the first and last items exchanged.
+return a sequence with every other item removed
+return a sequence with the first and last 4 items removed, and every other item in between
+return a sequence reversed (just with slicing)
+return a sequence with the middle third, then last third, then the first third in the new order
+
+
NOTE:
+these should work with ANY sequence – but you can use strings to test, if you like.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/sparse_array.html b/exercises/sparse_array.html
new file mode 100644
index 0000000..80b7899
--- /dev/null
+++ b/exercises/sparse_array.html
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+ Sparse Array Exercise — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sparse Array Exercise
+
+
Sparse Array
+
Goal:
+
Learn how to emulate a built-in class.
+
+
Sparse Array:
+
Oftentimes, at least in computation programming, we have large arrays of data that hold mostly zeros.
+
These are referred to as “sparse” as the information in them is widely scattered, or sparse.
+
Since they are mostly zeros, it can be memory an computationally efficient to store only the value that are non-zero.
+
But you want it to look like a regular array in user code.
+
In the real world, these are usually 2 dimensional arrays. But to keep it a bit simpler, we’ll make a 1 dimensional sparse array in this class.
+
(feel free to make it 2d for an extra challenge!)
+
+
+
A Sparse array class
+
A spare array class should present to the user the same interface as a regular list.
+
Some ideas of how to do that:
+
+Internally, it can store the values in a dict, with the index as the keys. So that only the indexes with non-zero values will be stored.
+It should take a sequence of values as an initializer:
+
+
sa = SparseArray ([ 1 , 2 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 4 ])
+
+
+
+you should be able to tell how long it is:
+
+
len ( my_array )
+
+This will give its "virtual" length -- with the zeros
+
+
+
+It should support getting and setting particular elements via indexing:
+
+
sa [ 5 ] = 12
+sa [ 3 ] = 0 # the zero won't get stored!
+val = sa [ 13 ] # it should get a zero if not set
+
+
+
+It should support deleting an element by index:
+
+
+
+It should raise an IndexError if you try to access an index beyond the end.
+it should have an append() method
+
+
+Can you make it support slicing?
+How else can you make it like a list?
+
+
In [10]: my_array = SparseArray ( ( 1 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 5 ) )
+In [11]: my_array [ 4 ]
+Out[11]: 2
+In [12]: my_array [ 2 ]
+Out[12]: 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/string_formatting.html b/exercises/string_formatting.html
new file mode 100644
index 0000000..f3ed7c2
--- /dev/null
+++ b/exercises/string_formatting.html
@@ -0,0 +1,272 @@
+
+
+
+
+
+
+
+
+
+
+ String Formatting Lab — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercises/trapezoid.html b/exercises/trapezoid.html
new file mode 100644
index 0000000..0b77e99
--- /dev/null
+++ b/exercises/trapezoid.html
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+
+
+
+
+ Trapezoidal Rule — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Trapezoidal Rule
+
+
Passing functions around
+
Goal:
+
Making use of functions as objects – functions that act on functions.
+
+
Trapezoidal rule
+
The “trapezoidal rule”:
+
https://en.wikipedia.org/wiki/Trapezoidal_rule
+
Is one of the easiest “quadrature” methods.
+
Otherwise known as computing a definite integral, or, simply,
+
Computing the area under a curve.
+
+
+
The task
+
Your task is to write a trapz() function that will compute the area under an arbitrary function, using the trapezoidal rule.
+
The function will take another function as an argument, as well as the start and end points to compute, and return the area under the curve.
+
+
+
Example:
+
def line ( x ):
+ '''a very simple straight horizontal line at y = 5'''
+ return 5
+
+area = trapz ( line , 0 , 10 )
+
+area
+50
+
+
+
About the simplest “curve” you can have is a horizontal straight line, in this case, at y = 5. The area under that line from 0 to 10 is a rectangle that is 10 wide and 5 high, so with an area of 50.
+
Of course in this case, it’s easiest to simply multiply the height times the width, but we want a function that will work for Any curve.
+
HINT: this simple example could be a good test case!
+
+
+
The Solution:
+
Your function definition should look like:
+
def trapz ( fun , a , b ):
+ """
+ Compute the area under the curve defined by
+ y = fun(x), for x between a and b
+
+ :param fun: the function to evaluate
+ :type fun: a function that takes a single parameter
+
+ :param a: the start point for teh integration
+ :type a: a numeric value
+
+ :param b: the end point for the integration
+ :type b: a numeric value
+ """
+ pass
+
+
+
In the function, you want to compute the following equation:
+
+\[area = \frac{b-a}{2N}(f(x_0) + 2f(x_1) + 2f(x_2) + \dotsb + 2f(x_{N-1}) + f(x_N))\]
+
So you will need to:
+
+
+create a list of x values from a to b (maybe 100 or so values to start)
+compute the function for each of those values and double them
+add them all up
+multiply by the half of the difference between a and b divided by the number of steps.
+
+
+
Note that the first and last values are not doubled, so it may be more efficient to rearrange it like this:
+
+\[area = \frac{b-a}{N} \left( \frac{f(x_0) + f(x_{N})}{2} + \sum_{i=1}^{N-1} f(x_i) \right)\]
+
Can you use comprehensions for this?
+
NOTE: range() only works for integers – how can you deal with that?
+
Once you have that, it should work for any function that can be evaluated between a and b.
+
Try it for some built-in math functions, like math.sin
+
+
+
tests
+
Do this using test-drive development.
+
A few examples of analytical solutions you can use for tests:
+
A simple horizontal line – see above.
+
A sloped straight line:
+
+\[\int_a^b y = mx + B = \frac{1}{2} m (b^2-a^2) + B (b-a)\]
+
The quadratic:
+
+\[\int_a^b y = Ax^2 + Bx + C = \frac{A}{3} (b^3-a^3) + \frac{B}{2} (b^2-a^2) + C (b-a)\]
+
The sine function:
+
+\[\int_a^b \sin(x) = \cos(a) - \cos(b)\]
+
+
+
Computational Accuracy
+
In the case of the linear functions, the result should theoretically be exact. But with the vagaries of floating point math may not be.
+
And for non-linear functions, the result will certainly not be exact.
+
So you want to check if the answer is close to what you expect.
+
In py3.5 – there is an isclose() function (PEP485)
+
https://www.python.org/dev/peps/pep-0485/
+
In earlier pythons – you’ll need your own. There is one in:
+
Examples/Session06/test_trapz.py
+
+
+
Stage two:
+
Some functions need extra parameters to do their thing. But the above will only handle a single parameter. For example, a quadratic function:
+
+\[y = A x^2 + Bx + C\]
+
Requires values for A, B, and C in order to compute y from an given x.
+
You could write a specialized version of this function for each A, B, and C:
+
def quad1 ( x ):
+ return 3 * x ** 2 + 2 * x + 4
+
+
+
But then you need to write a new function for any value of these parameters you might need.
+
Instead, you can pass in A, B and C each time:
+
def quadratic ( x , A = 0 , B = 0 , C = 0 ):
+ return A * x ** 2 + B * x + C
+
+
+
Nice and general purpose.
+
But how would we compute the area under this function?
+
The function we wrote above only passes x in to the function it is integrating.
+
+
+
Passing arguments through:
+
Update your trapz() function so that you can give it a function that takes arbitrary extra arguments, either positional or keyword, after the x.
+
So you can do:
+
trapz ( quadratic , 2 , 20 , A = 1 , B = 3 , C = 2 )
+
+
+
or
+
trapz ( quadratic , 2 , 20 , 1 , 3 , C = 2 )
+
+
+
or
+
coef = { 'A' : 1 , 'B' : 3 , 'C' : 2 }
+trapz ( quadratic , 2 , 20 , ** coef )
+
+
+
NOTE: Make sure this will work with ANY function, with ANY additional positional or keyword arguments – not just this particular function.
+
This is pretty conceptually challenging – but it’s very little code!
+
If you are totally lost – look at the lecture notes from last class – how can you both accept and pass arbitrary arguments to/from a function?
+
You want your trapz function to take ANY function that can take ANY arbitrary extra arguments – not just the quadratic function, and not just A,B, and C . So good to test with another example.
+
The generalized sine function is:
+
+\[A \sin(\omega t)\]
+
where \(A\) is the amplitude, and \(\omega\) is the frequency of the function. In this case, the area under the curve from a to b is:
+
+\[\frac{A}{\omega} \left( \cos(\omega a) - \cos(\omega b) \right)\]
+
The test code has a test for this one, too.
+
+
+
Currying
+
Another way to solve the above problem is to use the original trapz , and create a custom version of the quadratic() function instead.
+
Write a function that takes A, B, and C as arguments, and returns a function that evaluates the quadratic for those particular coefficients.
+
Try passing the results of this into your trapz() and see if you get the same answer.
+
+
+
partial
+
Do the above with functools.partial as well.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/genindex.html b/genindex.html
new file mode 100644
index 0000000..ed00913
--- /dev/null
+++ b/genindex.html
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+ Index — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/include.html b/include.html
new file mode 100644
index 0000000..561cc85
--- /dev/null
+++ b/include.html
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+ <no title> — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..3404fdc
--- /dev/null
+++ b/index.html
@@ -0,0 +1,266 @@
+
+
+
+
+
+
+
+
+
+
+ Intro To Python — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Intro To Python
+
+
In This Course
+
+
+
These materials copyright Christopher Barker and Cris Ewing, with thanks to
+Jon Jacky and Brian Dorsey for the materials from which these were derived.
+Licenced under the
+Creative Commons Attribution-ShareAlike 4.0 International Public License.
+
https://creativecommons.org/licenses/by-sa/4.0/legalcode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notebooks/ClassMethods.ipynb b/notebooks/ClassMethods.ipynb
deleted file mode 100644
index e44a01c..0000000
--- a/notebooks/ClassMethods.ipynb
+++ /dev/null
@@ -1,269 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Classy(object):\n",
- " x = 2\n",
- " \n",
- " @classmethod\n",
- " def class_method(cls, y):\n",
- " print(\"In class_method: \", cls)\n",
- " return y ** cls.x\n",
- " \n",
- " def bound_method(self):\n",
- " print(\"In bound_method\")\n",
- " \n",
- " def unbound_method():\n",
- " print(\"In unbound_method\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ">"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Classy.class_method"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "In class_method: \n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "16"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Classy.class_method(4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class SubClassy(Classy):\n",
- " x = 3"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "In class_method: \n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "4"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Classy.class_method(2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Classy.bound_method"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_classy = Classy()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ">"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_classy.bound_method"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Classy.unbound_method"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "ename": "TypeError",
- "evalue": "unbound_method() takes 0 positional arguments but 1 was given",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_classy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munbound_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m: unbound_method() takes 0 positional arguments but 1 was given"
- ]
- }
- ],
- "source": [
- "my_classy.unbound_method()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "In unbound_method\n"
- ]
- }
- ],
- "source": [
- "Classy.unbound_method()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/ClassVsInstanceAttributes.ipynb b/notebooks/ClassVsInstanceAttributes.ipynb
deleted file mode 100644
index 71b5ca8..0000000
--- a/notebooks/ClassVsInstanceAttributes.ipynb
+++ /dev/null
@@ -1,600 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 49,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyClass(object):\n",
- " my_class_attribute1 = \"This is a class attribute\"\n",
- " my_class_attribute2 = \"All instances of the class will have this\"\n",
- "\n",
- " def __init__(self, a, b):\n",
- " \"\"\"\n",
- " Define instance attributes here\n",
- " These will be unique to each instance of the class\n",
- " \"\"\"\n",
- " self.content = []\n",
- " self.x = a\n",
- " self.y = b"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### I think of classes as templates or blueprints for instances of the class. It is an imperfect metaphor, yet useful. Remember that just about everything in Python is an object and dir() provides an easy way to inspect things. What do we get out of the gate once the class is defined? Note that we have not yet created an instance from it."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['__class__',\n",
- " '__delattr__',\n",
- " '__dict__',\n",
- " '__dir__',\n",
- " '__doc__',\n",
- " '__eq__',\n",
- " '__format__',\n",
- " '__ge__',\n",
- " '__getattribute__',\n",
- " '__gt__',\n",
- " '__hash__',\n",
- " '__init__',\n",
- " '__le__',\n",
- " '__lt__',\n",
- " '__module__',\n",
- " '__ne__',\n",
- " '__new__',\n",
- " '__reduce__',\n",
- " '__reduce_ex__',\n",
- " '__repr__',\n",
- " '__setattr__',\n",
- " '__sizeof__',\n",
- " '__str__',\n",
- " '__subclasshook__',\n",
- " '__weakref__',\n",
- " 'my_class_attribute1',\n",
- " 'my_class_attribute2']"
- ]
- },
- "execution_count": 50,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(MyClass)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Now let's create an instance of the class."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_instance = MyClass(3,4)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What do we get once we have created an instance of the class? How does it differ from the class itself?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 52,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['__class__',\n",
- " '__delattr__',\n",
- " '__dict__',\n",
- " '__dir__',\n",
- " '__doc__',\n",
- " '__eq__',\n",
- " '__format__',\n",
- " '__ge__',\n",
- " '__getattribute__',\n",
- " '__gt__',\n",
- " '__hash__',\n",
- " '__init__',\n",
- " '__le__',\n",
- " '__lt__',\n",
- " '__module__',\n",
- " '__ne__',\n",
- " '__new__',\n",
- " '__reduce__',\n",
- " '__reduce_ex__',\n",
- " '__repr__',\n",
- " '__setattr__',\n",
- " '__sizeof__',\n",
- " '__str__',\n",
- " '__subclasshook__',\n",
- " '__weakref__',\n",
- " 'content',\n",
- " 'my_class_attribute1',\n",
- " 'my_class_attribute2',\n",
- " 'x',\n",
- " 'y']"
- ]
- },
- "execution_count": 52,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(my_instance)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's take a closer look..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "mappingproxy({'__init__': , 'my_class_attribute2': 'All instances of the class will have this', '__weakref__': , '__doc__': None, 'my_class_attribute1': 'This is a class attribute', '__dict__': , '__module__': '__main__'})"
- ]
- },
- "execution_count": 53,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "MyClass.__dict__"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 54,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'content': [], 'x': 3, 'y': 4}"
- ]
- },
- "execution_count": 54,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Ah! So the class attributes appear in the class's dictionary (namespace) whereas the instance attributes appear in the instance's dictionary (namespace). What sorts of behaviors might we expect from this?"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's work with instance attributes"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_instance.content = ['a', 'b', 'c']"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 56,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['a', 'b', 'c']"
- ]
- },
- "execution_count": 56,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.content"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's create a second instance"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_second_instance = MyClass(4,5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_second_instance.content = [6, 7, 8]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Since self.content is an instance attribute, each instance gets its own"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 59,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['a', 'b', 'c']"
- ]
- },
- "execution_count": 59,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.content"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 60,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[6, 7, 8]"
- ]
- },
- "execution_count": 60,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_second_instance.content"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Since my_class_attribute1 and my_class_attribute2 are class attributes, the instances share"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'This is a class attribute'"
- ]
- },
- "execution_count": 61,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.my_class_attribute1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 62,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'This is a class attribute'"
- ]
- },
- "execution_count": 62,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_second_instance.my_class_attribute1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What happens when I change a class attribute?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 63,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_instance.my_class_attribute1 = \"New value for my_class_attribute1\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 64,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'New value for my_class_attribute1'"
- ]
- },
- "execution_count": 64,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.my_class_attribute1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 65,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'This is a class attribute'"
- ]
- },
- "execution_count": 65,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_second_instance.my_class_attribute1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What??? Interersting, eh? I thouht we *modified* the *class attribute*, yet it was unchanged for my_second_instance. What's going on? Let's take a look at those dicts (namespaces) again...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 66,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "mappingproxy({'__init__': , 'my_class_attribute2': 'All instances of the class will have this', '__weakref__': , '__doc__': None, 'my_class_attribute1': 'This is a class attribute', '__dict__': , '__module__': '__main__'})"
- ]
- },
- "execution_count": 66,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "MyClass.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Huh. Scanning back to where we looked at this earlier it looks pretty much the same... perhaps exactly the same? How about the instance's dict/namespace?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 67,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'content': ['a', 'b', 'c'],\n",
- " 'my_class_attribute1': 'New value for my_class_attribute1',\n",
- " 'x': 3,\n",
- " 'y': 4}"
- ]
- },
- "execution_count": 67,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Woah! There it is... we now have an *instance* attribute called *my_class_attribute1*! We did not *modify* a class attribute, as we thought we had several steps above, rather, we created a new attribute on our instance with the same name as the class attribute, effectively overriding the class attribute. Gotcha! How do we get access to the original class attribute?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 68,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'This is a class attribute'"
- ]
- },
- "execution_count": 68,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "MyClass.my_class_attribute1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "### Hmm.. okay, but I'd like to access the original class attribute via the instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 69,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'This is a class attribute'"
- ]
- },
- "execution_count": 69,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_instance.__class__.my_class_attribute1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Exceptions_Lab.ipynb b/notebooks/Exceptions_Lab.ipynb
deleted file mode 100644
index 7b528c5..0000000
--- a/notebooks/Exceptions_Lab.ipynb
+++ /dev/null
@@ -1,184 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Focus on input()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on method raw_input in module ipykernel.kernelbase:\n",
- "\n",
- "raw_input(prompt='') method of ipykernel.ipkernel.IPythonKernel instance\n",
- " Forward raw_input to frontends\n",
- " \n",
- " Raises\n",
- " ------\n",
- " StdinNotImplentedError if active frontend doesn't support stdin.\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(input)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Two Exceptions"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- EOFError: Raised when one of the built-in functions (input() or raw_input()) hits an end-of-file condition (EOF) without reading any data. \n",
- "- KeyboardInterrupt: Raised when the user hits the interrupt key (normally Control-C or Delete). "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Logic"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Create a wrapper function, perhaps safe_input() that returns None rather rather than raising these exceptions, when the user enters ^C for Keyboard Interrupt, or ^D (^Z on Windows) for End Of File."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def a function asking for user input(see help(input()) for required args):\n",
- " try:\n",
- " getting a response from the user\n",
- " return that response\n",
- " except for EOFError, KeyboardInterrupt:\n",
- " when this happens, return none instead of the error"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### One possible implimentation\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def safe_input(message):\n",
- " try:\n",
- " user_input = input(message)\n",
- " return user_input\n",
- " except (KeyboardInterrupt, EOFError):\n",
- " return None"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Yoyo! asdf\n"
- ]
- }
- ],
- "source": [
- "response = safe_input(\"Yoyo! \")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'asdf'"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "response"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### As a demo this works better in straight ipython rather than in the notebook, because you can better see what happens when you hit ^c or ^d."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/HTML_Rendering.ipynb b/notebooks/HTML_Rendering.ipynb
deleted file mode 100644
index 536404e..0000000
--- a/notebooks/HTML_Rendering.ipynb
+++ /dev/null
@@ -1,990 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Overview of Basic HTML syntax"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# let the renderer know this is html\n",
- "\n",
- "\n",
- "# document starts here\n",
- "\n",
- "\n",
- " # tags label different sections with the format\n",
- " # \n",
- " # stuff in here\n",
- " # end tag>\n",
- " \n",
- " \n",
- " PythonClass = Revision 1087: \n",
- " \n",
- " \n",
- " # h1, h2, h3 = heading types\n",
- " PythonClass - Class 6 example \n",
- " \n",
- " # p = paragraph and defining attributes\n",
- " \n",
- " Here is a paragraph of text -- there could be more of them, \n",
- " but this is enough to show that we can do some text\n",
- "
\n",
- " \n",
- " # hr = horizontal rule\n",
- " \n",
- " \n",
- " # ul = unordered list\n",
- " \n",
- " # li = list item, will show as bullets\n",
- " \n",
- " The first item in a list\n",
- " \n",
- " \n",
- " This is the second item\n",
- " \n",
- " \n",
- " And this is a \n",
- " # anchor tag for html link\n",
- " link \n",
- " to google\n",
- " \n",
- " \n",
- " \n",
- "\n",
- "# ^ closing all the things"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Assignment"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Goal: Create a set of classes that will make this syntax a lot prettier to read"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## HTML Rendering Script"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "https://github.com/UWPCE-PythonCert/IntroPython2016a/blob/master/Examples/Session07/html_render/run_html_render.py\n",
- "\n",
- "- Broken down into steps\n",
- "- Uncomment each step as you work through \n",
- "- Encourages using test-driven development"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "## Review of OOP Basics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### What is a class? \n",
- " - Logical grouping of data and functions\n",
- " - Instruction manual for constructing objects, not the actual creation\n",
- " \n",
- " The following example is from: \n",
- " https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Customer(object):\n",
- " \"\"\"A customer of ABC Bank with a checking account. Customers have the\n",
- " following properties:\n",
- "\n",
- " Attributes:\n",
- " name: A string representing the customer's name.\n",
- " balance: A float tracking the current balance of the customer's account.\n",
- " \"\"\"\n",
- "\n",
- " def __init__(self, name, balance=0.0):\n",
- " \"\"\"Return a Customer object whose name is *name* and starting\n",
- " balance is *balance*.\"\"\"\n",
- " self.name = name\n",
- " self.balance = balance\n",
- "\n",
- " def withdraw(self, amount):\n",
- " \"\"\"Return the balance remaining after withdrawing *amount*\n",
- " dollars.\"\"\"\n",
- " if amount > self.balance:\n",
- " raise RuntimeError('Amount greater than available balance.')\n",
- " self.balance -= amount\n",
- " return self.balance\n",
- "\n",
- " def deposit(self, amount):\n",
- " \"\"\"Return the balance remaining after depositing *amount*\n",
- " dollars.\"\"\"\n",
- " self.balance += amount\n",
- " return self.balance"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### How does this work? "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "#We create a customer object: \n",
- "steve = Customer(\"Steve Jobs\", 1000.00)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<__main__.Customer at 0x7f9dc06ba940>"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# steve is an instance of the Customer class\n",
- "steve"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What does self do? \n",
- "\n",
- "def withdraw(self, amount)\n",
- "\n",
- "Self is a placeholder for whatever customer you create. So when you create Steve and call the withdraw function: \n",
- "\n",
- " jeff.withdraw(100,000.00) \n",
- "\n",
- "This is shortand for Customer.withdraw(jeff, 100,000.00)\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What is \\__init__ ? "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We use it to initialize objects (ready to use!), as in \n",
- "\n",
- " self.name = name\n",
- "\n",
- "Self is the instance and is equivalent to:\n",
- " \n",
- " steve.name = 'Steve Jobs'\n",
- " \n",
- "And self.balance = balance would be equivalent to:\n",
- "\n",
- " steve.balance = 100,000.00"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What is a Method? \n",
- "\n",
- "A function defined in a class"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What are Attributes? \n",
- "\n",
- "#### Class attributes\n",
- "- Set at the class level\n",
- "- Hold for all instances of a class\n",
- "\n",
- "Example:\n",
- "\n",
- " class Car(object):\n",
- "\n",
- " wheels = 4\n",
- "\n",
- " def __init__(self, make, model):\n",
- " self.make = make\n",
- " self.model = model\n",
- "\n",
- "A car will always have four wheels. \n",
- "\n",
- "### Instances\n",
- "A class is the blueprint, but the instance is a specific copy that contains all the content created from this blueprint. \n",
- "\n",
- "For example, a human class where Billy Bob is an instance of human class. \n",
- "\n",
- "#### Instance Attributes\n",
- "Declared inside an instance. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "## Step 1\n",
- "\n",
- "#### Create an element class for rendering an html element"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# class for rendering html elements\n",
- "class Element: \n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "type"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(Element)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Create class attributes for tag and indentation\n",
- "\n",
- "- Tag name = 'html'\n",
- "- Indentation = spaces to indent for pretty printing"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# class for rendering html elements\n",
- "class Element: \n",
- " \n",
- " # define class attributes \n",
- " tag = 'html'\n",
- " indent = ' '"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Add initializer signature\n",
- "\n",
- "- Element(content=None)\n",
- "- Content is expected to be a string\n",
- "- Need way to store content that can be updated (list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def __init__(self, content=None):\n",
- " # store content\n",
- " content = []\n",
- " # check for content\n",
- " if content is not None:\n",
- " self.content.append(content)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Add append method\n",
- "\n",
- "- Can add strings to content"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- " def append(self, content):\n",
- " self.content.append(content)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Add render method\n",
- "\n",
- "- render(file_out, ind = \"\")\n",
- "- renders starting from html tag and any strings in content container\n",
- "- calls write()\n",
- "- file_out = file writer object\n",
- "- ind = string with indentation level from zero to lots of spaces, dependng on tree depth\n",
- " - amt of indentation level set by class attribute indent"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# we're given this\n",
- "def render(self, file_out, ind=\"\"):\n",
- " \n",
- " # takes a file-like object\n",
- " \n",
- " # calls write() method, writing html for a tag\n",
- " \n",
- " \n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def render(self, file_out, ind=\"\"):\n",
- " # calling write method on a file object\n",
- " file_out.write()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def render(self, file_out, ind=\"\"):\n",
- " file_out.write()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### How do we render what's in between the tags? "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- " Some content. Some more content.\n",
- "<\\html>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def render(self, file_out, ind=\"\"):\n",
- " #start rendering at first html tag\n",
- " start_tag = \"<{}>\".format(self.tag)\n",
- " # add that start tag to your output\n",
- " file_out.write(start_tag)\n",
- " \n",
- " # render in-between tag stuff here\n",
- " \n",
- " # stop at the closing html tag\n",
- " end_tag = \"{}>\".format(self.tag)\n",
- " # add that tag to the end of file object\n",
- " file_out.write(end_tag)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Do the stuff (rendering)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def render(self, file_out, ind=\"\"):\n",
- " #start rendering at first html tag\n",
- " start_tag = \"<{}>\".format(self.tag)\n",
- " # add that start tag to your output\n",
- " file_out.write(start_tag)\n",
- " \n",
- " # grab things out of content\n",
- " for stuff in self.content:\n",
- " try:\n",
- " # render it\n",
- " stuff.render(file_out)\n",
- " except AttributeError:\n",
- " file_out.write(str(stuff))\n",
- " # stop at the closing html tag\n",
- " end_tag = \"{}>\".format(self.tag)\n",
- " # add that tag to the end of file object\n",
- " file_out.write(end_tag)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Code for Part 1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "# class for rendering html elements\n",
- "class Element: \n",
- " \n",
- " # define class attributes \n",
- " tag = 'html'\n",
- " indent = ' '\n",
- " \n",
- " def __init__(self, content=None):\n",
- " # store content\n",
- " self.content = []\n",
- " # check for content\n",
- " if content is not None:\n",
- " self.content.append(content)\n",
- " \n",
- " def append(self, content):\n",
- " self.content.append(content)\n",
- " \n",
- " def render(self, file_out, ind=\"\"):\n",
- " #start rendering at first html tag\n",
- " start_tag = \"<{}>\".format(self.tag)\n",
- " # add that start tag to your output\n",
- " file_out.write(start_tag)\n",
- " \n",
- " # grab things out of content\n",
- " for stuff in self.content:\n",
- " try:\n",
- " # render it\n",
- " stuff.render(file_out)\n",
- " except AttributeError:\n",
- " file_out.write(str(stuff))\n",
- " # stop at the closing html tag\n",
- " end_tag = \"{}>\".format(self.tag)\n",
- " # add that tag to the end of file object\n",
- " file_out.write(end_tag)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's try it out"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- Download [sample_html.html](https://raw.githubusercontent.com/UWPCE-PythonCert/IntroPython2016a/master/Examples/Session07/html_render/sample_html.html)\n",
- "- Download [run_html_render.py](https://raw.githubusercontent.com/UWPCE-PythonCert/IntroPython2016a/master/Examples/Session07/html_render/run_html_render.py)\n",
- "- Save your script as html_render.py\n",
- "- From your directory: \n",
- " \n",
- " python3 ./run_html_render.py\n",
- " "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " (py3env) summer@LinuxBox:~/python100_examples/Session7$ Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some textAnd here is another piece of text -- you should be able to add any number"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Part 2: Create Subclasses\n",
- "\n",
- "#### Goal\n",
- "Render more than just the content between the html tags"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Subclasses\n",
- "\n",
- "Taken from this [tutorial](http://www.jesshamrick.com/2011/05/18/an-introduction-to-classes-and-inheritance-in-python/): \n",
- "\n",
- "Let's create a class called Pets: "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Pet():\n",
- "\n",
- " def __init__(self, name, species):\n",
- " self.name = name\n",
- " self.species = species\n",
- "\n",
- " def getName(self):\n",
- " return self.name\n",
- "\n",
- " def getSpecies(self):\n",
- " return self.species\n",
- "\n",
- " def __str__(self):\n",
- " return \"%s is a %s\" % (self.name, self.species)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Even though all pets share common, basic attributes, we can all agree that cats and dogs are different. It makes sense to keep them both under pets, to retain their common attributes, but we can create subclasses to further distinguish them. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Dog(Pet):\n",
- "\n",
- " def __init__(self, name, chases_cats):\n",
- " Pet.__init__(self, name, \"Dog\")\n",
- " self.chases_cats = chases_cats\n",
- "\n",
- " def chasesCats(self):\n",
- " return self.chases_cats"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Cat(Pet):\n",
- "\n",
- " def __init__(self, name, hates_dogs):\n",
- " Pet.__init__(self, name, \"Cat\")\n",
- " self.hates_dogs = hates_dogs\n",
- "\n",
- " def hatesDogs(self):\n",
- " return self.hates_dogs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Inheritance\n",
- "\n",
- "A subclass inherits all the attributes, methods, etc of the parent class. You can change alter these attributes to change the behavior, and you can add new ones. \n",
- "\n",
- "isinstance() is a function that can be used to see if an instance is from a certain type of class. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "mister_pet = Pet(\"Mister\", \"Dog\")\n",
- "mister_dog = Dog(\"Mister\", True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Mister is a Dog\n"
- ]
- }
- ],
- "source": [
- "print (mister_pet)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Mister is a Dog\n"
- ]
- }
- ],
- "source": [
- "print (mister_dog)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "isinstance(mister_pet, Pet)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "isinstance(mister_pet, Dog)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "isinstance(mister_dog, Pet)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "isinstance(mister_dog, Dog)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create html, body and p subclasses"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Body(Element):\n",
- " tag = 'body'\n",
- "\n",
- "class P(Element):\n",
- " tag = 'p'\n",
- " \n",
- "class html(Element):\n",
- " tag = 'html'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Update render method to work for these other elements"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Element(object):\n",
- "\n",
- " tag = 'html' # shouldn't really be usable without properly subclassing\n",
- " indent = ' '\n",
- "\n",
- " def __init__(self, content=None, **attributes):\n",
- "\n",
- " self.content = []\n",
- " # adding attributes dictionary\n",
- " self.attributes = attributes\n",
- "\n",
- " if content is not None:\n",
- " self.content.append(content)\n",
- "\n",
- " def append(self, content):\n",
- " self.content.append(content)\n",
- "\n",
- " # added render tag method to deal with any type of tag at indentation level\n",
- " def render_tag(self, current_ind):\n",
- " # tag and then content for each class\n",
- " attrs = \"\".join([' {}=\"{}\"'.format(key, val) for key, val in self.attributes.items()])\n",
- " # indetation + tag + content\n",
- " tag_str = \"{}<{}{}>\".format(current_ind, self.tag, attrs)\n",
- " return tag_str\n",
- "\n",
- " def render(self, file_out, current_ind=\"\"):\n",
- " # render method now calls the render tag method instead of just a string\n",
- " file_out.write(self.render_tag(current_ind))\n",
- " file_out.write('\\n')\n",
- " for con in self.content:\n",
- " try:\n",
- " file_out.write(current_ind + self.indent + con+\"\\n\")\n",
- " except TypeError:\n",
- " con.render(file_out, current_ind+self.indent)\n",
- " # write out closing tag\n",
- " file_out.write(\"{}{}>\\n\".format(current_ind, self.tag))\n",
- " \n",
- "class Body(Element):\n",
- " tag = 'body'\n",
- "\n",
- "class P(Element):\n",
- " tag = 'p'\n",
- " \n",
- "class Html(Element):\n",
- " tag = 'html'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's try out Step 2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- Download [test_html_output2.html](https://github.com/UWPCE-PythonCert/IntroPython2016a/blob/master/Examples/Session07/html_render/test_html_output2.html)\n",
- "- Comment out Part 1 of run_html_render.py\n",
- "- Uncomment Part 2 of run_html_render.py"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "summer@LinuxBox:~/python100_examples/Session7$ python3 ./run_html_render.py \n",
- " \n",
- " \n",
- " \n",
- " Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text\n",
- "
\n",
- " \n",
- " And here is another piece of text -- you should be able to add any number\n",
- "
\n",
- " \n",
- " "
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.4.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/HTML_Rendering_Part_Deux.ipynb b/notebooks/HTML_Rendering_Part_Deux.ipynb
deleted file mode 100644
index 5845fa2..0000000
--- a/notebooks/HTML_Rendering_Part_Deux.ipynb
+++ /dev/null
@@ -1,555 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Recap Step 2\n",
- "\n",
- "- We can render a basic web page\n",
- "- We can handle html, body and p tags\n",
- "- Everything is indented nicely"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Element(object):\n",
- "\n",
- " tag = 'html' # shouldn't really be usable without properly subclassing\n",
- " indent = ' '\n",
- "\n",
- " def __init__(self, content=None, **attributes):\n",
- "\n",
- " self.content = []\n",
- " # adding attributes dictionary\n",
- " self.attributes = attributes\n",
- "\n",
- " if content is not None:\n",
- " self.content.append(content)\n",
- "\n",
- " def append(self, content):\n",
- " self.content.append(content)\n",
- "\n",
- " # added render tag method to deal with any type of tag at indentation level\n",
- " def render_tag(self, current_ind):\n",
- " # tag and then content for each class\n",
- " attrs = \"\".join([' {}=\"{}\"'.format(key, val) for key, val in self.attributes.items()])\n",
- " # indetation + tag + content\n",
- " tag_str = \"{}<{}{}>\".format(current_ind, self.tag, attrs)\n",
- " return tag_str\n",
- "\n",
- " def render(self, file_out, current_ind=\"\"):\n",
- " # render method now calls the render tag method instead of just a string\n",
- " file_out.write(self.render_tag(current_ind))\n",
- " file_out.write('\\n')\n",
- " for con in self.content:\n",
- " try:\n",
- " file_out.write(current_ind + self.indent + con+\"\\n\")\n",
- " except TypeError:\n",
- " con.render(file_out, current_ind+self.indent)\n",
- " # write out closing tag\n",
- " file_out.write(\"{}{}>\\n\".format(current_ind, self.tag))\n",
- " \n",
- "class Body(Element):\n",
- " tag = 'body'\n",
- "\n",
- "class P(Element):\n",
- " tag = 'p'\n",
- " \n",
- "class Html(Element):\n",
- " tag = 'html'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 3"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- Create a subclass for a head tag\n",
- "- Create a OneLineTag subclass of Element\n",
- " - Override the render method to render everything on one line\n",
- "- Create a Title subclass of OneLineTag\n",
- "\n",
- "#### Goal\n",
- "- Render an html doc with a head, title, body and p elements"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create a subclass for a head tag"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Head(Element):\n",
- " tag = 'head'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create a OneLineTag subclass of element\n",
- "\n",
- "- override render method to render everything between a tag on one line"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Overriding \n",
- "\n",
- "- Changing the implementation of a method provided by a parent class. \n",
- "- Copy another class, avoiding duplication, but customize and enhance to fit your needs\n",
- "- Define in the child class a method with the same name as the method in the parent class\n",
- "- Good practice: call the original implementation of a method whenever possible (super())\n",
- "\n",
- "Great tutorial [here](http://lgiordani.com/blog/2014/05/19/method-overriding-in-python/#.VtO-ER9ytBQ)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Parent(object):\n",
- " def __init__(self):\n",
- " self.value = 5\n",
- "\n",
- " def get_value(self):\n",
- " return self.value\n",
- "\n",
- "class Child(Parent):\n",
- " def get_value(self):\n",
- " return self.value + 1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "c = Child()\n",
- "\n",
- "c.get_value()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Here's our original render method"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def render(self, file_out, current_ind=\"\"):\n",
- " # render method now calls the render tag method instead of just a string\n",
- " file_out.write(self.render_tag(current_ind))\n",
- " file_out.write('\\n')\n",
- " for con in self.content:\n",
- " try:\n",
- " file_out.write(current_ind + self.indent + con+\"\\n\")\n",
- " except TypeError:\n",
- " con.render(file_out, current_ind+self.indent)\n",
- " # write out closing tag\n",
- " file_out.write(\"{}{}>\\n\".format(current_ind, self.tag))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Render everything on one line"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class OneLineTag(Element):\n",
- " def render(self, file_out, current_ind=''):\n",
- " # remove the new line \n",
- " file_out.write(self, render_tag(current_ind))\n",
- " for con in self.content:\n",
- " # skip the indentation\n",
- " file_out.write(con)\n",
- " file_out.write(\"{}>\\n\".format(self.tag))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Put it all together for Step 3"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Element(object):\n",
- "\n",
- " tag = 'html' # shouldn't really be usable without properly subclassing\n",
- " indent = ' '\n",
- "\n",
- " def __init__(self, content=None, **attributes):\n",
- "\n",
- " self.content = []\n",
- " # adding attributes dictionary\n",
- " self.attributes = attributes\n",
- "\n",
- " if content is not None:\n",
- " self.content.append(content)\n",
- "\n",
- " def append(self, content):\n",
- " self.content.append(content)\n",
- "\n",
- " # added render tag method to deal with any type of tag at indentation level\n",
- " def render_tag(self, current_ind):\n",
- " # tag and then content for each class\n",
- " attrs = \"\".join([' {}=\"{}\"'.format(key, val) for key, val in self.attributes.items()])\n",
- " # indetation + tag + content\n",
- " tag_str = \"{}<{}{}>\".format(current_ind, self.tag, attrs)\n",
- " return tag_str\n",
- "\n",
- " def render(self, file_out, current_ind=\"\"):\n",
- " # render method now calls the render tag method instead of just a string\n",
- " file_out.write(self.render_tag(current_ind))\n",
- " file_out.write('\\n')\n",
- " for con in self.content:\n",
- " try:\n",
- " file_out.write(current_ind + self.indent + con+\"\\n\")\n",
- " except TypeError:\n",
- " con.render(file_out, current_ind+self.indent)\n",
- " # write out closing tag\n",
- " file_out.write(\"{}{}>\\n\".format(current_ind, self.tag))\n",
- " \n",
- "class Body(Element):\n",
- " tag = 'body'\n",
- "\n",
- "class P(Element):\n",
- " tag = 'p'\n",
- " \n",
- "class Html(Element):\n",
- " tag = 'html'\n",
- " \n",
- "class Head(Element):\n",
- " tag = 'head'\n",
- " \n",
- "class OneLineTag(Element):\n",
- " def render(self, file_out, current_ind=''):\n",
- " # remove the new line \n",
- " file_out.write(self, render_tag(current_ind))\n",
- " for con in self.content:\n",
- " # skip the indentation\n",
- " file_out.write(con)\n",
- " file_out.write(\"{}>\\n\".format(self.tag))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 4\n",
- "\n",
- "- Extend Element class to accept attributes as keywords (**kwargs)\n",
- "- Update render method to work with attributes\n",
- "\n",
- "#### Goal\n",
- "Render tags with attributes"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- " def __init__(self, content=None, **attributes):\n",
- "\n",
- " self.content = []\n",
- " # adding attributes dictionary\n",
- " self.attributes = attributes\n",
- "\n",
- " if content is not None:\n",
- " self.content.append(content)\n",
- " \n",
- "# added render tag method to deal with any type of tag at indentation level\n",
- " def render_tag(self, current_ind):\n",
- " # tag and then content for each class\n",
- " attrs = \"\".join([' {}=\"{}\"'.format(key, val) for key, val in self.attributes.items()])\n",
- " # indetation + tag + content\n",
- " tag_str = \"{}<{}{}>\".format(current_ind, self.tag, attrs)\n",
- " return tag_str"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 5\n",
- "\n",
- "- Create a SelfClosingTag subclass to render things like horizontal rule and line breaks\n",
- " - < hr /> \n",
- " - < br />\n",
- "- Override render method to render just one tag and attributes (if any)\n",
- "- Create subclasses of SelfClosingTag for < hr /> and < br /> "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class SelfClosingTag(Element):\n",
- " def render(self, file_out, current_ind=''):\n",
- " # calling render tag, but not adding the regular closing\n",
- " file_out.write(self.render_tag(current_ind)[:-1])\n",
- " # adding the self-closing tag instead\n",
- " file_out.write(\" />\\n\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Hr(SelfClosingTag):\n",
- " tag = 'hr'\n",
- "\n",
- "class Br(SelfClosingTag):\n",
- " tag = 'br'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 6\n",
- "\n",
- "- Create an A class for anchor (link) element \n",
- "- A(self, link, content)\n",
- " - link = link\n",
- " - content is the text that contains the link, such as \"Click here!\"\n",
- "- Override the \\__init__ from Element"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class A(Element):\n",
- " # define our tag\n",
- " tag = 'a'\n",
- "\n",
- " # override init method using constructor given in hw\n",
- " def __init__(self, link, content=None, **attributes):\n",
- " Element.__init__(self, content, **attributes)\n",
- " # pulling out the link from the attributes dictionary\n",
- " self.attributes[\"href\"] = link"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 7\n",
- "- Create ul class for unordered lists, as a subclass of Element\n",
- "- Create a li class for ordered lists, subclass of Element\n",
- "- Create a Header class that takes an int argumentfor header level < h1 > < h2 > etc\n",
- " - Called like H(2, \"Text of header\") for an < h2 > header\n",
- " - Subclass OneLineTag\n",
- " - Overriding the \\__init__\n",
- " - Then calling superclass \\__init"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Ul(Element):\n",
- " tag = 'ul'\n",
- " \n",
- "class Li(Element):\n",
- " tag = 'li'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class H(OneLineTag):\n",
- " def __init__(self, level, content=None, **attributes):\n",
- " OneLineTag.__init__(self, content, **attributes)\n",
- " self.tag = \"h{:d}\".format(level)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Step 8"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- Update HTML Element to render < !DOCTYPE html > tags\n",
- " - Subclass Element and override render()\n",
- " - Call Element render from new render\n",
- "- Create subclass of SelfClosingTag for < meta charset=\"UTF 8\" /> \n",
- " - Like the Hr subclass\n",
- " - Add Meta Element to beginning of head element to encode your document"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Html(Element):\n",
- " tag = 'html'\n",
- "\n",
- " def render(self, file_out, current_ind=\"\"):\n",
- " file_out.write(\"\\n\")\n",
- " Element.render(self, file_out, current_ind=current_ind)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### charset\n",
- "\n",
- "To display a page properly, the browser must know the character set used on the page. This is specified in the meta tag. \n",
- "\n",
- "< meta charset=\"UTF-8\" >"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Meta(SelfClosingTag):\n",
- " tag = \"meta\"\n",
- "\n",
- " def __init__(self, content=None, **attributes):\n",
- " # give it a default value for charset\n",
- " if \"charset\" not in attributes:\n",
- " attributes['charset'] = \"UTF-8\"\n",
- " SelfClosingTag.__init__(self, content, **attributes)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.4.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/HowToGetInitToUseYourSetter.ipynb b/notebooks/HowToGetInitToUseYourSetter.ipynb
deleted file mode 100644
index 463f62d..0000000
--- a/notebooks/HowToGetInitToUseYourSetter.ipynb
+++ /dev/null
@@ -1,161 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### In the following code we want to trigger the exception if we are not passed Bob Jones"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Person:\n",
- " def __init__(self, name=None):\n",
- " self._name=name # Note that we're calling the _attribute, not the @property\n",
- "\n",
- " @property\n",
- " def name(self):\n",
- " return self._name\n",
- "\n",
- " @name.setter\n",
- " def name(self,value):\n",
- " if not (value in ('Bob Jones')):\n",
- " raise Exception (\"Invalid Bob\")\n",
- " self._name = value"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "bob = Person(\"Bob Smith\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'Bob Smith'"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "bob.name"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Uh oh... Bob Smith is an invalid Bob... what went wrong? Let's try again...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Person:\n",
- " def __init__(self, name=None):\n",
- " self.name = name # Note that I'm calling the @property, not the _attribute.\n",
- "\n",
- " @property\n",
- " def name(self):\n",
- " return self._name\n",
- "\n",
- " @name.setter\n",
- " def name(self,value):\n",
- " if not (value in ('Bob Jones')):\n",
- " raise Exception (\"Invalid Bob\")\n",
- " self._name = value"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "Exception",
- "evalue": "Invalid Bob",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mException\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mbob\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPerson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Bob Smith\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mPerson\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m\u001b[0m in \u001b[0;36mname\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'Bob Jones'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid Bob\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;31mException\u001b[0m: Invalid Bob"
- ]
- }
- ],
- "source": [
- "bob = Person(\"Bob Smith\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "### See the difference? Look at the declaration of name vs \\_name in the \\_\\_init\\_\\_"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Lambda_Lab.ipynb b/notebooks/Lambda_Lab.ipynb
deleted file mode 100644
index 3d71703..0000000
--- a/notebooks/Lambda_Lab.ipynb
+++ /dev/null
@@ -1,256 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## What is lambda? \n",
- "\n",
- "- A shortcut for building one-off functions\n",
- "- Define functions in-line"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# Traditional function\n",
- "\n",
- "import math\n",
- "def square_root(x):\n",
- " return math.sqrt(x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# using lambda\n",
- "\n",
- "square_rt = lambda x: math.sqrt(x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "square_root(25)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5.0"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "square_rt(25)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## When should you use lambda? "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "- Functions that should only be used once\n",
- "- Code that only performs one, well-defined task\n",
- "- Passing a function to other functions\n",
- "- Cleaner code, avoid duplication"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "25"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# traditional function\n",
- "def square(x):\n",
- " return x**2\n",
- "square(5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "25"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# lambda\n",
- "square = lambda x: x**2\n",
- "square(5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[25]"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# list comprehension\n",
- "a = [5]\n",
- "[x**2 for x in a]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Lambda Lab"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# write a function\n",
- "def function_builder():\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# return a list of n functions\n",
- "\n",
- "def function_builder(n):\n",
- " func_list = []\n",
- " for i in range(n):\n",
- " func_list.append(insert lambda function here)\n",
- " return (func_list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# fill in lambda function"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# update function to use list comprehension"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/OfficeHours_2016-02-21.ipynb b/notebooks/OfficeHours_2016-02-21.ipynb
deleted file mode 100644
index 07d3251..0000000
--- a/notebooks/OfficeHours_2016-02-21.ipynb
+++ /dev/null
@@ -1,438 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyClass(object):\n",
- " my_class_attribute1 = \"This is a class attribute\"\n",
- " my_class_attribute2 = \"All instances of the class will have this\"\n",
- "\n",
- " def __init__(self, a, b):\n",
- " \"\"\"\n",
- " Define instance attributes here\n",
- " These will be unique to each instance of the class\n",
- " \"\"\"\n",
- " self.content = []\n",
- " self.x = a\n",
- " self.y = b\n",
- " \n",
- " def assign_content(self, my_list):\n",
- " self.content = my_list\n",
- " \n",
- " def show_me_my_content(self):\n",
- " print(self.content)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### I think of classes as templates or blueprints for instances of the class. It is an imperfect metaphor, yet perhaps useful. Remember that just about everything in Python is an object and dir() provides an easy way to inspect things. What do we get out of the gate once the class is defined? Note that we have not yet created an instance from it."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['__class__',\n",
- " '__delattr__',\n",
- " '__dict__',\n",
- " '__dir__',\n",
- " '__doc__',\n",
- " '__eq__',\n",
- " '__format__',\n",
- " '__ge__',\n",
- " '__getattribute__',\n",
- " '__gt__',\n",
- " '__hash__',\n",
- " '__init__',\n",
- " '__le__',\n",
- " '__lt__',\n",
- " '__module__',\n",
- " '__ne__',\n",
- " '__new__',\n",
- " '__reduce__',\n",
- " '__reduce_ex__',\n",
- " '__repr__',\n",
- " '__setattr__',\n",
- " '__sizeof__',\n",
- " '__str__',\n",
- " '__subclasshook__',\n",
- " '__weakref__',\n",
- " 'assign_content',\n",
- " 'my_class_attribute1',\n",
- " 'my_class_attribute2',\n",
- " 'show_me_my_content']"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(MyClass)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Now let's create an instance of the class."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_instance = MyClass(3,4)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What do we get once we have created an instance of the calss?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['__class__',\n",
- " '__delattr__',\n",
- " '__dict__',\n",
- " '__dir__',\n",
- " '__doc__',\n",
- " '__eq__',\n",
- " '__format__',\n",
- " '__ge__',\n",
- " '__getattribute__',\n",
- " '__gt__',\n",
- " '__hash__',\n",
- " '__init__',\n",
- " '__le__',\n",
- " '__lt__',\n",
- " '__module__',\n",
- " '__ne__',\n",
- " '__new__',\n",
- " '__reduce__',\n",
- " '__reduce_ex__',\n",
- " '__repr__',\n",
- " '__setattr__',\n",
- " '__sizeof__',\n",
- " '__str__',\n",
- " '__subclasshook__',\n",
- " '__weakref__',\n",
- " 'assign_content',\n",
- " 'content',\n",
- " 'my_class_attribute1',\n",
- " 'my_class_attribute2',\n",
- " 'show_me_my_content',\n",
- " 'x',\n",
- " 'y']"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(my_instance)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "a_list = ['a', 'b', 'c']"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_instance.assign_content(a_list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['a', 'b', 'c']\n"
- ]
- }
- ],
- "source": [
- "my_instance.show_me_my_content()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "b_list = [6, 7, 8]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_instance.assign_content(b_list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[6, 7, 8]\n"
- ]
- }
- ],
- "source": [
- "my_instance.show_me_my_content()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_second_instance = MyClass(4,5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_second_instance.assign_content(a_list)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Since .content is an instance attribute, each instance gets its own"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['a', 'b', 'c']\n"
- ]
- }
- ],
- "source": [
- "my_second_instance.show_me_my_content()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[6, 7, 8]\n"
- ]
- }
- ],
- "source": [
- "my_instance.show_me_my_content()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Need a little help? Try help()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on built-in function append:\n",
- "\n",
- "append(...) method of builtins.list instance\n",
- " L.append(object) -> None -- append object to end\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(a_list.append)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Fun with strings"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "string1 = \"string_one\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "string2 = \"string_two\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "string3 = string1 + string2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'string_onestring_two'"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "string3"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session05.ipynb b/notebooks/Session05.ipynb
deleted file mode 100644
index afa2bad..0000000
--- a/notebooks/Session05.ipynb
+++ /dev/null
@@ -1,1202 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Strings\n",
- "======="
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "stringa = \"this is a string\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'this is a string'"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "stringa"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "str"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(stringa)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "str"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(str(33.55))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "csv = \"123, 654, 26\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['123', '654', '26']"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "csv.split(', ')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "csv.split?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "pipe_separated_values = '|'.join(csv.split(', '))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'123|654|26'"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "pipe_separated_values"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Raw strings\n",
- "-----------"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "new_line = '\\n'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "There is going to be a space below this line\n",
- "\n",
- "and a line here at the bottom\n"
- ]
- }
- ],
- "source": [
- "print('There is going to be a space below this line' + new_line + new_line + 'and a line here at the bottom')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "raw_string = r'one\\two'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'one\\\\two'"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "raw_string"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "regular_string = 'one\\two'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'one\\two'"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "regular_string"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "one\two\n"
- ]
- }
- ],
- "source": [
- "print(regular_string)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "one\\two\n"
- ]
- }
- ],
- "source": [
- "print(raw_string)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 45,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "ename": "SyntaxError",
- "evalue": "EOL while scanning string literal (, line 1)",
- "output_type": "error",
- "traceback": [
- "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m this_is_bad = r\"\\\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n"
- ]
- }
- ],
- "source": [
- "this_is_bad = r\"\\\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "... so ya gotta ask yourself... how raw is raw?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 46,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "this_is_less_bad = r\"\\\\\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 47,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\\\\\n"
- ]
- }
- ],
- "source": [
- "print(this_is_less_bad)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "121\n",
- "111\n",
- "100\n",
- "97\n"
- ]
- }
- ],
- "source": [
- "for i in 'yoda':\n",
- " print(ord(i))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "yoda"
- ]
- }
- ],
- "source": [
- "for i in(\n",
- " 121,\n",
- " 111,\n",
- " 100,\n",
- " 97,\n",
- " ):\n",
- " print(chr(i), end='', )"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "string formatting\n",
- "-----------------"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Note use of stringa from way up top toward the beginning of the notebook."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "stringb = \"And here's another\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 38,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "\"Hello this is a string! And here's another\""
- ]
- },
- "execution_count": 38,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "'Hello {first_string}! {second_string}'.format(second_string=stringb, first_string=stringa, )"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Lab: string formatting\n",
- "-----------------------"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "http://uwpce-pythoncert.github.io/IntroPython2016a/exercises/string_formatting.html"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Files & Streams\n",
- "==============="
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 49,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Session05.ipynb students.txt\r\n"
- ]
- }
- ],
- "source": [
- "!ls"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "with open('students.txt', 'r') as f:\n",
- " read_data = f.read()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 52,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 52,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "f.closed"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'Bindhu, Krishna\\nBounds, Brennen\\nGregor, Michael\\nHolmer, Deana\\nKumar, Pradeep\\nRees, Susan\\nRudolph, John\\nSolomon, Tsega\\nWarren, Benjamin\\nAleson, Brandon\\nChang, Jaemin\\nChinn, Kyle\\nDerdouri, Abderrazak\\nFannin, Calvin\\nGaffney, Thomas\\nGlogowski, Bryan\\nHo, Chi Kin\\nMcKeag, Gregory\\nMyerscough, Damian\\nNewton, Michael\\nSarpangala, Kishan\\nSchincariol, Mike\\nZhao, Yuanrui\\n'"
- ]
- },
- "execution_count": 51,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "read_data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Bindhu, Krishna\n",
- "Bounds, Brennen\n",
- "Gregor, Michael\n",
- "Holmer, Deana\n",
- "Kumar, Pradeep\n",
- "Rees, Susan\n",
- "Rudolph, John\n",
- "Solomon, Tsega\n",
- "Warren, Benjamin\n",
- "Aleson, Brandon\n",
- "Chang, Jaemin\n",
- "Chinn, Kyle\n",
- "Derdouri, Abderrazak\n",
- "Fannin, Calvin\n",
- "Gaffney, Thomas\n",
- "Glogowski, Bryan\n",
- "Ho, Chi Kin\n",
- "McKeag, Gregory\n",
- "Myerscough, Damian\n",
- "Newton, Michael\n",
- "Sarpangala, Kishan\n",
- "Schincariol, Mike\n",
- "Zhao, Yuanrui\n",
- "\n"
- ]
- }
- ],
- "source": [
- "print(read_data)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 54,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import io"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['BlockingIOError',\n",
- " 'BufferedIOBase',\n",
- " 'BufferedRWPair',\n",
- " 'BufferedRandom',\n",
- " 'BufferedReader',\n",
- " 'BufferedWriter',\n",
- " 'BytesIO',\n",
- " 'DEFAULT_BUFFER_SIZE',\n",
- " 'FileIO',\n",
- " 'IOBase',\n",
- " 'IncrementalNewlineDecoder',\n",
- " 'OpenWrapper',\n",
- " 'RawIOBase',\n",
- " 'SEEK_CUR',\n",
- " 'SEEK_END',\n",
- " 'SEEK_SET',\n",
- " 'StringIO',\n",
- " 'TextIOBase',\n",
- " 'TextIOWrapper',\n",
- " 'UnsupportedOperation',\n",
- " '__all__',\n",
- " '__author__',\n",
- " '__builtins__',\n",
- " '__cached__',\n",
- " '__doc__',\n",
- " '__file__',\n",
- " '__loader__',\n",
- " '__name__',\n",
- " '__package__',\n",
- " '__spec__',\n",
- " '_io',\n",
- " 'abc',\n",
- " 'open']"
- ]
- },
- "execution_count": 55,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(io)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 56,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import os"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['CLD_CONTINUED',\n",
- " 'CLD_DUMPED',\n",
- " 'CLD_EXITED',\n",
- " 'CLD_TRAPPED',\n",
- " 'EX_CANTCREAT',\n",
- " 'EX_CONFIG',\n",
- " 'EX_DATAERR',\n",
- " 'EX_IOERR',\n",
- " 'EX_NOHOST',\n",
- " 'EX_NOINPUT',\n",
- " 'EX_NOPERM',\n",
- " 'EX_NOUSER',\n",
- " 'EX_OK',\n",
- " 'EX_OSERR',\n",
- " 'EX_OSFILE',\n",
- " 'EX_PROTOCOL',\n",
- " 'EX_SOFTWARE',\n",
- " 'EX_TEMPFAIL',\n",
- " 'EX_UNAVAILABLE',\n",
- " 'EX_USAGE',\n",
- " 'F_LOCK',\n",
- " 'F_OK',\n",
- " 'F_TEST',\n",
- " 'F_TLOCK',\n",
- " 'F_ULOCK',\n",
- " 'MutableMapping',\n",
- " 'NGROUPS_MAX',\n",
- " 'O_ACCMODE',\n",
- " 'O_APPEND',\n",
- " 'O_ASYNC',\n",
- " 'O_CLOEXEC',\n",
- " 'O_CREAT',\n",
- " 'O_DIRECTORY',\n",
- " 'O_DSYNC',\n",
- " 'O_EXCL',\n",
- " 'O_EXLOCK',\n",
- " 'O_NDELAY',\n",
- " 'O_NOCTTY',\n",
- " 'O_NOFOLLOW',\n",
- " 'O_NONBLOCK',\n",
- " 'O_RDONLY',\n",
- " 'O_RDWR',\n",
- " 'O_SHLOCK',\n",
- " 'O_SYNC',\n",
- " 'O_TRUNC',\n",
- " 'O_WRONLY',\n",
- " 'PRIO_PGRP',\n",
- " 'PRIO_PROCESS',\n",
- " 'PRIO_USER',\n",
- " 'P_ALL',\n",
- " 'P_NOWAIT',\n",
- " 'P_NOWAITO',\n",
- " 'P_PGID',\n",
- " 'P_PID',\n",
- " 'P_WAIT',\n",
- " 'RTLD_GLOBAL',\n",
- " 'RTLD_LAZY',\n",
- " 'RTLD_LOCAL',\n",
- " 'RTLD_NODELETE',\n",
- " 'RTLD_NOLOAD',\n",
- " 'RTLD_NOW',\n",
- " 'R_OK',\n",
- " 'SCHED_FIFO',\n",
- " 'SCHED_OTHER',\n",
- " 'SCHED_RR',\n",
- " 'SEEK_CUR',\n",
- " 'SEEK_END',\n",
- " 'SEEK_SET',\n",
- " 'ST_NOSUID',\n",
- " 'ST_RDONLY',\n",
- " 'TMP_MAX',\n",
- " 'WCONTINUED',\n",
- " 'WCOREDUMP',\n",
- " 'WEXITED',\n",
- " 'WEXITSTATUS',\n",
- " 'WIFCONTINUED',\n",
- " 'WIFEXITED',\n",
- " 'WIFSIGNALED',\n",
- " 'WIFSTOPPED',\n",
- " 'WNOHANG',\n",
- " 'WNOWAIT',\n",
- " 'WSTOPPED',\n",
- " 'WSTOPSIG',\n",
- " 'WTERMSIG',\n",
- " 'WUNTRACED',\n",
- " 'W_OK',\n",
- " 'X_OK',\n",
- " '_Environ',\n",
- " '__all__',\n",
- " '__builtins__',\n",
- " '__cached__',\n",
- " '__doc__',\n",
- " '__file__',\n",
- " '__loader__',\n",
- " '__name__',\n",
- " '__package__',\n",
- " '__spec__',\n",
- " '_execvpe',\n",
- " '_exists',\n",
- " '_exit',\n",
- " '_fwalk',\n",
- " '_get_exports_list',\n",
- " '_putenv',\n",
- " '_spawnvef',\n",
- " '_unsetenv',\n",
- " '_wrap_close',\n",
- " 'abort',\n",
- " 'access',\n",
- " 'altsep',\n",
- " 'chdir',\n",
- " 'chflags',\n",
- " 'chmod',\n",
- " 'chown',\n",
- " 'chroot',\n",
- " 'close',\n",
- " 'closerange',\n",
- " 'confstr',\n",
- " 'confstr_names',\n",
- " 'cpu_count',\n",
- " 'ctermid',\n",
- " 'curdir',\n",
- " 'defpath',\n",
- " 'device_encoding',\n",
- " 'devnull',\n",
- " 'dup',\n",
- " 'dup2',\n",
- " 'environ',\n",
- " 'environb',\n",
- " 'errno',\n",
- " 'error',\n",
- " 'execl',\n",
- " 'execle',\n",
- " 'execlp',\n",
- " 'execlpe',\n",
- " 'execv',\n",
- " 'execve',\n",
- " 'execvp',\n",
- " 'execvpe',\n",
- " 'extsep',\n",
- " 'fchdir',\n",
- " 'fchmod',\n",
- " 'fchown',\n",
- " 'fdopen',\n",
- " 'fork',\n",
- " 'forkpty',\n",
- " 'fpathconf',\n",
- " 'fsdecode',\n",
- " 'fsencode',\n",
- " 'fstat',\n",
- " 'fstatvfs',\n",
- " 'fsync',\n",
- " 'ftruncate',\n",
- " 'fwalk',\n",
- " 'get_blocking',\n",
- " 'get_exec_path',\n",
- " 'get_inheritable',\n",
- " 'get_terminal_size',\n",
- " 'getcwd',\n",
- " 'getcwdb',\n",
- " 'getegid',\n",
- " 'getenv',\n",
- " 'getenvb',\n",
- " 'geteuid',\n",
- " 'getgid',\n",
- " 'getgrouplist',\n",
- " 'getgroups',\n",
- " 'getloadavg',\n",
- " 'getlogin',\n",
- " 'getpgid',\n",
- " 'getpgrp',\n",
- " 'getpid',\n",
- " 'getppid',\n",
- " 'getpriority',\n",
- " 'getsid',\n",
- " 'getuid',\n",
- " 'initgroups',\n",
- " 'isatty',\n",
- " 'kill',\n",
- " 'killpg',\n",
- " 'lchflags',\n",
- " 'lchmod',\n",
- " 'lchown',\n",
- " 'linesep',\n",
- " 'link',\n",
- " 'listdir',\n",
- " 'lockf',\n",
- " 'lseek',\n",
- " 'lstat',\n",
- " 'major',\n",
- " 'makedev',\n",
- " 'makedirs',\n",
- " 'minor',\n",
- " 'mkdir',\n",
- " 'mkfifo',\n",
- " 'mknod',\n",
- " 'name',\n",
- " 'nice',\n",
- " 'open',\n",
- " 'openpty',\n",
- " 'pardir',\n",
- " 'path',\n",
- " 'pathconf',\n",
- " 'pathconf_names',\n",
- " 'pathsep',\n",
- " 'pipe',\n",
- " 'popen',\n",
- " 'pread',\n",
- " 'putenv',\n",
- " 'pwrite',\n",
- " 'read',\n",
- " 'readlink',\n",
- " 'readv',\n",
- " 'remove',\n",
- " 'removedirs',\n",
- " 'rename',\n",
- " 'renames',\n",
- " 'replace',\n",
- " 'rmdir',\n",
- " 'scandir',\n",
- " 'sched_get_priority_max',\n",
- " 'sched_get_priority_min',\n",
- " 'sched_yield',\n",
- " 'sendfile',\n",
- " 'sep',\n",
- " 'set_blocking',\n",
- " 'set_inheritable',\n",
- " 'setegid',\n",
- " 'seteuid',\n",
- " 'setgid',\n",
- " 'setgroups',\n",
- " 'setpgid',\n",
- " 'setpgrp',\n",
- " 'setpriority',\n",
- " 'setregid',\n",
- " 'setreuid',\n",
- " 'setsid',\n",
- " 'setuid',\n",
- " 'spawnl',\n",
- " 'spawnle',\n",
- " 'spawnlp',\n",
- " 'spawnlpe',\n",
- " 'spawnv',\n",
- " 'spawnve',\n",
- " 'spawnvp',\n",
- " 'spawnvpe',\n",
- " 'st',\n",
- " 'stat',\n",
- " 'stat_float_times',\n",
- " 'stat_result',\n",
- " 'statvfs',\n",
- " 'statvfs_result',\n",
- " 'strerror',\n",
- " 'supports_bytes_environ',\n",
- " 'supports_dir_fd',\n",
- " 'supports_effective_ids',\n",
- " 'supports_fd',\n",
- " 'supports_follow_symlinks',\n",
- " 'symlink',\n",
- " 'sync',\n",
- " 'sys',\n",
- " 'sysconf',\n",
- " 'sysconf_names',\n",
- " 'system',\n",
- " 'tcgetpgrp',\n",
- " 'tcsetpgrp',\n",
- " 'terminal_size',\n",
- " 'times',\n",
- " 'times_result',\n",
- " 'truncate',\n",
- " 'ttyname',\n",
- " 'umask',\n",
- " 'uname',\n",
- " 'uname_result',\n",
- " 'unlink',\n",
- " 'unsetenv',\n",
- " 'urandom',\n",
- " 'utime',\n",
- " 'wait',\n",
- " 'wait3',\n",
- " 'wait4',\n",
- " 'waitpid',\n",
- " 'walk',\n",
- " 'write',\n",
- " 'writev']"
- ]
- },
- "execution_count": 57,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(os)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Lab: files\n",
- "---------"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "http://uwpce-pythoncert.github.io/IntroPython2016a/session05.html#lab-files"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Session05.ipynb students.txt\r\n"
- ]
- }
- ],
- "source": [
- "!ls"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 60,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Bindhu, Krishna: \r\n",
- "Bounds, Brennen: English\r\n",
- "Gregor, Michael: English\r\n",
- "Holmer, Deana: SQL, English\r\n",
- "Kumar, Pradeep: English, Hindi, Python, shell, d2k, SQL, Perl\r\n",
- "Rees, Susan: English, Latin, HTML, CSS, Javascript, Ruby, SQL\r\n",
- "Rudolph, John: English, Python, Sass, R, Basic\r\n",
- "Solomon, Tsega: C, C++, Perl, VHDL, Verilog, Specman\r\n",
- "Warren, Benjamin: English\r\n",
- "Aleson, Brandon: English\r\n",
- "Chang, Jaemin: English\r\n",
- "Chinn, Kyle: English\r\n",
- "Derdouri, Abderrazak: English\r\n",
- "Fannin, Calvin: C#, SQL, R\r\n",
- "Gaffney, Thomas: SQL, Python, R, VBA, English\r\n",
- "Glogowski, Bryan: Basic, Pascal, C, Perl, Ruby\r\n",
- "Ganzalez, Luis: Basic, C++, Python, English, Spanish\r\n",
- "Ho, Chi Kin: English\r\n",
- "McKeag, Gregory: C, Lisp, C++, Objective-C, SQL, R, Pascal, Ada, Perl, Prolog, Scheme, Assembley\r\n",
- "Myerscough, Damian: \r\n",
- "Newton, Michael: Python, Perl, Matlab\r\n",
- "Sarpangala, Kishan: \r\n",
- "Schincariol, Mike: Python, C#, C, Tcl, VBA, Perl, Bash, VHDL, Verilog, Matlab\r\n",
- "Zhao, Yuanrui: "
- ]
- }
- ],
- "source": [
- "!cat students.txt"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 70,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " \n",
- "\n",
- " English\n",
- "\n",
- " English\n",
- "\n",
- " SQL, English\n",
- "\n",
- " English, Hindi, Python, shell, d2k, SQL, Perl\n",
- "\n",
- " English, Latin, HTML, CSS, Javascript, Ruby, SQL\n",
- "\n",
- " English, Python, Sass, R, Basic\n",
- "\n",
- " C, C++, Perl, VHDL, Verilog, Specman\n",
- "\n",
- " English\n",
- "\n",
- " English\n",
- "\n",
- " English\n",
- "\n",
- " English\n",
- "\n",
- " English\n",
- "\n",
- " C#, SQL, R\n",
- "\n",
- " SQL, Python, R, VBA, English\n",
- "\n",
- " Basic, Pascal, C, Perl, Ruby\n",
- "\n",
- " Basic, C++, Python, English, Spanish\n",
- "\n",
- " English\n",
- "\n",
- " C, Lisp, C++, Objective-C, SQL, R, Pascal, Ada, Perl, Prolog, Scheme, Assembley\n",
- "\n",
- " \n",
- "\n",
- " Python, Perl, Matlab\n",
- "\n",
- " \n",
- "\n",
- " Python, C#, C, Tcl, VBA, Perl, Bash, VHDL, Verilog, Matlab\n",
- "\n",
- " \n"
- ]
- }
- ],
- "source": [
- "with open('students.txt', 'r') as f:\n",
- " for line in f:\n",
- " student_languages = line.rsplit(':')[1]\n",
- " print(student_languages)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 75,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{' C', ' \\n', ' English', ' HTML', ' Javascript', ' Verilog', ' Bash', ' VHDL', ' Python', ' English\\n', ' Matlab\\n', ' Perl\\n', ' Spanish\\n', ' ', ' Ruby', ' Sass', ' Pascal', ' d2k', ' C++', ' Prolog', ' C#', ' Specman\\n', ' SQL\\n', ' Tcl', ' Assembley\\n', ' Basic', ' R\\n', ' Perl', ' Ada', ' Scheme', ' Latin', ' Hindi', ' Basic\\n', ' R', ' Lisp', ' shell', ' VBA', ' CSS', ' SQL', ' Ruby\\n', ' Objective-C'}\n"
- ]
- }
- ],
- "source": [
- "language_set = set()\n",
- "with open('students.txt', 'r') as f:\n",
- " for line in f:\n",
- " student_languages = line.rsplit(':')[1]\n",
- " language_list = student_languages.split(',')\n",
- " for language in language_list:\n",
- " language_set.add(language)\n",
- "print(language_set)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "Check out Mike's work on this lab\n",
- "---------------------------------"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "https://github.com/UWPCE-PythonCert/IntroPython2016a/tree/master/students/MikeSchincariol"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session06.ipynb b/notebooks/Session06.ipynb
deleted file mode 100644
index 94e4a4b..0000000
--- a/notebooks/Session06.ipynb
+++ /dev/null
@@ -1,654 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Exceptions"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Set up and catch an IO Error"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "couldn't open missing.txt\n"
- ]
- }
- ],
- "source": [
- "try:\n",
- " do_something()\n",
- " f = open('missing.txt')\n",
- " process(f) # never called if file missing\n",
- "except:\n",
- " print(\"couldn't open missing.txt\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Cleaner to move the processing elsewhere so that you better know the error you're trapping."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "couldn't open missing.txt\n"
- ]
- }
- ],
- "source": [
- "try:\n",
- " do_something()\n",
- " f = open('missing.txt')\n",
- "except:\n",
- " print(\"couldn't open missing.txt\")\n",
- "else:\n",
- " process(f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### We covered context managers last week"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "couldn't open missing.txt\n"
- ]
- }
- ],
- "source": [
- "try:\n",
- " do_something()\n",
- " with open('missing.txt') as f:\n",
- " process(f)\n",
- "except:\n",
- " print(\"couldn't open missing.txt\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Advanced Argument Passing"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Be careful to actually call() a method() when() you() intend() to()."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "donor_name = 'Exit'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "bye\n"
- ]
- }
- ],
- "source": [
- "if donor_name.lower() == 'exit':\n",
- " print(\"bye\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "builtin_function_or_method"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(donor_name.lower)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "str"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(donor_name.lower())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### kwargs (key word arguments)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def myfunc(a=0, b=1, c=2):\n",
- " print(a, b, c)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0 1 2\n"
- ]
- }
- ],
- "source": [
- "myfunc()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "5 1 22\n"
- ]
- }
- ],
- "source": [
- "myfunc(5, c=22)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0 3232 456\n"
- ]
- }
- ],
- "source": [
- "myfunc(c=456, b=3232)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Positional and keyword args mixed, note that the positionals come first, which makes perfect sense and leads to some handy properties"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 41,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def my_positional_and_kwargs_func(x, y, z=\"Hi I'm z\", a=\"Hi I'm a\"):\n",
- " print(a, x, y, z, end=\" \")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 42,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 42,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_positional_and_kwargs_func"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Python can be helpful and explicit when you don't call a funciton correctly"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 43,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "ename": "TypeError",
- "evalue": "my_positional_and_kwargs_func() missing 2 required positional arguments: 'x' and 'y'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_positional_and_kwargs_func\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m: my_positional_and_kwargs_func() missing 2 required positional arguments: 'x' and 'y'"
- ]
- }
- ],
- "source": [
- "my_positional_and_kwargs_func()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Hi I'm a Hi I'm x Hi I'm y No, I'm asdfasdf "
- ]
- }
- ],
- "source": [
- "my_positional_and_kwargs_func(\"Hi I'm x\", \"Hi I'm y\", z=\"No, I'm asdfasdf\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Now that you know that kwargs are represented by dictionaries, what else can you do?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "mydict = {\"last_name\": 'Grimes', \"first_name\": 'Rick'}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'my name is Rick Grimes'"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\"my name is {first_name} {last_name}\".format(**mydict)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Dict as switch"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "switch_dict = {\n",
- " 0: 'zero',\n",
- " 1: 'one',\n",
- " 2: 'two',\n",
- "}"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Note that the values in the dictionary are strings."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'zero'"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_dict.get(0)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'two'"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_dict.get(2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Supplying a default"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'or nothing'"
- ]
- },
- "execution_count": 57,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_dict.get(234234, \"or nothing\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What would this be like if you used functions instead? Think of the possibilities."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def my_zero_func():\n",
- " return \"I'm zero\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def my_one_func():\n",
- " return \"I'm one\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "switch_func_dict = {\n",
- " 0: my_zero_func,\n",
- " 1: my_one_func,\n",
- "}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "\"I'm zero\""
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_func_dict.get(0)()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "\"I'm one\""
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_func_dict.get(1)()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### If you try something like this, don't forget to make the call()! Otherwise...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "switch_func_dict.get(1) # Missing the final ()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session07.ipynb b/notebooks/Session07.ipynb
deleted file mode 100644
index 5db9c2f..0000000
--- a/notebooks/Session07.ipynb
+++ /dev/null
@@ -1,300 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 111,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Point(object):\n",
- " \"\"\" All instances of a class get the same class attributes. \"\"\"\n",
- " size = 4\n",
- " color = 'red'\n",
- " \n",
- " def __init__(self, x, y):\n",
- " \"\"\" These are instance attributes, unique to each instance. \"\"\"\n",
- " self.origin = 0\n",
- " self.x = x\n",
- " self.y = y\n",
- " self.z = x * y -2\n",
- " \n",
- " def get_color(self):\n",
- " \"\"\" Compare to print_color() \"\"\"\n",
- " return self.color\n",
- " \n",
- " def print_color():\n",
- " \"\"\" Compare to get_color() \"\"\"\n",
- " return self.color\n",
- " \n",
- " def gimme_two_values(bob, a, b):\n",
- " \"\"\"\n",
- " Is 'self' a keyword? No, but it's a strong convention.\n",
- " Most programmers would say using 'bob' in this context simply looks wrong.\n",
- " \"\"\"\n",
- " bob.x = a\n",
- " bob.y = b"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 102,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_point = Point(2, 3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 103,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_other_point = Point(4, 5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 104,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_point.gimme_two_values(54, 765)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": false
- },
- "source": [
- "The interpreter is doing something close to this:\n",
- "\n",
- " Point.gimme_two_values(my_point, 54, 765)\n",
- "\n",
- "...and the first argument is silently or implicitly passed in, and by convention is referred to as self."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": false
- },
- "source": [
- "### Both my_point and my_other_point have access to the class attributes:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 105,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'red'"
- ]
- },
- "execution_count": 105,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_point.get_color()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 106,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'red'"
- ]
- },
- "execution_count": 106,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_other_point.get_color()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Both have their own instance attributes:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 107,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "54"
- ]
- },
- "execution_count": 107,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_point.x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 108,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "4"
- ]
- },
- "execution_count": 108,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_other_point.x"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Note that get_color() works:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 109,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'red'"
- ]
- },
- "execution_count": 109,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_point.get_color()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": false
- },
- "source": [
- "### Whereas my_point.print_color() is broken:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 110,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "TypeError",
- "evalue": "print_color() takes 0 positional arguments but 1 was given",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_point\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprint_color\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m: print_color() takes 0 positional arguments but 1 was given"
- ]
- }
- ],
- "source": [
- "my_point.print_color()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "#### ...and this is should help explian how the first argument to a method (self) works."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session08.ipynb b/notebooks/Session08.ipynb
deleted file mode 100644
index f1f05ad..0000000
--- a/notebooks/Session08.ipynb
+++ /dev/null
@@ -1,732 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Basic, single inheritance"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class A:\n",
- " def hello(self):\n",
- " print(\"Hi\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class B(A):\n",
- " def hello(self):\n",
- " # super().hello()\n",
- " print(\"there\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "b = B()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "there\n"
- ]
- }
- ],
- "source": [
- "b.hello()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### What's my MRO?"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Good insights to be got for calling help() on a class or instance:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on class B in module __main__:\n",
- "\n",
- "class B(A)\n",
- " | Method resolution order:\n",
- " | B\n",
- " | A\n",
- " | builtins.object\n",
- " | \n",
- " | Methods defined here:\n",
- " | \n",
- " | hello(self)\n",
- " | \n",
- " | ----------------------------------------------------------------------\n",
- " | Data descriptors inherited from A:\n",
- " | \n",
- " | __dict__\n",
- " | dictionary for instance variables (if defined)\n",
- " | \n",
- " | __weakref__\n",
- " | list of weak references to the object (if defined)\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(B)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Animal Kingdom"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Animal(object):\n",
- "\n",
- " def __init__(self):\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Mammal(Animal):\n",
- " gestation_in_a_womb = True\n",
- " warm_blood = True\n",
- " \n",
- " def __init__(self):\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Reptile(Animal):\n",
- " gestation_in_a_womb = False\n",
- " warm_blood = False\n",
- " \n",
- " def __init__(self):\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_mammal = Mammal()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_mammal.gestation_in_a_womb"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_reptile = Reptile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_reptile.gestation_in_a_womb"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Bird(Reptile):\n",
- " warm_blood = True\n",
- "\n",
- " def __init__(self):\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Snake(Reptile):\n",
- " \n",
- " def __init__(self):\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Dog(Mammal):\n",
- "\n",
- " def __init__(self, chases_cats=True):\n",
- " self.chases_cats = chases_cats\n",
- " pass\n",
- " \n",
- " def make_me_cold_blooded(self):\n",
- " self.warm_blood = False"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Cat(Mammal):\n",
- " \n",
- " def __init__(self, hates_dogs=True):\n",
- " self.hates_dogs = hates_dogs\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_dog = Dog(chases_cats=False)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_dog.chases_cats"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_dog.make_me_cold_blooded()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_dog.warm_blood"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 104,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_cat = Cat()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 105,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 105,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_cat.hates_dogs"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 106,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_dog.warm_blood = False"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 107,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "False"
- ]
- },
- "execution_count": 107,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_dog.warm_blood"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def main():\n",
- " pass"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 62,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "if __name__ == '__main__':\n",
- " main()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "# We got to about this point in class. I'm going to play around a little more in this space with in the hope of providing a few more insights."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's start at the top of the heirarchy. What else can we say about animals in general, or perhaps about any specific animal in particular?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 113,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Animal(object):\n",
- "\n",
- " def __init__(self, age=0, location=0, weight=0):\n",
- " self.age = age\n",
- " self.location = location\n",
- " self.weight = weight\n",
- " pass"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Or perhaps better if we start to handle arguments more gracefully..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Animal(object):\n",
- "\n",
- " def __init__(self, **kwargs):\n",
- " \n",
- " if 'age' in kwargs:\n",
- " self.age = kwargs['age']\n",
- " else:\n",
- " self.age = 0\n",
- " \n",
- " if 'location' in kwargs:\n",
- " self.location = kwargs['location']\n",
- " else:\n",
- " self.location = 0\n",
- "\n",
- " if 'weight' in kwargs:\n",
- " self.weight = kwargs['weight']\n",
- " else:\n",
- " self.weight = 0\n",
- " \n",
- " super().__init__()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Let's clean up Mammal while we're at it..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Mammal(Animal):\n",
- " gestation_in_a_womb = True\n",
- " warm_blood = True\n",
- " \n",
- " def __init__(self, **kwargs):\n",
- " super().__init__(**kwargs)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### How can we make Dog() more interesting? Let's check inputs against a collection of known breeds..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Dog(Mammal):\n",
- " breeds = ('Chow', 'Lab', 'Poodle', 'Samiod')\n",
- " \n",
- " def __init__(self, **kwargs):\n",
- "\n",
- " if 'breed' in kwargs and kwargs['breed'] in self.breeds:\n",
- " self.breed = kwargs['breed']\n",
- " else: self.breed = 'unknown'\n",
- "\n",
- " if 'chases_cats' in kwargs:\n",
- " self.chases_cats = kwargs['chases_cats']\n",
- " else:\n",
- " self.chases_cats = True\n",
- " \n",
- " super().__init__(**kwargs)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_dog = Dog(age=14, breed='Chow')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Note that we didn't handle .age until all the way back up in the parent Animal() class, passing it up through Mammal(), yet our dog still has a .age"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_dog.age"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'age': 14, 'breed': 'Chow', 'chases_cats': True, 'location': 0, 'weight': 0}"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_dog.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### We started talking about multiple inheritance. Let's touch on that..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Reptile(Animal):\n",
- " gestation_in_a_womb = False\n",
- " warm_blood = False\n",
- "\n",
- " def __init__(self, **kwargs):\n",
- " super().__init__(**kwargs)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class Platypus(Mammal, Reptile):\n",
- " gestation_in_a_womb = False\n",
- " warm_blood = True\n",
- " \n",
- " def __init__(self, **kwargs):\n",
- " super().__init__(**kwargs)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_platypus = Platypus(weight=30)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### All for now. Take over for me. :)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session09.ipynb b/notebooks/Session09.ipynb
deleted file mode 100644
index 23660ac..0000000
--- a/notebooks/Session09.ipynb
+++ /dev/null
@@ -1,839 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Composition"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Lifted mostly from Learn Python the Hard Way"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "http://learnpythonthehardway.org/book/ex44.html"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Other(object):\n",
- " \n",
- " def __init__(self):\n",
- " print(\"Other __init__\")\n",
- " \n",
- " def override(self):\n",
- " print(\"Other override()\")\n",
- " \n",
- " def implicit(self):\n",
- " print(\"Other implicit()\")\n",
- " \n",
- " def altered(self):\n",
- " print(\"Other altered()\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 59,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyComposedClass(object):\n",
- " \"\"\" I use Other, but I do not inherit from it \"\"\"\n",
- " \n",
- " def __init__(self):\n",
- " self.other = Other()\n",
- " \n",
- " def implicit(self):\n",
- " '''\n",
- " I do nothing myself, I delegate\n",
- " '''\n",
- " self.other.implicit()\n",
- " \n",
- " def override(self):\n",
- " \"\"\"\n",
- " I simply choose to ignore self.other.override()\n",
- " and instead do the work myself\n",
- " \"\"\"\n",
- " print(\"MyComposedClass override()\")\n",
- " \n",
- " def altered(self):\n",
- " \"\"\"\n",
- " I do some work myself, yet also delegate\n",
- " \"\"\"\n",
- " print(\"MyComposedClass, BEFORE OTHER altered()\")\n",
- " self.other.altered()\n",
- " print(\"MyComposedClass, AFTER OTHER altered()\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 60,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Other __init__\n"
- ]
- }
- ],
- "source": [
- "my_composed_class = MyComposedClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Other implicit()\n"
- ]
- }
- ],
- "source": [
- "my_composed_class.implicit()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 62,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "MyComposedClass override()\n"
- ]
- }
- ],
- "source": [
- "my_composed_class.override()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 63,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "MyComposedClass, BEFORE OTHER altered()\n",
- "Other altered()\n",
- "MyComposedClass, AFTER OTHER altered()\n"
- ]
- }
- ],
- "source": [
- "my_composed_class.altered()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Properties"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyClass(object):\n",
- " \n",
- " def __init__(self):\n",
- " self._x = 5\n",
- " \n",
- " def get_x(self):\n",
- " return self._x\n",
- " \n",
- " def set_x(self, x):\n",
- " if 2 < x < 9:\n",
- " self._x = x\n",
- " else:\n",
- " raise ValueError(\"Whoa, what are you thinking?\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_class = MyClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_class.get_x()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_class.set_x(4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "ValueError",
- "evalue": "Whoa, what are you thinking?",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m11\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;32m\u001b[0m in \u001b[0;36mset_x\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_x\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Whoa, what are you thinking?\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m: Whoa, what are you thinking?"
- ]
- }
- ],
- "source": [
- "my_class.set_x(11)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Okay, basic stuff here... what's the big deal? What if you have a few instances of MyClass floating around and you want to do some work with their attributes...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_other_class = MyClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "ValueError",
- "evalue": "Whoa, what are you thinking?",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmy_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mmy_other_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_x\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;32m\u001b[0m in \u001b[0;36mset_x\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_x\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Whoa, what are you thinking?\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m: Whoa, what are you thinking?"
- ]
- }
- ],
- "source": [
- "my_class.set_x(my_class.get_x() + my_other_class.get_x())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "4"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_class.get_x()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### That worked, but it sure was ugly. Note that the throwing of the exception was deliberate and planned! I set x to a value outside its perscribed range. The uglyness is in having to access an attribute via a method call. I'd rather do something like this..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_class._x = my_class._x + my_other_class._x"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### That was easy, the syntax clear, but I now have a value for x in my_class that is out of range: x should never be equal to or greater than 9! Oh no! The internal consistancy of my object has been violated! Mayhem ensues...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 64,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "9"
- ]
- },
- "execution_count": 64,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_class._x"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Enter properties!"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on class property in module builtins:\n",
- "\n",
- "class property(object)\n",
- " | property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n",
- " | \n",
- " | fget is a function to be used for getting an attribute value, and likewise\n",
- " | fset is a function for setting, and fdel a function for del'ing, an\n",
- " | attribute. Typical use is to define a managed attribute x:\n",
- " | \n",
- " | class C(object):\n",
- " | def getx(self): return self._x\n",
- " | def setx(self, value): self._x = value\n",
- " | def delx(self): del self._x\n",
- " | x = property(getx, setx, delx, \"I'm the 'x' property.\")\n",
- " | \n",
- " | Decorators make defining new properties or modifying existing ones easy:\n",
- " | \n",
- " | class C(object):\n",
- " | @property\n",
- " | def x(self):\n",
- " | \"I am the 'x' property.\"\n",
- " | return self._x\n",
- " | @x.setter\n",
- " | def x(self, value):\n",
- " | self._x = value\n",
- " | @x.deleter\n",
- " | def x(self):\n",
- " | del self._x\n",
- " | \n",
- " | Methods defined here:\n",
- " | \n",
- " | __delete__(self, instance, /)\n",
- " | Delete an attribute of instance.\n",
- " | \n",
- " | __get__(self, instance, owner, /)\n",
- " | Return an attribute of instance, which is of type owner.\n",
- " | \n",
- " | __getattribute__(self, name, /)\n",
- " | Return getattr(self, name).\n",
- " | \n",
- " | __init__(self, /, *args, **kwargs)\n",
- " | Initialize self. See help(type(self)) for accurate signature.\n",
- " | \n",
- " | __new__(*args, **kwargs) from builtins.type\n",
- " | Create and return a new object. See help(type) for accurate signature.\n",
- " | \n",
- " | __set__(self, instance, value, /)\n",
- " | Set an attribute of instance to value.\n",
- " | \n",
- " | deleter(...)\n",
- " | Descriptor to change the deleter on a property.\n",
- " | \n",
- " | getter(...)\n",
- " | Descriptor to change the getter on a property.\n",
- " | \n",
- " | setter(...)\n",
- " | Descriptor to change the setter on a property.\n",
- " | \n",
- " | ----------------------------------------------------------------------\n",
- " | Data descriptors defined here:\n",
- " | \n",
- " | __isabstractmethod__\n",
- " | \n",
- " | fdel\n",
- " | \n",
- " | fget\n",
- " | \n",
- " | fset\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(property)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyNewClass(object):\n",
- " \n",
- " def __init__(self):\n",
- " self._x = 5\n",
- " self._y = 33\n",
- " \n",
- " def get_x(self):\n",
- " return self._x\n",
- " \n",
- " def set_x(self, x):\n",
- " if 2 < x < 9:\n",
- " self._x = x\n",
- " else:\n",
- " raise ValueError(\"Whoa, what are you thinking?\")\n",
- " \n",
- " x = property(get_x, set_x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_new_class = MyNewClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 27,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_new_class.x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_new_class.x = 4"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "4"
- ]
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_new_class.x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "ValueError",
- "evalue": "Whoa, what are you thinking?",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_new_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m99\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;32m\u001b[0m in \u001b[0;36mset_x\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_x\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Whoa, what are you thinking?\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mproperty\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mget_x\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mset_x\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;31mValueError\u001b[0m: Whoa, what are you thinking?"
- ]
- }
- ],
- "source": [
- "my_new_class.x = 99"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 32,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "AttributeError",
- "evalue": "'MyClass' object has no attribute 'x'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_new_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmy_new_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mmy_other_class\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mAttributeError\u001b[0m: 'MyClass' object has no attribute 'x'"
- ]
- }
- ],
- "source": [
- "my_new_class.x = my_new_class.x + my_other_class.x"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Let's refactor the class to use decorators rather than a call to the property() built-in"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 47,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "class MyDecoratedClass(object):\n",
- " \n",
- " def __init__(self):\n",
- " self._x = 5\n",
- " self._y = 33\n",
- " \n",
- "# def get_x(self):\n",
- "# return self._x\n",
- "\n",
- " @property\n",
- " def x(self):\n",
- " return self._x\n",
- " \n",
- "# def set_x(self, x):\n",
- "# if 2 < x < 9:\n",
- "# self._x = x\n",
- "# else:\n",
- "# raise ValueError(\"Whoa, what are you thinking?\")\n",
- "\n",
- " @x.setter\n",
- " def x(self, x):\n",
- " if 2 < x < 9:\n",
- " self._x = x\n",
- " else:\n",
- " raise ValueError(\"Whoa, what are you thinking?\")\n",
- "\n",
- " def make_me_a_sandwhich(self):\n",
- " pass\n",
- "\n",
- " # x = property(get_x, set_x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 48,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_decorated_class = MyDecoratedClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 49,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_decorated_class.x = my_decorated_class.x + 1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 50,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_decorated_class.x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_decorated_class.x += 1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 52,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "7"
- ]
- },
- "execution_count": 52,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_decorated_class.x"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### To create a read-only attribute... don't define the setter"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class MyReadOnlyClass(object):\n",
- " \n",
- " def __init__(self):\n",
- " self._x = 5\n",
- " \n",
- " @property\n",
- " def x(self):\n",
- " return self._x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 54,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_read_only = MyReadOnlyClass()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 55,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_read_only.x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 56,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "AttributeError",
- "evalue": "can't set attribute",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_read_only\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[0;31mAttributeError\u001b[0m: can't set attribute"
- ]
- }
- ],
- "source": [
- "my_read_only.x = 6"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/Session10.ipynb b/notebooks/Session10.ipynb
deleted file mode 100644
index 25775f6..0000000
--- a/notebooks/Session10.ipynb
+++ /dev/null
@@ -1,1536 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Functional Programming"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## map()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "l = [2, 5, 7, 12, 6, 4]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def fun(x):\n",
- " return x * 2 + 10"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "m = map(fun, l)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "m"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "map"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(m)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[14, 20, 24, 34, 22, 18]"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "list(m)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Or, use a comprehension to accomplish the same thing in a single line!"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_new_list = [x * 2 + 10 for x in l]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[14, 20, 24, 34, 22, 18]"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_new_list"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## filter()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def fil(x):\n",
- " return x%2 == 0"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "f = filter(fil, l)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[2, 12, 6, 4]"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "list(f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Or, use a comprehension to accomplish the same thing in a single line!"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[2, 12, 6, 4]"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x for x in l if x%2 == 0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### A comprehension implimenting both map and filter..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[4, 14, 8, 6]"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[y+2 for y in l if y%2 == 0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Comprehensions as looping constructs"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0\n",
- "1\n",
- "4\n"
- ]
- }
- ],
- "source": [
- "for x in range(3):\n",
- " print(x ** 2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### The simple for loop can above can be expressed as the comprehension below"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 107,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[0, 1, 4]"
- ]
- },
- "execution_count": 107,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x ** 2 for x in range(3)]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2\n",
- "6\n",
- "10\n"
- ]
- }
- ],
- "source": [
- "for x in range(6):\n",
- " if x%2 !=0:\n",
- " print(x*2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### The for loop with an 'if' above can be expressed as a comprehension with the filter clause below"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[2, 6, 10]"
- ]
- },
- "execution_count": 28,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x*2 for x in range(6) if x%2 !=0]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 115,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0\n",
- "1\n",
- "2\n",
- "0\n",
- "1\n",
- "2\n",
- "0\n",
- "1\n",
- "2\n",
- "0\n",
- "1\n",
- "2\n",
- "0\n",
- "1\n",
- "2\n",
- "0\n",
- "1\n",
- "2\n"
- ]
- }
- ],
- "source": [
- "for x in range(6): # six iterations...\n",
- " for y in range(3): # of 0, 1, 2\n",
- " print(y)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 125,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]"
- ]
- },
- "execution_count": 125,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[[y for y in range(3)] for x in range(6)] # six lists of [0, 1, 2]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 123,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]"
- ]
- },
- "execution_count": 123,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "sum([[y for y in range(3)] for x in range(6)], []) # Flatten nested lists with sum(list,[])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 134,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[1, 2]"
- ]
- },
- "execution_count": 134,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x for x in range(3) if x in [1, 2, 3]]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Getting creative"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['ArithmeticError',\n",
- " 'AssertionError',\n",
- " 'AttributeError',\n",
- " 'BlockingIOError',\n",
- " 'BrokenPipeError',\n",
- " 'BufferError',\n",
- " 'ChildProcessError',\n",
- " 'ConnectionAbortedError',\n",
- " 'ConnectionError',\n",
- " 'ConnectionRefusedError',\n",
- " 'ConnectionResetError',\n",
- " 'EOFError',\n",
- " 'EnvironmentError',\n",
- " 'FileExistsError',\n",
- " 'FileNotFoundError',\n",
- " 'FloatingPointError',\n",
- " 'IOError',\n",
- " 'ImportError',\n",
- " 'IndentationError',\n",
- " 'IndexError',\n",
- " 'InterruptedError',\n",
- " 'IsADirectoryError',\n",
- " 'KeyError',\n",
- " 'LookupError',\n",
- " 'MemoryError',\n",
- " 'NameError',\n",
- " 'NotADirectoryError',\n",
- " 'NotImplementedError',\n",
- " 'OSError',\n",
- " 'OverflowError',\n",
- " 'PermissionError',\n",
- " 'ProcessLookupError',\n",
- " 'RecursionError',\n",
- " 'ReferenceError',\n",
- " 'RuntimeError',\n",
- " 'SyntaxError',\n",
- " 'SystemError',\n",
- " 'TabError',\n",
- " 'TimeoutError',\n",
- " 'TypeError',\n",
- " 'UnboundLocalError',\n",
- " 'UnicodeDecodeError',\n",
- " 'UnicodeEncodeError',\n",
- " 'UnicodeError',\n",
- " 'UnicodeTranslateError',\n",
- " 'ValueError',\n",
- " 'ZeroDivisionError']"
- ]
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[name for name in dir(__builtin__) if \"Error\" in name]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Pradeep's variation...."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 33,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['ArithmeticError',\n",
- " 'AssertionError',\n",
- " 'AttributeError',\n",
- " 'BaseException',\n",
- " 'BlockingIOError',\n",
- " 'BrokenPipeError',\n",
- " 'BufferError',\n",
- " 'BytesWarning',\n",
- " 'ChildProcessError',\n",
- " 'ConnectionAbortedError',\n",
- " 'ConnectionError',\n",
- " 'ConnectionRefusedError',\n",
- " 'ConnectionResetError',\n",
- " 'DeprecationWarning',\n",
- " 'EOFError',\n",
- " 'Ellipsis',\n",
- " 'EnvironmentError',\n",
- " 'Exception',\n",
- " 'False',\n",
- " 'FileExistsError',\n",
- " 'FileNotFoundError',\n",
- " 'FloatingPointError',\n",
- " 'FutureWarning',\n",
- " 'GeneratorExit',\n",
- " 'IOError',\n",
- " 'ImportError',\n",
- " 'ImportWarning',\n",
- " 'IndentationError',\n",
- " 'IndexError',\n",
- " 'InterruptedError',\n",
- " 'IsADirectoryError',\n",
- " 'KeyError',\n",
- " 'KeyboardInterrupt',\n",
- " 'LookupError',\n",
- " 'MemoryError',\n",
- " 'NameError',\n",
- " 'None',\n",
- " 'NotADirectoryError',\n",
- " 'NotImplemented',\n",
- " 'NotImplementedError',\n",
- " 'OSError',\n",
- " 'OverflowError',\n",
- " 'PendingDeprecationWarning',\n",
- " 'PermissionError',\n",
- " 'ProcessLookupError',\n",
- " 'RecursionError',\n",
- " 'ReferenceError',\n",
- " 'ResourceWarning',\n",
- " 'RuntimeError',\n",
- " 'RuntimeWarning',\n",
- " 'StopAsyncIteration',\n",
- " 'StopIteration',\n",
- " 'SyntaxError',\n",
- " 'SyntaxWarning',\n",
- " 'SystemError',\n",
- " 'SystemExit',\n",
- " 'TabError',\n",
- " 'TimeoutError',\n",
- " 'True',\n",
- " 'TypeError',\n",
- " 'UnboundLocalError',\n",
- " 'UnicodeDecodeError',\n",
- " 'UnicodeEncodeError',\n",
- " 'UnicodeError',\n",
- " 'UnicodeTranslateError',\n",
- " 'UnicodeWarning',\n",
- " 'UserWarning',\n",
- " 'ValueError',\n",
- " 'Warning',\n",
- " 'ZeroDivisionError',\n",
- " '__IPYTHON__',\n",
- " '__IPYTHON__active',\n",
- " '__build_class__',\n",
- " '__debug__',\n",
- " '__doc__',\n",
- " '__import__',\n",
- " '__loader__',\n",
- " '__name__',\n",
- " '__package__',\n",
- " '__spec__',\n",
- " 'abs',\n",
- " 'all',\n",
- " 'any',\n",
- " 'ascii',\n",
- " 'bin',\n",
- " 'bool',\n",
- " 'bytearray',\n",
- " 'bytes',\n",
- " 'callable',\n",
- " 'chr',\n",
- " 'classmethod',\n",
- " 'compile',\n",
- " 'complex',\n",
- " 'copyright',\n",
- " 'credits',\n",
- " 'delattr',\n",
- " 'dict',\n",
- " 'dir',\n",
- " 'divmod',\n",
- " 'dreload',\n",
- " 'enumerate',\n",
- " 'eval',\n",
- " 'exec',\n",
- " 'filter',\n",
- " 'float',\n",
- " 'format',\n",
- " 'frozenset',\n",
- " 'get_ipython',\n",
- " 'getattr',\n",
- " 'globals',\n",
- " 'hasattr',\n",
- " 'hash',\n",
- " 'help',\n",
- " 'hex',\n",
- " 'id',\n",
- " 'input',\n",
- " 'int',\n",
- " 'isinstance',\n",
- " 'issubclass',\n",
- " 'iter',\n",
- " 'len',\n",
- " 'license',\n",
- " 'list',\n",
- " 'locals',\n",
- " 'map',\n",
- " 'max',\n",
- " 'memoryview',\n",
- " 'min',\n",
- " 'next',\n",
- " 'object',\n",
- " 'oct',\n",
- " 'open',\n",
- " 'ord',\n",
- " 'pow',\n",
- " 'print',\n",
- " 'property',\n",
- " 'range',\n",
- " 'repr',\n",
- " 'reversed',\n",
- " 'round',\n",
- " 'set',\n",
- " 'setattr',\n",
- " 'slice',\n",
- " 'sorted',\n",
- " 'staticmethod',\n",
- " 'str',\n",
- " 'sum',\n",
- " 'super',\n",
- " 'tuple',\n",
- " 'type',\n",
- " 'vars',\n",
- " 'zip']"
- ]
- },
- "execution_count": 33,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[name if x is not None else '' for name in dir(__builtin__)]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Nested loops"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 35,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "5\n",
- "6\n",
- "6\n",
- "7\n",
- "7\n",
- "8\n"
- ]
- }
- ],
- "source": [
- "for x in range(3):\n",
- " for y in range(5, 7):\n",
- " print(x+y)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 139,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[5, 6, 7, 6, 7, 8]"
- ]
- },
- "execution_count": 139,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x+y for y in range(5, 7) for x in range(3)] # almost, but not quite"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 140,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[5, 6, 6, 7, 7, 8]"
- ]
- },
- "execution_count": 140,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[x+y for x in range(3) for y in range(5, 7)] # Got it!"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# reduce()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 40,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from functools import reduce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 42,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def my_sum(x, y):\n",
- " return x+y"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 43,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "r = reduce(my_sum, l)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "36"
- ]
- },
- "execution_count": 44,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "r"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Lambda"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### A standard function..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 47,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def f(x, y):\n",
- " return x+y"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 48,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "7"
- ]
- },
- "execution_count": 48,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "f(3,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "function"
- ]
- },
- "execution_count": 50,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Same thing as a lambda"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 49,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "l = lambda x, y: x+y"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "function"
- ]
- },
- "execution_count": 51,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(l)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 53,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "7"
- ]
- },
- "execution_count": 53,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "l(3,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 141,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_func_list = [lambda x, y: x+y, lambda x, y: x*y] # a list of functions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 142,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "7"
- ]
- },
- "execution_count": 142,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_func_list[0](3,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 143,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "12"
- ]
- },
- "execution_count": 143,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_func_list[1](3,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 144,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_func_dict = {'add': lambda x, y, z: x+y+z, 'mult':lambda x, y: x*y} # a dict of functions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 145,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "12"
- ]
- },
- "execution_count": 145,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_func_dict['add'](3,4,5) # Now I can call these by something meaningful"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 146,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "12"
- ]
- },
- "execution_count": 146,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_func_dict['mult'](3,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 147,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "my_list = [1, 2, 3, 4, 5]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 148,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "my_lambda = lambda my_list: print(my_list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 149,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[1, 2, 3, 4, 5]\n"
- ]
- }
- ],
- "source": [
- "my_lambda(my_list)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 150,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "12"
- ]
- },
- "execution_count": 150,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "my_func_dict['add'](z=5,y=4,x=3)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Closures"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 151,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def make_multiplier_of(n):\n",
- " def multiplier(x):\n",
- " return x * n\n",
- " return multiplier"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 152,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "times3 = make_multiplier_of(3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 153,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "times5 = make_multiplier_of(5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 154,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "24"
- ]
- },
- "execution_count": 154,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "times3(8)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 155,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "50"
- ]
- },
- "execution_count": 155,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "times5(10)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 156,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{}"
- ]
- },
- "execution_count": 156,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "times3.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Circle"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 157,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from math import pi\n",
- "\n",
- "class Circle(object):\n",
- " pi = 3.1415\n",
- " \n",
- " def __init__(self, **kwargs):\n",
- " \n",
- " if 'radius' not in kwargs and 'diameter' not in kwargs:\n",
- " raise AttributeError (\"Please supply either radius or diameter\")\n",
- " \n",
- " if 'radius' in kwargs:\n",
- " self.radius = kwargs['radius']\n",
- " \n",
- " if 'diameter' in kwargs:\n",
- " self.radius = kwargs['diameter'] / 2\n",
- " \n",
- " @property\n",
- " def radius(self):\n",
- " return self._radius\n",
- " \n",
- " @radius.setter\n",
- " def radius(self, radius):\n",
- " self._radius = radius\n",
- " \n",
- " @property\n",
- " def diameter(self):\n",
- " return self._radius * 2\n",
- " \n",
- " @diameter.setter\n",
- " def diameter(self, diameter):\n",
- " self._radius = diameter / 2\n",
- " \n",
- " @property\n",
- " def area(self):\n",
- " return pi * self._radius**2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 158,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "c = Circle(radius=3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 159,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 159,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "c.diameter"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 160,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "28.274333882308138"
- ]
- },
- "execution_count": 160,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "c.area"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 161,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "class Circle2(object):\n",
- " \n",
- " def __init__(self, radius):\n",
- " print(\"In Circle.__init__()\")\n",
- " self.radius = radius\n",
- " \n",
- " @classmethod\n",
- " def from_diameter(cls, diameter):\n",
- " return cls(diameter / 2.0)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 162,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "In Circle.__init__()\n"
- ]
- }
- ],
- "source": [
- "c2 = Circle2.from_diameter(9)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 163,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "4.5"
- ]
- },
- "execution_count": 163,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "c2.radius"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 164,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['__class__',\n",
- " '__delattr__',\n",
- " '__dict__',\n",
- " '__dir__',\n",
- " '__doc__',\n",
- " '__eq__',\n",
- " '__format__',\n",
- " '__ge__',\n",
- " '__getattribute__',\n",
- " '__gt__',\n",
- " '__hash__',\n",
- " '__init__',\n",
- " '__le__',\n",
- " '__lt__',\n",
- " '__module__',\n",
- " '__ne__',\n",
- " '__new__',\n",
- " '__reduce__',\n",
- " '__reduce_ex__',\n",
- " '__repr__',\n",
- " '__setattr__',\n",
- " '__sizeof__',\n",
- " '__str__',\n",
- " '__subclasshook__',\n",
- " '__weakref__',\n",
- " 'from_diameter']"
- ]
- },
- "execution_count": 164,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dir(Circle2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/SuperConsideredSuper/README.md b/notebooks/SuperConsideredSuper/README.md
deleted file mode 100644
index 93a8d6d..0000000
--- a/notebooks/SuperConsideredSuper/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Super() Considered Super!
-
-Raymond Hettinger's talk:
-
-https://youtu.be/EiOglTERPEo
-
-Sample/demo code within this directory.
-
-Enjoy.
diff --git a/notebooks/SuperConsideredSuper/organic_pizza.py b/notebooks/SuperConsideredSuper/organic_pizza.py
deleted file mode 100644
index bd05f9d..0000000
--- a/notebooks/SuperConsideredSuper/organic_pizza.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# organic_pizza.py
-
-from pizza import DoughFactory, Pizza
-
-
-class OrganicDoughFactory(DoughFactory):
- def get_dough(self):
- return "pure untreated wheat dough"
-
-
-class OrganicPizza(Pizza, OrganicDoughFactory):
- pass
-
-
-if __name__ == '__main__':
- my_pie = OrganicPizza()
- my_pie.order_pizza('pepperoni', 'shrooms')
diff --git a/notebooks/SuperConsideredSuper/pizza.py b/notebooks/SuperConsideredSuper/pizza.py
deleted file mode 100644
index 46561ac..0000000
--- a/notebooks/SuperConsideredSuper/pizza.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# pizza.py
-
-
-class DoughFactory(object):
-
- def get_dough(self):
- return "insecticide treated wheat dough"
-
-
-class Pizza(DoughFactory):
-
- def order_pizza(self, *toppings):
- print("Getting dough")
-
- # Uh oh, this is hard coded! What happens if we change the parent class?
- # dough = DoughFactory.get_dough(self)
- # dough = self.get_dough()
- dough = super().get_dough()
-
- print("Making pie with {}".format(dough))
-
- for topping in toppings:
- print("Adding {}".format(topping))
-
-
-if __name__ == '__main__':
- my_pie = Pizza()
- my_pie.order_pizza('pepperoni', 'shrooms')
diff --git a/notebooks/SuperConsideredSuper/robot.py b/notebooks/SuperConsideredSuper/robot.py
deleted file mode 100644
index b12a539..0000000
--- a/notebooks/SuperConsideredSuper/robot.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# robot.py
-
-class Robot(object):
-
- def fetch(self, tool):
- print("Physical Movement: Fetching")
-
- def move_forward(self, tool):
- print("Physical Movement: Moving forward")
-
- def move_backward(self, tool):
- print("Physical Movement: Moving backward")
-
- def replace(self, tool):
- print("Physical Movement: Replacing")
-
-
-class CleaningRobot(Robot):
-
- def clean(self, tool, times=3):
- super().fetch(tool)
- for _ in range(times):
- super().move_forward(tool)
- super().move_backward(tool)
- super().replace(tool)
-
-
-if __name__ == '__main__':
- t = CleaningRobot()
- t.clean('broom')
diff --git a/notebooks/SuperConsideredSuper/test_robot.py b/notebooks/SuperConsideredSuper/test_robot.py
deleted file mode 100644
index d45b8e3..0000000
--- a/notebooks/SuperConsideredSuper/test_robot.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# test_robot.py
-
-from robot import Robot, CleaningRobot
-
-
-class MockBot(Robot):
-
- def __init__(self):
- self.tasks = []
-
- def fetch(self, tool):
- self.tasks.append("fetching {}".format(tool))
-
- def move_forward(self, tool):
- self.tasks.append("forward {}".format(tool))
-
- def move_backward(self, tool):
- self.tasks.append("backward {}".format(tool))
-
- def replace(self, tool):
- self.tasks.append("replace {}".format(tool))
-
-
-class MockedCleaningRobot(CleaningRobot, MockBot):
- pass
-
-
-def test_clean():
- t = MockedCleaningRobot()
- t.clean('mop')
- expected = (
- ['fetching mop'] +
- ['forward mop', 'backward mop'] * 3 +
- ['replace mop']
- )
- assert t.tasks == expected
-
-
-if __name__ == '__main__':
- t = MockedCleaningRobot()
- t.clean('broom')
diff --git a/notebooks/Trap_Rule.ipynb b/notebooks/Trap_Rule.ipynb
deleted file mode 100644
index 1d7412c..0000000
--- a/notebooks/Trap_Rule.ipynb
+++ /dev/null
@@ -1,587 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Background"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You have a function f(x) and want to calculate the area under the curve of f(x) from a to b. \n",
- "\n",
- " \n",
- "\n",
- "- Intervals of equal length \n",
- "- h = (b - a) / n \n",
- " - where b = end point \n",
- " - a = start point \n",
- " - n = number of intervals "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## The goal "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Create a function that can integrate any function you pass to it: \n",
- "\n",
- "- Pass a function to this trapz function \n",
- "- Pass a start point \n",
- "- Pass an end point\n",
- "- Return the area under the curve"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def line(x):\n",
- " '''a very simple straight horizontal line at y = 5'''\n",
- " return 5\n",
- "\n",
- "area = trapz(line, 0, 10)\n",
- "\n",
- "print (area)\n",
- "\n",
- "50"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def trapz(fun, a, b):\n",
- " \"\"\"\n",
- " Compute the area under the curve defined by\n",
- " y = fun(x), for x between a and b\n",
- " \n",
- " :param fun: the function to evaluate\n",
- " :type fun: a function that takes a single parameter\n",
- "\n",
- " :param a: the start point for the integration\n",
- " :type a: a numeric value\n",
- "\n",
- " :param b: the end point for the integration\n",
- " :type b: a numeric value\n",
- " \"\"\" \n",
- " pass"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You will need to: \n",
- " - create list of x values from a to b \n",
- " - compute whatever the function is for each of those values \n",
- " - add the results up \n",
- " - multiply by half the difference between a and b divided by the number of steps "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create a function to test\n",
- "\n",
- "Let's use the straight line function from the example. \n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# create a straight line\n",
- "def line(x):\n",
- " '''a very simple straight horizontal line at y = 5'''\n",
- " return 5"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create a list of x values from a to b"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def create_range(a,b,n):\n",
- " '''\n",
- " a = start point\n",
- " b = end point\n",
- " n = number of intervals to create\n",
- " '''\n",
- " # create list of x values from a to b \n",
- " delta = float(b - a)/n\n",
- " return [a + i * delta for i in range(n + 1)]\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[1.0, 5.5, 10.0]\n"
- ]
- }
- ],
- "source": [
- "stuff = create_range(1,10,2)\n",
- "print (stuff)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Compute the function for each of those values and sum"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def trapz(fun, a, b, n):\n",
- " # create a range from a to b\n",
- " my_vals = create_range(a,b,n)\n",
- " # compute the function for each of those values and double\n",
- " s = [fun(x) for x in my_vals[1:-1]] * 2\n",
- " print (s)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[5, 5]\n"
- ]
- }
- ],
- "source": [
- "test_calc_fun = trapz(line, 1,10,2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def trapz(fun, a, b, n):\n",
- " # create a range from a to b\n",
- " my_vals = create_range(a,b,n)\n",
- " # compute the function for each of those values\n",
- " s = sum([fun(x) for x in my_vals[1:-1]] * 2)\n",
- " print (s)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "10\n"
- ]
- }
- ],
- "source": [
- "test_sum = trapz(line, 1,10,2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Multiply by half the difference between a and b divided by the number of steps"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def trapz(fun, a, b, n):\n",
- " # create a range from a to b\n",
- " my_vals = create_range(a,b,n)\n",
- " # compute the function for each of those values and double, then sum\n",
- " s = sum([fun(x) for x in my_vals[1:-1]] * 2)\n",
- " # calculate half the diff between a and b divided by n\n",
- " diff = ((b - a) * .5)/n\n",
- " print (diff)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2.25\n"
- ]
- }
- ],
- "source": [
- "test_diff = trapz(line, 1,10,2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def trapz(fun, a, b, n):\n",
- " # create a range from a to b\n",
- " my_vals = create_range(a,b,n)\n",
- " # compute the function for each of those values\n",
- " s = sum([fun(x) for x in my_vals[1:-1]])\n",
- " # calculate diff between f(a) and f(b) divided by n\n",
- " diff = ((b - a) * .5)/n\n",
- " # multiply s by diff\n",
- " area = s * diff\n",
- " return area"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "11.25\n"
- ]
- }
- ],
- "source": [
- "test_trapz = trapz(line, 1,10,2)\n",
- "print (test_trapz)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Test with a simple function"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def add_one(x):\n",
- " one_more = x + 1\n",
- " return one_more"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "3\n"
- ]
- }
- ],
- "source": [
- "print (add_one(2))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "14.625\n"
- ]
- }
- ],
- "source": [
- "test2 = trapz(add_one, 1,10,2)\n",
- "print (test2)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Stage 2: Passing functions with more than one argument"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "So far, the functions we pass to trapz can only take on argument. Let's update it so that we can pass through a function with any number of arguments. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Goal = pass a variable number or arguments to a function\n",
- "\n",
- "- trapz(quadratic, 2, 20, A=1, B=3, C=2) \n",
- "- trapz(quadratic, 2, 20, 1, 3, C=2) \n",
- "- coef = {'A':1, 'B':3, 'C': 2} \n",
- "- trapz(quadratic, 2, 20, **coef) "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Quick review of *args and **kwargs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Example from http://markmiyMashita.com/blog/python-args-and-kwargs/Mm"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def func_with_two(one, two):\n",
- " \"\"\"\n",
- " Takes in two arguments because we explicitly\n",
- " defined two formal parameters. \n",
- " Any more or any less will cause anerror.\n",
- " \"\"\"\n",
- " \n",
- "def func_with_start_args(*args):\n",
- " \"\"\"\n",
- " This function can take in any number of arguments, including zero!\n",
- " \"\"\"\n",
- " \n",
- "def func_with_both(one, two, *args):\n",
- " \"\"\"\n",
- " This function requires at least two arguments. The *args at the end\n",
- " says that it can take just two arguments or any number of arguments as long\n",
- " as there are at least two.\n",
- " \"\"\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "#keyword argument = you name the variable as you pass it\n",
- "def print_table(**kwargs):\n",
- " for key, value in kwargs.items():\n",
- " print(key, value)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "b 6\n",
- "c 7\n",
- "a 5\n"
- ]
- }
- ],
- "source": [
- "print_table(a = 5, b = 6, c = 7)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "How can you use *args and **kwargs to update the trapezoid function? "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# student example\n",
- "\n",
- "def trapz(fun, a, b, num_steps, **kwargs):\n",
- " \"\"\"\n",
- " Compute the area under the curve defined by\n",
- " y = fun(x), for x between a and b\n",
- " :param fun: the function to evaluate\n",
- " :type fun: a function that takes a single parameter\n",
- " :param a: the start point for the integration\n",
- " :type a: a numeric value\n",
- " :param b: the end point for the integration\n",
- " :type b: a numeric value\n",
- " \"\"\"\n",
- " STEP_SIZE = (b-a)/num_steps\n",
- "\n",
- " sum = 0\n",
- " for i in range(0, num_steps):\n",
- " left = a + (i * STEP_SIZE)\n",
- " right = a + ((i+1) * STEP_SIZE)\n",
- " sum += fun(left, **kwargs) + fun(right, **kwargs)\n",
- "\n",
- " sum = sum * STEP_SIZE / 2\n",
- " return sum"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "58.5"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "trapz(add_one, 1,10,2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.1"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebooks/students.txt b/notebooks/students.txt
deleted file mode 120000
index dfbe477..0000000
--- a/notebooks/students.txt
+++ /dev/null
@@ -1 +0,0 @@
-../Examples/students.txt
\ No newline at end of file
diff --git a/objects.inv b/objects.inv
new file mode 100644
index 0000000..226981f
Binary files /dev/null and b/objects.inv differ
diff --git a/search.html b/search.html
new file mode 100644
index 0000000..9fc9083
--- /dev/null
+++ b/search.html
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+ Search — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Please activate JavaScript to enable the search
+ functionality.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/searchindex.js b/searchindex.js
new file mode 100644
index 0000000..63801a6
--- /dev/null
+++ b/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({envversion:47,filenames:["exercises/circle_class","exercises/comprehensions_lab","exercises/dict_lab","exercises/exceptions_lab","exercises/fib_and_lucas","exercises/fizz_buzz","exercises/functions_as_args","exercises/grid_printer","exercises/html_renderer","exercises/index","exercises/kata_fourteen","exercises/lambda_magic","exercises/list_lab","exercises/mailroom","exercises/rot13","exercises/slicing","exercises/sparse_array","exercises/string_formatting","exercises/trapezoid","include","index","session01","session02","session03","session04","session05","session06","session07","session08","session09","session10","supplements/git_overview","supplements/index","supplements/install_nano_win","supplements/packaging","supplements/python_for_linux","supplements/python_for_mac","supplements/python_for_windows","supplements/python_learning_resources","supplements/shell","supplements/sublime_as_ide","supplements/unicode","supplements/virtualenv"],objects:{},objnames:{},objtypes:{},terms:{"05311584473e":[],"0c3401794933":23,"0ec059b9bfe1":22,"0th":24,"0x101e01090":[],"0x101e01350":[],"0x101e01710":[],"0x103604400":8,"0x1049cca28":[],"0x1049ccb90":[],"0x10911bf50":[],"0x2bf928":27,"0x2de918":27,"11th":[],"125kb":42,"12spring":30,"16bit":41,"1a7db9b70878":[],"1butthisisnot":21,"1dbbea504a9":21,"1st":11,"1th":24,"20learn":38,"20next":38,"20python":38,"20to":38,"20want":38,"20what":38,"20you":38,"28object":27,"28program":28,"2db728a46f78":23,"2th":24,"3132459951e4":21,"3239de7":22,"33m":39,"374f501f4567":[21,36],"3rdparti":[],"4363b2b69f73":22,"4529e5befb95":22,"50c56a77d95f":29,"59pm":[],"5a33b9d3e525":23,"60b725f10c9c":21,"641528ffa695":[],"6731d4ac4476":22,"685a01a77340":21,"6mb":42,"70c8add5d16":21,"7f87d44dfcfa":41,"8mb":42,"907616e55e2a":21,"9ddbdbb":22,"\u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439":41,"\u043c\u0438\u0440":41,"\u0561\u0577\u056d\u0561\u0580\u0570\u056b":41,"\u0562\u0561\u0580\u0565\u0582":41,"\u05e2\u05d5\u05dc\u05dd":41,"\u05e9\u05dc\u05d5\u05dd":41,"\u0627\u0644\u0639\u0627\u0644\u0645":41,"\u0645\u0631\u062d\u0628\u0627":41,"\u0924":41,"\u0926":41,"\u0928":41,"\u0928\u092e\u0938":41,"\u092f":41,"\u4e16\u754c":41,"\u4f60\u597d":41,"\uc138\uacc4":41,"\uc5ec\ubcf4\uc138\uc694":41,"__add__":[21,29],"__and__":29,"__builtin__":[21,26,30],"__call__":29,"__class__":21,"__contains__":[21,29],"__delattr__":21,"__delitem__":29,"__delslice__":29,"__divmod__":29,"__doc__":[21,22],"__enter__":[],"__eq__":21,"__exit__":[],"__floordiv__":29,"__format__":21,"__future__":[21,41],"__ge__":21,"__getattribute__":21,"__getitem__":[21,29],"__getnewargs__":21,"__getslice__":[21,29],"__git_ps1":39,"__gt__":21,"__init__":[],"__iter__":29,"__len__":[22,29],"__lshift__":29,"__main__":[13,14,21,22,26,27,29],"__mod__":29,"__mul__":29,"__name__":[13,14,22,26],"__next__":[],"__nonzero__":22,"__or__":29,"__path__":42,"__pow__":29,"__repr__":[0,29],"__reversed__":29,"__rshift__":29,"__setitem__":29,"__setslice__":29,"__str__":[0,29],"__sub__":29,"__xor__":29,"_asisthi":21,"_create_payload":29,"_del_x":[],"_download":24,"_set_x":[],"_test":26,"abstract":[27,41],"boolean":[],"break":[8,18,21,23,24,25,39,42],"byte":[21,23,24,25,29,41],"case":[],"catch":[],"char":[39,41],"default":4,"export":[39,42],"final":[],"float":[],"function":4,"goto":27,"import":[],"int":[21,23,24,26],"long":[16,23,24,25,29,30,39,40,42],"new":[4,15],"null":[39,40],"public":[20,22],"return":[4,15],"short":[10,14,21,23,24,38],"super":[],"throw":[38,39],"true":[],"try":[1,5,8,10,14,16,18,21,22,23,25,26,28,29,30,31,34,35,36,38,40,41,42],"var":[21,23,24,30],"while":4,a079bc472aca:[23,24,25],a_circl:0,a_class:27,a_class_method:29,a_condit:[23,24],a_float:21,a_funct:[21,27],a_gener:[],a_generator_funct:[],a_list2:30,a_list:[22,23,30],a_list_of_str:22,a_new_code_block:21,a_new_nam:22,a_result:29,a_sequ:30,a_subclass:27,a_tupl:[22,23],a_tuple_of_str:22,a_valu:22,aaadfbdd293:21,aabbbcccc:1,abc:23,abderrazak:[],abil:[0,22,26,38,40,42],abl:[0,2,7,8,10,12,13,16,21,22,30,34,35,36,37,39,40],about:[],about_comprehens:1,abov:[0,7,10,12,13,18,23,26,35,37,38,40,41],absolut:[25,38,41],abspath:25,academi:38,accent:41,accept:[6,8,10,18,22,28],access:[16,21,22,27,28,36,42],accomplish:[2,8,12,13,14,21,22,23,24,25],accord:21,accordingli:10,account:22,accumul:[23,27],accur:18,achiev:40,aco:22,acosh:22,across:[6,26],act:[18,27,29],action:[2,12,13,42],activ:39,activepython:34,activest:34,actual:[8,21,23,24,26,29,31,34,37,39,41,42],adam:30,adapt:[7,10,27],add:[0,2,4,8,10,11,12,13,14,18,21,22,23,24,25,27,28,29,30,31,35,36,37,40,42],addit:[8,18,21,22,23,24,38,40,42],address:[8,22],adjac:10,adopt:[21,22,41],adult:[21,28],advanc:[],advantag:[25,26,29,42],adventur:[10,24],advertis:38,aeiou:30,afraid:28,after:[7,8,12,13,18,21,22,24,26,27,35,36,39,40,41,42],again:[],ago:[],agp:27,agre:[23,24,25,27],aim:38,airship:10,aka:27,alert:[23,24],aleson:[19,21,22,23,24,25,26,27,28,29,30],alex:26,alford:[],algorithm:10,alia:[35,36],align:[8,13],all:[0,1,8,10,11,12,18,21,22,23,24,25,26,27,28,29,30,34,35,36,37,39,40,41,42],all_cap:22,all_lett:23,all_the_nam:[],allow:[8,10,21,22,23,24,25,26,28,31,40,42],almost:[21,23,24,26,30,34,41],along:[],alongsid:42,alphabet:[14,41],alreadi:[8,21,22,23,24,26,30,35,36,37],also:[1,7,8,21,22,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,40,42],alt:40,alter:[23,24],altern:[],alwai:[13,21,22,23,24,25,26,28,31,41,42],amaz:38,amazon:38,among:[27,40],amount:[8,13,14],amplitud:18,an_el:8,an_inst:27,an_integ:21,an_iter:[],anaconda:[34,37],analysi:10,analyt:18,anchor:8,andrei:[],andthennotparam:39,ani:[6,7,8,10,12,13,14,15,18,21,22,23,24,25,26,27,28,29,30,31,34,36,38,39,40,41,42],anim:[],annot:30,announc:[],anonym:[],anoth:[38,39,40,42],another_circl:0,another_nam:[8,22],another_valu:22,ansi:41,answer:[12,18,23,37],antoh:41,anybodi:24,anyon:[8,19,21,22,23,24,25,26,27,28,29,30],anyth:[8,21,22,23,24,25,26,27,29,34],anywai:38,anywher:[22,27],api:[22,26,27],apostroph:21,app:[34,36],appar:5,appear:[23,39,40],append:[8,10,16,23,24,27,30,39],appendix:38,appl:[12,21,34,36,42],appleton:10,appli:[5,10,22,23,30,42],applic:[],apply_soap:22,approach:[8,22,27,30,38],appropri:[8,25,27,29,34],approxim:22,appspot:21,april:[22,35],apropo:[],apt:[34,35],arbitrari:[7,10,17,18,24,25,27,41,42],arbitrarili:[8,24],area:[0,18,27],aren:[25,29,41,42],arg1:22,arg2:22,arg:[21,22,26,28,29,40],arg_dict:26,argum:39,argument:4,argw:28,aris:42,arithmet:21,arithmeticerror:[21,30],arm:39,armstrong:27,arn:14,around:[],arr:[23,24],arrai:[],arrow:[21,40],art:[],arti:[],articl:[],artima:30,ascii:[23,24,25,41],asid:27,asin:22,asinh:22,ask:[12,24,26,27,41,42],asp:8,aspect:38,aspx:34,assert:4,assertequ:26,assertionerror:[21,22,30],assig:8,assign:[],assist:[27,30],associ:[24,31,42],assum:[23,41],atan2:22,atan:22,atanh:22,att:28,attach:[8,21],attempt:[40,41],attent:21,attribut:[],attributeerror:[0,8,21,24,28,30],aug:42,augment:0,austin:[],author:30,authorit:38,auto:[27,34,39,40],autocomplet:39,automat:[],avaiabl:38,avail:[14,21,22,23,24,29,30,34,35,36,37,38,39,40,42],averag:[13,24],avinash:[],avinashv:[],avoid:[22,28,39,40],awai:[1,14],awar:23,awesom:21,awkward:26,axialcorp:41,azdwveidqji:26,b00kqtfhnk:38,back:[8,10,12,21,22,23,24,25,30,31,34,37,41,42],back_color:26,backgrond:21,background:[21,23],backslash:[23,24,25],backspac:[23,24,25],backtrack:10,backward:[1,41],bacon:[23,24],bad:[8,21,22,39],balloon:22,band:10,bannana:22,bar:[21,22,39],barf:41,barker:[7,20,26,30],base:4,baseexcept:21,basenam:[25,39],basestr:21,bash:[21,35,37,39,42],bashrc:35,basi:[12,39],basic:[],bat:[1,21],batch:[21,42],batteri:21,bauman:[],baz:22,bdist:34,bdist_rpm:34,bdist_wheel:34,bdist_wininst:34,bean:[23,24],bear:27,beat:10,beauti:8,becaus:[8,21,22,23,24,29,30,42],becom:[22,23,24,29,30,40],been:[35,39,42],befor:[],begin:[8,12,21,26,27,34,38,42],behav:[21,29],behavior:[21,27,28],behind:[21,26,28,39],beign:36,bel:[23,24,25],believ:22,bell:[23,24,25],belong:[8,21,22,27],below:[13,22],benefit:28,benign:[23,24],benjamin:[19,21,22,23,24,25,26,27,28,29,30],best:[21,26,37,38,40,42],bet:37,beta:[21,40],better:[7,8,22,23,26,29,30,34,37,41,42],between:[8,13,15,18,21,22,23,25,31,40,42],beyond:[],bhgfvqr:14,big:[25,26,30,36,40,41],bigger:[0,1],biggest:[8,34],biggi:41,bin:[23,25,36,39,40,42],binari:[22,25,34,41],bind:[22,23,24,25],bindhu:[19,21,22,23,24,25,26,27,28,29,30],bingga:[],bird:37,bit:[],bitpim:34,bitwis:21,black:10,blah:22,blend:27,blob:1,block:[4,13,14,17,21,22,23,24,25,26,29],blocksiz:29,blog:38,blogger:38,blogspot:[27,28,38],blow:41,blue:27,blurb:38,bob:[21,23,24,25],bodi:[8,22,23,24],boi:[10,28],bone:21,bonu:12,book:[10,21,22,25,31,38],bookmark:38,bool:22,boranga:22,border:29,bore:13,both:[4,5,8,18,21,23,24,26,28,37,38,41],bottom:28,bound:[19,21,22,23,24,25,26,27,28,29,30],box:[22,35,36,37],brace:39,bracket:39,branch:39,brand:36,brandon:[19,21,22,23,24,25,26,27,28,29,30],bread:[23,24],break_m:21,breakfast:1,breakpoint:40,breed:38,brendan:[],brennen:[19,21,22,23,24,25,26,27,28,29,30],brew:34,brian:[20,23,24],bring:[22,29,40],brittl:26,broken:8,browser:[8,31,38],bruce:[],bryan:[19,21,22,23,24,25,26,27,28,29,30],bsd:25,bucket:24,buckl:10,buffer:23,buffererror:[21,26,30],bug:[8,21,23,24,41],buid:34,build:[],buildout:[34,40],built:[],builtin:[21,23,24,40],bulk:[],bullet:8,bun:23,bunc:23,bunch:[0,22,23,24,26,29],buzzword:27,bytearrai:[23,41],bytecod:22,c1f9ac3b6fe:23,c816927c2fb8:21,c83386d97be3:28,cabin:10,cach:35,cagetori:6,cake:[1,2],calcul:[21,22,28],call:4,callabl:[],callable_inst:29,calm:[],calvin:[19,21,22,23,24,25,26,27,28,29,30],came:[10,26,34],camp:23,can:[3,5,13,15,17,35,36,37,38,39,40,42],cancel:3,cannot:[21,29,41],canopi:[34,37],canva:[19,21,22,23,24,25,26,27,28,29,30],capabl:[26,38],capit:[1,14,34],captur:10,car:[10,30],card:27,cardena:[],care:[21,22,23,24,30,35,42],carri:[1,30],carriag:[10,23,24,25],casetti:38,categori:[6,27],caught:8,caus:[21,23,24,31,40,42],caution:8,cautiou:26,caveat:[],ceil:22,center:8,central:22,ceo:26,cereal:1,certain:21,certainli:18,cew:[40,42],cgi:5,ch000549:37,challeng:38,cham:22,chanc:1,chang:[0,2,4,12,13,14,19,21,22,23,24,25,26,27,28,29,30,31,35,39,40,42],changeset:40,chao:[41,42],chapt:24,chapter:[21,22,23,31],charact:[14,21,23,24,25,39,40,41],charactor:41,charg:27,chariti:13,charset:8,chdir:25,checkout:[22,31],cheryl:[],chi:[19,21,22,23,24,25,26,27,28,29,30],chinn:[19,21,22,23,24,25,26,27,28,29,30],chmod:[2,12],chocol:[1,2],choic:[10,23,24,37],choos:[],chop:38,chore:39,chose:10,chosen:22,chr:[23,24,25,41],chri:[1,2,7,23,24,25,26,30],christoph:20,chunk:[18,21],cimino:[],circler2:27,circler:27,cite:38,citi:[1,2],clang:42,clarifi:[],clariti:[28,30],clash:[],class_method:29,classi:29,classmethod:[0,29],claus:[8,26],clean:40,cleaner:[21,41],cleanli:13,cleanup:40,clear:[13,38,42],click:[35,37],client:[26,36,37],clipboard:21,clone:[2,4,12,14,22,42],close:[],closure_:30,clue:42,clutter:28,cobalt:40,code:[4,5],codec:41,codecademi:38,codekata:[10,24],coder:38,codingbat:[1,21,22,23,26],coef:18,coeffici:18,coffe:[],collaps:27,collect:[10,22,23,24,25,29,35,40,42],colon:[21,22],color:[8,21,26,27,39,40],color_off:39,color_schem:40,column:[7,13],com:[1,5,8,10,19,21,22,23,24,25,26,27,28,29,30,31,34,36,37,38,39,41],combin:[7,23,28,30,31,39,40,41],comfi:40,comfort:[21,39],comma:[23,24,25],command:[],commenc:10,comment:4,commit:4,common:[8,20,21,22,23,24,25,26,27,29,30,41],commonli:25,commun:[22,31,34],comp130:30,comp:[1,30],compact:41,compani:[26,34],companion:10,compar:[0,26,28],comparison:21,comparison_of_unicode_encod:41,compat:[21,34,41,42],compil:[],complet:[],complex:[],complex_funct:22,compliant:8,complic:[21,23,25,27,39,41],compon:34,compos:13,composit:[],compress:22,comput:[],computation:16,computer_program:30,computerhop:37,concept:[],conceptu:18,concern:[8,21,27],concis:4,condit:[22,23,24,26,30],confer:42,confid:37,config:22,configur:[22,26,39,40],configuration_kei:22,conflict:[31,42],confus:[22,39],connect:22,consensu:30,consid:[21,23,24,27,28,29,30,39,40,41,42],consist:34,consol:8,constant:[22,23,24],constantli:40,constrain:10,construct:[21,23,26,30,39],constructor:[],consum:21,contain:[40,42],content:[],context:[],context_manag:[],contextlib:[],continu:[],continuum:34,contractor:26,contradictori:30,contrast:[23,24],contrib:39,control:[],convens:[23,24],convent:[],convers:21,convert:[23,24,26,29,41,42],cookbook:17,cool:[21,29,30],cooper:28,copi:[],copyright:[20,21,35,36,37,42],copysign:22,core:[8,22,27,30,37,38],corepython:38,correct:22,correctli:8,correspond:[12,39],cosh:22,cote:[],could:[39,40,42],couldn:[26,30],count_even:1,counter:30,countless:8,coupl:[],cours:[],cover:[21,24,26,28,38,40],crappi:21,crazi:26,creat:4,creativ:[20,30],creativecommon:20,credit:[],cri:[20,34],crunch:26,cshop:34,cstringio:[8,25],csv:[23,24,25],cto:26,ctrl:40,cube:30,cupcak:22,curat:34,curi:22,curl:39,curli:39,current:[],current_ind:8,cursor:[],curtain:21,curv:18,custom:[],customiz:42,cut:14,cyclomat:40,cypher:14,d8100c70edef:21,dai:[21,23,24,25,30,41],daili:[22,39,40],damian:[19,21,22,23,24,25,26,27,28,29,30],danc:22,darwin:[21,42],data:[13,16,21,24,25,26,27,28,29,30,41],databas:[30,41],datamodel:29,date:[22,30],datetim:29,dave:[10,24],de2c0c873dfc:[],dead:[10,38],deadli:23,deal:[8,18,21,23,24,25,39,41,42],deana:[19,21,22,23,24,25,26,27,28,29,30],deb:34,deborah:27,debug:[21,26,40],debugg:40,dec:[],decad:27,decemb:[],decid:[7,8,13,31,42],decim:[23,24,25],decis:[],deck:27,declar:21,decor:[],decorator_on:[],decorator_two:[],decrypt:14,deep:[8,22,30],deepcopi:[],deeper:22,def:[],defens:[],defin:[0,4,8,18,21,22,24,25,26,27,28,29,30,39,40],definit:[],degre:22,del:[16,21,23,24,28,29],deleg:28,delet:[],delicaci:1,delimit:21,delin:21,delta_x:27,delx:[],demand:10,demo:[],demoenv:42,demonstr:[4,8,14,22,42],demostr:[],depend:[36,42],dependency_inject:28,deploi:34,depric:[],dequ:[23,24],derdouri:[],deriv:[20,27],descend:28,describ:[8,22],descript:[14,21,22,38],descriptor:[],design:[37,40],dest_dir:42,destin:25,detail:[21,27,28,29,34,35,36,37],determin:[4,18,21,22,38,42],dev:[18,21,22,26,30,34],devel:34,develop:5,devlin:[],devot:1,dialect:8,diamet:[0,27,29],dict_comprehens:1,dict_item:24,dict_kei:24,dict_lab:2,dict_of_weapon:1,dict_valu:24,didn:[21,41],diederich:27,differ:[],differenti:[],differnc:[],dimension:16,dinner:38,dir:[2,8,12,14,21,26,29,30],direct:22,directli:[0,2,12,22,24,35,39,40,42],directori:[],dirnam:25,disabl:40,disappear:39,discov:40,discoveri:[26,34],discreet:13,discuss:[21,27,30,41],discussion_top:[19,21,22,23,24,25,26,27,28,29,30],disk:[25,41],dispatch:[],displai:[2,12,23,24,25],distinct:[21,24,41],distinguish:40,distribut:[],dive:[21,22,23,24,25,38],diveintopython3:[21,22,25,38],divid:[18,21,26],divis:[0,1,2,21],divisor:[],divmod:29,divsion:21,dmg:34,do_some_clean:26,do_someth:[22,23,24,26,29],do_something_bad:21,do_something_differ:26,do_something_els:27,do_something_with:26,do_something_with_lin:25,do_something_with_oth:27,do_stuff:[],doc:[17,38],dock:36,docstr:4,doctyp:8,document:[],docutil:42,doe:[],doer:21,doesn:[8,22,26,27,29,30,34,35,36,39,40],domin:[],don:[1,7,8,10,21,22,23,24,25,26,27,28,29,34,35,36,40,41],donat:13,done:[0,2,10,12,13,14,21,22,23,24,25,26,28,37,38,40,42],donor:13,donor_nam:26,dont:[],door:8,dopnt:41,dorsei:20,dot:[19,21,22,23,24,25,26,27,28,29,30],doubler:[],doug:[],down:[8,15,21,22,26,30,38],downei:7,download:[27,30,34,36,37,39,40,42],dozen:26,drag:36,draw:7,draw_white_spac:40,drawn:38,dread:6,driscol:38,drive:[18,24,26,30],driven:[],driver:[],drop:42,dry:[1,21],due:[],dug:10,dump:8,dunder:29,dure:37,dusti:28,dylan:10,dynam:[],e_traceback:[],e_typ:[],e_val:[],each:[0,1,2,6,8,10,11,12,13,14,18,21,22,23,24,25,26,27,29,30,31,34,38,40,41],eafp:[8,26],earli:[13,14,22,23,24,25,41],earlier:[18,41],easi:[22,23,34,36,41],easier:[8,21,23,25,26,27,37,40,41],easiest:[18,34],easili:[39,42],easy_instal:42,eat:21,ebook:38,echo:[22,35,39],edit:[1,21,22,31],editor:[],edu:[19,21,22,23,24,25,26,27,28,29,30,34],educ:21,ee879c0ffa11:37,effbot:22,effect:[22,30,42],effici:[1,16,18,24,26,41],effort:40,egg:[1,23,24],egg_info:42,eight:[],either:[0,1,8,18,21,23,25,30,36,39,42],elaps:[],eleg:26,element:4,elgant:[],elif:[],els:[],elsewher:40,email:[13,22,29],embed:21,emphasi:28,emploi:30,empti:[8,22,24,28,39,40],emul:[],enabl:35,encapsul:27,enclos:[10,22],encod:[],encourag:22,end:[3,4,7,8,10,12,13,16,18,21,22,23,24,25,30,39],end_of_the_block:21,enforc:27,engag:38,engin:30,english:41,engrain:40,enhanc:[21,22,30,35,36,37,38,39],ensur:[4,21,22,27,40],ensurepip:[36,37],enter:[39,40],entertain:38,enthought:[34,37],entir:[1,8,21,23,24,25,30,34,39,40,42],entri:2,enumer:[23,24],env:[22,39,42],environment:[39,42],eof:3,eoferror:[3,30],eol:[23,24,25],epel:35,equal:[],equat:[18,29],equiv:[],equival:[1,24,40],erf:22,erfc:22,eric:[],erica:[],error:[8,21,23,24,26,30,31,40,41],escal:30,escap:[21,23,24,25,41],especi:[21,22,23,30,38,39,40],essenti:[8,21,24,34,37],establish:[22,27,30],etc:[],european:41,eval:[0,29],evalu:[],eventu:42,ever:[8,21,23],everi:[8,15,21,22,27,30,34,35,40,41,42],everybodi:28,everyon:[22,25,30,40],everyth:[8,21,22,24,27,28,34,36,39,41],everytim:22,evolv:21,ex11:22,ex40:25,exact:[18,22],exactli:[27,31,37],exampl:[],exc_tb:[],exc_typ:[],exc_val:[],excel:[21,34,40],exchang:15,excit:21,exclud:40,excus:41,exec:21,execut:[2,12,13,21,22,23,24,26,34,40,42],exercis:[],exhaust:42,exist:[],exit:[21,23,24,26,42],exp:[22,26,30],expand:[21,39],expans:[22,39],expect:[8,18,21,22,24,26,29,36,41],expens:[],experi:[10,22,24,38,39,40],experienc:37,experiment:38,expir:[],explain:[4,22],explicilti:21,explicit:[24,28],explicitli:[22,28,42],explor:[21,30],expm1:22,expon:30,exponenti:21,expr:30,express:[],extend:39,extens:[8,21,22,34],extern:30,extra2:34,extra:[],extra_info:26,extran:30,fab:22,face:40,facil:21,fact:[],factor:[13,27],factori:[22,30],fail:[0,8],fair:[14,27,41],fairli:[22,41],fall:[10,23],fals:[],falsei:28,familar:8,famili:23,familiar:[1,27,30,31],fanat:1,fanci:[23,24,25],fannin:[19,21,22,23,24,25,26,27,28,29,30],far:[10,13,22,26,29,39],farther:13,fashion:[21,29],fast:[21,22,23,24,26],faster:[23,24,25,36,37,40],favorit:8,fear:1,feast:1,fedoraproject:35,feed:10,feedback:22,feel:[16,21,23,36,37,41],fellow:22,fetch:[22,40],fetch_head:22,few:39,fewer:[21,23],fib:4,fibinacci:4,fifteen:1,fifth:1,figur:[1,8,21,41,42],file:[],file_002:17,file_cont:[],file_handl:[],file_out:8,filenam:[22,25,41],filesystem:[22,26],fill:[6,29,30],find:[],fine:[1,13,22,36],finish:[4,10,21,22,23,24,25,26,29,42],fink:34,fire:[10,42],first:[4,15,17],first_nam:7,fit:[10,21,41],five:5,fix:[0,26,31,40,42],fix_the_problem:21,fizzbuzz:[5,23],fizzbuzztest:5,flag:[23,24],flake8:40,flavor:[35,39],flexibl:[21,23,24,25,26],flickr:23,floatcanva:[],floatingpoint:27,floor:[21,22],flow:[13,23,24],flower:6,flower_pow:6,fmod:22,focu:[23,24,25],fogarti:[],folder:[4,22,34,40],folk:[23,27,38,39],follow:[35,37,38,39],font:[8,40],font_fac:40,font_siz:40,foo:[22,39,42],foobar:[21,39],foobarandthennotparam:39,food2:[23,24],food:[23,24],food_copi:[23,24],food_pref:1,fopen:25,forc:21,fore_color:26,forget:13,forgiv:26,fork:[4,22],form:[4,10,22,39],format:[],formula:4,forth:1,fortran:34,forum:21,forward:[22,38],foster:30,found:[0,12,23,35,40,42],foundat:38,founder:28,four:[],fourteen:[],framework:[26,36,41],fred:[23,24,25,30],free:[16,21,22,36,37,40],frenchman:10,frequenc:18,frequent:[2,4,10,12,13],frexp:22,fri:1,fridai:[],friend:[21,40],friendli:29,frobnagl:22,from:[4,5],from_diamet:0,from_iter:[],fromkei:29,front3:23,front:[10,21,23,24,25],frown:8,frozenset:[2,24],fruit:[1,2,12],fsum:22,ftp:36,fuhm:28,full:[8,13,23,24,25,26,27,36,38],fun:[],func:22,function_build:11,functool:[],further:39,gabriel:[],gaffnei:[19,21,22,23,24,25,26,27,28,29,30],gain:[22,28],game:[6,14],gamma:22,ganzalez:[19,21,22,23,24,25,26,27,28,29,30],garbanzo:23,gate:22,gave:27,gcc:[21,35,42],geek:[18,36],gen:[],gen_a:[],gen_b:[],genexpr:[],georg:[],get:15,get_area:27,get_color:27,get_item:[],get_x:28,getcwd:25,getdefaultencod:41,getvalu:25,getx:28,gift:13,gist:39,git:4,git_ps1_showcolorhint:39,git_ps1_showdirtyst:39,git_ps1_showstashst:39,git_ps1_showupstream:39,github:[4,17],give:[1,4,8,10,16,18,21,22,27,30,31,36],givebirth:[],given:[1,7,10,13,18,21,22,27,29],glad:41,global:[],glogowski:[19,21,22,23,24,25,26,27,28,29,30],go_on_her:26,goad:26,god:42,goe:[7,8,10,22,42],gohlk:34,gone:[21,42],good:[4,8,10,12,13,18,21,22,25,27,34,36,37,39,41,42],goof:23,googl:[8,37,41],googlegroup:[],got:[7,8,21,23,39,42],gotta:22,gov:34,grab:22,grace:26,gradual:38,grant:41,graph:22,great:[10,21,23,24,25,36,38,39,40,42],greatest:35,greek:1,greenteapress:[21,22,25,38],gregmalcolm:1,gregor:[19,21,22,23,24,25,26,27,28,29,30],gregori:[19,21,22,23,24,25,26,27,28,29,30],grep:35,grid_print:[22,23,25],group:[23,24],grow:[],gtk:27,guarante:27,guest:[],gui:[34,36,37],guid:[21,34],guido:30,gun:6,gusev:[],gutenberg:10,gvr:30,had:[1,10],hadoop:30,half:[18,39,41],hall:[],halt:8,ham:[1,23,24],hand:[6,10,21,22,27,29,38,40],hand_weapon:6,handi:[],handl:[],handle_error:[],happen:39,happili:40,hard:[8,21,22,23,34,38,39,42],hardi:10,harm:[28,41],hasattr:8,hash1:31,hash2:31,hash:[24,31],hashabl:24,hatch:38,hate:40,have:[0,1,4,6,7,8,10,13,16,18,21,22,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,40,41,42],haven:[8,26,40],head:[8,21,22,31,39],header:[8,22],header_s:25,hear:37,heavi:[8,26,40],height:[8,18],held:41,hellmann:[],hello:[21,22,23,24,25,41],hello_unicod:41,help:[],helper:14,henc:11,her:[10,38],here:[13,35,36,37,39,40,42],heterogen:23,hetting:[25,27,28,29],heurist:10,hex:[1,23,24,25],hexadecim:1,hexidecim:1,hidden:21,hierarchi:28,high:[10,18,35],higher:[22,25,41],highest:8,highli:[24,42],highlight:40,hijack:42,histor:13,histori:[13,22,27,28,30,31],hit:[21,40],hitchhik:34,hky2:[],hold:[1,13,16,21,30,38,41],holder:23,holm:[10,24],holmer:[19,21,22,23,24,25,26,27,28,29,30],home:[21,25,26,34,35,39,42],homebrew:[34,36],homogen:[23,24],honestli:36,hood:41,hook:42,hope:[21,30,34,41],hopper:26,horizont:[8,18,23,24,25],hot:[],hous:[10,27],how:[],howev:[10,21,22,35,37,38],howto:[29,41],howzit:[23,24,25],href:8,htink:41,htlu2dfodtg:[25,27],htm:[22,37],html_basic:8,html_render:8,html_render_wrap:8,http:[1,5,8,10,12,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,41],huge:29,huh:27,human:[8,17],hundr:10,hurt:28,hx0:27,hyper:8,hypertext:8,hypot:22,ian:[],ibafp:[],icaneatglass:41,idea:[16,21,27,41,42],ideal:[0,29,30,34],ident:4,identifi:31,idiom:[22,25,26],idx:[23,24],ignor:[23,24,25,39,40,41],ignored_packag:40,illuminaut:23,imag:23,imagin:14,immed:42,immedi:[23,24,39],immut:[23,24],imper:[],implement:[4,10,21,22,24,29,41],implic:[],implicitli:27,impos:[30,42],improv:[3,10,22,39],in_the_bodi:[23,24],inamidst:41,inc:21,includ:[4,13,14,21,22,23,40,42],inclus:5,incompat:41,incomplet:[],incorpor:22,incr:30,increas:[11,40],increasingli:27,incred:[13,39],increment:[11,30],incrementalencod:41,ind:8,indent:[8,21,22],independ:[25,36],index:[],indexerror:[16,23,24,25],indic:[8,21,22,40,42],individu:[8,10,13,22,25],inevet:42,infil:[],infilenam:[],infin:41,infinit:[23,24],inflex:26,info:[12,17,26],inform:[4,16,21,22,23,24,26,29,35,36,37,39,42],inherit:[],inheritance_:27,initi:36,inlin:22,input:40,inquisit:1,insert:[12,23,24],insid:[1,8,21,22,40,41],inspect:21,instal:[],installed_app:22,instanc:[0,8,22,27,28,29],instanti:27,instead:[1,5,8,11,18,21,22,23,25,26,28,29,35,36,37,39,41,42],instructor_2_email:[],instructor_2_nam:[],instrument:10,integ:[1,4,6,7,8,18,21,22,23,24,25,26,30,41],integr:[18,37,41],intel:34,intend:[22,30],intent:41,intention:24,inter:21,interact:[],interchang:[],interest:[1,10,21,22,24,27,30,38,39,42],interfac:[16,27,28],intermedi:38,intermediate_python_workshop:38,intern:[16,20,23,24],internet:[30,41],interrupt:[3,21,23,24],intersect:[2,24],interview:5,intimid:8,intricaci:[],intro:17,introduc:[21,29],introduct:[],introductori:21,intropython2015:[2,22,25],intropython2016a:[19,21,22,23,24,25,26,27,28,29,30],introspect:40,introtopython:[24,26],intuit:[22,42],invalid:21,inventor:10,invert:22,invit:[],invok:28,ioerror:26,iow:[],ipython3:35,ipython:[5,17],is_dir:25,isalnum:[23,24,25],isalpha:[23,24,25],isclos:[18,27],isdigit:26,isdisjoint:24,ish:23,isinf:22,isinst:[8,26,27],isn:[8,10,13,18,21,28,29,38,40],isnan:22,isnumer:[23,24,25],isol:[31,34,42],issu:[2,12,14,22,24,27,31,34,37,40],issubclass:27,issubset:24,issue18695:41,ist:28,itch:38,item:15,item_copi:24,item_view:24,iter:[],iterat:[],iterateme_1:[],iterateme_2:[],iterator_1:[],iterator_2:[],iterdir:25,iteritem:1,ith:24,itself:[6,8,22,23,24,30,36,37,39],jack:27,jacki:20,jaemin:[19,21,22,23,24,25,26,27,28,29,30],jail:10,jam:13,jame:28,java:[21,26,28,41],javascript:21,jenkin:[],jetbrain:21,job:[5,13,26,31],joe:[23,24,25],joelonsoftwar:41,john:[19,21,22,23,24,25,26,27,28,29,30],join:[22,23,24,25],jon:20,jone:30,jorg:22,joseph:[],json:[40,41],jsp:30,jsut:[],judg:40,judici:22,juju:41,jump:[21,40],jun:[35,37],junit:26,junk2:25,junkfil:25,just:[2,3,7,8,10,12,15,18,21,22,23,24,25,26,28,29,30,31,34,35,41,42],just_about_anyth:[],kai:[],kata14:[10,24],kata:[],kata_fourteen:24,kathleen:[],keep:[6,8,12,16,21,22,24,25,26,28,30,31,38,40,42],keep_go:[23,24],kei:[],kept:27,key1:24,key2:24,keyboard:[3,40],keyboardinterrupt:3,keyerror:24,keyword:[],kick:34,kid:21,kill:[22,37,42],kind:[8,21,23,24,25,39,41],kindl:38,kishan:[19,21,22,23,24,25,26,27,28,29,30],kitten:42,knight:28,know:[35,36,37,38,39,42],knowledg:[22,30,39],known:[18,23,24,26,27,30,38,39],koan:1,krishna:[19,21,22,23,24,25,26,27,28,29,30],kumar:[19,21,22,23,24,25,26,27,28,29,30],kwarg1:22,kwarg:[8,26,28,29],kyle:[19,21,22,23,24,25,26,27,28,29,30],l100:[],label:[31,38],lack:28,lai:[],lamb:1,lambda:[],languag:[],larg:[6,16,22,24],larger:7,lasagna:1,last:15,last_nam:7,later:[7,21,22,23,24,25,28],latest:[26,34,35,36,37,38],latex:42,lather:21,latin1_test:41,latitud:21,law:29,layegg:[],ldexp:22,lead:[23,24,42],learncodethehardwai:21,learngitbranch:31,learnpythonthehardwai:[21,22,25,38],least:[1,2,8,12,13,14,16,21,22,23,26,29,30,34,41],leav:[22,28,39],lectur:[],left:[22,28,42],legalcod:20,len:[1,16,23,26,29],length:[],lesli:[],less:[21,26,30],let:[0,1,10,13,21,22,23,24,25,26,27,28,29,30,35,41,42],letter:[2,12,14,21,23,24,25,40],level:[8,21,22,25,29,35,40],lexical_analysi:[23,24,25],lfd:34,lgamma:22,lib:[35,41,42],librari:17,licenc:20,licens:[20,21,35,36,37,42],life:37,lifejacket:38,light:40,lighten:[],lightweight:[],like:[0,1,2,4,5,7,8,12,15,16,18,21,22,23,24,25,26,27,28,29,30,31,34,35,37,38,39,40,41,42],limit:[21,22,26,30],lin:[],line:[],line_count:21,linear:[18,40],linefe:[23,24,25],liner:[1,22],link:[8,22,24,34,37,40],link_color:26,lint:[],linter:[22,40],linux2:35,linux:[],lisp:21,list1:[],list2:[],list3:[],list:[],list_it:[],list_lab:[12,24],list_of_stuff:24,list_of_tupl:1,listdir:[25,41],listiter:[],lite:1,littl:[],live:22,llvm:42,local:[],locat:[21,22,28,40,42],log10:22,log1p:22,log:22,logged_func:[],logging_add:[],logic:[13,23,24],longer:[21,22,30],look:[0,1,4,5,8,10,16,18,21,22,23,24,25,26,27,28,29,30,31,34,35,38,39],lookup:24,loop:[],lost:[18,39],lot:[1,5,8,21,23,24,27,29,34,38,39,41,42],loud:[23,24],low:[10,29],lower:[23,24,25,26],lowercas:12,lpthw:[21,25],lst:30,luck:8,luckili:39,lui:[19,21,22,23,24,25,26,27,28,29,30],lumberjack:1,lutz:30,mac:[],maccami:[],machin:[21,22,30,36,39,41],macosx10:36,macport:[34,36],macroman:41,made:[21,22,23,24,40,41],magic:[],magicmethod:29,mai:[1,8,10,18,21,22,23,27,28,29,31,34,36,37,40,41],mail:[],mailroom2:26,mailroom:[],main:[13,26,40],maintain:[22,24,28,34],major:26,make:4,maker:42,malform:3,mammal:[],man:25,manag:[],mango:[1,2],mani:[10,21,23,24,25,26,30,35,37,39,41],manpagez:25,manual:[31,35,40,42],map:[],marathon:2,marc:[],march:35,mari:22,maria:38,maria_mckinlei:22,mark:[8,22,30],marker:31,markup:8,marta:38,martelli:26,marti:[],masako:[],mask:22,mass:10,massiv:28,master:[1,22,31],match:[12,26,34],math:[0,6,18,22,24,27],mathemat:[22,30],matter:22,max:[23,40],maximum:[22,30,40],maxwel:[],mayb:[8,18,24,25,36],mccabe:40,mckeag:[19,21,22,23,24,25,26,27,28,29,30],md5:24,mean:[2,8,12,21,22,23,24,26,27,28,30,39,41,42],meantim:30,measur:39,meat:1,mechan:[],medium:6,meet:[10,21],meetup:[],member:24,membership:[],memoiz:[],memori:[8,16,21,25,40,41],menu:13,merg:[22,31,34],meringolo:[],mess:[34,36],messag:[4,13,14,22,41],meta:8,metaclass:30,metadata:8,metaphor:37,method:[],michael:[19,21,22,23,24,25,26,27,28,29,30,38],michel:[],microsoft:34,middl:[8,15,23,24,41],might:[8,10,18,21,22,26,38,40,41],migrat:26,mike:[19,21,22,23,24,25,26,27,28,29,30],milk:[],milkwood:[10,24],million:5,min:23,mind:[6,27],minim:21,minimum:[21,34,41],minor:23,minu:7,minut:[21,22,26],miss:[21,26,34],mistak:40,mix:[],mixin:[],mkaz:17,mkdir:[21,22,25,42],mod:1,mode:[],model:[],modern:[8,21],modf:22,modifi:[23,25,39,40],modul:4,modula2:27,modular:27,module_a:34,module_b:34,modulenam:22,modulo:[21,29],modulu:21,moin:[21,23,24],moment:[21,28],monaco:40,mongodb:30,monkei:28,monkey_patch:28,more:17,morin:[],most:[8,21,22,23,24,25,26,27,28,29,34,35,40,41,42],mostli:[16,22,25,28,41],motif:30,motiv:[],mous:40,move:[21,26,31,40,42],mro:[],msg:24,msi:34,much:[1,8,21,22,23,24,25,26,27,30,31,38,41,42],mul:30,multi:[],multiinst:22,multipl:5,multiple_inherit:[27,28],multipli:[0,7,12,18,22,23,30],muscl:40,must:[21,22,23,24,25,26,28,39,41],mutabl:[],mutat:[10,23,24],my_arrai:16,my_for:[],my_fun:29,my_func:26,my_it:[],my_mod:26,my_one_func:26,my_packag:34,my_personal_directori:22,my_python_fil:[],my_quad:29,my_sequ:[],my_zero_func:26,mycomposedclass:28,myerscough:[19,21,22,23,24,25,26,27,28,29,30],myfunctestcas:26,mytest:26,nag:[22,23],nall:21,name:[],nameerror:21,namespac:[],nano:[],natur:4,navig:40,necesari:[],necessari:22,need:[],neg:23,neither:26,nest:[],net:[21,22,25,28,30,36,38,41],network:[40,41],never:[8,21,22,24,26,34,38,41],new_dict:30,new_funct:[],new_i:21,new_list:30,new_set:30,newcircl:27,newcod:38,newcom:38,newlin:[7,10,21,25,39],newton:[19,21,22,23,24,25,26,27,28,29,30],next:4,nice:[0,8,13,17,18,21,22,23,24,25,28,30,34,35,36,39,40,41,42],nicer:[],nift:[],nifti:5,nightmar:42,nine:[],nix:[25,36,41],no_error:21,noaa:34,noarch:35,nobodi:28,nois:40,non:[16,18,22,23,24,34,39,40,41,42],none:[1,3,8,21,22,23,24,26,28,29,30,42],noon:[19,21,22,23,24,25,26,27,28,29,30],nope:[26,41],noplugin:22,nor:[21,26],normal:[23,24,39,42],nose:26,nosess:22,nosql:30,notabbar:22,note:4,notepad:[21,22],noth:[21,22,23,24,26,27,28,39],notic:[21,31,39,42],now:5,nstring:21,nth:[4,11],nthat:[23,24,25],nuco:34,nul:29,num:[1,23,24],num_in:26,number2:42,number:[],numer:[3,4,38],numpi:[],obei:27,obj:21,object:[],obliqu:8,obscur:[30,41],observ:4,obviou:[21,24,26],obvious:30,occasion:21,occur:[23,26],occurr:12,octal:[23,24,25],odd:22,oddli:36,off:[21,23],offer:[21,38,39,40],offici:[17,21,29,35,38],offset:25,often:[5,8,14,21,22,24,27,29,31,34,38,40,42],oftentim:16,ohashi:[],okai:[23,24],old:[],older:[34,40],omelett:40,onc:[],one_line_comprehension_her:1,onelinetag:8,onli:[],onlin:[],onto:[22,30,39],ooo:[23,24,25],oop:27,open:[8,24,25,26,31,34,36,38,40,41],openhatch:38,oper:5,operand:22,operation:24,oppos:27,opt:35,optim:[24,26,30],optimum:40,oracl:26,orang:12,orangutan:1,ord:[23,24,25,41],order:15,ordereddict:29,org:[8,12,17,18,20,21,22,23,24,25,26,27,28,29,30,34,35,36,37,38,41],organ:[22,30],orient:[],oriented_program:27,origin:[12,13,18,21,22,23,24,26,34],oserror:26,osx:[36,40],other:[],other_count:21,otherwis:[18,23,24,37,39],our:[],out:[0,1,2,5,6,7,8,10,11,12,13,16,17,21,22,23,24,25,26,27,28,29,30,31,36,38,39,41,42],out_fil:8,outer:30,outfil:[8,25],outfilenam:[],output:[1,7,8,10,13,25,39,41],over:[13,21,22,23,24,25,26,29,30,38,41],overflow:[],overload:[27,30],overrid:[],overview:[],own:[],p189616:1,p_wrapper:[],pacakg:36,pace:38,packag:[],packagenam:22,page:[8,21,27],pai:21,pain:[34,35],pair:[10,24,40],palett:40,paradigm:[],paragraph:[8,10],parallel:30,param:[18,39],paramet:4,parameter:26,paramt:39,paren:21,parent1:28,parent2:28,parent3:28,parent:[27,28,31],parenth:21,parenthes:[21,23],pars:39,parti:[22,26,34,36],particular:[8,16,18,22,23,24,26,27,29,30,42],particularli:[7,21,22,23,26,34],partli:26,partygo:22,pass:17,passiv:21,past:[21,23,25,27],pasta:1,patch:28,path:[],pattern:[6,23,24,26],payload:29,pbear:14,pce:30,pcottl:31,pdbsublimetextsupport:40,pdf:27,peach:12,pear:12,pei:[],peopl:[5,30],pep343:[],pep428:25,pep485:18,pep8:[21,40],pep:[],per:[22,25,40,41],perhap:[3,10,23,39],perl:21,perman:21,permiss:[22,26],pernici:[23,24],person:[],phdcomic:22,phillip:28,pick:[26,42],pictur:[],piec:[8,21,24],pile:22,pip3:35,pip_build_root:42,pipermail:22,pitt:[],pivot:31,pkg:36,place:[],plain:8,plan:38,planningadinn:38,platform:[25,34],platon:41,platypu:[],pleas:[21,22,23,25,29],pleasant:38,plu:[7,21,34],plugin:[],plural:[],poach:1,point:[],pokerhand:27,pollut:42,polymorph:27,pop:[23,24,40],popitem:24,popul:[13,22],popular:[34,35,38],port:26,portingpythontopy3k:21,posit:[18,22,26,41],position:22,posixpath:25,possibl:[8,10,13,21,26,28,37,40],post:5,postcondit:27,poster:38,postgr:26,potenti:[10,23,24],pow:22,power:[6,8,21,23,24,25,26,29,30,38],powershel:37,ppc:34,practic:[6,14,21,22,23,38],pradeep:[19,21,22,23,24,25,26,27,28,29,30],pre:[],precondit:27,prefer:[8,21,26,36,39,40],preformat:[],preinstal:35,preliminari:40,prepar:28,prepend:39,present:[16,22,23,38,39,42],preserv:[14,22],pretti:[5,8,18,21,22,23,24,25,26,34,41],previou:4,previous:[],price:38,primari:[8,23],prime:[],print:[4,5],print_grid2:7,print_grid:7,privaci:36,privat:42,privileg:42,pro:[30,31],prob:1,probabl:[21,25,34,35,36,37,41],process:[],produc:[4,17,21,39],product:[21,30,34],profesion:5,profil:42,program:5,programiz:30,programm:[5,21,29,38],programming_paradigm:27,progress:[23,24],proid:[],project:[],project_hom:42,projectenv:40,prompt:[12,13,21,22,23,24,25,37,39,42],prompt_command:39,prone:[23,24],pronounc:29,propag:[],proper:[8,21,22,30],properli:[4,8,14],properti:[],properties_exampl:28,property_:28,property_ugli:[],proport:[23,24],propos:30,protocol:[],prove:22,provid:[8,14,21,22,23,24,26,27,28,30,34,36,38,39,40,41,42],proxi:24,ps1:39,pst:[],psv:[23,24,25],psych:5,pth:25,publish:[22,38],pull:[2,4,12,13,14,21,22,26,31],punctuat:[10,14],puppi:28,pure:[],purpos:[37,42],push:[2,4,12,13,14,22],pushup:21,put:[0,2,7,8,12,13,21,22,24,26,27,39,40,42],puzzl:[21,22],pwd:[21,42],py200:[],py2app:34,py2ex:34,py300:[],py3:[],py3k:21,py_modul:34,pyc:[0,22,41],pycharm:21,pycon:38,pyconslid:[25,27],pydanni:30,pyflak:[21,40],pyformat:17,pyhton:25,pyinstal:34,pymbook:38,pymotw:[25,30],pypa:34,pypi:[21,34],python2:[21,35,41,42],python300:[19,21,22,23,24,25,26,27,28,29,30],python34:[35,37],python3:[1,21,22,23,25,26,35,36],python3wo:21,python:17,python_interpreter_path:40,python_koan:1,python_package_path:40,python_path:40,pythoncert:[19,21,22,23,24,25,26,27,28,29,30],pythonchb:[],pythonclass:8,pythonhost:34,pythonlib:34,pythonlibrari:38,pythonpath:22,pythonstuff:25,pyvideo:[21,27],quack:[8,21],quad1:18,quadrat:[18,29],quadratur:18,qualifi:29,quark:27,quarter:[],queri:[0,12,23],question:[],quick:[10,21,24,25,35,36,37,38,42],quicki:[],quickref:[21,35,36,37],quit:[10,13,21,26,29,38,40],quiz:30,quot:[21,22],radian:22,radic:30,radioact:22,radiu:[0,27],rae:[19,21,22,23,24,25,26,27,28,29,30],rafekettl:29,raid:10,rais:[],ram:[22,30],ran:[26,42],random:[10,23,24,42],rang:[],rare:21,raspberri:23,rate:29,rather:[3,4,21,22,25,26,28,29,30,34,36,40,41],raw:[],raw_input:22,raymond:[25,27,28],read_data:25,readabl:[8,17,22],reader:[],readi:[22,23,24,34,38],readlin:25,readm:22,readthedoc:[25,26,34,38],real:[8,16,21,30,31,41],realiti:[],realli:5,rearrang:18,reason:[38,40],rebind:21,recal:21,receiv:[22,28],recent:[21,22,23,24,25,28,29,41],reconcil:31,rectangl:18,recurs:[],recus:4,red:[],reduc:[],redund:22,ree:[19,21,22,23,24,25,26,27,28,29,30],ref:[],refactor:[8,27,28],refer:[8,16,17,21,23,24,25,29,35,36,37,38,41],referenc:[22,39],reflect:0,refus:10,regard:38,regardless:[24,37],regex:[23,25],regular:[16,29,30,41],rel:[25,30],relat:4,relationship:[27,28],releas:[27,30,34,35],relev:40,reli:34,reliabl:[],reload:22,relpath:25,remaind:[1,29],rememb:[0,8,10,21,22,23,24,27,28,29,30,31,34,39,42],remov:[12,15,21,23,24,31,40,42],repe:[23,24],repeat:[1,8,21,23],repetit:[13,23,24],replac:[14,40],repo:[2,12,13,21,22,25,35,39],repositori:4,repr:[0,29,41],repres:[0,6,22,28,31,38],represent:[1,21,29],represet:6,request:[2,4,12,13,14,21,22,31,42],requir:4,research:38,resid:22,resolv:31,resolve_party_favor:22,respect:23,respons:[12,34],rest:[22,23,27,30],restor:34,restructuredtext:42,result:4,return_a_str:[],reus:[27,28,30],revers:[12,15,23,24],review:[],revisit:[1,22],rewrit:[17,24],rhetting:28,rhscl:35,rice:30,rich:[],rick:[19,21,22,23,24,25,26,27,28,29,30],riehl:[19,21,22,23,24,25,26,27,28,29,30],right:[],rins:21,rjust:21,robert:[19,21,22,23,24,25,26,27,28,29,30],robust:40,rogerdudl:21,roll:39,room:[13,23],root:35,rosko:[],rot13:[],rough:23,round:[7,41],row:[7,13],rpartit:21,rpm:[34,35],rriehl:[19,21,22,23,24,25,26,27,28,29,30],rsplit:21,rst2html:42,rst2latex:42,rst2xml:42,rst:22,rstpep2html:42,rstrip:21,rubi:21,rudolph:[19,21,22,23,24,25,26,27,28,29,30],rule:[],ruler:40,run:5,run_html_rend:8,runtim:28,runtimeerror:[],ruthless:1,ryan:[],sad:23,safe:37,safe_input:3,safer:[23,25,27],safeti:[23,24],sai:[2,10,12,23,24,26,27,30,34,36],said:21,sake:28,salad:1,salient:27,same:[1,2,8,10,14,16,18,21,22,23,24,27,28,29,30,31,34,37,40,41,42],sampl:[8,23,24,25],sample_html:8,sane:22,sarpangala:[19,21,22,23,24,25,26,27,28,29,30],saturdai:10,sauc:29,save:[21,22,30,40],saw:41,scale:6,scan:[],scara:[],scatter:16,scene:21,scheme:[14,40],schincariol:[19,21,22,23,24,25,26,27,28,29,30],scienc:[5,38],scientif:[10,37],scipi:34,scl:35,scm:[31,36],score:[6,24],scoundrel:10,script:[],sdist:34,sdk:34,search:[21,26,30,35,38,40],seattl:[1,2],sebz:14,second:[1,6,8,13,21,38,39,40],secondari:8,secret:[22,25,29],secret_data:25,secret_head:25,secret_rest:25,section:[8,23,37],secur:[36,42],see:[0,1,8,11,18,21,22,23,24,25,26,27,29,30,31,35,39,40,41,42],seek:[23,25],seem:[26,41],seen:[8,22,23,24,26,29,30],select:[13,25,40],self:[],selfclosingtag:8,semi:31,semin:[],sens:[0,8,22,25,27,28,30],sentenc:22,sep:[21,36],separ:[8,13,21,23,24,25,27,31,40,42],separt:[23,24,25],seq:[23,25,29],sequenc:15,sequenti:[],seri:[],serious:22,serv:22,servic:38,session01:[21,31],session02:4,session03:14,session04:2,session05:26,session06:[11,18],session07:[8,27],session09:34,session10:[],session5:12,session:[],session_02:22,set:[],set_x:28,setdefault:24,setting_up_your_environ:[],setup:[21,22,23,26,34,36,42],setuptool:[34,42],setx:[],seven:[],sever:[6,21,26,42],sgml:8,sha:24,shallow:[23,24],shape:26,share:[21,22,23,27,34],sharealik:20,she:[10,38],shell:37,sherlock:[10,24],sherlock_smal:10,sherm:22,sherm_the_boranga:22,shift:40,ship:10,shoot:10,shop:10,shortcut:[22,40],shorter:[10,21],shorthand:[],should:[0,1,2,4,5,8,11,12,13,14,15,16,18,21,22,23,24,26,27,29,30,31,34,35,36,37,38,39,40,41,42],should_be_remov:[23,24],shouldn:[],shout:[],show:[1,13,21,22,26,31,39,40,42],shown:22,shudder:[],shutil:25,side:[22,30,42],sign:[21,41],signal:10,signatur:[0,8,27],signific:21,silli:40,similar:[],similarli:26,simpl:5,simple_class:27,simpler:[16,21,27,30,34],simplest:[18,21,27],simpli:[8,18,21,22,28,31,36],simplifi:[23,24,40],sin:[18,22],sinc:[8,16,22,39],sine:18,singl:[8,18,21,22,23,24,27,29,30,34,39,40,42],singleton:[],sinh:22,site:[26,34,35,38,42],situat:[10,22,26,39,42],six:[],size:[6,7,8,10,24,25,26,27,40],skip:[23,24,25,37],skit:1,slash:[8,21],slave:27,sleep_in:22,slice:[],slide:21,slightli:[1,21],slope:18,slot:30,sloth:1,slowli:10,small:[6,13,18,22,23,24,30],smaller:[7,22,30],smart:[8,21],smooth:21,soap:22,socket:[],soda:40,softwar:[35,36,39,42],softwarecollect:35,solid:[38,40],solomon:[19,21,22,23,24,25,26,27,28,29,30],solut:5,solv:[18,21,22,30],some:[0,8,10,14,15,16,18,21,22,23,24,25,26,27,28,29,30,34,38,39,40,41,42],some_argu:29,some_cod:[23,24],some_food:[23,24],some_initil:29,some_nam:21,some_paramet:29,some_stuff:[],some_tag:8,someenv:39,somelist:[23,24],someon:41,somestuff:25,someth:[0,1,5,7,8,10,21,22,23,24,25,26,27,28,29,30,34,35,37,39],somethign:8,something_els:21,something_is_tru:30,sometim:[21,22,23,24,29,31,34,41],somth:24,soon:[21,30],sorri:27,sort:[],sourc:[35,38,39,40,42],sourceforg:36,space:[],spaghetti:[23,24],spam:[1,23,24],spare:16,spars:[],sparsearrai:16,spasmod:[],speak:37,speaker:41,speakerdeck:[25,27],special:[],specif:[1,8,21,27,31,41],specifi:[0,6,7,23,24,25,26,29,30,34,40,41],spell:[],spelunk:14,spend:[10,23,24,25],split:[21,22,23,24,25],splitext:25,splitlin:21,spong:22,spread:26,sprint:21,sprintf:[23,24,25],sqrt:[22,27],squar:[30,39],stabl:[34,35,38],stackoverflow:[],stage:[],standard:[],start:4,start_at:30,starter:21,startswith:21,startup:[39,42],stash:39,state:[],statement:4,static_method:29,staticadd:29,staticmethod:29,statu:[22,39],statvf:41,stdin:24,stdlib:34,stdout:[],stdtype:[22,23,24,25],stevedor:42,steven:[],stick:[23,24,25],still:[8,21,23,24,25,34,35,37,38,39,40,41,42],stink:[],stock:29,stone:37,stop:[40,42],stopiter:[],store:[8,16,21,22,23,24,25,29,30,34,36],str:[],straight:[18,22,30,42],straightforward:[5,34],strang:26,strategi:[26,39],strength:[27,28],strict:[8,41],strictli:[],string:[],strip:21,strive:22,strong:[21,40],struct:[23,24,25],structur:[],struggl:[2,12],stuck:[28,41],student:[2,4,12,13,14,21,22,25,29,38],stuff:[],style:[8,21,22,23,24,25,27,28,37,38,40],stylist:[10,40],sub:[8,23,27],subclass:[],subclassi:29,subclsss:8,subl:22,sublenv:40,sublim:[],sublime_text:22,sublimecodeintel:40,sublimejedi:40,sublimelint:40,sublimetext:[21,40],submit:[1,22],subscript:21,subset:2,substitut:14,substr:23,subsub:8,subtl:21,subtract:21,subtyp:27,subvers:37,successfulli:[40,42],sudo:[35,42],sue:21,suffic:39,sugar:[],suggest:[21,27],suit:40,suitabl:41,sum2x:[],sum:[4,24,29,30],sum_seri:4,summ:[19,21,22,23,24,25,26,27,28,29,30],summer:[19,21,22,23,24,25,26,27,28,29,30],sundai:[19,21,22,23,24,25,26,27,28,29,30],super1:28,super2:28,super3:28,superclass:[8,27,28],superset:41,superus:42,supplement:[],suppli:26,support:[8,16,21,23,24,27,29,34,37,40,41,42],suppos:27,sure:[0,8,10,18,21,22,34,36,40,42],surfac:40,surpris:[1,10],surreal:10,surround:8,susan:[19,21,22,23,24,25,26,27,28,29,30],sushi:[23,24],svn2github:[],swallow:[10,41],swap:21,swapcas:[21,23,24,25],swash:10,sweet:42,swift:[],switch_func_dict:26,symlink:36,symmetric_differ:24,sync:[24,28],syntact:[31,40],syntax:[],syntaxerror:[21,22,23,24,25],system:[6,19,21,22,23,24,25,26,27,28,29,30,34,35,36,37,40,41,42],sytem:37,tab:[21,22,23,24,25,39,40],tab_siz:40,tabl:[10,24,26,41],tabular:13,tack:27,take:[6,17,38,39,40,42],taken:[],taketh:[],tan:22,tanh:22,tar:42,tarbal:34,tare:[23,24,25],tarfil:29,tarinfo:29,task:[],tast:[23,24],taxonomi:27,tbd:[19,21,22,23,24,25,26,27,28,29,30],tby:[23,24,25],tcsh:39,teal:[],team:31,tear:26,teardown:[],tebbett:[],technic:[10,22],techniqu:35,tediou:42,teh:18,tell:[7,16,21,25,31],templat:25,ten:[],tend:[22,36],term:[27,28,30,37,42],termin:[],test:[],test_:26,test_cigar_parti:26,test_gener:[],test_html_ouput:8,test_html_output2:8,test_html_output3:8,test_html_output4:8,test_html_output5:8,test_html_output6:8,test_html_output7:8,test_html_output8:8,test_my_func:26,test_my_mod:26,test_p_wrapp:[],test_scor:6,test_tautolog:26,test_thi:26,test_trapz:18,test_val:26,testabl:[27,40],testcas:26,testenv:42,text:[],textbook:38,textedit:21,textwrapp:8,than:[1,3,4,7,13,21,22,23,24,25,26,28,29,30,34,36,37,39,40,41,42],the_diamond_problem:[27,28],the_error:26,the_fil:21,the_list:11,the_name_of_the_fil:21,the_name_of_the_script:21,the_packag:34,the_radiu:0,the_shell_command:21,the_superclass:27,thei:[0,7,8,10,13,16,21,22,23,24,25,26,27,29,30,31,34,41,42],thelist:8,them:[],theme:[22,40],themselv:38,theoret:18,theori:27,thequickbrownfoxjumpedoverthelazydog:23,therefor:[28,41],theyar:[],thi:[4,5],thing:[],think:[7,8,10,18,21,22,23,25,26,27,28,30,38,40,41],thinkpython009:22,thinkpython016:25,thinkpython2:21,thinkpython:[22,25,38],third:[1,4,10,15,23,26,34,36,39],third_lett:[23,24],this_0:30,this_1:30,this_2:30,this_3:30,this_4:30,this_:30,this_could_be_a_filenam:23,this_is_2:21,this_is_a_symbol:21,thisthat:7,thoma:[10,24],those:[8,12,13,18,21,22,23,26,28,29,30,31,34,36,37,40,41],though:[21,22,23,27,34,37,38],thought:[10,27,42],thousand:26,thread:30,three:[4,5],through:[],thu:[8,11,28,37,40],thursdai:[],tidbit:[],tiffani:[],till:26,time:[],timecomplex:[23,24],timed_func:[],timelin:31,timer:[],tini:[8,21],tire:13,titl:[8,21,23,24,25],tmp:42,tmtheme:40,toast:[23,24],todai:[],todo:22,togeth:[0,7,22,34],told:[],tom:[],ton:40,too:[8,10,18,21,22,23,24,25,30,31,36,40,41,42],took:42,tool:[],toolkit:[],top:[13,22,28,41],topic:[],tortoisegit:37,total:[13,18,41],touch:[22,23,24],toward:24,tprint:21,trace:[21,42],track:[25,38,42],tradeoff:30,trail:40,trailing_spaces_modified_lines_onli:40,trailing_spaces_trim_on_sav:40,trailingspac:40,transform:[23,24],translat:[21,25,37],translate_tabs_to_spac:40,transmit:41,trap:23,trapedzoid:27,trapezoid:[],trapezoidal_rul:18,trapz:18,treat:[8,10,26],tree:[8,38],tresult:[],tri:21,trick:17,tricki:[8,22],trigger:26,trim:40,trim_trailing_whitespace_on_sav:40,trip:41,tripl:22,trivial:42,troubl:30,trunc:22,tsega:[19,21,22,23,24,25,26,27,28,29,30],tsepar:[23,24,25],ttab:[23,24,25],tupleiter:[],turn:[],tutori:[],twenti:[1,2],twice:[10,22],twist:23,twith:[],two:4,txt:[10,22,23,24,25,26,41],typeerror:[21,23,24,26,27,29],typesseq:[23,24],typic:[],typo:26,u221:41,u222b:41,uci:34,ugli:34,unari:[21,22],unbind:21,unbound:[21,28,29],unboundlocalerror:22,uncom:8,under:[],underli:29,underscor:[21,29],underspecifi:[7,24],understand:[37,40],understood:26,unexpect:[22,41],unfortun:22,unhash:24,unichr:41,unicod:[],unicode_exception_test:41,unicode_liter:41,unicodedecodeerror:41,unicodeencodeerror:41,unicodifi:41,unidata:41,uninstal:40,union:[2,24],uniqu:[21,23,24,31],unit:[],unix:[22,25,36,37],unless:22,unlik:[21,29],unnam:21,unord:[8,24],unsatisfi:[],unset:39,unsign:36,until:[12,23,24,27],untrack:39,untrus:36,updat:[3,8,18,21,22,23,24,25,29,36,37,38,40],upgrad:[34,36,37],upload:[29,34],upon:[8,30],upper:[1,21,23,24,25],upriss:12,upstream:22,upward:10,urg:[38,42],url:[],urlib:[],urllib:[],urlopen:[],usabl:37,usag:[21,38,40,42],use_tab_stop:40,user:[0,3,8,12,13,16,22,23,24,25,30,34,35,37,40,42],usr:[22,35,42],usual:[14,16,22,24,26,28,29,30,34,41],usus:[],utc:41,utf16:41,utf32:41,utf8:41,utf:[],utf_8:41,utf_8_decod:41,util:[22,30,35,36,40],uuh:[],uvh:35,uwpc:[19,21,22,23,24,25,26,27,28,29,30],vacat:22,vagari:18,val1:[21,26],val2:[21,26],val3:21,val:[16,24],valid:[8,28,41],valu:[4,17],valueerror:[23,24,26],vapor:10,var2:30,variat:39,varieti:[6,26],variou:[6,8,29,38],vector:[22,29],vegor:[],vendor:41,verbos:[26,28],veri:[],verifi:13,verison:41,versa:[23,24],versino:36,version:[],versu:22,via:[16,23,24,40],vice:[23,24],victor:10,video:[21,27],view:8,viewer:21,viewpost:30,vintag:40,violat:[27,40],virtual:[16,28,42],virtual_env:[39,42],virtualenv:[],visibl:22,visionari:[],visit:[23,24,39],visited_color:26,vital:40,voic:10,voilà:39,volunt:24,vora:[],vowel:30,w3school:8,waddl:[],wai:[7,8,18,21,22,23,24,25,26,27,28,29,30,31,34,37,38,39,41,42],walk:25,wander:[],want:[7,8,14,16,18,21,22,23,24,25,26,27,28,29,30,34,35,36,37,38,39,40,41,42],warmup:[21,23],warn:[10,35,36],warnign:36,warren:[19,21,22,23,24,25,26,27,28,29,30],wart:21,wasn:[27,28,34],watch:[23,26],water:[23,24],weak:27,weapon:[1,6],weapon_s:6,weapon_typ:6,web:5,web_connect:[],weblog:30,websit:[22,38],week:[],weekdai:22,weekend:[],weigh:21,weird:23,well:[4,8,18,21,23,24,25,26,27,28,29,30,34,36,37,38,39,41],were:[20,22,26,30,34,41,42],western:41,whaddaya:[23,24,25],what:[4,5],whatev:[12,23,25],whatsnew:30,when:4,whenev:[27,42],where:[],wherev:42,whether:2,which:[4,5,35,37,39],whitespac:[14,21,22,40],whl:42,who:[],whoa:42,whole:[8,24],whozit:22,why:4,wide:[16,18,26,34,41],width:[18,40],wierd:[],wiki:5,wikipedia:[18,27,28,30,41],wil:8,wild:21,win:22,winberri:[],wind:[10,39],window:[],wire:42,wise:29,wish:[10,22],within:[21,22,27,30,34],without:[0,5,22,25,26],won:[8,10,16,21,22,23,24,29,41],wonder:[38,40],wood:[],word:[],word_wrap:40,wordpress:28,work:[4,15],worker:22,workfil:25,workflow:[22,26,42],workon_hom:42,workshop:38,world:[16,21,31,41,42],worri:[1,8,22],wors:22,worst:41,worth:[23,24,25,28,31],would:[7,8,10,18,24,26,38,39,41,42],wouldn:[10,22],wrap:[],wrap_width:40,wrapper:[3,8],wring:10,write:[4,5,15,17],writelin:25,written:[21,26,34,38,41],wrong:[21,26,28,42],wrote:[18,22],wtf:22,www:[8,12,18,21,22,25,26,27,29,30,34,35,36,37,38,41],wxpython:[],x00:41,x00h:41,x00i:41,x86:22,x86_64:35,xb2:41,xcode:[34,36],xfe:41,xfet:41,xff:41,xhh:[23,24,25],xkcd:21,xml:[8,41],xrang:21,y_rang:[],yagni:[],yang:[],yeach:41,yeah:[],year:[10,26],yellow:39,yet:[21,26,36,40],yield:[],yield_exampl:[],ymb0l:[23,24,25],yoru:[21,36],you:[4,5],your:[4,5],yourself:[],youtu:[25,27],youtub:26,yuanrui:[19,21,22,23,24,25,26,27,28,29,30],yum:[34,35],zero:[],zerodivisionerror:[21,26],zeroth:11,zfill:21,zhao:[19,21,22,23,24,25,26,27,28,29,30],zip:[21,24,29,34],zntargvp:14,zola:30,zone:22,zsh:39},titles:["Circle Class Excercise","Comprehensions Lab","Dictionary and Set Lab","Exceptions Lab","Fibonacci Series Exercise","Fizz Buzz Exercise","Passing functions to functions","Grid Printer Exercise","HTML Renderer Exercise","Exercises","Kata Fourteen: Tom Swift Under Milk Wood","lambda and keyword Magic","List Lab","Mailroom","ROT13","Slicing Lab","Sparse Array Exercise","String Formatting Lab","Trapezoidal Rule","<no title>","Intro To Python","Session One: Introductions","Session Two: gitHub, Functions, Booleans and Modules","Session Three: Sequences, Iteration and String Formatting","Session Four: Lists, Iteration, Strings, Dictionaries, Sets","Session Five: Files, Streams & String IO","Session Six: Exceptions, Testing and Advanced Argument Passing","Session Seven: Object Oriented Programming","Session Eight: Object Oriented Programming 2","Session Nine: Object Oriented Programming 3","Session Ten: Functional Programming","git Overview","Supplemental Materials","Installing Nano on Windows","Packages and Packaging","Setting Up Python For Linux","Setting up your Mac for Python","Setting up Windows for Python","Useful Python Learning Resources","Shell Customizations for Python Development","Turning Sublime Text Into a Lightweight Python IDE","Unicode","Working with Virtualenv"],titleterms:{"__builtins__":21,"__init__":27,"boolean":22,"case":[23,24,25,26],"catch":25,"class":[0,16,21,22,27,28,29,30],"default":[],"final":[26,34],"float":27,"function":[6,7,18,21,22,26,27,30],"import":22,"new":[23,24,25,30],"return":[21,22],"static":29,"super":28,"switch":[23,24,25,26],"true":22,"while":[23,24],about:[2,12,30],accuraci:18,activ:42,advanc:26,again:39,ahead:8,along:40,altern:29,announc:[24,25,26,27,28,29,30],anonym:30,anoth:[],anywai:41,applic:34,argument:[18,21,26,28,30],ariti:27,around:18,arrai:[16,29],art:27,articl:28,assert:22,assign:[21,23,24],attribut:[8,27,28],autocomplet:40,automat:[],base:27,basic:[8,21,22,27,34,40,41],been:30,befor:25,beginn:38,beyond:22,bit:30,branch:[],build:[17,23,25],built:[26,30],bundl:34,buzz:[5,22],call:[11,21,26],callabl:29,can:27,caveat:[],cento:35,chain:26,challeng:41,check:8,choos:[23,24],circl:0,classic:5,clean:42,clear:28,cli:21,close:[],closur:30,code:[11,21,22,40],come:8,command:21,comment:24,commit:22,compil:34,complet:13,complex:[23,24,25,34],composit:28,comprehens:[1,30],comput:[4,18],concaten:23,concept:27,concis:28,consider:[23,24],constructor:[24,29],contain:29,content:9,context:[],contextmanag:[],continu:29,contribut:30,control:22,convent:[23,24],copi:[23,24],could:30,count:1,coupl:17,cours:[20,21],creat:13,credit:18,critic:41,current:34,curri:[18,30],custom:[29,39],deactiv:42,debian:35,decis:22,decod:41,decor:28,def:21,definit:27,delet:[21,28],demo:26,depend:28,descriptor:29,design:27,develop:[26,34,39],diamond:[27,28],dict:[1,24,26,30],dictionari:[1,2,24],did:8,differ:21,directori:[],dispatch:27,distribut:34,distro:35,distutil:34,doc:41,docstr:22,document:[22,23,24],doe:[],domin:27,doubl:1,driven:26,driver:[],duck:[8,21],dynam:21,ecosystem:21,editor:[21,22,40],eight:28,element:8,elif:26,els:26,emul:29,encod:41,encrypt:14,enough:21,enter:41,environ:21,equal:21,etc:21,evalu:38,even:1,everywher:41,exampl:[11,18,28,29],except:[3,8,21,26],excercis:0,exercis:[4,5,7,8,9,16,17],exist:26,express:[21,22],extend:40,extra:18,fact:41,fals:22,featur:[0,21,23],fedora:35,few:42,fibonacci:[4,22,30],file:[21,24,25],filter:[1,30],find:34,first:[22,27,30],five:25,fizz:[5,22],fly:8,follow:40,footnot:35,format:[17,23,24,25,26],four:24,fourteen:10,frame:[26,27,28,29,30],from:[8,22,23,24,30],frozen:24,fun:24,functool:30,gener:[0,4,8,29],get:[21,22,36,37],getter:28,git:[21,22,23,31,35,36,37],github:22,global:22,goal:[0,2,4,5,6,7,8,11,12,13,14,15,21],gotcha:[22,27,41],graphic:31,grid:[7,22],grow:[23,24],guidelin:13,handi:24,handl:8,happen:42,hat:35,heck:41,help:[],here:30,hint:[5,7,12,24],homework:[21,22,23,24,25,26,27,28,29,30],hour:21,how:21,html:8,ident:21,index:[23,24],inherit:[27,28],initi:27,inject:28,input:25,instal:[21,26,33,34,42],instruct:[0,8],instructor:21,interact:22,interpret:[21,38],intricaci:22,intro:20,introduct:21,ipython:[21,35,36,37,38],item:24,iter:[23,24],itertool:[],kata:10,kei:24,keyword:[11,21,26,30],know:30,lab:[1,2,3,12,15,17,21,22,23,24,25,26,27,28,29,30,34,41],lambda:[11,30],languag:[21,38],last:[23,24,42],latin:41,learn:[2,3,12,38],lectur:20,length:23,librari:[26,34],lighten:25,lightn:[21,22,23,24,26,27,28,29,30],lightweight:40,line:21,lint:40,linux:35,list:[1,12,21,22,23,24,30],liter:[21,23,24,25,41],littl:22,local:22,loop:[22,23,24],luca:4,mac:36,magic:11,mail:21,mailroom:13,make:[7,22],manag:40,manipul:[7,23,24,25],map:30,materi:[20,21,25,32],mechan:41,meetup:30,membership:23,method:[23,24,25,27,28,29,30],milk:10,mint:35,miscellan:[23,24],mix:[],mkproject:42,mkvirtualenv:42,mode:34,model:[27,28],modul:[22,25,34],more:[22,23,24,27,30,34,39],mro:28,multi:30,multipl:[21,23,24,25,27,28],mutabl:23,name:[23,24,25,29,39],namespac:22,nano:33,need:[24,27],nest:[],next:[21,22,23,25,38],nifti:[21,24],nine:29,note:[8,27,28],now:21,number:[1,4,41],numer:29,object:[10,26,27,28,29,30],offic:21,old:[23,24,25],onc:24,onli:28,onlin:21,oper:[21,24],option:[0,8,26,38],order:[24,27,28],ordin:[23,24,25],orient:[27,28,29],other:[1,21,23,24,26,31],our:21,outlin:22,overrid:27,overview:[21,31],own:29,packag:[22,34,42],paradigm:27,paramet:[7,21,22,26],part:7,partial:[18,30],pass:[6,18,26,28],path:25,pathlib:25,pep:30,perform:[23,24],person:[],pictur:31,pip:[21,35,36,37],place:21,placehold:[23,24,25],plai:1,plugin:40,point:27,pre:26,preced:21,previou:23,primer:[8,22],print:[7,21,22],printer:[7,22],problem:[5,10,27,28],procedur:[2,12],process:25,program:[13,27,28,29,30],project:30,properti:[24,28,29],protocol:29,purpos:28,py200:30,py2:[21,41],py300:30,py3:21,pycon:29,pytest:26,python:[20,21,22,23,27,28,30,34,35,36,37,38,39,40,41],question:[22,23,24,25,26,27,28,29,30],rais:26,rang:[23,24],raw:[23,24,25],read:[21,23,24,25,27,28,29,30],realli:27,reason:42,recommend:[24,34],recurs:[22,30],red:35,reduc:30,relat:35,remind:[],remot:22,render:8,report:13,repositori:22,requir:40,resolut:[27,28],resourc:[1,31,38],result:5,review:[22,23,24,25,26,27,28,29,30],right:8,road:[],root:27,rot13:14,rule:18,run:21,runner:26,scan:30,scenario:6,schedul:21,scope:22,script:34,self:27,semin:28,send:13,sequenc:[23,29],seri:4,session:[9,21,22,23,24,25,26,27,28,29,30],set:[1,2,21,22,24,30,35,36,37,40],setter:28,seven:27,shell:39,shrink:[23,24],similar:[23,24],simpl:7,six:26,slice:[15,23],softwar:27,solut:18,sort:[],sourc:30,space:40,spars:[16,29],special:[8,28,29],stack:21,stage:18,standard:[26,29],start:[22,23],state:34,statement:21,step:[0,4,8,21,38],stop:27,str:[26,41],stream:25,string:[7,17,21,23,24,25,41],stringio:[],structur:[21,22,27],stuff:[],subclass:27,sublim:40,submiss:13,summari:29,superpow:28,supplement:32,swift:10,symbol:21,syntax:21,tag:8,take:30,talk:[21,22,23,24,25,26,27,28,29,30],task:[11,14,15,18,21,23],ten:30,termin:[35,36,37],ternari:22,test:[4,8,18,21,23,24,25,26],text:[24,40],thank:13,them:26,thi:[20,21],thing:[],three:23,through:[18,24],time:8,todai:[22,23,24],tom:10,tool:[36,37],toolkit:27,topic:24,traceback:21,trapezoid:[18,27],trick:[21,23,24],trigram:10,truthi:22,tupl:[1,22,23,24],turn:40,tutori:31,two:[7,18,22,24,28],type:[8,21,23,27,29],typic:27,ubuntu:35,under:10,understand:27,unicod:41,unit:8,unittest:26,unpack:1,utf:41,valu:[21,22,23,24,25],variabl:[21,22,26],veri:21,version:[21,22,40],virtualenv:[34,42],virtualenvwrapp:42,wait:39,warm:[],web:[],week:[23,25],what:[21,22,23,27,29,30,39,41,42],wheel:34,when:27,where:[8,30,39],which:40,white:40,who:21,why:[21,22,23,29,42],wiki:35,window:[33,37],wood:10,word:42,work:[22,42],workon:42,wrap:39,write:[25,27,29],yield:[],you:[13,21,27,30],your:[21,22,29,36,38],yourself:[],zero:23}})
\ No newline at end of file
diff --git a/session01.html b/session01.html
new file mode 100644
index 0000000..577b4e9
--- /dev/null
+++ b/session01.html
@@ -0,0 +1,1725 @@
+
+
+
+
+
+
+
+
+
+
+ Session One: Introductions — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session One: Introductions
+
+
Introductions
+
In which you are introduced to this class, your instructors, your environment,
+and your new best friend, Python.
+
+
+
xkcd.com/353
+
+
+
Goals for Session One:
+
+Meet each other, set expectations for the class.
+Schedule lightning talks.
+Get you all up and running with Python
+Start having fun with Python with a quick tutorial
+
+
+
+
Introductions
+
In which we meet each-other
+
+
Your instructors
+
+
Rick Riehle
+
rriehle (at) uw (dot) edu
+
+
+
+
Summer Rae
+
summe (at) uw (dot) edu
+
+
+
+
+
Who are you?
+
Tell us a tiny bit about yourself:
+
+name
+programming background: what languages have you used?
+what do you hope to get from this class
+
+
+
+
+
Introduction to This Class
+
Intro to Python
+
+
+
Class Structure
+
Class Time:
+
+
+Some lecture – as little as possible
+Lots of demos
+Lab time: lots of hand-on practice
+- Take a break if you need one then...
+Lather, Rinse, Repeat.....
+
+
+
Interrupt me with questions – please!
+
(Some of the best learning prompted by questions)
+
+
+
Homework:
+
+Most homework will be reading, and the occasional Video
+
+Exercises will be started in class – but you can finish them at home.
+
+You are adults – it’s up to you to do it
+
+You can do a gitHub “pull request” if you want us to review your work.
+
+
+We’ll review how to do that in the second Session
+
+
+
+
+
+
+
+
Lightning Talks
+
Lightning Talks:
+
+
+5 minutes each (including setup) - no kidding!
+Every student will give one
+Purposes: introduce yourself, share interests, show Python applications
+Any topic you like, that is related to Python – according to you!
+
+
+
+
+
+
Python Ecosystem
+
+
What is Python?
+
+Dynamic
+Object oriented
+Byte-compiled
+Interpreted
+
+
But what does that mean?
+
+
+
Python Features
+
+Unlike C, C++, C#, Java ... More like Ruby, Lisp, Perl, Javascript
+...
+Dynamic – no type declarations
+Programs are shorter
+Programs are more flexible
+Less code means fewer bugs
+
+
+Interpreted – no separate compile, build steps - programming process is
+simpler
+
+
+
+
What’s a Dynamic language
+
Dynamic typing .
+
+Type checking and dispatch happen at run-time
+
+
+
+What is a ?
+What is b ?
+What does it mean to add them?
+a and b can change at any time before this process
+
+
Strong typing .
+
In [1]: a = 5
+
+In [2]: type ( a )
+Out[2]: int
+
+In [3]: b = '5'
+
+In [4]: type ( b )
+Out[4]: str
+
+
+
+everything has a type.
+the type of a thing determines what it can do.
+
+
+
+
Duck Typing
+
“If it looks like a duck, and quacks like a duck – it’s probably a duck”
+
If an object behaves as expected at run-time, it’s the right type.
+
+
+
Python Versions
+
Python 2.x
+
+“Classic” Python
+Evolved from original
+
+
Python 3.x (“py3k”)
+
+Updated version
+Removed the “warts”
+Allowed to break code
+
+
This class uses Python 3 – not Python 2
+
+Adoption of Python 3 is growing fast
+
+If you find yourself needing to work with Python 2 and 3, there are ways to write compatible code: https://wiki.python.org/moin/PortingPythonToPy3k
+We will cover that more later in the program. Also: a short intro to the differences you really need to know about up front later this session.
+
+
+
+
+
Introduction to Your Environment
+
There are three basic elements to your environment when working with Python:
+
+Your Command Line
+Your Interpreter
+Your Editor
+
+
+
Your Command Line (cli)
+
Having some facility on the command line is important
+
We won’t cover this much in class, so if you are not comfortable,
+please bone up at home.
+
I suggest running through the cli tutorial at “learn code the hard way”:
+
http://cli.learncodethehardway.org/book/
+
Windows:
+
Most of the demos in class, etc, will be done using the “bash” command line shell on OS-X. This is identical to the bash shell on Linux.
+
Windows provides the “DOS” command line, which is OK, but pretty old and limited, or “Power Shell” – a more modern, powerful, flexible command shell.
+
If you are comfortable with either of these – go for it.
+
If not, you can use the “git Bash” shell – which is much like the bash shell on OS-X and Linux.
+
+
+
Your Interpreter
+
Python comes with a built-in interpreter.
+
You see it when you type python at the command line:
+
$ python
+Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
+[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
+Type "help", "copyright", "credits" or "license" for more information.
+
+
+
That last thing you see, >>> is the “Python prompt”.
+
This is where you type code.
+
+
+
+
Python in the Interpreter
+
Try it out:
+
>>> print ( "hello world!" )
+hello world!
+>>> 4 + 5
+9
+>>> 2 ** 8 - 1
+255
+>>> print ( "one string" + " plus another" )
+one string plus another
+>>>
+
+
+
When you are in an interpreter, there are a number of tools available to
+you.
+
There is a help system:
+
>>> help ( str )
+Help on class str in module __builtin__:
+
+class str(basestring)
+ | str(object='') -> string
+ |
+ | Return a nice string representation of the object.
+ | If the argument is a string, the return value is the same object.
+ ...
+
+
+
You can type q to exit the help viewer.
+
You can also use the dir builtin to find out about the attributes of a
+given object:
+
>>> bob = "this is a string"
+>>> dir ( bob )
+['__add__', '__class__', '__contains__', '__delattr__',
+ '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
+ '__getitem__', '__getnewargs__', '__getslice__', '__gt__',
+ ...
+ 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines',
+ 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper',
+ 'zfill']
+>>> help ( bob . rpartition )
+
+
+
This allows you quite a bit of latitude in exploring what Python is.
+
In addition to the built-in interpreter, there are several more advanced
+interpreters available to you.
+
We’ll be using one in this course called iPython
+
More on this soon.
+
+
+
Your Editor
+
Typing code in an interpreter is great for exploring.
+
But for anything “real”, you’ll want to save the work you are doing in a more permanent
+fashion.
+
This is where an Editor fits in.
+
Any good text editor will do.
+
MS Word is not a text editor.
+
Nor is TextEdit on a Mac.
+
Notepad is a text editor – but a crappy one.
+
You need a real “programmers text editor”
+
A text editor saves only what it shows you, with no special formatting
+characters hidden behind the scenes.
+
At a minimum, your editor should have:
+
+Syntax Colorization
+Automatic Indentation
+
+
In addition, great features to add include:
+
+Tab completion
+Code linting
+Jump-to-definition
+
+
Have an editor that does all this? Feel free to use it.
+
If not, I suggest SublimeText :
+
http://www.sublimetext.com/
+
(Use version 3, even though it’s “beta”)
+
+
+
Why No IDE?
+
An IDE does not give you much that you can’t get with a good editor plus a good interpreter.
+
An IDE often weighs a great deal
+
Setting up IDEs to work with different projects can be challenging and time-consuming.
+
Particularly when you are first learning, you don’t want too much done for you.
+
+
+
+
+
Setting Up Your Environment
+
Shared setup means reduced complications.
+
+
Our Class Environment
+
We are going to work from a common environment in this class.
+
We will take the time here in class to get this going.
+
This helps to ensure that you will be able to work.
+
+
+
Step 1: Python 3
+
Do you already have this??
+
$ python
+Python 3.5.0 ( v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
+[ GCC 4.2.1 ( Apple Inc. build 5666) ( dot 3)] on darwin
+Type "help" , "copyright" , "credits" or "license" for more information.
+>>> ^D
+
+
+
If not:
+
+
+
+
+
Step 2: Pip
+
Python comes with quite a bit (“batteries included”).
+
Sometimes you need a bit more.
+
Pip allows you to install Python packages to expand your system.
+
The previous instructions include pip as well - make sure it’s working.
+
Once you’ve installed pip, you use it to install Python packages by name:
+
$ python -m pip install foobar
+...
+
+
+
To find packages (and their proper names), you can search the python
+package index (PyPI):
+
https://pypi.python.org/pypi
+
+
+
Step 3: Install iPython
+
As this is an intro class, we are going to use almost entirely features
+of standard library. But there are a couple things you may want:
+
iPython is an “enhanced python shell” – it make s it easier to work with python interatively.
+
$ python -m pip install ipython
+
+
+
+
+
+
Introduction to iPython
+
+
+
The very basics of iPython
+
iPython can do a lot for you, but for starters, here are the key pieces
+you’ll want to know:
+
Start it up
+
$ ipython
+Python 3.5.0 ( v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
+Type "copyright" , "credits" or "license" for more information.
+
+IPython 4.0.0 -- An enhanced Interactive Python.
+? -> Introduction and overview of IPython's features.
+%quickref -> Quick reference.
+help -> Python' s own help system.
+object? -> Details about 'object' , use 'object??' for extra details.
+
+
+
This is the stuff I use every day:
+
+command line recall:
+hit the “up arrow” key
+if you have typed a bit, it will find the last command that starts the same way.
+
+
+basic shell commands:
+
+any shell command:
+
+
+
+
+pasting from the clipboard:
+%paste (this keeps whitespace cleaner for you)
+
+
+
+
+getting help:
+
+tab completion:
+
+running a python file:
+run the_name_of_the_file.py
+
+
+
+
That’s it – you can get a lot done with those.
+
+
+
How to run a python file
+
A file with python code in it is a ‘module’ or ‘script’
+
(more on the distinction later on...)
+
It should be named with the .py extension: some_name.py
+
To run it, you have a couple options:
+
+call python on the command line, and pass in your module name
+
+
$ python the_name_of_the_script.py
+
+
+
+run iPython , and run it from within iPython with the run command
+
+
In [1]: run the_file . py
+
+
+
+
+
+
Basic Python Syntax
+
(Follow along in the iPython interpreter...)
+
+
Values, Types, and Symbols
+
+
Expressions and Statements
+
+
+
Values
+
All of programming is really about manipulating values.
+
+Values are pieces of unnamed data: 42, 'Hello, world',
+In Python, all values are objects
+Try dir(42) - lots going on behind the curtain!
+
+
+Every value belongs to a type
+Try type(42) - the type of a value determines what it can do
+
+
+
+
+
+
Literals for the Basic Value types:
+
+Numbers:
+
+floating point: 3.4
+integers: 456
+
+
+Text:
+
+"a bit of text"
+'a bit of text'
+(either single or double quotes work – why?)
+
+
+Boolean values:
+
+
+
+
(There are intricacies to all of these that we’ll get into later)
+
+
+
Code structure
+
Each line is a piece of code.
+
Comments:
+
In [3]: # everything after a '#' is a comment
+
+
+
Expressions:
+
In [4]: # evaluating an expression results in a value
+
+In [5]: 3 + 4
+Out[5]: 7
+
+
+
Statements:
+
In [6]: # statements do not return a value, may contain an expression
+
+In [7]: line_count = 42
+
+In [8]: return something
+
+
+
It’s kind of obvious, but handy when playing with code:
+
In [1]: print ( "something" )
+something
+
+
+
You can print multiple things:
+
In [2]: print ( "the value is" , 5 )
+the value is 5
+
+
+
Any python object can be printed (though it might not be pretty...)
+
In [1]: class bar ( object ):
+ ...: pass
+ ...:
+
+In [2]: print ( bar )
+<class '__main__.bar'>
+
+
+
Blocks of code are delimited by a colon and indentation:
+
def a_function ():
+ a_new_code_block
+end_of_the_block
+
+
+
for i in range ( 100 ):
+ print ( i ** 2 )
+
+
+
try :
+ do_something_bad ()
+except :
+ fix_the_problem ()
+
+
+
Python uses indentation to delineate structure.
+
This means that in Python, whitespace is significant .
+
(but ONLY for newlines and indentation)
+
The standard is to indent with 4 spaces .
+
SPACES ARE NOT TABS
+
TABS ARE NOT SPACES
+
These two blocks look the same:
+
for i in range ( 100 ):
+ print ( i ** 2 )
+
+
+
for i in range ( 100 ):
+ print ( i ** 2 )
+
+
+
But they are not:
+
for i in range ( 100 ):
+\s \s \s \sprint i ** 2
+
+
+
for i in range ( 100 ):
+\tprint i ** 2
+
+
+
ALWAYS INDENT WITH 4 SPACES
+
NEVER INDENT WITH TABS
+
Make sure your editor is set to use spaces only –
+
Even when you hit the <tab> key
+
+
+
Expressions
+
An expression is made up of values and operators.
+
+An expression is evaluated to produce a new value: 2 + 2
+The Python interpreter can be used as a calculator to evaluate expressions
+
+
+Integer vs. float arithmetic
+(Python 3 smooths this out)
+Always use / when you want float results, // when you want
+floored (integer) results
+
+
+Type conversions
+This is the source of many errors, especially in handling text
+
+
+Type errors - checked at run time only
+
+
+
+
Symbols
+
Symbols are how we give names to values (objects).
+
+Symbols must begin with an underscore or letter
+Symbols can contain any number of underscores, letters and numbers
+this_is_a_symbol
+this_is_2
+_AsIsThis
+1butThisIsNot
+nor-is-this
+
+
+Symbols don’t have a type; values do
+This is why python is “Dynamic”
+
+
+
+
+
+
Symbols and Type
+
Evaluating the type of a symbol will return the type of the value to which
+it is bound.
+
In [19]: type ( 42 )
+Out[19]: int
+
+In [20]: type ( 3.14 )
+Out[20]: float
+
+In [21]: a = 42
+
+In [22]: b = 3.14
+
+In [23]: type ( a )
+Out[23]: int
+
+In [25]: a = b
+
+In [26]: type ( a )
+Out[26]: float
+
+
+
+
+
Assignment
+
A symbol is bound to a value with the assignment operator: =
+
+This attaches a name to a value
+A value can have many names (or none!)
+Assignment is a statement, it returns no value
+
+
Evaluating the name will return the value to which it is bound
+
In [26]: name = "value"
+
+In [27]: name
+Out[27]: 'value'
+
+In [28]: an_integer = 42
+
+In [29]: an_integer
+Out[29]: 42
+
+In [30]: a_float = 3.14
+
+In [31]: a_float
+Out[31]: 3.14
+
+
+
+
+
Variables?
+
+In most languages, what I’m calling symbols, or names, are called “variables”.
+In fact, I’ll probably call them variables in this class.
+That’s because they are used, for the most part, for the same purposes.
+But often a “variable” is defined as something like:
+“a place in memory that can store values”
+That is NOT what a name in python is!
+A name can be bound to a value – but that has nothing to do with a
+location in memory.
+
+
+
+
In-Place Assignment
+
You can also do “in-place” assignment with += .
+
In [32]: a = 1
+
+In [33]: a
+Out[33]: 1
+
+In [34]: a = a + 1
+
+In [35]: a
+Out[35]: 2
+
+In [36]: a += 1
+
+In [37]: a
+Out[37]: 3
+
+
+
also: -=, *=, /=, **=, \%=
+
(not quite – really in-place assignment for mutables....)
+
+
+
Multiple Assignment
+
You can assign multiple names from multiple expressions in one
+statement
+
In [48]: x = 2
+
+In [49]: y = 5
+
+In [50]: i , j = 2 * x , 3 ** y
+
+In [51]: i
+Out[51]: 4
+
+In [52]: j
+Out[52]: 243
+
+
+
Python evaluates all the expressions on the right before doing any assignments
+
+
+
Nifty Python Trick
+
Using this feature, we can swap values between two names in one statement:
+
In [51]: i
+Out[51]: 4
+
+In [52]: j
+Out[52]: 243
+
+In [53]: i , j = j , i
+
+In [54]: i
+Out[54]: 243
+
+In [55]: j
+Out[55]: 4
+
+
+
Multiple assignment and symbol swapping can be very useful in certain contexts
+
+
+
Deleting
+
You can’t actually delete anything in python...
+
del only deletes a name (or “unbinds” the name...)
+
In [56]: a = 5
+
+In [57]: b = a
+
+In [58]: del a
+
+In [59]: a
+---------------------------------------------------------------------------
+NameError Traceback (most recent call last)
+<ipython-input-59-60b725f10c9c> in <module> ()
+----> 1 a
+
+NameError : name 'a' is not defined
+
+
+
The object is still there...python will only delete it if there are no
+references to it.
+
In [15]: a = 5
+
+In [16]: b = a
+
+In [17]: del a
+
+In [18]: a
+---------------------------------------------------------------------------
+NameError Traceback (most recent call last)
+<ipython-input-18-60b725f10c9c> in <module> ()
+----> 1 a
+
+NameError : name 'a' is not defined
+
+In [19]: b
+Out[19]: 5
+
+
+
+
+
Identity
+
Every value in Python is an object.
+
Every object is unique and has a unique identity , which you can inspect with
+the id builtin :
+
In [68]: id ( i )
+Out[68]: 140553647890984
+
+In [69]: id ( j )
+Out[69]: 140553647884864
+
+In [70]: new_i = i
+
+In [71]: id ( new_i )
+Out[71]: 140553647890984
+
+
+
+
+
Testing Identity
+
You can find out if the values bound to two different symbols are the same
+object using the is operator:
+
In [72]: count = 23
+
+In [73]: other_count = count
+
+In [74]: count is other_count
+Out[74]: True
+
+In [75]: count = 42
+
+In [76]: other_count is count
+Out[76]: False
+
+
+
+
+
Equality
+
You can test for the equality of certain values with the == operator
+
In [77]: val1 = 20 + 30
+
+In [78]: val2 = 5 * 10
+
+In [79]: val1 == val2
+Out[79]: True
+
+In [80]: val3 = '50'
+
+In [81]: val1 == val3
+Out[84]: False
+
+
+
+
+
Operator Precedence
+
Operator Precedence determines what evaluates first:
+
4 + 3 * 5 != ( 4 + 3 ) * 5
+
+
+
To force statements to be evaluated out of order, use parentheses.
+
+
+
Python Operator Precedence
+
+Parentheses and Literals:
+(), [], {}
+"", b'', ''
+
+Function Calls:
+f(args)
+Slicing and Subscription:
+a[x:y]
+b[0], c['key']
+
+Attribute Reference:
+obj.attribute
+
+
+Exponentiation:
+**
+Bitwise NOT, Unary Signing:
+~x
++x, -x
+
+Multiplication, Division, Modulus:
+*, /, %
+Addition, Subtraction:
++, -
+
+
+Bitwise operations:
+<<, >>,
+&, ^, |
+
+Comparisons:
+<, <=, >, >=, !=, ==
+Membership and Identity:
+in, not in, is, is not
+Boolean operations:
+or, and, not
+Anonymous Functions:
+lambda
+
+
+
+
String Literals
+
A “string” is a chunk of text.
+
You define a string value by writing a string literal :
+
In [1]: 'a string'
+Out[1]: 'a string'
+
+In [2]: "also a string"
+Out[2]: 'also a string'
+
+In [3]: "a string with an apostrophe: isn't it cool?"
+Out[3]: "a string with an apostrophe: isn't it cool?"
+
+In [4]: 'a string with an embedded "quote"'
+Out[4]: 'a string with an embedded "quote"'
+
+
+
In [5]: """a multi-line
+ ...: string
+ ...: all in one
+ ...: """
+Out[5]: 'a multi-line\nstring\nall in one\n'
+
+In [6]: "a string with an \n escaped character"
+Out[6]: 'a string with an \n escaped character'
+
+In [7]: r'a "raw" string, the \n comes through as a \n'
+Out[7]: 'a "raw" string, the \\n comes through as a \\n'
+
+
+
+
+
Keywords
+
Python defines a number of keywords
+
These are language constructs.
+
You cannot use these words as symbols.
+
and del from not while
+as elif global or with
+assert else if pass yield
+break except import print
+class exec in raise
+continue finally is return
+def for lambda try
+
+
+
If you try to use any of the keywords as symbols, you will cause a
+SyntaxError :
+
In [13]: del = "this will raise an error"
+ File "<ipython-input-13-c816927c2fb8>" , line 1
+ del = "this will raise an error"
+ ^
+SyntaxError : invalid syntax
+
+
+
In [14]: def a_function ( else = 'something' ):
+ ....: print ( else )
+ ....:
+ File "<ipython-input-14-1dbbea504a9e>" , line 1
+ def a_function ( else = 'something' ):
+ ^
+SyntaxError : invalid syntax
+
+
+
+
+
__builtins__
+
Python also has a number of pre-bound symbols, called builtins
+
Try this:
+
In [6]: dir ( __builtins__ )
+Out[6]:
+['ArithmeticError',
+ 'AssertionError',
+ 'AttributeError',
+ 'BaseException',
+ 'BufferError',
+ ...
+ 'unicode',
+ 'vars',
+ 'xrange',
+ 'zip']
+
+
+
You are free to rebind these symbols:
+
In [15]: type ( 'a new and exciting string' )
+Out[15]: str
+
+In [16]: type = 'a slightly different string'
+
+In [17]: type ( 'type is no longer what it was' )
+---------------------------------------------------------------------------
+TypeError Traceback (most recent call last)
+<ipython-input-17-907616e55e2a> in <module> ()
+----> 1 type ( 'type is no longer what it was' )
+
+TypeError : 'str' object is not callable
+
+
+
In general, this is a BAD IDEA .
+
+
+
Exceptions
+
Notice that the first batch of __builtins__ are all Exceptions
+
Exceptions are how Python tells you that something has gone wrong.
+
There are several exceptions that you are likely to see a lot of:
+
+NameError : indicates that you have tried to use a symbol that is not bound to a value.
+TypeError : indicates that you have tried to use the wrong kind of object for an operation.
+SyntaxError : indicates that you have mis-typed something.
+AttributeError : indicates that you have tried to access an attribute or
+method that an object does not have (this often means you have a different
+type of object than you expect)
+
+
+
+
Functions
+
What is a function?
+
A function is a self-contained chunk of code
+
You use them when you need the same code to run multiple times,
+or in multiple parts of the program.
+
(DRY)
+
Or just to keep the code clean
+
Functions can take and return information
+
Minimal Function does nothing
+
def <name>():
+ <statement>
+
+
+
Pass Statement (Note the indentation!)
+
+
+
+
Functions: def
+
def is a statement :
+
+it is executed
+it creates a local name
+it does not return a value
+
+
function defs must be executed before the functions can be called:
+
In [23]: unbound ()
+---------------------------------------------------------------------------
+NameError Traceback (most recent call last)
+<ipython-input-23-3132459951e4> in <module> ()
+----> 1 unbound ()
+
+NameError : name 'unbound' is not defined
+
+
+
In [18]: def simple ():
+ ....: print ( "I am a simple function" )
+ ....:
+
+In [19]: simple ()
+I am a simple function
+
+
+
+
+
Calling Functions
+
You call a function using the function call operator (parens):
+
In [2]: type ( simple )
+Out[2]: function
+In [3]: simple
+Out[3]: <function __main__.simple>
+In [4]: simple ()
+I am a simple function
+
+
+
Calling a function is how you run the code in that function.
+
+
+
Functions: Call Stack
+
functions call functions – this makes an execution stack – that’s all a trace back is
+
In [5]: def exceptional ():
+ ...: print ( "I am exceptional!" )
+ ...: print 1 / 0
+ ...:
+In [6]: def passive ():
+ ...: pass
+ ...:
+In [7]: def doer ():
+ ...: passive ()
+ ...: exceptional ()
+ ...:
+
+
+
You’ve defined three functions, one of which will call the other two.
+
+
+
Functions: Tracebacks
+
In [8]: doer ()
+I am exceptional!
+---------------------------------------------------------------------------
+ZeroDivisionError Traceback (most recent call last)
+<ipython-input-8-685a01a77340> in <module> ()
+----> 1 doer ()
+
+<ipython-input-7-aaadfbdd293e> in doer ()
+ 1 def doer ():
+ 2 passive ()
+----> 3 exceptional ()
+ 4
+
+<ipython-input-5-d8100c70edef> in exceptional ()
+ 1 def exceptional ():
+ 2 print ( "I am exceptional!" )
+----> 3 print ( 1 / 0 )
+ 4
+
+ZeroDivisionError : integer division or modulo by zero
+
+
+
+
+
Functions: return
+
Every function ends by returning a value
+
This is actually the simplest possible function:
+
def fun ():
+ return None
+
+
+
if you don’t explicilty put return there, Python will:
+
In [9]: def fun ():
+ ...: pass
+ ...:
+In [10]: fun ()
+In [11]: result = fun ()
+In [12]: print ( result )
+None
+
+
+
note that the interpreter eats None – you need to call print() to see it.
+
Only one return statement in a function will ever be executed.
+
Ever.
+
Anything after a executed return statement will never get run.
+
This is useful when debugging!
+
In [14]: def no_error ():
+ ....: return 'done'
+ ....: # no more will happen
+ ....: print ( 1 / 0 )
+ ....:
+In [15]: no_error ()
+Out[15]: 'done'
+
+
+
However, functions can return multiple results:
+
In [16]: def fun ():
+ ....: return ( 1 , 2 , 3 )
+ ....:
+In [17]: fun ()
+Out[17]: (1, 2, 3)
+
+
+
Remember multiple assignment?
+
In [18]: x , y , z = fun ()
+In [19]: x
+Out[19]: 1
+In [20]: y
+Out[20]: 2
+In [21]: z
+Out[21]: 3
+
+
+
+
+
Functions: parameters
+
In a def statement, the values written inside the parens are
+parameters
+
In [22]: def fun ( x , y , z ):
+ ....: q = x + y + z
+ ....: print ( x , y , z , q )
+ ....:
+
+
+
x, y, z are local names – so is q
+
+
+
Functions: arguments
+
When you call a function, you pass values to the function parameters as
+arguments
+
In [23]: fun ( 3 , 4 , 5 )
+3 4 5 12
+
+
+
The values you pass in are bound to the symbols inside the function and used.
+
+
+
The if Statement
+
In order to do anything interesting at all, you need to be able to make a decision.
+
In [12]: def test(a):
+ ....: if a == 5:
+ ....: print("that's the value I'm looking for!")
+ ....: elif a == 7:
+ ....: print("that's an OK number")
+ ....: else:
+ ....: print("that number won't do!")
+
+In [13]: test(5)
+that's the value I'm looking for!
+
+In [14]: test(7)
+that's an OK number
+
+In [15]: test(14)
+that number won't do!
+
+
+
There is more to it than that, but this will get you started.
+
+
+
Enough For Now
+
That’s it for our basic intro to Python
+
Before next session, you’ll use what you’ve learned here today to do some
+exercises in Python programming
+
+
+
Schedule the lightning talks:
+
+We need to schedule your lightning talks.
+Let’s use Python for that !
+
+
[demo]
+
+
+
+
Python 2-3 Differences
+
Much of the example code you’ll find online is Python2, rather than Python3
+
For the most part, they are the same – so you can sue those examples to learn from.
+
There are a lot of subtle differences that you don’t need to concern yourself with just yet.
+
But a couple that you’ll need to know right off the bat:
+
+
print()
+
In python2, print is a “statement”, rather than a function. That means it didn’t require parenthes around what you want printed:
+
print something, something_else
+
+
+
This made it a bit less flexible and powerful.
+
But – if you try to use it that way in Python3, you’ll get an error:
+
In [15]: print "this"
+ File "<ipython-input-15-70c8add5d16e>", line 1
+ print "this"
+ ^
+SyntaxError: Missing parentheses in call to 'print'
+
+
+
So – if you get this error, simply add the parentheses:
+
In [16]: print ("this")
+this
+
+
+
In python 3, the divsion operator is “smart” when you divide integers:
+
In [17]: 1 / 2
+Out[17]: 0.5
+
+
+
However in python2, integer division, will give you an integer result:
+
+
In both versions, you can get “integer division” if you want it with a double slash:
+
In [1]: 1//2
+Out[1]: 0
+
+
+
And in python2, you can get the behavior of py3 with “true division”:
+
In [2]: from __future__ import division
+
+In [3]: 1/2
+Out[3]: 0.5
+
+
+
For the most part, you just need to be a bit careful with the rare cases where py2 code counts on integer division.
+
+
+
Other py2/py3 differences
+
Most of the other differences are essentially of implementation details, like getting iterators instead of sequences – we’ll talk about that more when it comes up in class.
+
There are also a few syntax differences with more advances topics: Exceptions, super(), etc.
+
We’ll talk about all that when we cover those topics.
+
+
+
+
Homework
+
Tasks and reading by next week
+
+
+
Task 2
+
Set Up a Great Dev Environment
+
Make sure you have the basics of command line usage down:
+
Work through the supplemental tutorials on setting up your
+Command Line (:Shell Customizations for Python Development ) for good development support.
+
Make sure you’ve got your editor set up productively – at the very very
+least, make sure it does Python indentation and syntax coloring well.
+
Advanced Editor Setup:
+
If you are using SublimeText, here are some notes to make it super-nifty:
+
:Turning Sublime Text Into a Lightweight Python IDE
+
At the end, your editor should support tab completion and pep8 and pyflakes
+linting.
+
If you are not using SublimeText, look for plugins that accomplish the same
+goals for your own editor. If none are available, please consider a change of
+editor.
+
+
+
Task 3
+
Python Pushups
+
To get a bit of exercise solving some puzzles with Python, work on the Python
+exercises at “Coding Bat”: http://codingbat.com/python
+
There are 8 sets of puzzles. Do as many as you can, but try to at least
+get all the “Warmups” done.
+
+
+
Task 4
+
Explore Errors
+
+Create a new directory in your working dir for the class:
+$ mkdir session01
+$ cd session01
+
+
+
+Add a new file to it called break_me.py
+
+In the break_me.py file write four simple Python functions:
+
+Each function, when called, should cause an exception to happen
+Each function should result in one of the four common exceptions from our
+lecture.
+for review: NameError , TypeError , SyntaxError , AttributeError
+
+
+
+
(hint – the interpreter will quit when it hits a Exception – so you can comment out all but the one you are testing at the moment)
+
+
+
+
+
+
+
+
Next Class
+
Next week, we’ll:
+
+
+get set up with git
+Some more basic Python
+More on Functions
+Boolean Expressions
+Code Structure, Modules, and Namespaces
+
+
+
+
Office Hours
+
We will have office hours 10 a.m. to noon on Sundays.
+
Preferences?
+
Locations?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session02.html b/session02.html
new file mode 100644
index 0000000..d8df674
--- /dev/null
+++ b/session02.html
@@ -0,0 +1,1313 @@
+
+
+
+
+
+
+
+
+
+
+ Session Two: gitHub, Functions, Booleans and Modules — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Two: gitHub, Functions, Booleans and Modules
+
+
Review/Questions
+
+Values and Types
+Expressions
+Intro to functions
+
+
+
Homework Review
+
Any questions that are nagging?
+
+
+
Lightning Talks Today:
+
+
+
+
+
+
First a little git Primer...
+
Let’s get to know git a bit
+
+
Why Version Control?
+
+
“Piled Higher and Deeper” by Jorge Cham
+
www.phdcomics.com
+
+
+
What is git?
+
+
A “version control system”
+
A history of everything everyone does to your code
+
A graph of states in which the code has existed
+
That last one is a bit tricky, and is not necessary to understand right out of the gate. When you are ready, you can look at this supplement to gain a better understanding:
+
git Overview
+
+
+
+
Setting up git
+
You should have git installed on your machine and accessible from the command line. There will be a little bit of setup for git that you should only have to do once.
+
$ git config --global user.name "Marie Curie"
+$ git config --global user.email "marie@radioactive.com"
+
+
+
+
+
Editor
+
You will never have to use an editor with git for anything extensive, so a simple editor is fine. Unfortunately, the default, VI, is not intuitive to new users. So, unless you already know vi, you should set up a different editor.
+Nano is a straight-forward, simple editor, available out of the box on Macs and Linux boxes, but needs to be installed on Windows (or you can use sublime or Notepad++ as shown in link below). To install nano on Windows: Installing Nano on Windows
+
Once you have chosen/installed an editor, configure git to use it:
+
nano
+$ git config --global core.editor "nano -w"
+
sublime (mac)
+$ git config --global core.editor "subl -n -w"
+
sublime (win)
+$ git config --global core.editor "'c:/program files/sublime text 2/sublime_text.exe' -w"
+
Notepad++ (Win)
+$ git config --global core.editor "'c:/program files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
+
+
+
Repositories
+
A repository is just a collection of files that ‘belong together’.
+
Since git is a distributed versioning system, there is no central
+repository that serves as the one to rule them all. This simply means that all repositories should look the same.
+
However, to keep things sane, there is generally one repository chosen that users check with for changes, for us this is GitHub.
+
+
+
Working with Remotes
+
With git, you work with local repositories and remotes that they are connected to.
+
+
Git uses shortcuts to address remotes . Cloned repositories get an origin shortcut for free:
+
$ git remote -v
+origin https://github.com/UWPCE-PythonCert/IntroPython2016a ( fetch)
+origin https://github.com/UWPCE-PythonCert/IntroPython2016a ( push)
+
+
+
This shows that the local repo on my machine originated from the one in
+the UWPCE-PythonCert gitHub account (don’t worry that it shows it twice, they should be the same)
+
+
+
You can work on any project you wish to that has a public repository on Github. However, since you won’t have permission to edit most projects directly, there is such a thing as forking a project.
+
When you fork a repository, you make a copy of that repository in your own (Github) account.
+
When you have made changes that you believe the rest of the community will want to adopt, you make a pull request to the original project. The maintainer(s) of that project than have the option of accepting your changes, in which case your changes will become part of that project.
+
This is how we will be working in this class. When you want feedback on your work, you will make a pull request to the instructors.
+
+
Our class materials reside in a repository on Github in the UWPCE-PythonCert organization:
+
+
We will do a live demo of setting up a machine. Please follow along.
+
We will now create a fork of the class repository from the UWPCE-PythonCert
+account on GitHub into your personal account. This is done on the GitHub website.
+
+
The next step is to make a clone of your fork on your own computer, which means that
+your fork in github is the origin (Demo):
+
+
We will now set up our individual folders and include a README in this folder. In your terminal, cd
+into the students directory in the directory created when we made the clone, which may or may not be called IntroPython2015.
+
+
$ cd IntroPython2015/students
+$ git status
+
+
+
$ git pull origin master
+
+
+
+
+
$ echo "# Python code for UWPCE-PythonCert class" >> README.rst
+
+
+
+
+
Check the status
+
+
Add anything you want to commit to your commit:
+
+
Make your commit:
+
$ git commit -m 'added a readme file'
+
+
+
Push your changes:
+
$ git push origin master
+
+
+
Go onto GitHub, and make a pull request!
+
+
You’ve pushed your own changes to that fork, and then issued pull requests to have that worked merged back to the UWPCE-PythonCert original.
+
+
You want to keep your fork up-to-date with that original copy as the class
+goes forward.
+
To do this, you add a new remote repository to your local clone.
+
+
You can add remotes at will, to connect your local repository to other
+copies of it in different remote locations.
+
When you add a remote (existing git repository), it creates a directory with the name of the repository at the top level.
+
+
This allows you to grab changes made to the repository in these other
+locations.
+
For our class, we will add an upstream remote to our local copy that points
+to the original copy of the material in the UWPCE-PythonCert account.
+
$ git remote add upstream https://github.com/UWPCE-PythonCert/IntroPython2016a.git
+
+$ git remote -v
+origin https://github.com/UWPCE-PythonCert/IntroPython2016a.git ( fetch)
+origin https://github.com/UWPCE-PythonCert/IntroPython2016a.git ( push)
+upstream https://github.com/UWPCE-PythonCert/IntroPython2016a.git ( fetch)
+upstream https://github.com/UWPCE-PythonCert/IntroPython2016a.git ( push)
+
+
+
+
This should leave you in a situation that looks like this:
+
+
To get the updates from your new remote, you’ll need first to fetch everything:
+
$ git fetch --all
+Fetching origin
+Fetching upstream
+...
+
+
+
Then you can see the branches you have locally available:
+
$ git branch -a
+* master
+ remotes/origin/HEAD -> origin/master
+ remotes/origin/master
+ remotes/upstream/master
+
+
+
Finally, you can fetch and then merge changes from the upstream master.
+
Start by making sure you are on your own master branch:
+
+
This is really really important. Take the time to ensure you are where you
+think you are, in other words, not on a remote. Use git status to see where you are.
+
Then, fetch the upstream master branch and merge it into your master:
+
$ git fetch upstream master
+From https://github.com/UWPCE-PythonCert/IntroPython2015
+ * branch master -> FETCH_HEAD
+
+$ git merge upstream/master
+Updating 3239de7..9ddbdbb
+Fast-forward
+ Examples/README.rst | 4 ++++
+...
+ create mode 100644 Examples/README.rst
+...
+
+
+
NOTE: you can do that in one step with:
+
$ git pull upstream master
+
+
+
Now all the changes from upstream are present in your local clone.
+You should do this pull everytime you start to work on code.
+
In order to preserve them in your fork on GitHub, you’ll have to push:
+
$ git status
+On branch master
+Your branch is ahead of 'origin/master' by 10 commits.
+ (use "git push" to publish your local commits)
+$ git push origin master
+Counting objects: 44, done.
+...
+$
+
+
+
(A simple git push will usually do the right thing)
+
You can incorporate this into your daily workflow:
+
$ git checkout master
+$ git pull upstream master
+$ git push
+[do some work]
+$ git commit -a 'I wrote some Python.'
+[add a good commit message]
+$ git push
+[make a pull request on the GitHub website]
+
+
+
Because of the way we have set up the class, you will be able
+to see all work submitted to us from everyone in the class in
+the students directory on your machine. This is not a bad thing.
+The files tend to be small.
+
We encourage sharing of knowledge in this class. Helping your
+fellow students will also help you to better understand. Share
+your code, and get used to giving and receiving feedback on how
+to improve your code, if you are not already.
+
+
+
+
LAB: Grid Printer
+
With only the ability to do a bit with numbers and text, you should be
+able to do this little project:
+
Grid Printer Exercise
+
+
Getting Started:
+
Lets use git and gitHub to manage this project:
+
Start by putting a python file in your clone of the class gitHub project:
+
$ cd my_personal_directory
+$ mkdir session_02
+$ cd session_02
+$ touch grid_printer.py
+$ git add grid_printer.py
+
+
+
Then put your code in grid_printer.py
+
+
+
Committing your code
+
When your code does something useful, you can commit it.
+
First check the status:
+
+
If it’s what you expect, you can commit and push:
+
$ git commit -a -m "first version"
+$ git push
+
+
+
And when you want us to take a look, you can go to gitHub and do a “Pull Request”
+(make sure you commit and push first)
+
+
+
Committing your code
+
Commit early and often.
+
+
+
Lightning Talk:
+
+
+
+
Beyond Printing
+
Because there’s a few things you just gotta have
+
+
Basics
+
You really can’t really do much at all without at least
+conditionals, looping, and a container type...
+
+
+
Making a Decision
+
“Conditionals”
+
if and elif (else if) allow you to make decisions:
+
if a :
+ print ( 'a' )
+elif b :
+ print ( 'b' )
+elif c :
+ print ( 'c' )
+else :
+ print ( 'that was unexpected' )
+
+
+
What’s the difference between these two?
+
if a :
+ print ( 'a' )
+elif b :
+ print ( 'b' )
+
+## versus...
+if a :
+ print ( 'a' )
+if b :
+ print ( 'b' )
+
+
+
+
+
Lists
+
A way to store a bunch of stuff in order
+
Pretty much like an “array” or “vector” in other languages
+
a_list = [ 2 , 3 , 5 , 9 ]
+a_list_of_strings = [ 'this' , 'that' , 'the' , 'other' ]
+
+
+
You can put any type of object in a list...
+
+
+
Tuples
+
Another way to store an ordered list of things
+
a_tuple = ( 2 , 3 , 4 , 5 )
+a_tuple_of_strings = ( 'this' , 'that' , 'the' , 'other' )
+
+
+
You can also put any type of object in a tuple...
+(sense a theme here?)
+
Tuples are not the same as lists.
+
The exact difference is a topic for next session.
+
+
+
for loops
+
Sometimes called a ‘determinate’ loop
+
When you need to do something to all the objects in a sequence
+
In [10]: a_list = [ 2 , 3 , 4 , 5 ]
+
+In [11]: for item in a_list :
+ ....: print ( item )
+ ....:
+2
+3
+4
+5
+
+
+
range builds sequences of numbers automatically
+
Use it when you need to do something a set number of times
+
In [31]: for i in range ( 4 ):
+ print('*', end=' ')
+ ....:
+* * * *
+
+
+
NOTE: range(n) creates an “iterable” – something you can loop over
+– more on that later.
+
+
+
Intricacies
+
This is enough to get you started.
+
Each of these have intricacies special to python
+
We’ll get to those over the next couple of classes
+
+
+
+
LAB: Fizz Buzz
+
We now have the tools to do a implementation of the classic “Fizz Buzz” problem:
+
Fizz Buzz Exercise
+
Do the same git / gitHub dance with this, too!
+
+
Lightning Talk:
+
+
+
+
More on Functions
+
+
Variable scope
+
Defining a function:
+
def fun ( x , y ):
+ z = x + y
+ return z
+
+
+
x, y, z are local names
+
+
+
Local vs. Global
+
Names bound in Python have a scope
+
That scope determines where a symbol is visible, or what value it has in a
+given block.
+
In [14]: x = 32
+In [15]: y = 33
+In [16]: z = 34
+In [17]: def fun ( y , z ):
+ ....: print ( x , y , z )
+ ....:
+In [18]: fun ( 3 , 4 )
+32 3 4
+
+
+
x is global, y and z local to the function
+
But, did the value of y and z change in the global scope?
+
In [19]: y
+Out[19]: 33
+
+In [20]: z
+Out[20]: 34
+
+
+
In general, you should use global bindings mostly for constants.
+
The python convention is to designate global constants by typing the
+symbols we bind to them in ALL_CAPS
+
INSTALLED_APPS = [ u'foo' , u'bar' , u'baz' ]
+CONFIGURATION_KEY = u'some secret value'
+...
+
+
+
This is just a convention, but it’s a good one to follow.
+
+
+
Global Gotcha
+
Take a look at this function definition:
+
In [21]: x = 3
+
+In [22]: def f ():
+ ....: y = x
+ ....: x = 5
+ ....: print ( x )
+ ....: print ( y )
+ ....:
+
+
+
What is going to happen when we call f
+
Try it and see:
+
In [34]: f ()
+---------------------------------------------------------------------------
+UnboundLocalError Traceback (most recent call last)
+<ipython-input-34-0ec059b9bfe1> in <module> ()
+----> 1 f ()
+
+<ipython-input-33-4363b2b69f73> in f ()
+ 1 def f ():
+----> 2 y = x
+ 3 x = 5
+ 4 print ( x )
+ 5 print ( y )
+
+UnboundLocalError : local variable 'x' referenced before assignment
+
+
+
Because you are binding the symbol x locally, it becomes a local and masks
+the global value already bound.
+
+
+
Parameters
+
So far we’ve seen simple parameter lists:
+
def fun ( x , y , z ):
+ print ( x , y , z )
+
+
+
These types of parameters are called positional
+
When you call a function, you must provide arguments for all positional
+parameters in the order they are listed
+
You can provide default values for parameters in a function definition:
+
In [24]: def fun ( x = 1 , y = 2 , z = 3 ):
+ ....: print ( x , y , z )
+ ....:
+
+
+
When parameters are given with default values, they become optional
+
+
You can provide arguments to a function call for optional parameters
+positionally:
+
In [26]: fun ( 6 )
+6 2 3
+In [27]: fun ( 6 , 7 )
+6 7 3
+In [28]: fun ( 6 , 7 , 8 )
+6 7 8
+
+
+
Or, you can use the parameter name as a keyword to indicate which you mean:
+
In [29]: fun ( y = 4 , x = 1 )
+1 4 3
+
+
+
Once you’ve provided a keyword argument in this way, you can no longer
+provide any positional arguments:
+
In [30]: fun ( x = 5 , 6 )
+ File "<ipython-input-30-4529e5befb95>" , line 1
+ fun ( x = 5 , 6 )
+SyntaxError : non-keyword arg after keyword arg
+
+
+
+
+
Documentation
+
It’s often helpful to leave information in your code about what you were
+thinking when you wrote it.
+
This can help reduce the number of WTFs per minute in reading it later.
+
There are two approaches to this:
+
+
Comments go inline in the body of your code, to explain reasoning:
+
if ( frobnaglers > whozits ):
+ # borangas are shermed to ensure frobnagler population
+ # does not grow out of control
+ sherm_the_boranga ()
+
+
+
You can use them to mark places you want to revisit later:
+
for partygoer in partygoers :
+ for balloon in balloons :
+ for cupcake in cupcakes :
+ # TODO: Reduce time complexity here. It's killing us
+ # for large parties.
+ resolve_party_favor ( partygoer , balloon , cupcake )
+
+
+
Be judicious in your use of comments.
+
Use them when you need to.
+
Make them useful.
+
This is not useful:
+
for sponge in sponges :
+ # apply soap to each sponge
+ worker . apply_soap ( sponge )
+
+
+
Note: Nothing special about Python here – basic good programing practice.
+
+
+
Docstrings
+
In Python, docstrings are used to provide in-line documentation in a number of places.
+
The first place we will see is in the definition of functions .
+
To define a function you use the def keyword.
+
If a string literal is the first thing in the function block following the
+header, it is a docstring :
+
def complex_function ( arg1 , arg2 , kwarg1 = u'bannana' ):
+ """Return a value resulting from a complex calculation."""
+ # code block here
+
+
+
You can then read this in an interpreter as the __doc__ attribute of the
+function object.
+
A docstring should:
+
+Be a complete sentence in the form of a command describing what the function
+does.
+“”“Return a list of values based on blah blah”“” is a good docstring
+“”“Returns a list of values based on blah blah”“” is not
+
+
+Have a useful single line.
+If more description is needed, make the first line a complete sentence and
+add more lines below for enhancement.
+
+
+Be enclosed with triple-quotes.
+This allows for easy expansion if required at a later date
+Always close on the same line if the docstring is only one line.
+
+
+
+
For more information see PEP 257: Docstring Conventions .
+
+
+
Recursion
+
You’ve seen functions that call other functions.
+
If a function calls itself , we call that recursion
+
Like with other functions, a call within a call establishes a call stack
+
With recursion, if you are not careful, this stack can get very deep.
+
Python has a maximum limit to how much it can recurse. This is intended to
+save your machine from running out of RAM.
+
Recursion is especially useful for a particular set of problems.
+
For example, take the case of the factorial function.
+
In mathematics, the factorial of an integer is the result of multiplying that
+integer by every integer smaller than it down to 1.
+
5! == 5 * 4 * 3 * 2 * 1
+
+
+
We can use a recursive function nicely to model this mathematical function
+
+
+
assert
+
Writing tests that demonstrate that your program works is an important part of learning to program.
+
The python assert statement is useful in writing simple tests
+for your code.
+
In [1]: def add ( n1 , n2 ):
+ ...: return n1 + n2
+ ...:
+
+In [2]: assert add ( 3 , 4 ) == 7
+
+In [3]: assert add ( 3 , 4 ) == 10
+
+---------------------------------------------------------------------
+AssertionError Traceback (most recent call last)
+<ipython-input-3-6731d4ac4476> in <module> ()
+----> 1 assert add ( 3 , 4 ) == 10
+
+AssertionError :
+
+
+
+
+
+
+
Boolean Expressions
+
+
Truthiness
+
What is true or false in Python?
+
+
Determining Truthiness:
+
+
+
+
+
What is True?
+
Everything Else
+
+
+
Pythonic Booleans
+
Any object in Python, when passed to the bool() type object, will
+evaluate to True or False .
+
When you use the if keyword, it automatically does this to the expression provided.
+
Which means that this is redundant, and not Pythonic:
+
if xx == True :
+ do_something ()
+# or even worse:
+if bool ( xx ) == True :
+ do_something ()
+
+
+
Instead, use what Python gives you:
+
if xx :
+ do_something ()
+
+
+
+
+
and , or and not
+
Python has three boolean keywords, and , or and not .
+
and and or are binary expressions, and evaluate from left to right.
+
and will return the first operand that evaluates to False, or the last
+operand if none are True:
+
In [35]: 0 and 456
+Out[35]: 0
+
+
+
or will return the first operand that evaluates to True, or the last
+operand if none are True:
+
In [36]: 0 or 456
+Out[36]: 456
+
+
+
On the other hand, not is a unary expression and inverts the boolean value
+of its operand:
+
In [39]: not True
+Out[39]: False
+
+In [40]: not False
+Out[40]: True
+
+
+
Because of the return value of these keywords, you can write concise
+statements:
+
if x is false,
+x or y return y,
+ else return x
+
+ if x is false,
+x and y return x
+ else return y
+
+ if x is false,
+not x return True,
+ else return False
+
+
+
a or b or c or d
+a and b and c and d
+
+
+
The first value that defines the result is returned
+
+
+
Ternary Expressions
+
This is a fairly common idiom:
+
if something :
+ x = a_value
+else :
+ x = another_value
+
+
+
In other languages, this can be compressed with a “ternary operator”:
+
result = a > b ? x : y;
+
+
+
In python, the same is accomplished with the ternary expression:
+
+
PEP 308:
+(http://www.python.org/dev/peps/pep-0308/ )
+
+
+
Boolean Return Values
+
Remember this puzzle from the CodingBat exercises?
+
def sleep_in ( weekday , vacation ):
+ if weekday == True and vacation == False :
+ return False
+ else :
+ return True
+
+
+
Though correct, that’s not a particularly Pythonic way of solving the problem.
+
Here’s a better solution:
+
def sleep_in ( weekday , vacation ):
+ return not ( weekday == True and vacation == False )
+
+
+
And here’s an even better one:
+
def sleep_in ( weekday , vacation ):
+ return ( not weekday ) or vacation
+
+
+
In python, the boolean types are subclasses of integer:
+
In [1]: True == 1
+Out[1]: True
+In [2]: False == 0
+Out[2]: True
+
+
+
And you can even do math with them (though it’s a bit odd to do so):
+
In [6]: 3 + True
+Out[6]: 4
+
+
+
+
+
+
LAB: Booleans
+
Working with Booleans, Ternary Expressions, etc:
+
Re-write a couple CodingBat exercises, returning the direct boolean results, and/or using ternary expressions.
+
Experiment with locals by adding this statement one of the functions you wrote today:
+
+
+
+
Code Structure, Modules, and Namespaces
+
How to get what you want when you want it.
+
+
Code Structure
+
In Python, the structure of your code is determined by whitespace.
+
How you indent your code determines how it is structured
+
block statement:
+ some code body
+ some more code body
+ another block statement:
+ code body in
+ that block
+
+
+
The colon that terminates a block statement is also important...
+
You can put a one-liner after the colon:
+
In [167]: x = 12
+In [168]: if x > 4 : print ( x )
+12
+
+
+
But this should only be done if it makes your code more readable.
+
Whitespace is important in Python.
+
An indent could be:
+
+Any number of spaces
+A tab
+A mix of tabs and spaces:
+
+
If you want anyone to take you seriously as a Python developer:
+
Always use four spaces – really!
+
(PEP 8)
+
Other than indenting – space doesn’t matter, technically.
+
x = 3 * 4 + 12 / func ( x , y , z )
+x = 3 * 4 + 12 / func ( x , y , z )
+
+
+
But you should strive for proper style. Read PEP 8 and install a linter in
+your editor.
+
+
+
Modules and Packages
+
Python is all about namespaces – the “dots”
+
name.another_name
+
The “dot” indicates that you are looking for a name in the namespace of the
+given object. It could be:
+
+name in a module
+module in a package
+attribute of an object
+method of an object
+
+
A module is simply a namespace.
+
It might be a single file, or it could be a collection of files that define a
+shared API.
+
To a first approximation, you can think of the files you write that end in
+.py as modules.
+
A package is a module with other modules in it.
+
On a filesystem, this is represented as a directory that contains one or more
+.py files, one of which must be called __init__.py .
+
When you have a package, you can import the package, or any of the modules
+inside it.
+
import modulename
+from modulename import this , that
+import modulename as a_new_name
+from modulename import this as that
+
+
+
+
+
importing from packages
+
import packagename.modulename
+from packagename.modulename import this , that
+from package import modulename
+
+
+
http://effbot.org/zone/import-confusion.htm
+
from modulename import *
+
+
+
Don’t do this!
+
+
+
import
+
When you import a module, or a symbol from a module, the Python code is
+compiled to bytecode .
+
The result is a module.pyc file.
+
Then after compiling, all the code in the module is run at the module scope .
+
For this reason, it is good to avoid module-scope statements that have global
+side-effects.
+
+
+
Re-import
+
The code in a module is NOT re-run when imported again
+
It must be explicitly reloaded to be re-run
+
import modulename
+reload ( modulename )
+
+
+
In addition to importing modules, you can run them.
+
There are a few ways to do this:
+
+$ python hello.py – must be in current working directory
+$ python -m hello – any module on PYTHONPATH anywhere on the system
+$ ./hello.py – put #!/usr/env/python at top of module (Unix)
+In [149]: run hello.py – at the IPython prompt – running a module brings its names into the interactive namespace
+
+
Like importing, running a module executes all statements at the module level.
+
But there’s an important difference.
+
When you import a module, the value of the symbol __name__ in the module
+is the same as the filename.
+
When you run a module, the value of the symbol __name__ is __main__ .
+
This allows you to create blocks of code that are executed only when you run a module
+
if __name__ == '__main__' :
+ # Do something interesting here
+ # It will only happen when the module is run
+
+
+
This is useful in a number of cases.
+
You can put code here that lets your module be a utility script
+
You can put code here that demonstrates the functions contained in your module
+
You can put code here that proves that your module works.
+
+
+
Import Interactions
+
Let’s experiment with importing different ways:
+
In [3]: import math
+
+In [4]: math .< TAB >
+math.acos math.degrees math.fsum math.pi
+math.acosh math.e math.gamma math.pow
+math.asin math.erf math.hypot math.radians
+math.asinh math.erfc math.isinf math.sin
+math.atan math.exp math.isnan math.sinh
+math.atan2 math.expm1 math.ldexp math.sqrt
+math.atanh math.fabs math.lgamma math.tan
+math.ceil math.factorial math.log math.tanh
+math.copysign math.floor math.log10 math.trunc
+math.cos math.fmod math.log1p
+math.cosh math.frexp math.modf
+
+
+
In [6]: math . sqrt ( 4 )
+Out[6]: 2.0
+In [7]: import math as m
+In [8]: m . sqrt ( 4 )
+Out[8]: 2.0
+In [9]: from math import sqrt
+In [10]: sqrt ( 4 )
+Out[10]: 2.0
+
+
+
Experiment with importing different ways:
+
import sys
+print sys . path
+import os
+print os . path
+
+
+
You wouldn’t want to import * those!
+
+– check out
+
os . path . split ( '/foo/bar/baz.txt' )
+os . path . join ( '/foo/bar' , 'baz.txt' )
+
+
+
+
+
+
Next Class
+
+Sequences
+Iteration
+Strings and String Formatting
+Lightning talks by:
+
+
+
Office hours: 10 a.m. to noon on Sundays
+
+
Homework
+
Review and/or finish reading these class notes.
+
Finish any labs from class....
+
Reading:
+
Think Python, chapters 8, 9, 10, 12
+
(http://greenteapress.com/thinkpython/html/thinkpython009.html )
+
Learn Python the Hard way: exercises 11 – 14, 18, 19, 21, 28-33
+(the ones in between are about files – we’ll get to that later.)
+
http://learnpythonthehardway.org/book/ex11.html
+
NOTE: In python3, you use input , rather than raw_input
+
Dive Into Python: chapter 4
+
(http://www.diveintopython3.net/strings.html )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session03.html b/session03.html
new file mode 100644
index 0000000..5ada512
--- /dev/null
+++ b/session03.html
@@ -0,0 +1,1552 @@
+
+
+
+
+
+
+
+
+
+
+ Session Three: Sequences, Iteration and String Formatting — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session04.html b/session04.html
new file mode 100644
index 0000000..4fbdeac
--- /dev/null
+++ b/session04.html
@@ -0,0 +1,1471 @@
+
+
+
+
+
+
+
+
+
+
+ Session Four: Lists, Iteration, Strings, Dictionaries, Sets — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Docs »
+
+ Session Four: Lists, Iteration, Strings, Dictionaries, Sets
+
+
+
+ View page source
+
+
+
+
+
+
+
+
+
+
+
Session Four: Lists, Iteration, Strings, Dictionaries, Sets
+
+
Announcements
+
+
+
Review/Questions
+
+
Homework
+
Let’s take a look.
+
+
+
+
Topics for Today
+
+Lists
+Iteration
+Strings
+Dictionaries
+Sets
+
+
+Driving toward the mailroom.
+
+
Lightning Talks
+
Chi Ho
+
Tom Gaffney
+
Anybody else ready? I’ll be asking for volunteers at the end of class.
+
+
+
+
Lists
+
In addition to all the methods supported by sequences we’ve already seen, mutable sequences such as Lists have a number of other methods.
+
You can find all these in the Standard Library Documentation:
+
https://docs.python.org/3/library/stdtypes.html#typesseq-mutable
+
+
Assignment
+
You’ve already seen changing a single element of a list by assignment.
+
Pretty much the same as “arrays” in most languages:
+
In [100]: list = [ 1 , 2 , 3 ]
+In [101]: list [ 2 ] = 10
+In [102]: list
+Out[102]: [1, 2, 10]
+
+
+
+
+
Growing the List
+
.append() , .insert() , .extend()
+
In [74]: food = [ 'spam' , 'eggs' , 'ham' ]
+In [75]: food . append ( 'sushi' )
+In [76]: food
+Out[76]: ['spam', 'eggs', 'ham', 'sushi']
+In [77]: food . insert ( 0 , 'beans' )
+In [78]: food
+Out[78]: ['beans', 'spam', 'eggs', 'ham', 'sushi']
+In [79]: food . extend ([ 'bread' , 'water' ])
+In [80]: food
+Out[80]: ['beans', 'spam', 'eggs', 'ham', 'sushi', 'bread', 'water']
+
+
+
You can pass any sequence to .extend() :
+
In [85]: food
+Out[85]: ['beans', 'spam', 'eggs', 'ham', 'sushi', 'bread', 'water']
+In [86]: food . extend ( 'spaghetti' )
+In [87]: food
+Out[87]:
+['beans', 'spam', 'eggs', 'ham', 'sushi', 'bread', 'water',
+ 's', 'p', 'a', 'g', 'h', 'e', 't', 't', 'i']
+
+
+
+
+
Shrinking a List
+
.pop() , .remove()
+
In [203]: food = [ 'spam' , 'eggs' , 'ham' , 'toast' ]
+In [204]: food . pop ()
+Out[204]: 'toast'
+In [205]: food . pop ( 0 )
+Out[205]: 'spam'
+In [206]: food
+Out[206]: ['eggs', 'ham']
+In [207]: food . remove ( 'ham' )
+In [208]: food
+Out[208]: ['eggs']
+
+
+
You can also delete slices of a list with the del keyword:
+
In [92]: nums = range ( 10 )
+In [93]: nums
+Out[93]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+In [94]: del nums [ 1 : 6 : 2 ]
+In [95]: nums
+Out[95]: [0, 2, 4, 6, 7, 8, 9]
+In [96]: del nums [ - 3 :]
+In [97]: nums
+Out[97]: [0, 2, 4, 6]
+
+
+
+
+
Copying Lists
+
You can make copies of part of a list using slicing :
+
In [227]: food = [ 'spam' , 'eggs' , 'ham' , 'sushi' ]
+In [228]: some_food = food [ 1 : 3 ]
+In [229]: some_food [ 1 ] = 'bacon'
+In [230]: food
+Out[230]: ['spam', 'eggs', 'ham', 'sushi']
+In [231]: some_food
+Out[231]: ['eggs', 'bacon']
+
+
+
If you provide no arguments to the slice, it makes a copy of the entire list:
+
In [232]: food
+Out[232]: ['spam', 'eggs', 'ham', 'sushi']
+In [233]: food2 = food [:]
+In [234]: food is food2
+Out[234]: False
+
+
+
The copy of a list made this way is a shallow copy .
+
The list is itself a new object, but the objects it contains are not.
+
Mutable objects in the list can be mutated in both copies:
+
In [249]: food = [ 'spam' , [ 'eggs' , 'ham' ]]
+In [251]: food_copy = food [:]
+In [252]: food [ 1 ] . pop ()
+Out[252]: 'ham'
+In [253]: food
+Out[253]: ['spam', ['eggs']]
+In [256]: food . pop ( 0 )
+Out[256]: 'spam'
+In [257]: food
+Out[257]: [['eggs']]
+In [258]: food_copy
+Out[258]: ['spam', ['eggs']]
+
+
+
Consider this common pattern:
+
for x in somelist :
+ if should_be_removed ( x ):
+ somelist . remove ( x )
+
+
+
This looks benign enough, but changing a list while you are iterating over it can be the cause of some pernicious bugs.
+
For example:
+
In [27]: l = list ( range ( 10 ))
+In [28]: l
+Out[28]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+In [29]: for item in l :
+ ....: l . remove ( item )
+ ....:
+
+
+
For example:
+
In [27]: l = list ( range ( 10 ))
+In [28]: l
+Out[28]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+In [29]: for item in l :
+ ....: l . remove ( item )
+ ....:
+In [30]: l
+Out[30]: [1, 3, 5, 7, 9]
+
+
+
Iterate over a copy, and mutate the original:
+
In [33]: l = list ( range ( 10 ))
+
+In [34]: for item in l [:]:
+ ....: l . remove ( item )
+ ....:
+In [35]: l
+Out[35]: []
+
+
+
Okay, so we’ve done this a bunch already, but let’s state it out loud.
+
You can iterate over a sequence.
+
for element in sequence :
+ do_something ( element )
+
+
+
which is what we mean when we say a sequence is an “iterable”.
+
Again, we’ll touch more on this in a short while, but first a few more words about Lists and Tuples.
+
+
+
Miscellaneous List Methods
+
These methods change a list in place and are not available on immutable sequence types.
+
.reverse()
+
In [129]: food = [ 'spam' , 'eggs' , 'ham' ]
+In [130]: food . reverse ()
+In [131]: food
+Out[131]: ['ham', 'eggs', 'spam']
+
+
+
.sort()
+
In [132]: food . sort ()
+In [133]: food
+Out[133]: ['eggs', 'ham', 'spam']
+
+
+
Because these methods mutate the list in place, they have a return value of None
+
.sort() can take an optional key parameter.
+
It should be a function that takes one parameter (list items one at a time) and returns something that can be used for sorting:
+
In [137]: def third_letter ( string ):
+ .....: return string [ 2 ]
+ .....:
+In [138]: food . sort ( key = third_letter )
+In [139]: food
+Out[139]: ['spam', 'eggs', 'ham']
+
+
+
+
+
+
Choosing Lists or Tuples
+
Here are a few guidelines on when to choose a list or a tuple:
+
+If it needs to mutable: list
+If it needs to be immutable: tuple
+(safety when passing to a function)
+
+
+
+
Otherwise ... taste and convention
+
+
+
Convention
+
Lists are Collections (homogeneous):
+– contain values of the same type
+– simplifies iterating, sorting, etc
+
tuples are mixed types:
+– Group multiple values into one logical thing
+– Kind of like simple C structs.
+
+
+
Other Considerations
+
+Do the same operation to each element?
+
+Small collection of values which make a single logical item?
+
+To document that these values won’t change?
+
+Build it iteratively?
+
+Transform, filter, etc?
+
+
+
+
+
+
List Lab
+
Let’s play a bit with Python lists...
+
List Lab
+
+
+
+
Lightning Talk
+
Chi Ho
+
+
+
Iteration
+
Repetition, Repetition, Repetition, Repe...
+
+
For Loops
+
We’ve seen simple iteration over a sequence with for ... in :
+
In [170]: for x in "a string" :
+ .....: print ( x )
+ .....:
+a
+s
+t
+r
+i
+n
+g
+
+
+
Contrast this with other languages, where you must build and use an index :
+
for ( var i = 0 ; i < arr . length ; i ++ ) {
+ var value = arr [ i ];
+ alert ( i + value );
+}
+
+
+
If you do need an index, you can use enumerate :
+
In [140]: for idx , letter in enumerate ( 'Python' ):
+ .....: print ( idx , letter , end = ' ' )
+ .....:
+0 P 1 y 2 t 3 h 4 o 5 n
+
+
+
+
+
range and for Loops
+
The range builtin is useful for looping a known number of times:
+
In [171]: for i in range ( 5 ):
+ .....: print ( i )
+ .....:
+0
+1
+2
+3
+4
+
+
+
But you don’t really need to do anything at all with i
+
In fact, it’s a common convension to make this clear with a “nothing” name:
+
In [21]: for __ in range ( 5 ):
+ ....: print ( "*" )
+ ....:
+*
+*
+*
+*
+*
+
+
+
Sometimes you want to interrupt or alter the flow of control through a loop.
+
Loops can be controlled in two ways, with break and continue
+
The break keyword will cause a loop to immediately terminate:
+
In [141]: for i in range ( 101 ):
+ .....: print ( i )
+ .....: if i > 50 :
+ .....: break
+ .....:
+0 1 2 3 4 5... 46 47 48 49 50 51
+
+
+
The continue keyword will skip later statements in the loop block, but
+allow iteration to continue:
+
In [143]: for in in range ( 101 ):
+ .....: if i > 50 :
+ .....: break
+ .....: if i < 25 :
+ .....: continue
+ .....: print ( i , end = ' ' )
+ .....:
+ 25 26 27 28 29 ... 41 42 43 44 45 46 47 48 49 50
+
+
+
For loops can also take an optional else block.
+
Executed only when the loop exits normally (not via break):
+
In [147]: for x in range ( 10 ):
+ .....: if x == 11 :
+ .....: break
+ .....: else :
+ .....: print ( 'finished' )
+finished
+In [148]: for x in range ( 10 ):
+ .....: if x == 5 :
+ .....: print ( x )
+ .....: break
+ .....: else :
+ .....: print ( 'finished' )
+5
+
+
+
This is a really nice unique Python feature!
+
+
+
While Loops
+
The while keyword is for when you don’t know how many loops you need.
+
It continues to execute the body until condition is not True :
+
while a_condition :
+ some_code
+ in_the_body
+
+
+
while is more general than for
+
– you can always express for as while , but not always vice-versa.
+
while is more error-prone – requires some care to terminate
+
loop body must make progress, so condition can become False
+
potential error – infinite loops:
+
i = 0 ;
+while i < 5 :
+ print ( i )
+
+
+
Use break :
+
In [150]: while True :
+ .....: i += 1
+ .....: if i > 10 :
+ .....: break
+ .....: print ( i )
+ .....:
+1 2 3 4 5 6 7 8 9 10
+
+
+
Set a flag:
+
In [156]: import random
+In [157]: keep_going = True
+In [158]: while keep_going :
+ .....: num = random . choice ( range ( 5 ))
+ .....: print ( num )
+ .....: if num == 3 :
+ .....: keep_going = False
+ .....:
+3
+
+
+
Use a condition:
+
In [161]: while i < 10 :
+ .....: i += random . choice ( range ( 4 ))
+ .....: print ( i )
+ .....:
+0 0 2 3 4 6 8 8 8 9 12
+
+
+
+
+
Similarities
+
Both for and while loops can use break and continue for
+internal flow control.
+
Both for and while loops can have an optional else block
+
In both loops, the statements in the else block are only executed if the
+loop terminates normally (no break )
+
+
+
+
Lightning Talk
+
Tom Gaffney
+
+
+
Strings
+
Quick review: a string literal creates a string type:
+
"this is a string"
+
+'So is this'
+
+"And maybe y'all need somthing like this!"
+
+"""and this also"""
+
+
+
You can also use str()
+
In [256]: str ( 34 )
+Out[256]: '34'
+
+
+
+
String Methods
+
String objects have a lot of methods.
+
Here are just a few:
+
+
+
String Manipulations
+
split and join :
+
In [167]: csv = "comma, separated, values"
+In [168]: csv . split ( ', ' )
+Out[168]: ['comma', 'separated', 'values']
+In [169]: psv = '|' . join ( csv . split ( ', ' ))
+In [170]: psv
+Out[170]: 'comma|separated|values'
+
+
+
+
+
Case Switching
+
In [171]: sample = 'A long string of words'
+In [172]: sample . upper ()
+Out[172]: 'A LONG STRING OF WORDS'
+In [173]: sample . lower ()
+Out[173]: 'a long string of words'
+In [174]: sample . swapcase ()
+Out[174]: 'a LONG STRING OF WORDS'
+In [175]: sample . title ()
+Out[175]: 'A Long String Of Words'
+
+
+
+
+
Testing
+
In [181]: number = "12345"
+In [182]: number . isnumeric ()
+Out[182]: True
+In [183]: number . isalnum ()
+Out[183]: True
+In [184]: number . isalpha ()
+Out[184]: False
+In [185]: fancy = "Th!$ $tr!ng h@$ $ymb0l$"
+In [186]: fancy . isalnum ()
+Out[186]: False
+
+
+
+
+
+
Raw Strings
+
Add an r in front of the string literal:
+
Escape Sequences Ignored
+
In [408]: print ( "this \n that" )
+this
+that
+In [409]: print ( r"this\nthat" )
+this\nthat
+
+
+
Gotcha
+
In [415]: r" \"
+SyntaxError: EOL while scanning string literal
+
+
+
+
+
Ordinal values
+
Characters in strings are stored as numeric values:
+
+“ASCII” values: 1-127
+Unicode values – 1 - 1,114,111 (!!!)
+
+
To get the value:
+
In [109]: for i in 'Chris' :
+ .....: print ( ord ( i ), end = ' ' )
+67 104 114 105 115
+In [110]: for i in ( 67 , 104 , 114 , 105 , 115 ):
+ .....: print ( chr ( i ), end = '' )
+Chris
+
+
+
(these days, stick with ASCII, or use full Unicode: more on that in a few weeks)
+
+
+
+
Multiple placeholders:
+
In [65]: "the number is {} is {}" . format ( 'five' , 5 )
+Out[65]: 'the number is five is 5'
+
+In [66]: "the first 3 numbers are {}, {}, {}" . format ( 1 , 2 , 3 )
+Out[66]: 'the first 3 numbers are 1, 2, 3'
+
+
+
The counts must agree:
+
In [67]: "string with {} formatting {}" . format ( 1 )
+---------------------------------------------------------------------------
+IndexError Traceback (most recent call last)
+<ipython-input-67-a079bc472aca> in <module> ()
+----> 1 "string with {} formatting {}" . format ( 1 )
+
+IndexError : tuple index out of range
+
+
+
+
+
Named placeholders:
+
In [69]: "Hello, {name}, whaddaya know?" . format ( name = "Joe" )
+Out[69]: 'Hello, Joe, whaddaya know?'
+
+
+
You can use values more than once, and skip values:
+
In [73]: "Hi, {name}. Howzit, {name}?" . format ( name = 'Bob' )
+Out[73]: 'Hi, Bob. Howzit, Bob?'
+
+
+
The format operator works with string variables, too:
+
In [80]: s = "{:d} / {:d} = {:f}"
+
+In [81]: a , b = 12 , 3
+
+In [82]: s . format ( a , b , a / b )
+Out[82]: '12 / 3 = 4.000000'
+
+
+
So you can dynamically build a format string
+
+
+
+
One Last Trick
+
For some of the exercises, you’ll need to interact with a user at the
+command line.
+
There’s a nice built in function to do this - input :
+
In [85]: fred = input ( 'type something-->' )
+type something-->I've typed something
+
+In [86]: print ( fred )
+I've typed something
+
+
+
This will display a prompt to the user, allowing them to input text and
+allowing you to bind that input to a symbol.
+
+
+
Fun with strings
+
+Rewrite: the first 3 numbers are: %i, %i, %i"%(1,2,3)
+
+
+for an arbitrary number of numbers...
+
+
+
+
+
+
+
+
+
Dictionaries
+
Python calls it a dict
+
Other languages call it:
+
+
+dictionary
+associative array
+map
+hash table
+hash
+key-value pair
+
+
+
+
Dictionary Constructors
+
>>> { 'key1' : 3 , 'key2' : 5 }
+{'key1': 3, 'key2': 5}
+
+>>> dict ([( 'key1' , 3 ),( 'key2' , 5 )])
+{'key1': 3, 'key2': 5}
+
+>>> dict ( key1 = 3 , key2 = 5 )
+{'key1': 3, 'key2': 5}
+
+>>> d = {}
+>>> d [ 'key1' ] = 3
+>>> d [ 'key2' ] = 5
+>>> d
+{'key1': 3, 'key2': 5}
+
+
+
+
+
Dictionary Indexing
+
>>> d = { 'name' : 'Brian' , 'score' : 42 }
+
+>>> d [ 'score' ]
+42
+
+>>> d = { 1 : 'one' , 0 : 'zero' }
+
+>>> d [ 0 ]
+'zero'
+
+>>> d [ 'non-existing key' ]
+Traceback (most recent call last):
+ File "<stdin>" , line 1 , in <module>
+KeyError : 'non-existing key'
+
+
+
Keys can be any immutable:
+
+
+
In [325]: d [ 3 ] = 'string'
+In [326]: d [ 3.14 ] = 'pi'
+In [327]: d [ 'pi' ] = 3.14
+In [328]: d [ ( 1 , 2 , 3 ) ] = 'a tuple key'
+In [329]: d [ [ 1 , 2 , 3 ] ] = 'a list key'
+ TypeError: unhashable type: 'list'
+
+
+
Actually – any “hashable” type.
+
Hash functions convert arbitrarily large data to a small proxy (usually int)
+
Always return the same proxy for the same input
+
MD5, SHA, etc
+
Dictionaries hash the key to an integer proxy and use it to find the key and value.
+
Key lookup is efficient because the hash function leads directly to a bucket with very few keys (often just one)
+
What would happen if the proxy changed after storing a key?
+
Hashability requires immutability
+
Key lookup is very efficient
+
Same average time regardless of size
+
Note: Python name look-ups are implemented with dict – it’s highly optimized
+
Key to value:
+
+
+
Value to key:
+
+
+requires visiting the whole dict
+
+
+
If you need to check dict values often, create another dict or set
+
(up to you to keep them in sync)
+
+
+
Dictionary Ordering (not)
+
Dictionaries have no defined order
+
In [352]: d = { 'one' : 1 , 'two' : 2 , 'three' : 3 }
+In [353]: d
+Out[353]: {'one': 1, 'three': 3, 'two': 2}
+In [354]: d . keys ()
+Out[354]: dict_keys(['three', 'two', 'one'])
+
+
+
+
+
Dictionary Iterating
+
for iterates over the keys
+
In [15]: d = { 'name' : 'Brian' , 'score' : 42 }
+
+In [16]: for x in d :
+ print(x)
+ ....:
+score
+name
+
+
+
(note the different order...)
+
+
+
dict keys and values
+
In [20]: d = { 'name' : 'Brian' , 'score' : 42 }
+
+In [21]: d . keys ()
+Out[21]: dict_keys(['score', 'name'])
+
+In [22]: d . values ()
+Out[22]: dict_values([42, 'Brian'])
+
+In [23]: d . items ()
+Out[23]: dict_items([('score', 42), ('name', 'Brian')])
+
+
+
+
+
dict keys and values
+
Iterating on everything
+
In [26]: d = { 'name' : 'Brian' , 'score' : 42 }
+
+In [27]: for k , v in d . items ():
+ print("%s: %s" % (k,v))
+ ....:
+score: 42
+name: Brian
+
+
+
+
+
+
Other dict operations:
+
See them all here:
+
https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
+
Is it in there?
+
In [5]: d
+Out[5]: {'that': 7, 'this': 5}
+
+In [6]: 'that' in d
+Out[6]: True
+
+In [7]: 'this' not in d
+Out[7]: False
+
+
+
Containment is on the keys.
+
Getting something: (like indexing)
+
In [9]: d . get ( 'this' )
+Out[9]: 5
+
+
+
But you can specify a default
+
In [11]: d . get ( 'something' , 'a default' )
+Out[11]: 'a default'
+
+
+
Never raises an Exception (default default is None)
+
iterating
+
In [13]: for item in d :
+ ....: print ( item )
+ ....:
+this
+that
+
+
+
which is equivalent to, but faster than:
+
In [15]: for key in d . keys ():
+ print(key)
+ ....:
+this
+that
+
+
+
but to get values, must specify you want values:
+
In [16]: for val in d . values ():
+ print(val)
+ ....:
+5
+7
+
+
+
“Popping”: getting the value while removing it
+
pop out a particular key
+
In [19]: d . pop ( 'this' )
+Out[19]: 5
+
+In [20]: d
+Out[20]: {'that': 7}
+
+
+
pop out an arbitrary key, value pair
+
In [23]: d . popitem ()
+Out[23]: ('that', 7)
+
+In [24]: d
+Out[24]: {}
+
+
+
This one is handy:
+
setdefault(key[, default])
+
gets the value if it’s there, sets it if it’s not
+
In [27]: d . setdefault ( 'something' , 'a value' )
+Out[27]: 'a value'
+
+In [28]: d
+Out[28]: {'something': 'a value'}
+
+
+
Assignment maintains link to the original dict
+
In [47]: d
+Out[47]: {'something': 'a value'}
+
+In [48]: item_view = d
+
+In [49]: d [ 'something else' ] = 'another value'
+
+In [50]: item_view
+Out[50]: {'something': 'a value', 'something else': 'another value'}
+
+
+
Use explicit copy method to get a copy
+
In [51] item_copy = d.copy()
+
+In [52]: d [ 'another thing' ] = 'different value'
+
+In [53]: d
+Out[53]:
+{'another thing': 'different value',
+ 'something': 'a value',
+ 'something else': 'another value'}
+
+ In [54]: item_copy
+ Out[54]: {'something': 'a value', 'something else': 'another value'}
+
+
+
+
+
+
Sets
+
set is an unordered collection of distinct values
+
Essentially a dict with only keys
+
Set Constructors
+
>>> set ()
+set ()
+
+>>> set ([ 1 , 2 , 3 ])
+{ 1 , 2 , 3 }
+
+>>> { 1 , 2 , 3 }
+{ 1 , 2 , 3 }
+
+>>> s = set ()
+
+>>> s . update ([ 1 , 2 , 3 ])
+>>> s
+{ 1 , 2 , 3 }
+
+
+
+
Set Properties
+
Set members must be hashable
+
Like dictionary keys – and for same reason (efficient lookup)
+
No indexing (unordered)
+
>>> s [ 1 ]
+Traceback ( most recent call last ):
+ File "<stdin>" , line 1 , in < module >
+TypeError : 'set' object does not support indexing
+
+
+
+
+
Set Methods
+
>> s = set ([ 1 ])
+>>> s . pop () # an arbitrary member
+1
+>>> s . pop ()
+Traceback ( most recent call last ):
+ File "<stdin>" , line 1 , in < module >
+KeyError : 'pop from an empty set'
+>>> s = set ([ 1 , 2 , 3 ])
+>>> s . remove ( 2 )
+>>> s . remove ( 2 )
+Traceback ( most recent call last ):
+ File "<stdin>" , line 1 , in < module >
+KeyError : 2
+
+
+
All the “set” operations from math class...
+
s . isdisjoint ( other )
+
+s . issubset ( other )
+
+s . union ( other , ... )
+
+s . intersection ( other , ... )
+
+s . difference ( other , ... )
+
+s . symmetric_difference ( other , ... )
+
+
+
+
+
Frozen Set
+
Another kind of set: frozenset
+
immutable – for use as a key in a dict
+(or another set...)
+
>>> fs = frozenset (( 3 , 8 , 5 ))
+>>> fs . add ( 9 )
+Traceback (most recent call last):
+ File "<stdin>" , line 1 , in <module>
+AttributeError : 'frozenset' object has no attribute 'add'
+
+
+
+
+
+
+
Homework
+
+
Handy hints for/from Homework
+
You almost never need to loop through the indexes of a sequence
+
+
+
nifty for loop tricks
+
tuple unpacking:
+
remember this?
+
+
You can do that in a for loop, also:
+
In [4]: l = [( 1 , 2 ), ( 3 , 4 ), ( 5 , 6 )]
+
+In [5]: for i , j in l :
+ print("i:%i, j:%i"%(i, j))
+
+i:1, j:2
+i:3, j:4
+i:5, j:6
+
+
+
(Mailroom example)
+
+
+
Looping through two loops at once:
+
zip
+
In [10]: l1 = [ 1 , 2 , 3 ]
+
+In [11]: l2 = [ 3 , 4 , 5 ]
+
+In [12]: for i , j in zip ( l1 , l2 ):
+ ....: print ( "i: %i , j: %i " % ( i , j ))
+ ....:
+i:1, j:3
+i:2, j:4
+i:3, j:5
+
+
+
Can be more than two:
+
for i , j , k , l in zip ( l1 , l2 , l3 , l4 ):
+
+
+
+
+
Need the index and the item?
+
enumerate
+
In [2]: l = [ 'this' , 'that' , 'the other' ]
+
+In [3]: for i , item in enumerate ( l ):
+ ...: print ( "the %i th item is: %s " % ( i , item ))
+ ...:
+the 0th item is: this
+the 1th item is: that
+the 2th item is: the other
+
+
+
+
+
+
Recommended Reading:
+
+
+Dive Into Python: Chapt. 13,14
+
+
+
+
+
Assignments:
+
+
+Finish lab exercises
+Coding kata: trigrams
+Paths and files
+Update mailroom with dicts and exceptions
+
+
+
+
+
Text and files and dicts, and...
+
+
+Use The Adventures of Sherlock Holmes as input:
+
+
+
+This is intentionally open-ended and underspecified. There are many interesting decisions to make.
+
+Experiment with different lengths for the lookup key. (3 words, 4 words, 3 letters, etc)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session05.html b/session05.html
new file mode 100644
index 0000000..8b573de
--- /dev/null
+++ b/session05.html
@@ -0,0 +1,741 @@
+
+
+
+
+
+
+
+
+
+
+ Session Five: Files, Streams & String IO — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Five: Files, Streams & String IO
+
+
Announcements
+
+
+
Review & Questions
+
+
+
Homework
+
Code review – let’s take a look.
+
+
+
Lightening talks
+
Today’s lightening talks will be from:
+
+
+
Strings
+
Quick review: a string literal creates a string type:
+
"this is a string"
+
+'So is this'
+
+"And maybe y'all need something like this!"
+
+"""and this also"""
+
+
+
You can also use str()
+
In [256]: str ( 34 )
+Out[256]: '34'
+
+
+
+
String Manipulation
+
split and join :
+
In [167]: csv = "comma, separated, values"
+In [168]: csv . split ( ', ' )
+Out[168]: ['comma', 'separated', 'values']
+In [169]: psv = '|' . join ( csv . split ( ', ' ))
+In [170]: psv
+Out[170]: 'comma|separated|values'
+
+
+
+
+
Case Switching
+
In [171]: sample = 'A long string of words'
+In [172]: sample . upper ()
+Out[172]: 'A LONG STRING OF WORDS'
+In [173]: sample . lower ()
+Out[173]: 'a long string of words'
+In [174]: sample . swapcase ()
+Out[174]: 'a LONG STRING OF WORDS'
+In [175]: sample . title ()
+Out[175]: 'A Long String Of Words'
+
+
+
+
+
Testing
+
In [181]: number = "12345"
+In [182]: number . isnumeric ()
+Out[182]: True
+In [183]: number . isalnum ()
+Out[183]: True
+In [184]: number . isalpha ()
+Out[184]: False
+In [185]: fancy = "Th!$ $tr!ng h@$ $ymb0l$"
+In [186]: fancy . isalnum ()
+Out[186]: False
+
+
+
+
+
+
Raw Strings
+
Add an r in front of the string literal:
+
Escape Sequences Ignored
+
In [408]: print ( "this \n that" )
+this
+that
+In [409]: print ( r"this\nthat" )
+this\nthat
+
+
+
Gotcha
+
In [415]: r" \"
+SyntaxError: EOL while scanning string literal
+
+
+
(handy for regex, windows paths...)
+
+
+
Ordinal values
+
Characters in strings are stored as numeric values:
+
+“ASCII” values: 1-127
+Unicode values – 1 - 1,114,111 (!!!)
+
+
To get the value:
+
In [109]: for i in 'Chris' :
+ .....: print ( ord ( i ), end = ' ' )
+67 104 114 105 115
+In [110]: for i in ( 67 , 104 , 114 , 105 , 115 ):
+ .....: print ( chr ( i ), end = '' )
+Chris
+
+
+
(these days, stick with ASCII, or use full Unicode: more on that in a few weeks)
+
+
+
+
+
Multiple placeholders
+
In [65]: "the number is {} is {}" . format ( 'five' , 5 )
+Out[65]: 'the number is five is 5'
+
+In [66]: "the first 3 numbers are {}, {}, {}" . format ( 1 , 2 , 3 )
+Out[66]: 'the first 3 numbers are 1, 2, 3'
+
+
+
The counts must agree:
+
In [67]: "string with {} formatting {}" . format ( 1 )
+---------------------------------------------------------------------------
+IndexError Traceback (most recent call last)
+<ipython-input-67-a079bc472aca> in <module> ()
+----> 1 "string with {} formatting {}" . format ( 1 )
+
+IndexError : tuple index out of range
+
+
+
+
+
Named placeholders
+
In [69]: "Hello, {name}, whaddaya know?" . format ( name = "Joe" )
+Out[69]: 'Hello, Joe, whaddaya know?'
+
+
+
You can use values more than once, and skip values:
+
In [73]: "Hi, {name}. Howzit, {name}?" . format ( name = 'Bob' )
+Out[73]: 'Hi, Bob. Howzit, Bob?'
+
+
+
The format operator works with string variables, too:
+
In [80]: s = "{:d} / {:d} = {:f}"
+
+In [81]: a , b = 12 , 3
+
+In [82]: s . format ( a , b , a / b )
+Out[82]: '12 / 3 = 4.000000'
+
+
+
So you can dynamically build a format string
+
+
+
+
+
+
+
Files
+
Text Files
+
f = open ( 'secrets.txt' )
+secret_data = f . read ()
+f . close ()
+
+
+
secret_data is a string
+
NOTE: these days, you probably need to use Unicode for text – we’ll get to that next week
+
Binary Files
+
f = open ( 'secrets.bin' , 'rb' )
+secret_data = f . read ()
+f . close ()
+
+
+
secret_data is a byte string
+
(with arbitrary bytes in it – well, not arbitrary – whatever is in the file.)
+
(See the struct module to unpack binary data )
+
File Opening Modes
+
f = open ( 'secrets.txt' , [ mode ])
+'r' , 'w' , 'a'
+'rb' , 'wb' , 'ab'
+r + , w + , a +
+r + b , w + b , a + b
+
+
+
These follow the Unix conventions, and aren’t all that well documented
+in the Python docs. But these BSD docs make it pretty clear:
+
http://www.manpagez.com/man/3/fopen/
+
Gotcha – ‘w’ modes always clear the file
+
Text is default
+
+
+Newlines are translated: \r\n -> \n
+– reading and writing!
+Use *nix-style in your code: \n
+
+
+
Gotcha:
+
+
+no difference between text and binary on *nix
+breaks on Windows
+
+
+
+
File Reading
+
Reading part of a file
+
header_size = 4096
+f = open ( 'secrets.txt' )
+secret_header = f . read ( header_size )
+secret_rest = f . read ()
+f . close ()
+
+
+
Common Idioms
+
for line in open ( 'secrets.txt' ):
+ print ( line )
+
+
+
(the file object is an iterator!)
+
f = open ( 'secrets.txt' )
+while True :
+ line = f . readline ()
+ if not line :
+ break
+ do_something_with_line ()
+
+
+
We will learn more about the keyword with later, but for now, just understand
+the syntax and the advantage over the try-finally block:
+
with open ( 'workfile' , 'r' ) as f :
+ read_data = f . read ()
+f . closed
+True
+
+
+
+
+
File Writing
+
outfile = open ( 'output.txt' , 'w' )
+for i in range ( 10 ):
+ outfile . write ( "this is line: %i \n " % i )
+outfile . close ()
+
+with open ( 'output.txt' , 'w' ) as f :
+ for i in range ( 10 ):
+ f . write ( "this is line: %i \n " % i )
+
+
+
+
+
File Methods
+
Commonly Used Methods
+
f . read () f . readline () f . readlines ()
+
+f . write ( str ) f . writelines ( seq )
+
+f . seek ( offset ) f . tell () # for binary files, mostly
+
+f . close ()
+
+
+
+
+
Stream IO
+
In [ 417 ]: import io
+In [ 420 ]: f = io . StringIO ()
+In [ 421 ]: f . write ( "somestuff" )
+In [ 422 ]: f . seek ( 0 )
+In [ 423 ]: f . read ()
+Out [ 423 ]: 'somestuff'
+Out [ 424 ]: stuff = f . getvalue ()
+Out [ 425 ]: f . close ()
+
+
+
(handy for testing file handling code...)
+
There is also cStringIO – a bit faster.
+
from cStringIO import StringIO
+
+
+
+
+
Paths
+
Paths are generally handled with simple strings (or Unicode strings)
+
Relative paths:
+
'secret.txt'
+'./secret.txt'
+
+
+
Absolute paths:
+
'/home/chris/secret.txt'
+
+
+
Either work with open() , etc.
+
(working directory only makes sense with command-line programs...)
+
+
+
os module
+
os . getcwd ()
+os . chdir ( path )
+os . path . abspath ()
+os . path . relpath ()
+
+
+
os . path . split ()
+os . path . splitext ()
+os . path . basename ()
+os . path . dirname ()
+os . path . join ()
+
+
+
(all platform independent)
+
os . listdir ()
+os . mkdir ()
+os . walk ()
+
+
+
(higher level stuff in shutil module)
+
+
+
pathlib
+
pathlib is a package for handling paths in an OO way:
+
http://pathlib.readthedocs.org/en/pep428/
+
All the stuff in os.path and more:
+
In [64]: import pathlib
+In [65]: pth = pathlib . Path ( './' )
+In [66]: pth . is_dir ()
+Out[66]: True
+In [67]: pth . absolute ()
+Out[67]: PosixPath('/Users/Chris/PythonStuff/UWPCE/IntroPython2015')
+In [68]: for f in pth . iterdir ():
+ print(f)
+junk2.txt
+junkfile.txt
+...
+
+
+
+
+
Lab: Files
+
In the class repo, in:
+
Examples\students.txt
+
You will find the list I generated of all the students in the class, and
+what programming languages they have used in the past.
+
Write a little script that reads that file, and generates a list of all
+the languages that have been used.
+
Extra credit: keep track of how many students specified each language.
+
+
+
+
Homework
+
+
Catch up!
+
+Finish the LABs from today
+Catch up from last week.
+Add Exception handling to mailroom
+and add some tests
+and list (and dict, and set) comprehensions...
+
+
+If you’ve done all that – check out the collections module:
+
+
+
+
+
Paths and File Processing
+
+write a program which prints the full path to all files in the current
+directory, one per line
+write a program which copies a file from a source, to a destination
+(without using shutil, or the OS copy command)
+advanced: make it work for any size file: i.e. don’t read the entire
+contents of the file into memory at once.
+Note that if you want it to do any kind of file, you need to open the files in binary mode:
+open(filename, 'rb') (or 'wb' for writing.)
+
+
+update mailroom from last week to:
+Use dicts where appropriate
+Write a full set of letters to everyone to individual files on disk
+See if you can use a dict to switch between the users selections
+Try to use a dict and the .format() method to do the letter as one
+big template – rather than building up a big string in parts.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session06.html b/session06.html
new file mode 100644
index 0000000..fe09c27
--- /dev/null
+++ b/session06.html
@@ -0,0 +1,791 @@
+
+
+
+
+
+
+
+
+
+
+ Session Six: Exceptions, Testing and Advanced Argument Passing — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Docs »
+
+ Session Six: Exceptions, Testing and Advanced Argument Passing
+
+
+
+ View page source
+
+
+
+
+
+
+
+
+
+
+
Session Six: Exceptions, Testing and Advanced Argument Passing
+
+
Announcements
+
+
+
Review & Questions
+
+
+
Homework
+
Code review – let’s take a look.
+
+
+
Lightning talks
+
+
Gregory McKeag
+
Bryan Glogowski
+
(anyone?)
+
(anyone?)
+
(anyone?)
+
+
+
+
+
Framing
+
You’ve just started a new job, or you’ve inherited a project as a contractor. Your task is to migrate a system from Python 2.something to Python 3.something. All of the frameworks and major libraries in the system are years behind current versions. There are thousands of lines of code spread across dozens of modules. And you’re moving from Oracle to Postgres. What do you do?
+
You are the CTO of a new big data company. Your CEO wants you to open the your Python API so that third-party developers, your clients, can supply their own functions to crunch data on your systems. What do you do?
+
+
+
Exceptions
+
What might go wrong here?
+
try :
+ do_something ()
+ f = open ( 'missing.txt' )
+ process ( f ) # never called if file missing
+except IOError :
+ print ( "couldn't open missing.txt" )
+
+
+
+
Exceptions
+
Use Exceptions, rather than your own tests:
+
Don’t do this:
+
do_something ()
+if os . path . exists ( 'missing.txt' ):
+ f = open ( 'missing.txt' )
+ process ( f ) # never called if file missing
+
+
+
It will almost always work – but the almost will drive you crazy
+
Example from homework
+
if num_in . isdigit ():
+ num_in = int ( num_in )
+
+
+
but – int(num_in) will only work if the string can be converted to an integer.
+
So you can do
+
try :
+ num_in = int ( num_in )
+except ValueError :
+ print ( "Input must be an integer, try again." )
+
+
+
Or let the Exception be raised....
+
“it’s Easier to Ask Forgiveness than Permission”
+
+– Grace Hopper
+
http://www.youtube.com/watch?v=AZDWveIdqjY
+
(PyCon talk by Alex Martelli)
+
For simple scripts, let exceptions happen.
+
Only handle the exception if the code can and will do something about it.
+
(much better debugging info when an error does occur)
+
+
+
Exceptions – finally
+
try :
+ do_something ()
+ f = open ( 'missing.txt' )
+ process ( f ) # never called if file missing
+except IOError :
+ print ( "couldn't open missing.txt" )
+finally :
+ do_some_clean - up
+
+
+
The finally: clause will always run
+
+
+
Exceptions – else
+
try :
+ do_something ()
+ f = open ( 'missing.txt' )
+except IOError :
+ print ( "couldn't open missing.txt" )
+else :
+ process ( f ) # only called if there was no exception
+
+
+
Advantage:
+
you know where the Exception came from
+
+
+
Exceptions – using them
+
try :
+ do_something ()
+ f = open ( 'missing.txt' )
+except IOError as the_error :
+ print ( the_error )
+ the_error . extra_info = "some more information"
+ raise
+
+
+
Particularly useful if you catch more than one exception:
+
except ( IOError , BufferError , OSError ) as the_error :
+ do_something_with ( the_error )
+
+
+
+
+
Raising Exceptions
+
def divide ( a , b ):
+ if b == 0 :
+ raise ZeroDivisionError ( "b can not be zero" )
+ else :
+ return a / b
+
+
+
when you call it:
+
In [515]: divide ( 12 , 0 )
+ZeroDivisionError: b can not be zero
+
+
+
+
+
Built in Exceptions
+
You can create your own custom exceptions
+
But...
+
exp = \
+ [ name for name in dir ( __builtin__ ) if "Error" in name ]
+len ( exp )
+32
+
+
+
For the most part, you can/should use a built in one
+
Choose the best match you can for the built in Exception you raise.
+
Example (from last week’s exercises):
+
if ( not isinstance ( m , int )) or ( not isinstance ( n , int )):
+ raise ValueError
+
+
+
Is it the value or the input the problem here?
+
Nope: the type is the problem:
+
if ( not isinstance ( m , int )) or ( not isinstance ( n , int )):
+ raise TypeError
+
+
+
but should you be checking type anyway? (EAFP)
+
+
+
Lab: Exceptions
+
A number of you already did this – so do it at home if you haven’t
+
Exceptions Lab
+
+
+
+
Testing
+
+
You’ve already seen some a very basic testing strategy.
+
You’ve written some tests using that strategy.
+
These tests were pretty basic, and a bit awkward in places (testing error
+conditions in particular).
+
It gets better
+
+
+
Test Runners
+
So far our tests have been limited to code in an if __name__ == "__main__":
+block.
+
+They are run only when the file is executed
+They are always run when the file is executed
+You can’t do anything else when the file is executed without running tests.
+
+
+
This is not optimal.
+
Python provides testing systems to help.
+
+
+
+
Standard Library: unittest
+
The original testing system in Python.
+
import unittest
+
More or less a port of Junit from Java
+
A bit verbose: you have to write classes & methods
+
(And we haven’t covered that yet!)
+
+
+
Using unittest
+
You write subclasses of the unittest.TestCase class:
+
# in test.py
+import unittest
+
+class MyTests ( unittest . TestCase ):
+ def test_tautology ( self ):
+ self . assertEquals ( 1 , 1 )
+
+
+
Then you run the tests by using the main function from the unittest
+module:
+
# in test.py
+if __name__ == '__main__' :
+ unittest . main ()
+
+
+
This way, you can write your code in one file and test it from another:
+
# in my_mod.py
+def my_func ( val1 , val2 ):
+ return val1 * val2
+
+# in test_my_mod.py
+import unittest
+from my_mod import my_func
+
+class MyFuncTestCase ( unittest . TestCase ):
+ def test_my_func ( self ):
+ test_vals = ( 2 , 3 )
+ expected = reduce ( lambda x , y : x * y , test_vals )
+ actual = my_func ( * test_vals )
+ self . assertEquals ( expected , actual )
+
+if __name__ == '__main__' :
+ unittest . main ()
+
+
+
+
The unittest module is pretty full featured
+
It comes with the standard Python distribution, no installation required.
+
It provides a wide variety of assertions for testing all sorts of situations.
+
It allows for a setup and tear down workflow both before and after all tests and before and after each test.
+
It’s well known and well understood.
+
+
+
It’s Object Oriented, and quite heavy.
+
+
+modeled after Java’s junit and it shows...
+
+
+
It uses the framework design pattern, so knowing how to use the features
+means learning what to override.
+
Needing to override means you have to be cautious.
+
Test discovery is both inflexible and brittle.
+
And there is no built-in parameterized testing.
+
+
+
+
Other Options
+
There are several other options for running tests in Python.
+
+
Both are very capable and widely used. I have a personal preference for pytest – so we’ll use it for this class
+
+
+
Installing pytest
+
The first step is to install the package:
+
$ python3 -m pip install pytest
+
+
+
Once this is complete, you should have a py.test command you can run
+at the command line:
+
+
If you have any tests in your repository, that will find and run them.
+
+Do you?
+
+
+
Pre-existing Tests
+
Let’s take a look at some examples.
+
IntroToPython\Examples\Session05
+
`` $ py.test``
+
You can also run py.test on a particular test file:
+
py.test test_this.py
+
The results you should have seen when you ran py.test above come
+partly from these files.
+
Let’s take a few minutes to look these files over.
+
When you run the py.test command, pytest starts in your current
+working directory and searches the filesystem for things that might be tests.
+
It follows some simple rules:
+
+Any python file that starts with test_ or _test is imported.
+Any functions in them that start with test_ are run as tests.
+Any classes that start with Test are treated similarly, with methods that begin with test_ treated as tests.
+
+
This test running framework is simple, flexible and configurable.
+
Read the documentation for more information.
+
What we’ve just done here is the first step in what is called Test Driven
+Development .
+
A bunch of tests exist, but the code to make them pass does not yet exist.
+
The red you see in the terminal when we run our tests is a goad to us to write
+the code that fixes these tests.
+
Let’s do that next!
+
+
+
Test Driven development demo
+
In Examples/Session05/test_cigar_party.py
+
+
+
Lab: Testing
+
Pick an example from codingbat:
+
http://codingbat.com
+
Do a bit of test-driven development on it:
+
+
+run something on the web site.
+write a few tests using the examples from the site.
+then write the function, and fix it ‘till it passes the tests.
+
+
+
Do at least two of them.
+
+
+
+
Advanced Argument Passing
+
+
Calling a function
+
Python functions are objects, so if you don’t call them, you don’t get an error, you just get the function object, usually not what you want:
+
elif donor_name.lower == "exit":
+
+
+
This is comparing the string lower method to the string “exit” and they are never going to be equal!
+
That should be:
+
elif donor_name.lower() == "exit":
+
+
+
This is actually a pretty common typo – keep an eye out for it when you get strange errors, or something just doesn’t seem to be getting triggered.
+
+
+
Keyword arguments
+
When defining a function, you can specify only what you need – in any order
+
In [151]: def fun ( x = 0 , y = 0 , z = 0 ):
+ print(x,y,z)
+ .....:
+In [152]: fun ( 1 , 2 , 3 )
+1 2 3
+In [153]: fun ( 1 , z = 3 )
+1 0 3
+In [154]: fun ( z = 3 , y = 2 )
+0 2 3
+
+
+
A Common Idiom:
+
def fun ( x , y = None ):
+ if y is None :
+ do_something_different
+ go_on_here
+
+
+
Can set defaults to variables
+
In [156]: y = 4
+In [157]: def fun ( x = y ):
+ print("x is:", x)
+ .....:
+In [158]: fun ()
+x is: 4
+
+
+
Defaults are evaluated when the function is defined
+
In [156]: y = 4
+In [157]: def fun ( x = y ):
+ print("x is:", x)
+ .....:
+In [158]: fun ()
+x is: 4
+In [159]: y = 6
+In [160]: fun ()
+x is: 4
+
+
+
+
+
Function arguments in variables
+
function arguments are really just
+
+a tuple (positional arguments)
+a dict (keyword arguments)
+
+
def f ( x , y , w = 0 , h = 0 ):
+ print ( "position: {}, {} -- shape: {}, {}" . format ( x , y , w , h ))
+
+position = ( 3 , 4 )
+size = { 'h' : 10 , 'w' : 20 }
+
+>>> f ( * position , ** size )
+position : 3 , 4 -- shape : 20 , 10
+
+
+
+
+
Function parameters in variables
+
You can also pull the parameters out in the function as a tuple and a dict:
+
def f(*args, **kwargs):
+ print("the positional arguments are:", args)
+ print("the keyword arguments are:", kwargs)
+
+In [389]: f ( 2 , 3 , this = 5 , that = 7 )
+the positional arguments are: (2, 3)
+the keyword arguments are: {'this': 5, 'that': 7}
+
+
+
This can be very powerful...
+
+
+
+
Lab: Keyword Arguments
+
keyword arguments:
+
+Write a function that has four optional parameters (with defaults):
+fore_color
+back_color
+link_color
+visited_color
+
+
+Have it print the colors (use strings for the colors)
+Call it with a couple different parameters set
+Have it pull the parameters out with *args, **kwargs
+- and print those
+
+
+
+
+
switch-case
+
A number of languages have a “switch-case” construct:
+
switch(argument) {
+ case 0:
+ return "zero";
+ case 1:
+ return "one";
+ case 2:
+ return "two";
+ default:
+ return "nothing";
+};
+
+
+
How do you say this in Python?
+
+
+
if-elif chains
+
The obvious way to say it is a chain of elif statements:
+
if argument == 0 :
+ return "zero"
+elif argument == 1 :
+ return "one"
+elif argument == 2 :
+ return "two"
+else :
+ return "nothing"
+
+
+
And there is nothing wrong with that, but....
+
+
+
Dict as switch
+
The elif chain is neither elegant nor efficient. There are a number of ways to say it in python – but one elegant one is to use a dict:
+
arg_dict = { 0 : "zero" , 1 : "one" , 2 : "two" }
+ dict . get ( argument , "nothing" )
+
+
+
Simple, elegant and fast.
+
You can do a dispatch table by putting functions as the value.
+
Example: Chris’ mailroom2 solution.
+
+
+
Switch with functions
+
What would this be like if you used functions instead? Think of the possibilities.
+
In [11]: def my_zero_func ():
+return "I'm zero"
+
+In [12]: def my_one_func ():
+ return "I'm one"
+
+In [13]: switch_func_dict = {
+ 0: my_zero_func,
+ 1: my_one_func,
+}
+
+In [14]: switch_func_dict . get ( 0 )()
+Out[14]: "I'm zero"
+
+
+
+
+
Lab: Functions as objects
+
Let’s use some of this ability to use functions as objects for something useful:
+
Trapezoidal Rule
+
+
+
+
Review framing questions
+
+
+
Homework
+
Finish the Labs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session07.html b/session07.html
new file mode 100644
index 0000000..33c5577
--- /dev/null
+++ b/session07.html
@@ -0,0 +1,833 @@
+
+
+
+
+
+
+
+
+
+
+ Session Seven: Object Oriented Programming — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Seven: Object Oriented Programming
+
+
Announcements
+
+
+
Review & Questions
+
+
+
Homework Review
+
Code review – let’s take a look.
+
+
Homework Review: Trapezoid
+
Did you all get a trapedzoidal rule function working?
+
Anyone get the “passing through of arguments”?
+
How about the adaptive solutions?
+
+
+
Notes on Floating point
+
Did anyone look at the isclose() function?
+
How to make a range of numbers in floating point?
+
Anyone do something like this?:
+
s = []
+x = a
+while x <= b :
+ s . append ( x )
+ x += delta_x
+
+-- see my solution .
+
+
+
Some notes about FP issues:
+
https://docs.python.org/3.5/tutorial/floatingpoint.html
+
+
+
+
Lightning Talks
+
+
(anyone?)
+
Michael Gregor
+
Tsega Solomon
+
Yuanrui (Robert) Zhao
+
tbd
+
+
+
+
+
Framing
+
In the Beginning there was the GOTO.
+
And in fact, there wasn’t even that.
+
+
+
Programming Paradigms
+
https://en.wikipedia.org/wiki/Programming_paradigm
+
+
Software Design
+
Good software design is about code re-use, clean separation of concerns,
+refactorability, testability, etc...
+
+OO can help with all that, but:
+
+It doesn’t guarantee it
+It can get in the way
+
+
+
+
What is Object Oriented Programming?
+
+
“Objects can be thought of as wrapping their data
+within a set of functions designed to ensure that
+the data are used appropriately, and to assist in
+that use”
+
+
+
http://en.wikipedia.org/wiki/Object-oriented_programming
+
Even simpler:
+
“Objects are data and the functions that act on them in one place.”
+
This is the core of “encapsulation”
+
+
+
The Dominant Model
+
OO is the dominant model for the past couple decades, but it is not the only model, and languages such as Python increasingly mix and blend among models.
+
+
+
Object Oriented Concepts
+
+
Classes
+
Instances or Objects
+
Encapsulation
+
Class and instance attributes
+
Subclassing
+
Overriding methods
+
Operator Overloading
+
Polymorphism
+
Dynamic Dispatch
+
+
+
+
Definitions
+
+class
+A category of objects: particular data and behavior: A “circle” (same as a type in python)
+instance
+A particular object of a class: a specific circle
+object
+The general case of an instance – really any value (in Python anyway)
+attribute
+Something that belongs to an object (or class): generally thought of
+as a variable, or single object, as opposed to a ...
+method
+A function that belongs to a class
+
+
+
+
Python and OO
+
Is Python a “True” Object-Oriented Language?
+
What are its strengths and weaknesses vis-a-vis OO?
+
It does not support full encapsulation, i.e., it does not require classes, etc.
+
Folks can’t even agree on what OO “really” means
+
See: The Quarks of Object-Oriented Development
+
+
+
http://agp.hx0.ru/oop/quarks.pdf
+
+Think in terms of what makes sense for your project
+– not any one paradigm of software design.
+
+
OO Buzzwords
+
+
+data abstraction
+encapsulation
+modularity
+polymorphism
+inheritance
+
+
+
Python provides for all of this, though it doesn’t enforce or require any of it.
+
+
+
Python’s roots
+
+
C
+
C with Classes (aka C++)
+
Modula2
+
+
+
+
+
You can do OO in C
+
Which today is not considered an OO Language.
+
See the GTK+ project.
+
OO languages give you some handy tools to make it easier (and safer):
+
+
+polymorphism (duck typing gives you this)
+inheritance
+
+
+
+
+
You will need to understand OO
+
+It’s a good idea for a lot of problems
+You’ll need to work with OO packages
+
+
(Even a fair bit of the standard library is Object Oriented)
+
+
+
+
Python Classes
+
The class statement
+
class creates a new type object:
+
In [4]: class C :
+ pass
+ ...:
+In [5]: type ( C )
+Out[5]: type
+
+
+
A class is a type – interesting!
+
It is created when the statement is run – much like def
+
A simple class
+
About the simplest class you can write
+
>>> class Point :
+... x = 1
+... y = 2
+>>> Point
+<class __main__.Point at 0x2bf928>
+>>> Point . x
+1
+>>> p = Point ()
+>>> p
+<__main__.Point instance at 0x2de918>
+>>> p . x
+1
+
+
+
+
Basic Structure of a class
+
class Point :
+# everything defined in here is in the class namespace
+
+ def __init__ ( self , x , y ):
+ self . x = x
+ self . y = y
+
+## create an instance of the class
+p = Point ( 3 , 4 )
+
+## access the attributes
+print ( "p.x is:" , p . x )
+print ( "p.y is:" , p . y )
+
+
+
see: Examples/Session07/simple_classes.py
+
+
+
The Initializer
+
The __init__ special method is called when a new instance of a class is created.
+
You can use it to do any set-up you need
+
class Point ( object ):
+ def __init__ ( self , x , y ):
+ self . x = x
+ self . y = y
+
+
+
It gets the arguments passed when you call the class object:
+
+
+
+
Self
+
What is this self thing?
+
The instance of the class is passed as the first parameter for every method.
+
“self ” is only a convention – but you DO want to use it.
+
class Point :
+ def a_function ( self , x , y ):
+...
+
+
+
Does this look familiar from C-style procedural programming?
+
Anything assigned to a self. attribute is kept in the instance
+name space – self is the instance.
+
That’s where all the instance-specific data is.
+
class Point ( object ):
+ size = 4
+ color = "red"
+ def __init__ ( self , x , y ):
+ self . x = x
+ self . y = y
+
+
+
+
+
Class Attributes
+
Anything assigned in the class scope is a class attribute – every
+instance of the class shares the same one.
+
Note: the methods defined by def are class attributes as well.
+
The class is one namespace, the instance is another.
+
class Point :
+ size = 4
+ color = "red"
+...
+ def get_color ():
+ return self . color
+>>> p3 . get_color ()
+ 'red'
+
+
+
class attributes are accessed with self also.
+
+
+
Typical methods
+
class Circle :
+ color = "red"
+
+ def __init__ ( self , diameter ):
+ self . diameter = diameter
+
+ def grow ( self , factor = 2 ):
+ self . diameter = self . diameter * factor
+
+
+
Methods take some parameters, manipulate the attributes in self .
+
They may or may not return something useful.
+
+
+
Arity Gotcha
+
...
+ def grow ( self , factor = 2 ):
+ self . diameter = self . diameter * factor
+...
+In [ 205 ]: C = Circle ( 5 )
+In [ 206 ]: C . grow ( 2 , 3 )
+
+TypeError : grow () takes at most 2 arguments ( 3 given )
+
+
+
Huh???? I only gave 2
+
self is implicitly passed in for you by python.
+
+
+
Functions (methods) are First Class
+
Note that in python, functions are first class objects, so a method is an attribute
+
+
+
LAB: Classes
+
Let’s say you need to render some html...
+
The goal is to build a set of classes that render an html
+page.
+
We’ll start with a single class, then add some sub-classes
+to specialize the behavior
+
Details in:
+
HTML Renderer Exercise
+
Do Step 1. in class and then wait to do the rest until after discussing Subclassing and Inheritance.
+
+
+
+
Subclassing & Inheritance
+
+
Inheritance
+
In object-oriented programming (OOP), inheritance is a way to reuse code
+of existing objects, or to establish a subtype from an existing object.
+
Objects are defined by classes, classes can inherit attributes and behavior
+from pre-existing classes called base classes or super classes.
+
The resulting classes are known as derived classes or subclasses.
+
(http://en.wikipedia.org/wiki/Inheritance_%28object-oriented_programming%29 )
+
+
+
Subclassing
+
A subclass “inherits” all the attributes (methods, etc) of the parent class.
+
You can then change (“override”) some or all of the attributes to change the behavior.
+
You can also add new attributes to extend the behavior.
+
The simplest subclass in Python:
+
class A_subclass ( The_superclass ):
+ pass
+
+
+
A_subclass now has exactly the same behavior as The_superclass
+
+
+
Overriding attributes
+
Overriding is as simple as creating a new attribute with the same name:
+
class Circle :
+ color = "red"
+
+...
+
+class NewCircle ( Circle ):
+ color = "blue"
+>>> nc = NewCircle
+>>> print ( nc . color )
+blue
+
+
+
all the self instances will have the new attribute.
+
+
+
Overriding methods
+
Same thing, but with methods (remember, a method is an attribute in python)
+
class Circle :
+...
+ def grow ( self , factor = 2 ):
+ """grows the circle's diameter by factor"""
+ self . diameter = self . diameter * factor
+...
+
+class NewCircle ( Circle ):
+...
+ def grow ( self , factor = 2 ):
+ """grows the area by factor..."""
+ self . diameter = self . diameter * math . sqrt ( 2 )
+
+
+
all the instances will have the new method
+
Here’s a program design suggestion:
+
Whenever you override a method, the interface of the new method should be the same as the old. It should take the same parameters, return the same type, and obey the same preconditions and postconditions.
+
If you obey this rule, you will find that any function designed to work with an instance of a superclass, like a Deck, will also work with instances of subclasses like a Hand or PokerHand. If you violate this rule, your code will collapse like (sorry) a house of cards.
+
+
+
+
More on Subclassing
+
+
Overriding __init__
+
__init__ common method to override
+
You often need to call the super class __init__ as well
+
class Circle :
+ color = "red"
+ def __init__ ( self , diameter ):
+ self . diameter = diameter
+...
+class CircleR ( Circle ):
+ def __init__ ( self , radius ):
+ diameter = radius * 2
+ Circle . __init__ ( self , diameter )
+
+
+
exception to: “don’t change the method signature” rule.
+
+
+
More subclassing
+
You can also call the superclass’ other methods:
+
class Circle :
+...
+ def get_area ( self , diameter ):
+ return math . pi * ( diameter / 2.0 ) ** 2
+
+
+class CircleR2 ( Circle ):
+...
+ def get_area ( self ):
+ return Circle . get_area ( self , self . radius * 2 )
+
+
+
There is nothing special about __init__ except that it gets called
+automatically when you instantiate an instance.
+
+
+
When to Subclass
+
“Is a” relationship: Subclass/inheritance
+
“Has a” relationship: Composition
+
“Is a” vs “Has a”
+
You may have a class that needs to accumulate an arbitrary number of objects.
+
A list can do that – so should you subclass list?
+
Ask yourself:
+
– Is your class a list (with some extra functionality)?
+
or
+
– Does you class have a list?
+
You only want to subclass list if your class could be used anywhere a list can be used.
+
+
+
+
What are Python classes, really?
+
Putting aside the OO theory...
+
Python classes are:
+
+
+Namespaces
+One for the class object
+One for each instance
+
+
+Attribute resolution order
+Auto tacking-on of self when methods are called
+
+
+
That’s about it – really!
+
+
+
Type-Based dispatch
+
You’ll see code that looks like this:
+
if isinstance ( other , A_Class ):
+ Do_something_with_other
+else :
+ Do_something_else
+
+
+
When it’s called for:
+
+
+isinstance()
+issubclass()
+
+
+
+
+
LAB: Subclassing & Inheritance
+
+html renderer: let’s see how much more we can do!
+
+
HTML Renderer Exercise
+
Now we have a base class, and we can:
+
+Subclass overriding class attributes
+Subclass overriding a method
+Subclass overriding the __init__
+
+
These are the core OO approaches
+
+
+
+
Review framing questions
+
Think about OO in Python:
+
Think about what makes sense for your code:
+
+Code re-use
+Clean APIs
+...
+
+
Don’t be a slave to what OO is supposed to look like.
+
Let OO work for you, not create work for you
+
+
+
Homework
+
Let’s say you need to render some html.
+
The goal is to build a set of classes that render an html
+page.
+
We’ll start with a single class, then add some sub-classes
+to specialize the behavior
+
HTML Renderer Exercise
+
+
+
Readings
+
+
The Art of Subclassing
+
The Art of Subclassing by Raymond Hettinger
+
http://pyvideo.org/video/879/the-art-of-subclassing
+
The most salient points from that video are as follows:
+
+Subclassing is not for Specialization
+Classes and subclassing are for code re-use – not creating taxonomies
+Bear in mind that the subclass is in charge
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session08.html b/session08.html
new file mode 100644
index 0000000..141d4ff
--- /dev/null
+++ b/session08.html
@@ -0,0 +1,575 @@
+
+
+
+
+
+
+
+
+
+
+ Session Eight: Object Oriented Programming 2 — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Eight: Object Oriented Programming 2
+
Object Oriented Programming continued...
+
+
Announcements
+
+
+
Review & Questions
+
+
+
Homework
+
Code review – let’s take a look.
+
+
Homework Notes:
+
**kwargs will always define a kwargs dict: it just may be empty.
+
And there is no need to check if it’s empty before trying to loop through it.
+
if self . attributes != {}:
+ for key , value in self . attributes . items ():
+ self . atts += ' {}="{}"' . format ( key , value )
+
+
+
no need for != {} – an empty dict is “Falsey”
+
but no need for that check at all. If the dict (or ist, or tuple) is
+empty, then the loop is a do-nothing operation:
+
+notes on Duck Typing: HTML Renderer Exercise and code review
+anyone stuck that wants to work through your code?
+
+
+
+
+
Lightning Talks
+
+
Deana Holmer
+
Brennen Bounds
+
tbd
+
tbd
+
tbd
+
+
+
+
+
Framing
+
+
+
Multiple Inheritance
+
Multiple inheritance: Inheriting from more than one class.
+
Simply provide more than one parent.
+
class Combined ( Parent1 , Parent2 , Parent3 ):
+ def __init__ ( self , something , something else ):
+ # some custom initialization here.
+ Parent1 . __init__ ( self , ...... )
+ Parent2 . __init__ ( self , ...... )
+ Parent3 . __init__ ( self , ...... )
+ # possibly more custom initialization
+
+
+
Calls to the parent class __init__ are optional and case dependent.
+
+
Purpose
+
What was the purpose behind inheritance?
+
Code reuse.
+
What is the purpose behind multiple inheritance?
+
Code reuse.
+
What wasn’t the purpose of inheritance?
+
Building massive class hierarchies for their own sake.
+
What isn’t the purpose of multiple inheritance?
+
Building massive class hierarchies for their own sake.
+
+
+
Python’s Multiple Inheritance Model
+
Cooperative Multiple Inheritance
+
Emphasis on cooperative!
+
+Play by the rules and everybody benefits (parents, descendants).
+Play by the rules and nobody gets hurt (yourself, mostly).
+We’re all adults here.
+
+
What could go wrong?
+
+
+
+
super()
+
super() : use it to call a superclass method, rather than explicitly calling the unbound method on the superclass.
+
instead of:
+
class A ( B ):
+ def __init__ ( self , * args , ** kwargs )
+ B . __init__ ( self , * argw , ** kwargs )
+ ...
+
+
+
You can do:
+
class A ( B ):
+ def __init__ ( self , * args , ** kwargs )
+ super () . __init__ ( * argw , ** kwargs )
+ ...
+
+
+
+
+
MRO: Method Resolution Order
+
class Combined ( Super1 , Super2 , Super3 )
+
+
+
Attributes are located bottom-to-top, left-to-right
+
+Is it an instance attribute ?
+Is it a class attribute ?
+Is it a superclass attribute ?
+Is it an attribute of the left-most superclass?
+Is it an attribute of the next superclass?
+and so on up the hierarchy...
+
+
+Is it a super-superclass attribute ?
+... also left to right ...
+
+
http://python-history.blogspot.com/2010/06/method-resolution-order.html
+
+
+
Super’s Superpowers
+
It works out – dynamically at runtime – which classes are in the delegation order.
+
Do not be afraid. And be very afraid.
+
+
+
+
Argument Passing
+
Remember that super does not only delegate to your superclass, it delegates to any class in the MRO.
+
Therefore you must be prepared to call any other class’s method in the hierarchy and be prepared to be called from any other class’s method.
+
The general rule is to pass all arguments you received on to the super function. If classes can take differing arguments, accept * args and ** kwargs.
+
+
+
Two seminal articles
+
“Super Considered Harmful” – James Knight
+
https://fuhm.net/super-harmful/
+
“Super() considered super!” – Raymond Hettinger
+
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/
+
(Both worth reading....)
+
+
+
+
Composition
+
+
Composition vs Inheritance
+
Composition does virtually the same thing as multiple inheritance, in the sense that it allows your class to reuse the functionality of other classes.
+
With inheritance you are thinking in terms of ‘is-a’ relationships.
+
With composition you are thinking in terms of ‘has-a’ relationships.
+
Composition is more explicit than inheritance and it avoids the complexity of super(). It of course also gains nothing from super()’s superpowers.
+
+
+
An example
+
class Other ( object ):
+
+ def __init__ ( self ):
+ print ( "Other __init__()" )
+
+
+class MyComposedClass ( object ):
+""" I inherit from object """
+
+ def __init__ ( self ):
+ self . other = Other () # I contain Other()
+
+
+
Remember: ‘has-a’ not ‘is-a’
+
+
+
+
Properties
+
https://en.wikipedia.org/wiki/Property_%28programming%29#Python
+
+
Attributes are clear and concise
+
+
One of the strengths of Python is lack of clutter.
+
In [5]: class C :
+ def __init__(self):
+ self.x = 5
+In [6]: c = C ()
+In [7]: c . x
+Out[7]: 5
+In [8]: c . x = 8
+In [9]: c . x
+Out[9]: 8
+
+
+
+
And we want to maintain this clarity.
+
+
+
Getter and Setters
+
But what if you need to add behavior later?
+
+do some calculation
+check data validity
+keep things in sync
+
+
In [5]: class C :
+ ...: def __init__ ( self ):
+ ...: self . x = 5
+ ...: def get_x ( self ):
+ ...: return self . x
+ ...: def set_x ( self , x ):
+ ...: self . x = x
+ ...:
+In [6]: c = C ()
+In [7]: c . get_x ()
+Out[7]: 5
+In [8]: c . set_x ( 8 )
+In [9]: c . get_x ()
+Out[9]: 8
+
+
+
This is verbose – Java ?
+
+
+
Properties
+
class C:
+ _x = None
+ @property
+ def x(self):
+ return self._x
+ @x.setter
+ def x(self, value):
+ self._x = value
+
+In [28]: c = C ()
+In [30]: c . x = 5
+In [31]: print ( c . x )
+5
+
+
+
Now the interface is like simple attribute access!
+
+
+
Decorators
+
What’s up with the “@” symbols?
+
Those are “decorations” it is a syntax for wrapping functions up with something special.
+
We will cover decorators in detail in another part of the program, but for now just copy the syntax.
+
@property
+def x ( self ):
+
+
+
means: make a property called x with this as the “getter”.
+
@x.setter
+def x ( self , value ):
+
+
+
means: make the “setter” of the ‘x’ property this new function
+
+
+
Read Only Attributes
+
You do not need to define a setter. If you don’t, you get a “read only” attribute:
+
In [11]: class D ():
+ ....: def __init__ ( self , x = 5 ):
+ ....: self . _x = 5
+ ....: @property
+ ....: def getx ( self ):
+ ....: """I am read only"""
+ ....: return self . _x
+ ....:
+In [12]: d = D ()
+In [13]: d . x
+Out[13]: 5
+In [14]: d . x = 6
+---------------------------------------------------------------------------
+AttributeError Traceback (most recent call last)
+<ipython-input-14-c83386d97be3> in <module> ()
+----> 1 d . x = 6
+AttributeError : can't set attribute
+
+
+
+
+
Deleters
+
If you want to do something special when a property is deleted, you can define a deleter as well:
+
In [11]: class D ():
+ ....: def __init__ ( self , x = 5 ):
+ ....: self . _x = 5
+ ....: @property
+ ....: def x ( self ):
+ ....: return self . _x
+ ....: @x.deleter
+ ....: def x ( self ):
+ ....: del self . _x
+
+
+
If you leave this out, the property can’t be deleted, which is usually
+what you want.
+
[demo: properties_example.py ]
+
+
+
+
LAB: Properties, class methods, special methods
+
Let’s use some of this to build a nice class to represent a Circle.
+
For now, Let’s do steps 1-4 of:
+
Circle Class Excercise
+
+
+
Review framing questions
+
+
+
Homework
+
Complete the Circle class
+
Complete the Sparse Array class
+
Refactor mailroom to use classes.
+
+
+
Readings
+
Python 3 Object Oriented Programming: Dusty Phillips
+
(Dusty is a local boy and co-founder of PuPPy)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session09.html b/session09.html
new file mode 100644
index 0000000..5582fa2
--- /dev/null
+++ b/session09.html
@@ -0,0 +1,678 @@
+
+
+
+
+
+
+
+
+
+
+ Session Nine: Object Oriented Programming 3 — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Nine: Object Oriented Programming 3
+
+
Announcements
+
Lightning talk schedule
+
Please Upload your lightning talk materials to your student directory.
+
+
+
+
Review & Questions
+
Questions emailed in over the week.
+
+
+
Homework
+
Code review – let’s take a look.
+
+
+
Lightning Talks
+
+
Krishna Bindhu
+
Calvin Fannin
+
tbd
+
tbd
+
Pradeep Kumar
+
tbd
+
tbd
+
tbd
+
tbd
+
tbd
+
+
+
+
+
Framing
+
+
+
Static and Class Methods
+
+
You’ve seen how methods of a class are bound to an instance when it is
+created.
+
And you’ve seen how the argument self is then automatically passed to
+the method when it is called.
+
And you’ve seen how you can call unbound methods on a class object so
+long as you pass an instance of that class as the first argument.
+
+
But what if you don’t want or need an instance?
+
+
+
Static Methods
+
A static method is a method that doesn’t get self:
+
In [36]: class StaticAdder :
+
+ ....: @staticmethod
+ ....: def add ( a , b ):
+ ....: return a + b
+ ....:
+
+In [37]: StaticAdder . add ( 3 , 6 )
+Out[37]: 9
+
+
+
[demo: static_method.py ]
+
+
Where are static methods useful?
+
Usually they aren’t. It is often better just to write a module-level function.
+
An example from the Standard Library (tarfile.py):
+
class TarInfo :
+ # ...
+ @staticmethod
+ def _create_payload ( payload ):
+ """Return the string payload filled with zero bytes
+ up to the next 512 byte border.
+ """
+ blocks , remainder = divmod ( len ( payload ), BLOCKSIZE )
+ if remainder > 0 :
+ payload += ( BLOCKSIZE - remainder ) * NUL
+ return payload
+
+
+
+
+
+
Class Methods
+
A class method gets the class object, rather than an instance, as the first
+argument
+
In [41]: class Classy :
+ ....: x = 2
+ ....: @classmethod
+ ....: def a_class_method ( cls , y ):
+ ....: print ( "in a class method: " , cls )
+ ....: return y ** cls . x
+ ....:
+In [42]: Classy . a_class_method ( 4 )
+in a class method: <class '__main__.Classy'>
+Out[42]: 16
+
+
+
[demo: class_method.py ]
+
+
+
Why?
+
+
Unlike static methods, class methods are quite common.
+
They have the advantage of being friendly to subclassing.
+
Consider this:
+
In [44]: class SubClassy ( Classy ):
+ ....: x = 3
+ ....:
+
+In [45]: SubClassy . a_class_method ( 4 )
+in a class method: <class '__main__.SubClassy'>
+Out[45]: 64
+
+
+
+
+
+
Alternate Constructors
+
Because of this friendliness to subclassing, class methods are often used to
+build alternate constructors.
+
Consider the case of wanting to build a dictionary with a given iterable of
+keys:
+
In [57]: d = dict ([ 1 , 2 , 3 ])
+---------------------------------------------------------------------------
+TypeError Traceback (most recent call last)
+<ipython-input-57-50c56a77d95f> in <module> ()
+----> 1 d = dict ([ 1 , 2 , 3 ])
+
+TypeError : cannot convert dictionary update sequence element #0 to a sequence
+
+
+
The stock constructor for a dictionary won’t work this way. So the dict object
+implements an alternate constructor that can .
+
@classmethod
+def fromkeys ( cls , iterable , value = None ):
+ '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
+ If not specified, the value defaults to None.
+ '''
+ self = cls ()
+ for key in iterable :
+ self [ key ] = value
+ return self
+
+
+
(this is actually from the OrderedDict implementation in collections.py )
+
See also datetime.datetime.now(), etc....
+
Properties, Static Methods and Class Methods are powerful features of Python’s
+OO model.
+
They are implemented using an underlying structure called descriptors
+
Here is a low level look at how the descriptor protocol works.
+
The cool part is that this mechanism is available to you, the programmer, as
+well.
+
For the Circle Lab: use a class method to make an alternate constructor that takes
+the diameter instead.
+
+
+
+
Special Methods & Protocols
+
+
Special methods (also called magic methods) are the secret sauce to Python’s Duck typing.
+
Defining the appropriate special methods in your classes is how you make your class act like standard classes.
+
+
+
What’s in a Name?
+
We’ve seen at least one special method so far:
+
+
It’s all in the double underscores...
+
Pronounced “dunder” (or “under-under”)
+
try: dir(2) or dir(list)
+
+
+
Generally Useful Special Methods
+
Most classes should at least have these special methods:
+
+object.__str__ :
+Called by the str() built-in function and by the print function to compute
+the informal string representation of an object.
+object.__repr__ :
+Called by the repr() built-in function to compute the official string representation of an object.
+(ideally: eval( repr(something) ) == something )
+
+
+
+
+
Protocols
+
+
The set of special methods needed to emulate a particular type of Python object is called a protocol .
+
Your classes can “become” like Python built-in classes by implementing the methods in a given protocol.
+
Remember, these are more guidelines than laws. Implement what you need.
+
+
+
+
The Numerics Protocol
+
Do you want your class to behave like a number? Implement these methods:
+
object . __add__ ( self , other )
+object . __sub__ ( self , other )
+object . __mul__ ( self , other )
+object . __floordiv__ ( self , other )
+object . __mod__ ( self , other )
+object . __divmod__ ( self , other )
+object . __pow__ ( self , other [, modulo ])
+object . __lshift__ ( self , other )
+object . __rshift__ ( self , other )
+object . __and__ ( self , other )
+object . __xor__ ( self , other )
+object . __or__ ( self , other )
+
+
+
+
+
The Container Protocol
+
Want to make a container type? Here’s what you need:
+
object . __len__ ( self )
+object . __getitem__ ( self , key )
+object . __setitem__ ( self , key , value )
+object . __delitem__ ( self , key )
+object . __iter__ ( self )
+object . __reversed__ ( self )
+object . __contains__ ( self , item )
+object . __getslice__ ( self , i , j )
+object . __setslice__ ( self , i , j , sequence )
+object . __delslice__ ( self , i , j )
+
+
+
+
+
An Example
+
Each of these methods supports a common Python operation.
+
For example, to make ‘+’ work with a sequence type in a vector-like fashion,
+implement __add__ :
+
def __add__ ( self , v ):
+ """return the element-wise vector sum of self and v
+ """
+ assert len ( self ) == len ( v )
+ return vector ([ x1 + x2 for x1 , x2 in zip ( self , v )])
+
+
+
[a more complete example may be seen here ]
+
+
+
Protocols in Summary
+
Use special methods when you want your class to act like a “standard” class in some way.
+
Look up the special methods you need and define them.
+
There’s more to read about the details of implementing these methods:
+
+
+
+
+
LAB: Properties, class methods, special methods continued
+
Let’s complete our Circle class:
+
Steps 5-8 of:
+
Circle Class Excercise
+
+
+
Emulating Standard types
+
Making your classes behave like the built-ins
+
+
Callable classes
+
We’ve been using functions a lot:
+
def my_fun ( something ):
+ do_something
+ ...
+ return something
+
+
+
And then we can call it:
+
result = my_fun ( some_arguments )
+
+
+
But what if we need to store some data to know how to evaluate that function?
+
Example: a function that computes a quadratic function:
+
+\[y = a x^2 + bx + c\]
+
You could pass in a, b and c each time:
+
def quadratic ( x , a , b , c ):
+ return a * x ** 2 + b * x + c
+
+
+
But what if you are using the same a, b, and c numerous times?
+
Or what if you need to pass this in to something
+(like map) that requires a function that takes a single argument?
+
+
+
“Callables”
+
Various places in python expect a “callable” – something that you can
+call like a function:
+
a_result = something ( some_arguments )
+
+
+
“something” in this case is often a function, but can be anything else
+that is “callable”.
+
What have we been introduced to recently that is “callable”, but not a
+function object?
+
+
+
Custom callable objects
+
The trick is one of Python’s “magic methods”
+
__call__ ( * args , ** kwargs )
+
+
+
If you define a __call__ method in your class, it will be used when
+code “calls” an instance of your class:
+
class Callable :
+ def __init__ ( self , ..... )
+ some_initilization
+ def __call__ ( self , some_parameters )
+
+
+
Then you can do:
+
callable_instance = Callable ( some_arguments )
+
+result = callable_instance ( some_arguments )
+
+
+
+
+
Writing your own sequence type
+
Python has a handful of nifty sequence types built in:
+
+
+lists
+tuples
+strings
+...
+
+
+
But what if you need a sequence that isn’t built in?
+
+
+
A Sparse array
+
Example: Sparse Array
+
Sometimes we have data sets that are “sparse” – i.e. most of the values are zero.
+
So you may not want to store a huge bunch of zeros.
+
But you do want the array to look like a regular old sequence.
+
So how do you do that?
+
+
+
+
LAB: Callables & Sparse Arrays
+
+
+
Callables
+
Write a class for a quadratic equation.
+
+The initializer for that class should take the parameters: a, b, c
+It should store those parameters as attributes.
+The resulting instance should evaluate the function when called, and return the result:
+
+
my_quad = Quadratic ( a = 2 , b = 3 , c = 1 )
+
+my_quad ( 0 )
+
+
+
+
+
+
+
Review framing questions
+
+
+
Homework
+
Finish up the labs.
+
Bring your questions to office hours.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/session10.html b/session10.html
new file mode 100644
index 0000000..80e97f6
--- /dev/null
+++ b/session10.html
@@ -0,0 +1,776 @@
+
+
+
+
+
+
+
+
+
+
+ Session Ten: Functional Programming — Introduction To Python 1.3 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction To Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Session Ten: Functional Programming
+
+
Announcements
+
+
+
Review & Questions
+
+
+
Homework
+
Code review – let’s take a look.
+
+
+
Lightning Talks
+
+
Benjamin Warren
+
Brandon Aleson
+
Susan Rees
+
Luis Ganzalez
+
Damian Myerscough
+
Kyle Chinn
+
Michael Newton
+
Kishan Sarpangala
+
Jaemin Chang
+
tbd
+
+
+
+
+
Framing
+
+
+
Functional Programming
+
No real consensus about what that means.
+
But there are some “classic” methods available in Python.
+
+
map
+
map “maps” a function onto a sequence of objects – It applies the function to each item in the list, returning another list
+
In [23]: l = [ 2 , 5 , 7 , 12 , 6 , 4 ]
+In [24]: def fun ( x ):
+ return x*2 + 10
+In [25]: map ( fun , l )
+Out[25]: [14, 20, 24, 34, 22, 18]
+
+
+
But if it’s a small function, and you only need it once:
+
In [26]: map ( lambda x : x * 2 + 10 , l )
+Out[26]: [14, 20, 24, 34, 22, 18]
+
+
+
+
+
filter
+
filter “filters” a sequence of objects with a boolean function –
+It keeps only those for which the function is True – filtering our the rest.
+
To get only the even numbers:
+
In [27]: l = [ 2 , 5 , 7 , 12 , 6 , 4 ]
+In [28]: filter ( lambda x : not x % 2 , l)
+Out[28]: [2, 12, 6, 4]
+
+
+
If you pass None to filter() , you get only items that evaluate to true:
+
In [1]: l = [ 1 , 0 , 2.3 , 0.0 , 'text' , '' , [ 1 , 2 ], [], False , True , None ]
+
+In [2]: filter ( None , l )
+Out[2]: [1, 2.3, 'text', [1, 2], True]
+
+
+
+
+
reduce
+
reduce “reduces” a sequence of objects to a single object with a function that combines two arguments
+
To get the sum:
+
In [30]: l = [ 2 , 5 , 7 , 12 , 6 , 4 ]
+In [31]: reduce ( lambda x , y : x + y , l )
+Out[31]: 36
+
+
+
To get the product:
+
In [32]: reduce ( lambda x , y : x * y , l )
+Out[32]: 20160
+
+
+
or
+
In [13]: import operator
+In [14]: reduce ( operator . mul , l )
+Out[14]: 20160
+
+
+
+
+
Comprehensions
+
Couldn’t you do all this with comprehensions?
+
Yes:
+
In [33]: [ x + 2 + 10 for x in l ]
+Out[33]: [14, 17, 19, 24, 18, 16]
+
+In [34]: [ x for x in l if not x % 2 ]
+Out[34]: [2, 12, 6, 4]
+
+In [6]: l
+Out[6]: [1, 0, 2.3, 0.0, 'text', '', [1, 2], [], False, True, None]
+In [7]: [ i for i in l if i ]
+Out[7]: [1, 2.3, 'text', [1, 2], True]
+
+
+
(Except Reduce)
+
But Guido thinks almost all uses of reduce are really sum()
+
+
+
Functional Programming
+
Comprehensions and map, filter, reduce are all “functional programming” approaches}
+
map, filter and reduce pre-date comprehensions in Python’s history
+
Some people like that syntax better
+
And “map-reduce” is a big concept these days for parallel processing of “Big Data” in NoSQL databases.
+
(Hadoop, MongoDB, etc.)
+
+
+
+
Comprehensions
+
+
List comprehensions
+
A bit of functional programming
+
consider this common for loop structure:
+
new_list = []
+for variable in a_list :
+ new_list . append ( expression )
+
+
+
This can be expressed with a single line using a “list comprehension”
+
new_list = [ expression for variable in a_list ]
+
+
+
What about nested for loops?
+
new_list = []
+for var in a_list :
+ for var2 in a_list2 :
+ new_list . append ( expression )
+
+
+
Can also be expressed in one line:
+
new_list = [ exp for var in a_list for var2 in a_list2 ]
+
+
+
You get the “outer product”, i.e. all combinations.
+
But usually you at least have a conditional in the loop:
+
new_list = []
+for variable in a_list :
+ if something_is_true :
+ new_list . append ( expression )
+
+
+
You can add a conditional to the comprehension:
+
new_list = [ expr for var in a_list if something_is_true ]
+
+
+
Examples:
+
In [341]: [ x ** 2 for x in range ( 3 )]
+Out[341]: [0, 1, 4]
+
+In [342]: [ x + y for x in range ( 3 ) for y in range ( 5 , 7 )]
+Out[342]: [5, 6, 6, 7, 7, 8]
+
+In [343]: [ x * 2 for x in range ( 6 ) if not x % 2 ]
+Out[343]: [0, 4, 8]
+
+
+
Get creative....
+
[ name for name in dir ( __builtin__ ) if "Error" in name ]
+[ 'ArithmeticError' ,
+ 'AssertionError' ,
+ 'AttributeError' ,
+ 'BufferError' ,
+ 'EOFError' ,
+ ....
+
+
+
+
+
Set Comprehensions
+
You can do it with sets, too:
+
new_set = { value for variable in a_sequence }
+
+
+
same as for loop:
+
new_set = set ()
+for key in a_list :
+ new_set . add ( value )
+
+
+
Example: finding all the vowels in a string...
+
In [19]: s = "a not very long string"
+
+In [20]: vowels = set ( 'aeiou' )
+
+In [21]: { l for l in s if l in vowels }
+Out[21]: {'a', 'e', 'i', 'o'}
+
+
+
Side note: why did I do set('aeiou') rather than just aeiou ?
+
+
+
Dict Comprehensions
+
Also with dictionaries
+
new_dict = { key : value for variable in a_sequence }
+
+
+
same as for loop:
+
new_dict = {}
+for key in a_list :
+ new_dict [ key ] = value
+
+
+
Example
+
In [22]: { i : "this_ %i " % i for i in range(5) }
+Out[22]: {0: 'this_0', 1: 'this_1', 2: 'this_2',
+ 3: 'this_3', 4: 'this_4'}
+
+
+
(not as useful with the dict() constructor...)
+
+
+
+
+
Lightning Talk
+
+
+
+
Anonymous functions
+
+
lambda
+
In [171]: f = lambda x , y : x + y
+In [172]: f ( 2 , 3 )
+Out[172]: 5
+
+
+
Content of function can only be an expression – not a statement
+
Anyone remember what the difference is?
+
Called “Anonymous”: it doesn’t get a name.
+
It’s a python object, it can be stored in a list or other container
+
In [7]: l = [ lambda x , y : x + y ]
+In [8]: type ( l [ 0 ])
+Out[8]: function
+
+
+
And you can call it:
+
In [9]: l [ 0 ]( 3 , 4 )
+Out[9]: 7
+
+
+
+
+
Functions as first class objects
+
You can do that with “regular” functions too:
+
In [12]: def fun ( x , y ):
+ ....: return x + y
+ ....:
+In [13]: l = [ fun ]
+In [14]: type ( l [ 0 ])
+Out[14]: function
+In [15]: l [ 0 ]( 3 , 4 )
+Out[15]: 7
+
+
+
+
+
A bit more about lambda
+
It is very useful for specifying sorting as well:
+
In [55]: lst = [( "Chris" , "Barker" ), ( "Fred" , "Jones" ), ( "Zola" , "Adams" )]
+
+In [56]: lst . sort ()
+
+In [57]: lst
+Out[57]: [('Chris', 'Barker'), ('Fred', 'Jones'), ('Zola', 'Adams')]
+
+In [58]: lst . sort ( key = lambda x : x [ 1 ])
+
+In [59]: lst
+Out[59]: [('Zola', 'Adams'), ('Chris', 'Barker'), ('Fred', 'Jones')]
+
+
+
+
+
lambda in keyword arguments
+
In [186]: l = []
+In [187]: for i in range ( 3 ):
+ l.append(lambda x, e=i: x**e)
+ .....:
+In [189]: for f in l :
+ print(f(3))
+1
+3
+9
+
+
+
Note when the keyword argument is evaluated: this turns out to be very handy!
+
+
+
+
+
Closures and function Currying
+
Defining specialized functions on the fly
+
+
Closures
+
“Closures” and “Currying” are cool CS terms for what is really just defining functions on the fly.
+
you can find a “proper” definition here:
+
http://en.wikipedia.org/wiki/Closure_(computer_programming )
+
but I even have trouble following that.
+
So let’s go straight to an example:
+
def counter ( start_at = 0 ):
+ count = [ start_at ]
+ def incr ():
+ count [ 0 ] += 1
+ return count [ 0 ]
+ return incr
+
+
+
What’s going on here?
+
We have stored the start_at value in a list.
+
Then defined a function, incr that adds one to the value in the list, and returns that value.
+
[ Quiz: why is it: count = [start_at] , rather than just count=start_at ]
+
So what type of object do you get when you call counter() ?
+
In [37]: c = counter ( start_at = 5 )
+
+In [38]: type ( c )
+Out[38]: function
+
+
+
So we get a function back – makes sense. The def defines a function, and that function is what’s getting returned.
+
Being a function, we can, of course, call it:
+
In [39]: c ()
+Out[39]: 6
+
+In [40]: c ()
+Out[40]: 7
+
+
+
Each time is it called, it increments the value by one.
+
But what happens if we call counter() multiple times?
+
In [41]: c1 = counter ( 5 )
+
+In [42]: c2 = counter ( 10 )
+
+In [43]: c1 ()
+Out[43]: 6
+
+In [44]: c2 ()
+Out[44]: 11
+
+
+
So each time counter() is called, a new function is created. And that function has its own copy of the count object. This is what makes in a “closure” – it carries with it the scope in which is was created.
+
the returned incr function is a “curried” function – a function with some parameters pre-specified.
+
+
+
+
Recursion
+
You’ve seen functions that call other functions.
+
If a function calls itself , we call that recursion
+
Like with other functions, a call within a call establishes a call stack
+
With recursion, if you are not careful, this stack can get very deep.
+
Python has a maximum limit to how much it can recurse. This is intended to
+save your machine from running out of RAM.
+
Recursion is especially useful for a particular set of problems.
+
For example, take the case of the factorial function.
+
In mathematics, the factorial of an integer is the result of multiplying that
+integer by every integer smaller than it down to 1.
+
5! == 5 * 4 * 3 * 2 * 1
+
+
+
We can use a recursive function nicely to model this mathematical function
+
+
+
+
+
Where we’ve been....
+
+
Python 100
+
Once upon a time, there was a little scripting language called Python.
+
Python 100, this course, is designed to provide the basics or the core of the language.
+
By the end of this course you should be able to “create something useful” with Python.
+
+
+
Python 200
+
Also known as Internet Programming with Python, Python 200 is designed to provide the basics of web programming.
+
Here, already, you’re going to run into Python language constructs that were once upon a time considered “optional.”
+
+
+
Python 300
+
“As soon as an optional advanced language feature is used by anyone in an organization, it is no longer optional–it is effectively imposed on everyone in the organization. The same holds true for externally developed software you use in your systems–if the software’s author uses an advanced or extraneous language feature, it’s no longer entirely optional for you, because you have to understand the feature to reuse or change the code.”
+
“Generators, decorators, slots, properties, descriptors, metaclasses, context managers, closures, super, namespace packages, unicode, function annotations, relative imports, keyword-only arguments, class and static methods, and even obscure applications of comprehensions and operator overloading....
+
If any person or program you need to work with uses such tools, they automatically become part of your required knowledge base too. The net effect of such over-engineering is to either escalate learning requirements radically, or foster a user base that only partially understands the tools they employ. This is obviously less than ideal for those hoping to use Python in simpler ways, and contradictory to the scripting motif.”
+
– Mark Lutz on Optional Language Features
+
+
+
. . . and where we’re going
+
We’ve been learning to drive this car called Python. You’ll learn more about how to drive it in Python 200.
+
In Python 300 we give you the tools to become a mechanic.
+
In the meantime you should at least be familiar with some of these language constructs....
+
+
+
+
Where could you go from here?
+
+
+
Scan the PEPs
+
Python Enhancement Proposals
+
https://www.python.org/dev/peps/
+
Know what sorts of topics are discussed. Find the ones that interest you and could assist in your work.
+
These will provided clarity into the sorts of problems the language designers are trying to solve, how they choose to solve them, and the tradeoffs they needed to make. PEPs also provide hints to alternative solutions.
+
+
+
+
+
+
+
+
+
Review framing questions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/slides_sources/LICENSE.txt b/slides_sources/LICENSE.txt
deleted file mode 100644
index 8b88d6b..0000000
--- a/slides_sources/LICENSE.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-Creative Commons Attribution-ShareAlike 4.0 International Public License
-
-By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
-
-Section 1 – Definitions.
-
-Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
-Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
-BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License.
-Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
-Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
-Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
-License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
-Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
-Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
-Licensor means the individual(s) or entity(ies) granting rights under this Public License.
-Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
-Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
-You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
-Section 2 – Scope.
-
-License grant.
-Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
-reproduce and Share the Licensed Material, in whole or in part; and
-produce, reproduce, and Share Adapted Material.
-Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
-Term. The term of this Public License is specified in Section 6(a).
-Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
-Downstream recipients.
-Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
-Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
-No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
-No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
-Other rights.
-
-Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
-Patent and trademark rights are not licensed under this Public License.
-To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
-Section 3 – License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the following conditions.
-
-Attribution.
-
-If You Share the Licensed Material (including in modified form), You must:
-
-retain the following if it is supplied by the Licensor with the Licensed Material:
-identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
-a copyright notice;
-a notice that refers to this Public License;
-a notice that refers to the disclaimer of warranties;
-a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
-indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
-indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
-You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
-If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
-ShareAlike.
-In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
-
-The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
-You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
-You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
-Section 4 – Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
-
-for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
-if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
-You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
-For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
-Section 5 – Disclaimer of Warranties and Limitation of Liability.
-
-Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
-To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
-The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
-Section 6 – Term and Termination.
-
-This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
-Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
-
-automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
-upon express reinstatement by the Licensor.
-For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
-For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
-Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
-Section 7 – Other Terms and Conditions.
-
-The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
-Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
-Section 8 – Interpretation.
-
-For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
-To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
-No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
-Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
-Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
-
-Creative Commons may be contacted at creativecommons.org.
\ No newline at end of file
diff --git a/slides_sources/Makefile b/slides_sources/Makefile
deleted file mode 100644
index b01d75f..0000000
--- a/slides_sources/Makefile
+++ /dev/null
@@ -1,186 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = build
-SASSBUILD = sassc
-SASSOPTS = --include-path './scss_sources'
-
-# User-friendly check for sphinx-build
-ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
-endif
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make ' where is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Foundations2Python.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Foundations2Python.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/Foundations2Python"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Foundations2Python"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-latexpdfja:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
-
-
-slides:
- $(SPHINXBUILD) -b slides $(ALLSPHINXOPTS) $(BUILDDIR)/slides
- $(SASSBUILD) $(SASSOPTS) scss_sources/slides_custom.scss > $(BUILDDIR)/slides/_static/custom.css
- @echo "Build finished. The HTML slides are in $(BUILDDIR)/slides."
-
diff --git a/slides_sources/Readme.rst b/slides_sources/Readme.rst
deleted file mode 100644
index ab24192..0000000
--- a/slides_sources/Readme.rst
+++ /dev/null
@@ -1,86 +0,0 @@
-******************************
-Sources for Slides / Materials
-******************************
-
-This directory holds the source materials (RestructuredText, mostly) used
-to build the slides and HTML pages for the class.
-
-The ``old_versions`` dir has older version of the materials, done in LaTeX.
-The contents are a bit different and have been updated. There are just
-there for reference.
-
-The documentation is written in `ReStructuredText`_ and output formats are
-included for html, epub and `html5slides`_ (via the excellent `hieroglyph`_
-package).
-
-.. _ReStructuredText: http://docutils.sourceforge.net/rst.html
-.. _html5slides: https://code.google.com/p/io-2012-slides/
-.. _hieroglyph: http://docs.hieroglyph.io/en/latest/index.html
-
-
-Building The Documents
-======================
-
-You will need a handful of Python packages to build this project. You may want to use `virtualenv`_ to help manage those dependencies.
-
-.. _virtualenv: http://virtualenv.org
-.. _virtualenvwrapper: http://virtualenvwrapper.readthedocs.org:
-
-
-First step is to clone this repository:
-
-.. code-block:: bash
-
- $ git clone https://github.com/UWPCE-PythonCert/IntroToPython.git
- ...
- $ cd codefellows_f2_python
-
-Once that is complete, you can install all the required packages with `pip`_:
-
-.. _pip: http://www.pip-installer.org
-
-.. code-block:: bash
-
- $ pip install -r requirements.txt
-
-Finally, build the documentation using one of the output targets. To build the
-plain html version, for example:
-
-.. code-block:: bash
-
- $ make html
- sphinx-build -b html -d build/doctrees source build/html
- Running Sphinx v1.2.2
- ...
- build succeeded.
-
- Build finished. The HTML pages are in build/html.
-
-Or the html5 slides:
-
-.. code-block:: bash
-
- $ make slides
- sphinx-build -b slides -d build/doctrees source build/slides
- Running Sphinx v1.2.2
- ...
- Build finished. The HTML slides are in build/slides.
-
-
-License
-=======
-
-Copyright 2014 Christopher Barker, Cris Ewing.
-
-Thanks to Jon Jacky and Brian Dorsey, who developed the materials from which
-this course was derived.
-
-This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
-International License.
-
-To view a copy of this license, visit
-` `_ or send a letter to:
-
-Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
-
-A copy of this license in text format is included in this package in the LICENSE.txt file.
diff --git a/slides_sources/ToDo.txt b/slides_sources/ToDo.txt
deleted file mode 100644
index e51851c..0000000
--- a/slides_sources/ToDo.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Things to do for the UWPCE Intro to Python class:
-
-Notes about homework:
-
-" ".join(dict.keys())
-
-no need to make a list first.
-
-NEED to do more with iterators vs iterables vs sequences.
-
-Future Sessions:
-
-
-add pathlib examples
-
diff --git a/slides_sources/build_gh_pages.sh b/slides_sources/build_gh_pages.sh
deleted file mode 100755
index c40feb7..0000000
--- a/slides_sources/build_gh_pages.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-# simple script to build and push to gh-pages
-# designed to be run from master
-
-# make the docs
-make html
-
-# copy to other repo (on the gh-pages branch)
-cp -R build/html/ ../../IntroPython2016a-ghpages
-cd ../../IntroPython2016a-ghpages
-git checkout gh-pages
-touch .nojekyll # Make sure the repo has this file in its root, otherwise it will not render on github.io
-git add * # in case there are new files added
-git commit -a -m "updating presentation materials"
-git pull -s ours
-git push
diff --git a/slides_sources/old_versions/readme.rst b/slides_sources/old_versions/readme.rst
deleted file mode 100644
index d341140..0000000
--- a/slides_sources/old_versions/readme.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Old versions of the class materials
-====================================
-
-These are the versinos of the class materials from 2013 -- since updated
-and moved to the Sphinx/Hieroglyph documentation system.
-
diff --git a/slides_sources/old_versions/week-01/GvR.jpg b/slides_sources/old_versions/week-01/GvR.jpg
deleted file mode 100644
index 70446f1..0000000
Binary files a/slides_sources/old_versions/week-01/GvR.jpg and /dev/null differ
diff --git a/slides_sources/old_versions/week-01/PythonOrigins.jpg b/slides_sources/old_versions/week-01/PythonOrigins.jpg
deleted file mode 100644
index 3312068..0000000
Binary files a/slides_sources/old_versions/week-01/PythonOrigins.jpg and /dev/null differ
diff --git a/slides_sources/old_versions/week-01/code/.DS_Store b/slides_sources/old_versions/week-01/code/.DS_Store
deleted file mode 100644
index 5008ddf..0000000
Binary files a/slides_sources/old_versions/week-01/code/.DS_Store and /dev/null differ
diff --git a/slides_sources/old_versions/week-01/code/schedule.py b/slides_sources/old_versions/week-01/code/schedule.py
deleted file mode 100644
index 67a8051..0000000
--- a/slides_sources/old_versions/week-01/code/schedule.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
-Schedule students for lightning talks, fall 2013
-"""
-import random
-
-students = open('students.txt').read()
-
-students = students.split('\n')
-
-students.remove('')
-
-random.shuffle(students)
-
-weeks = range(2,11)
-
-weeks4 = weeks*4
-
-schedule = zip(weeks4, students)
-
-schedule.sort()
-
-outfile = open('schedule.txt', 'w')
-
-print schedule
-
-for week, student in schedule:
- line = 'week %s: %s\n' % (week, student)
- print line,
- outfile.write(line)
-outfile.close()
-
diff --git a/slides_sources/old_versions/week-01/code/schedule.txt b/slides_sources/old_versions/week-01/code/schedule.txt
deleted file mode 100644
index 046460d..0000000
--- a/slides_sources/old_versions/week-01/code/schedule.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-week 2: Antoun, Jo-Anne: python (GIS)
-week 2: Onen, Omer: matlab, skil
-week 2: Small, Edward (Ryan): python, JS
-week 2: Warren, Catherine: SQL
-week 3: Flagg, Nate: basic, pascal, C, c#, TCL
-week 3: Rakita, Joshua C# Java Python JavaScript
-week 3: Wright, Duane
-week 3: name languages
-week 4: Eaton, Sako: php, sql
-week 4: Ivers, Brandon: ruby,
-week 4: Pei, Guangyu (gary): C, C++
-week 4: Savage, Nathan: py3, PHP,
-week 5: Chhen, Rithy: PHP, java, JS, SQL
-week 5: Edson, Howard: SQL, C++
-week 5: Kang, Dong: Java
-week 5: Werner, Steven: javascript
-week 6: Chan, Lawrence: VB
-week 6: Colwell, Kimberly: pascal
-week 6: Petrova, Maria: R, SQL
-week 6: Tran, Linh: html, java
-week 7: Rajagopalan, Sridharan: C, Java, C++
-week 7: Salkodu Parameshwar, Maitri: C, C++, bash
-week 7: Smith, Richard: C++, Java, XML, Shell
-week 7: Thach, Phuc: all of them: php, JS
-week 8: Barker, Chris Python C C++ Shell Fortran Pascal
-week 8: Cypret, Luke: bash, python, sql
-week 8: Moore, Blane: C++, java
-week 8: Parrish, Brent: python, JS
-week 9: AuBuchon, Harlan: py (java)
-week 9: Gapasin, Anne-Lynn: java, C#, perl, XML, assembly
-week 9: Popish, Mario: shell
-week 9: Schmitz, Brian: javascript, PHP
-week 10: Bae, Andrew: pascal, C, C#
-week 10: Grizzel, Travis: shell,
-week 10: Leblanc, Adam: C, C++, ADA, Java, C#
diff --git a/slides_sources/old_versions/week-01/code/split_student_names.py b/slides_sources/old_versions/week-01/code/split_student_names.py
deleted file mode 100644
index 657d51b..0000000
--- a/slides_sources/old_versions/week-01/code/split_student_names.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-fr = open('C:\Users\Josh\PYTHON100\courseenrollees 9-30-13 - Sheet1.csv')
-lines = fr.readlines()[1:]
-fr.close()
-
-#print(type(lines))
-#print(len(lines))
-
-studentNames = []
-for line in lines:
- segments = line.split(',')
- studentNames.append(segments[0] + ", " + segments[1])
-
-# Python is smart enough to not keep on appending to this file when run multiple times
-# (use the 'a' flag if you DO want to append)
-
-fw = open('C:\Users\Josh\PYTHON100\IntroToPython\week-01\students.txt', 'w')
-
-for name in studentNames:
- fw.write(name + '\n')
-fw.close()
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-01/code/students.txt b/slides_sources/old_versions/week-01/code/students.txt
deleted file mode 100644
index 7c93ec6..0000000
--- a/slides_sources/old_versions/week-01/code/students.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-name: languages
-Barker, Chris: Python, C, C++, Shell, Fortran, Pascal
-Rakita, Joshua: C#, Java, Python, JavaScript
-Antoun, Jo-Anne: python (GIS)
-AuBuchon, Harlan: python, java
-Bae, Andrew: pascal, C, C#
-Chan, Lawrence: VB
-Chhen, Rithy: PHP, java, JS, SQL
-Colwell, Kimberly: pascal
-Cypret, Luke: bash, python, sql
-Eaton, Sako: php, sql
-Edson, Howard: SQL, C++
-Flagg, Nate: basic, pascal, C, c#, TCL
-Gapasin, Anne-Lynn: java, C#, perl, XML, assembly
-Grizzel, Travis: shell,
-Ivers, Brandon: ruby,
-Kang, Dong: Java
-Leblanc, Adam: C, C++, ADA, Java, C#
-Moore, Blane: C++, java
-Onen, Omer: matlab, skil
-Parrish, Brent: python, JS
-Pei, Guangyu (gary): C, C++
-Petrova, Maria: R, SQL
-Popish, Mario: shell
-Rajagopalan, Sridharan: C, Java, C++
-Salkodu Parameshwar, Maitri: C, C++, bash
-Savage, Nathan: py3, PHP,
-Schmitz, Brian: javascript, PHP
-Small, Edward (Ryan): python, JS
-Smith, Richard: C++, Java, XML, Shell
-Thach, Phuc: php, JS
-Tran, Linh: html, java
-Warren, Catherine: SQL
-Werner, Steven: javascript
-Wright, Duane:
diff --git a/slides_sources/old_versions/week-01/demo_notes.txt b/slides_sources/old_versions/week-01/demo_notes.txt
deleted file mode 100644
index c314c8f..0000000
--- a/slides_sources/old_versions/week-01/demo_notes.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-Notes for class 1 demo:
-
-Values
-
-integers -- regular, long -- sys.maxint
-
-sys.maxint + 1
-
-floats (C doubles)
-
-Special values:
- None
- True False
-
-note: True False not key words -- but don't re-assign!
-
-strings:
-
-'a string'
-
-"also a string"
-
-"""and this"""
-
-r"a raw string"
-
-
-
-equals vs. is:
-
-5 == 5.0
-5 is 5.0
-
-In [1]: 5 == 5.0
-Out[1]: True
-
-In [2]: 5 is 5.0
-Out[2]: False
-
-In [3]:
-
-In [3]: 5 is 5
-Out[3]: True
-
-In [4]:
-
-In [4]: x = 32
-
-In [5]: y = 32
-
-In [6]: x is y
-Out[6]: True
-
-In [7]: x = 45e234
-
-In [8]: y = 45e234
-
-In [9]: x is y
-Out[9]: False
-
-In [10]: s = 'this'
-
-In [11]: s2 = 'this'
-
-In [12]: s is s2
-Out[12]: True
-
-In [13]: s2 = 'this is a fairly long string'
-
-In [14]: s1 = 'this is a fairly long string'
-
-In [15]:
-
-In [15]: s1 is s2
-Out[15]: False
-
diff --git a/slides_sources/old_versions/week-01/homework.rst b/slides_sources/old_versions/week-01/homework.rst
deleted file mode 100644
index f34b521..0000000
--- a/slides_sources/old_versions/week-01/homework.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-Homework for week 1 (Due week 2)
-==================================
-
-(adapted from Downey, "Think Python", ex. 3.5)
-
-
-Part 1
-----------
-
-Write a function that draws a grid like the following::
-
-
- + - - - - + - - - - +
- | | |
- | | |
- | | |
- | | |
- + - - - - + - - - - +
- | | |
- | | |
- | | |
- | | |
- + - - - - + - - - - +
-
-Hint: to print more than one value on a line, you can print a comma-separated sequence:
-``print '+', '-'``
-
-If the sequence ends with a comma, Python leaves the line unfinished, so the value printed next appears on the same line.
-
-::
-
- print '+',
- print '-'
-
-The output of these statements is ``'+ -'``.
-
-A print statement all by itself ends the current line and goes to the next line.
-
-
-Part 2:
---------
-
-Write a function ``print_grid()`` that takes one integer argument
-and prints a grid like the picture above, BUT the size of the
-grid is given by the argument.
-
-For example, ``print_grid(11)`` prints the grid in the above picture.
-
-This problem is underspecified. Do something reasonable.
-
-Hints:
-
- A character is a string of length 1
-
- ``s + t`` is string ``s`` followed by string ``t``
-
- ``s * n`` is string ``s`` replicated n times
-
-Part 3:
-----------
-
-Write a function that draws a similar grid with three rows and three columns.
-
-(what to do about rounding?)
-
-
-
diff --git a/slides_sources/old_versions/week-01/homework1_solution.py b/slides_sources/old_versions/week-01/homework1_solution.py
deleted file mode 100644
index 1154348..0000000
--- a/slides_sources/old_versions/week-01/homework1_solution.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Chris' solution to the week 1 homework problem.
-
-Note that we hadn't talked about loops yet, so this is a solution with no loops.
-
-Note also that there is nore than one way to skin a cat -- or code a function
-"""
-
-
-def print_grid(size):
- """
- print a 2x2 grid with a total size of size
-
- :param size: total size of grid -- it will be rounded if not onemore than a multiple of 2
- """
- N = 2
- s = int( (size-1) // 2 ) # size of one grid box
- print "s:", s
- # top row
- top = ('+ ' + '- '*s)*N + '+' + '\n'
- middle = ('| ' + ' '*2*s)*N + '|' + '\n'
-
- row = top + middle*s
-
- grid = row*N + top
-
- print grid
-
-
-def print_grid2(N, s):
- """
- print a NxN grid with each box of size s
-
- :param N: number of grid boxes (row and column)
-
- :param s: size of each grid box
- """
- # top row
- top = ('+ ' + '- '*s)*N + '+' + '\n'
- middle = ('| ' + ' '*2*s)*N + '|' + '\n'
-
- row = top + middle*s
-
- grid = row*N + top
-
- print grid
-
-def print_grid3(size):
- """
- same as print_grid, but calling print_grid2 to do the work
- """
- N = 2
- s = (size-1) / 2 # size of one grid box
- print_grid2(N, s)
-
-print_grid(11)
-print_grid(7)
-
-print_grid2(3,3)
-print_grid2(3,5)
-
-print_grid3(11)
diff --git a/slides_sources/old_versions/week-01/presentation-week01.pdf b/slides_sources/old_versions/week-01/presentation-week01.pdf
deleted file mode 100644
index c5d2f64..0000000
Binary files a/slides_sources/old_versions/week-01/presentation-week01.pdf and /dev/null differ
diff --git a/slides_sources/old_versions/week-01/presentation-week01.tex b/slides_sources/old_versions/week-01/presentation-week01.tex
deleted file mode 100644
index fea3ce0..0000000
--- a/slides_sources/old_versions/week-01/presentation-week01.tex
+++ /dev/null
@@ -1,1228 +0,0 @@
-\documentclass{beamer}
-%\usepackage[latin1]{inputenc}
-\usetheme{Warsaw}
-\title[Intro to Python: Week 1]{Introduction to Python\\ General Introduction, Basic Data Types, Functions}
-\author{Christopher Barker}
-\institute{UW Continuing Education}
-\date{October 1, 2013}
-
-\usepackage{listings}
-\usepackage{hyperref}
-
-\begin{document}
-
-\begin{frame}
-\titlepage
-\end{frame}
-
-\begin{frame}
-\frametitle{Table of Contents}
-%\tableofcontents[currentsection]
-\tableofcontents
-\end{frame}
-
-\section{Intro to the Class}
-
-\begin{frame}{Instuctors}
-
-{\large
-Christopher Barker: \url{PythonCHB@gmail.com}
-
-
-\vfill
-{\bf TA:}
-
-Fulvio Casali: \url{fulviocasali@gmail.com}
-
-\vfill
-But for the next two weeks:
-
-\vfill
-Josh Rakita: \url{joshuarakita@gmail.com}
-
-\vfill
-(Fulvio is at the Plone conference in Brazil)
-
-\vfill
-
-}
-\end{frame}
-
-
-\begin{frame}{Chris' History}
-
-{\Large First computer:}
-\begin{itemize}
- \item Commodore Pet -- 8k RAM
- \begin{itemize}
- \item Basic
- \end{itemize}
-\end{itemize}
-
-
-{\Large High School:}
-\begin{itemize}
- \item PDP 11 -- paper printer terminal 200baud modem
- \begin{itemize}
- \item Basic
- \end{itemize}
-\end{itemize}
-
-
-{\Large College: }
-\begin{itemize}
- \item Pascal: VAX/VMS 750
- \item Scheme: Unix VAX 780
-\end{itemize}
-
-\vspace{0.25in}
-
-
-Then a long Break: Theater Arts Major, Scenery, Lighting...
-
-\end{frame}
-
-
-
-\begin{frame}{Chris' History (cont) }
-
- {\Large Back to School: PhD Coastal Engineering }
- \begin{itemize}
- \item DOS / Windows 3.1
- \begin{itemize}
- \item FORTRAN
- \item MATLAB
- \item Discovered Linux (RedHat 2.0)
- \end{itemize}
- \end{itemize}
-
- \vspace{0.25in}
-
- {\Large Now: }
- \begin{itemize}
- \item Oceanographer for NOAA
- \item Oil Spill Modeling
- \item Software Development
- \end{itemize}
-
- \vspace{0.25in}
- {\Large Gave TCL a try............ }
-
- \vspace{0.15in}
- {\Large Gave Perl a try............}
-
-\end{frame}
-
-\begin{frame}{Chris' History}
-
-{\Large Discovered Python in 1998}
-\begin{itemize}
- \item It could do what Perl could do,
- \begin{itemize}
- \item what TCL could do, what MATLAB could do,
- \end{itemize}
- \item But I liked it -- it fit my brain
-\end{itemize}
-
-\vspace{0.1in}
-
-{\Large My Python use now:}
-\begin{itemize}
- \item Lots of text file crunching / data processing
- \item Desktop GUIs (wxPython)
- \item computational code
- \item wrapping C/C++ code
- \item web apps (Pylons, Pyramid)
- \item GIS processing
- \item Ask me about ``BILS''
-\end{itemize}
-\end{frame}
-
-
-\begin{frame}{Who are you?}
-
-{\Large A bit about you:}
-\begin{itemize}
- \item name
- \item What do you do at your day job?
- \item programing background (languages)
-\end{itemize}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Class Structure}
-
-{\LARGE github project} \\
-\url{https://github.com/UWPCE-PythonCert/IntroToPython}
-
-\vspace{0.2in}
-{\large Syllabus:} \\
-\url{https://github.com/UWPCE-PythonCert/IntroToPython/blob/master/Syllabus.rst}
-
-\vspace{0.2in}
-{\large Presentations, Sample Code, etc:}
-
-{\small
-\begin{verbatim}
-git clone https://github.com/UWPCE-PythonCert/IntroToPython.git
-\end{verbatim}
-}
-\end{frame}
-
-\begin{frame}{Class Structure}
-
-{\large \bf Class Time:}
- \begin{itemize}
- \item Some lecture, lots of demos
- \item Lab time: lots of hand-on practice
- \item Later, Rinse, Repeat.....
- \end{itemize}
-
-Interrupt me with questions -- please!
-
-(Some of the best learning promted by questions)
-
-\vfill
-{\large \bf Homework:}
- \begin{itemize}
- \item Assigned at each class
- \item You are adults -- it's up to you to do it
- \item Send it to me if you want me to review it
- \item I'll review at the next class
- \end{itemize}
-
-\end{frame}
-
-\begin{frame}{Lightning Talks}
-
-{\Large Lightning Talks}
-\begin{itemize}
- \item 5 minutes (including setup) - no kidding!
- \item Every student will give one
- \item Purposes: introduce yourself, share interests, also show Python applications
- \item Any topic you like, that is related to Python -- according to you!
-\end{itemize}
-\end{frame}
-
-
-\begin{frame}{Mailing list and Office Hours}
-
-\vfill
-{\Large We've set up a google group\\
- -- you will all be invited to join.}
-
-\url{programming-in-python@googlegroups.com}
-
-\vfill
-{\Large ``Office Hours'' \\
--- Useful? Will you come?}
-
-\vfill
-
-\end{frame}
-
-
-
-
-\begin{frame}{Python Ecosystem}
-
-{\Large Used for:}
-\begin{itemize}
- \item CS education (this course!)
- \item Application scripting (GIS, GNU Radio, Blender...)
- \item Systems administration and ``glue''
- \item Web applications (Django etc. etc. etc.)
- \item Scientific/technical computing (a la MATLAB, Mathematica, also BioPython etc. ..)
- \item Software tools (automated software testing, distributed version control, ...)
- \item Research (natural language, graph theory, distributed computing, ...)
-\end{itemize}
-
- An unusually large number of niches -- versatile
-\end{frame}
-
-\begin{frame}{Python Ecosystem}
-
-{\Large Used by:}
-\begin{itemize}
- \item Beginners
- \item Professional software developers, computer system administrators, ...
- \item Professionals OTHER THAN computer specialists: biologists, urban planners, ....
-\end{itemize}
-\vspace{0.25in}
- An unusually large number of types of users -- versatile\\[0.25in]
- You can be productive in Python WITHOUT full-time immersion!
-\end{frame}
-
-
-\begin{frame}{Python Features}
-
-{\Large Gets many things right:}
-\begin{itemize}
- \item Readable -- looks nice, makes sense
- \item No ideology about best way to program --
- object-oriented programming, functional, etc.
- \item No platform preference -- Windows, Mac, Linux, ...
- \item Easy to connect to other languages -- C, Fortran - essential for science/math
- \item Large standard library
- \item Even larger network of external packages
- \item Countless conveniences, large and small, make it pleasant to work with
-\end{itemize}
-\end{frame}
-
-\section{What is Python?}
-
-\begin{frame}{What is Python?}
- \begin{itemize}
- \item Dynamic
- \item Object oriented
- \item Byte-compiled
- \item interpreted
- \item ....
- \end{itemize}
-\end{frame}
-
-
-\begin{frame}{Python Features}
-
-{\Large Features:}
-
-\begin{itemize}
- \item Unlike C, C++, C\#, Java ... More like Ruby, Lisp, Perl, Matlab, Mathematica ...
- \item Dynamic - no type declarations
- \begin{itemize}
- \item programs are shorter
- \item programs are more flexible
- \item less code means fewer bugs
- \end{itemize}
- \item Interpreted - no separate compile, build steps - programming process is simpler
-\end{itemize}
-
-\end{frame}
-
-\begin{frame}[fragile]{What's a Dynamic language}
-
-{Strong, Dynamic typing.}
-
- - Type checking and dispatch happen at run-time
-
-\vspace{0.25in}
-{\Large \verb!X = A+B!}
-\vspace{0.1in}
-\begin{itemize}
-\pause
- \item What is A?
- \item What is B?
- \item What does it mean to add them?
-\vspace{0.2in}
-\pause
- \item A and B can change at any time before this process
-\end{itemize}
-
-\end{frame}
-
-
-\begin{frame}{Duck Typing}
-
-\vspace{0.25in}
-{\center \Large ``If it looks like a duck, and quacks like a duck -- it's probably a duck''}
-
-\pause
-\vspace{0.5in}
-{\center \Large If an object behaves as expected at run-time, it's the right type.}
-
-\end{frame}
-
-
-
-\begin{frame}{Python Versions}
-
-{\Large Python 2.*}
-
-``Classic'' Python -- evolved from original
-
-\vfill
-{\Large Python 3.* (``py3k'')}
-
-Updated version -- removed the ``warts'' allowed to break code
-
-(but really not all that different)
-
-Adoption is growing fast, but a few key packages still not supported.
-(\url{https://python3wos.appspot.com/})
-
-\vfill
-This program uses Python 2.7 not Python 3 (next year?)
-
-\end{frame}
-
-
-\begin{frame}{Implementations}
-
-\begin{itemize}
- \item Jython (JVM)
- \item Iron Python (.NET)
- \item PyPy -- Python written in Python (actually RPy...)
-\end{itemize}
-
-\vspace{0.25in}
- We will use CPython 2.7 from python.org for this course.
-
-\end{frame}
-
-
-\begin{frame}{A Tiny Bit of History}
-
-Invented/developed by Guido van Rossum in 1989 -- first version was written on
-a Mac. Time of origin similar to TCL and Perl.
-
- \begin{columns}[t] % contents are top vertically aligned
- \begin{column}[T]{4.5cm} % each column can also be its own environment
- \begin{tabular}[pos]{lr}
- Date & Version \\
- \hline
- Dec 1989 & started \\
- Feb 1991 & 0.9.0 \\
- Jan 1994 & 1.0.0 \\
- Apr 1999 & 1.5.2 \\
- Sept 2006 & 2.5 \\
- Dec 2008 & 3.0 \\
- Jul 2010 & 2.7, 3.2 \\
- Sept 2013 & 2.7.5, 3.3.2
- \end{tabular}
- \end{column}
- \begin{column}[T]{5.5cm} % alternative top-align that's better for graphics
- GvR at Google -- still the BDFL \\
- \includegraphics[height=2.0in]{GvR.jpg}
- \end{column}
- \end{columns}
-Code swarm for Python history: \url{http://vimeo.com/1093745}
-
-\end{frame}
-
-\begin{frame}[fragile]{Using Python}
-
-{All you need for Python:}
-\begin{itemize}
- \item A good programmer's text editor
- \begin{itemize}
- \item Good Python mode
- \item Particularly indentation!
- \end{itemize}
- \item The command line to run code
- \item The interactive shell
- \begin{itemize}
- \item regular interpreter
- \item \verb+IPython+ is an excellent enhancement\\
- \url{http://ipython.org/}
- \end{itemize}
-\end{itemize}
-
-\vspace{.2in}
-There are lots of Editors, IDES, etc.:\\
- maybe you'll find one you like.
-
-\end{frame}
-
-\begin{frame}[fragile]{Running Python Code}
-
-\begin{itemize}
- \item At an interpreter prompt:\\
- \begin{verbatim}
- $ python
- >>> print 'Hello, world!'
- Hello, world!
- \end{verbatim}
-\end{itemize}
-
-\end{frame}
-
-\begin{frame}[fragile]{Running Python Modules}
-
-
-{\Large Running Modules}\\[0.05in]
--- a file that contains Python code, filename ends with \verb+.py+
-
- \begin{enumerate}
- \item \verb+$ python hello.py+ -- must be in current working directory
-
- \item \verb+$ python -m hello+ -- any module on PYTHONPATH anywhere on the system
-
- \item \verb+$ ./hello.py+ -- put \verb+#!/usr/env/python+ at top of module (Unix)
-
- \item \verb+$ python -i hello.py+ -- import module, remain in interactive session
-
- \item \verb+>>> import hello+ -- at the python prompt -- importing a module executes its contents
-
- \item \verb+run hello.py+ -- at the IPython prompt -- running a module brings the names into the interactive namespace
-\end{enumerate}
-
-\end{frame}
-
-\begin{frame}[fragile]{Documentation}
-
-{\Large \url{www.python.org} docs:}
-
-\url{http://docs.python.org/index.html}
-
-\vspace{0.25in}
-{\Large Particularly the library reference:}
-
-\url{http://docs.python.org/library/index.html}
-
-\vspace{0.25in}
-(The tutorial is pretty good, too)
-
-\end{frame}
-
-\begin{frame}[fragile]{PEPs}
-
-{\large \url{http://www.python.org/dev/peps/} }
-
-\vspace{0.25in}
-\begin{description}
- \item[PEP 1] PEP Purpose and Guidelines
- \item[PEP 8] Style Guide for Python Code
- \item[PEP 20] the Zen of Python (\verb+import this+)
-\end{description}
-
-\end{frame}
-
-\begin{frame}[fragile]{pydoc}
-
-{Suite of tools for processing ``docstrings''}
-
-And an online source at the interpreter:
-
-\begin{verbatim}
->>> from pydoc import help
->>> help(int)
-Help on class int in module __builtin__:
-
-class int(object)
- | int(x[, base]) -> integer
- |
- | Convert a string or number to an integer, if possible. A floating point
- ...
-\end{verbatim}
-or: \verb+$ pydoc+
-
-(but I prefer IPython's \verb+?+)
-
-\end{frame}
-
-\begin{frame}[fragile]{Documentation}
-
-{\LARGE\bf google}
-
-\vspace{0.25in}
-But be careful!
-
-\vspace{0.25in}
-Lots of great info out there!
-
-\vspace{0.25in}
-Most of it is opinionated and out of date.\\
-(might still be correct, though!)
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Lab}
-
-\vfill
-A (very) Quick tour of the gitHub project
-
-\vfill
-\url{https://github.com/UWPCE-PythonCert/IntroToPython}
-
-\vfill
-{\small
-\url{https://github.com/UWPCE-PythonCert/IntroToPython.git}
-}
-\vfill
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Lab}
-
-{\Large Getting everyone on-line and at a command line.}
-
-\begin{itemize}
- \item Do a \verb+git clone+ of the project
- \item Start up the Python interpreter:\\
- \verb+$ python+ [\verb=ctrl+D= (\verb|ctrl+Z| on Windows)or \verb|exit()| to exit]
- \item Run \verb+hello.py+ (in the \verb+week-01/code+ dir)
- \item Open \verb|hello.py| in your editor, change it, and save it.
- \begin{itemize}
- \item (Optional) Start up \verb+IPython+ \\
- \verb+$ ipython+ ( also \verb=ctrl+D=, etc. to exit )
- \item Run \verb+hello.py+ in \verb+IPython+
- \item use \verb+?+ in \verb+IPython+ on anything...
- \end{itemize}
- \item if you have time:\\
-\url{http://learnpythonthehardway.org/book/ex1.html}\\
-\url{http://learnpythonthehardway.org/book/ex2.html}
-
-...
-
-\end{itemize}
-
-\end{frame}
-
-
-\section{Values, Expressions, and Types}
-
-\begin{frame}[fragile]{Code structure}
-
-\vfill
-{\large Each line is a piece of code}
-
-\vfill
-{\large {\bf Comments:} everything following a \verb|#| is a comment}
-
-
-\vfill
-{\large {\bf Expression:} something that results in a value: \verb|3+4|}
-
-\vfill
-{\large {\bf Statement:} Line of code that does not return a value: \\
- \verb|print "this"|}
-
-\vfill
-{\large Blocks of code are delimited by a colon and indentation:
-\begin{verbatim}
-def a_function():
- a_new_code_block
-end_of_the_block
-\end{verbatim}
-}
-
-\vfill
-\end{frame}
-
-\begin{frame}[fragile]{The print statement}
-
-{\large
-Kind of obvious, but handy when playing with code:
-
-\vfill
-\verb|print something| prints \verb|something| to the console.
-
-\vfill
-Can print multiple things: \verb|print "the value is", 5|
-
-\vfill
-Automatically adds a newline.
-
-\vfill
-You can suppress the newline with a comma: \\
-\verb|print "the value is",|\\
-\verb|print 5|
-
-\vfill
-Any python object can be printed\\
-(though it might not be pretty...)
-
-}
-
-\end{frame}
-
-\begin{frame}[fragile]{Values, expressions, and types}
-
-{\large Values (data) vs. variables (names with values)}
-
-\begin{itemize}
- \item Values are pieces of unnamed data: \verb+42, 'Hello, world',+
-
- \item In Python, all values are objects\\
- Try \verb+dir(42)+ - lots going on behind the curtain! (demo)
-
- \item Every value belongs to a type: integer, float, str, ... (demo)
-
- \item An expression is made up of values and operators, is evaluated to
- produce a value: \verb!2 + 2!, etc.
-
- \item Python interpreter can be used as a calculator to evaluate expressions (demo)
-
- \item Integer vs. float arithmetic (demo)
-
- \item Type errors - checked at run time only (demo)
-
- \item Type conversions (demo)
-\end{itemize}
-
-\end{frame}
-
-\begin{frame}[fragile]{Variables}
-
-{\large Variables are names for values (objects)}
-
--- Variables don't have a type; values do --
-this is where the dynamic comes from
-
-\begin{verbatim}
->>> type(42)
-
->>> type(3.14)
-
->>> a = 42
->>> b = 3.14
->>> type(a)
-
->>> a = b
->>> type(a)
-
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{Assignment}
-
-{\Large Assignment is really name binding: }
-\begin{itemize}
- \item Attaching a name to a value
- \item A value can have many names (or none!)
-\end{itemize}
-
-\vfill
-{\large \verb|=| assigns (binds a name)}
-
-\vfill
-{\large \verb|+=| also an assignment: \verb|a += 1| same as \verb|a = a+1|}
-
-\hspace{0.1in}also: \verb|-=, *=, /=, **=, \%=|
-
-(not quite -- really in-place assignment for mutables....)
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Multiple Assignment}
-
-{\large You can assign multiple variables from multiple expressions in one statement}
-
-\vfill
-\verb|i, j = 2 + x, 3 * y| \# commas separate variables on lhs, exprs on rhs
-
-\vfill
-{\large Python evaluates all the expressions on the right before doing any assignments}
-
-\vfill
-\verb|i, j = j, i| \# parlor trick: swap in one statement
-
-\vfill
-\large{These are just tricks, but multiple assignment is more helpful in other contexts}
-
-\vfill
-(more on what's really going on later...)
-
-\vfill
-(demo)
-\end{frame}
-
-
-\begin{frame}[fragile]{Deleting}
-
-{\large You can't actually delete anything in python...}
-
-\vfill
-
-{\large \verb|del| only unbinds a name}
-
-\vfill
-\begin{verbatim}
-a = 5
-b = a
-del a
-\end{verbatim}
-
-The object is still there...python will only delete it if there are no references to it.
-
-\vfill
-(demo)
-
-\end{frame}
-
-
-\begin{frame}[fragile]{equality and identity}
-
-{\large
-\vspace{0.1in}
-\verb|==| checks equality
-
-\vspace{0.1in}
-\verb|is| checks identity
-
-\vspace{0.1in}
-\verb|id()| queries identity
-}
-
-\vspace{0.2in}
-(demo)
-
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Operator Precedence}
-
-{Operator Precedence determines what evaluates first:}
-
-\verb^4 + 3 * 5 != (4 + 3) * 5^ -- Use parentheses !
-
-Precedence of common operators:
-
-Arithmetic \\
-\verb!**! \\
-\verb!+x, -x! \\
-\verb!*, /, %! \\
-\verb!+, -! \\
-
-Comparisons:
-
-\verb^<, <=, >, >=, !=, ==^
-
-Boolean operators:
-
-\verb!or, and, not!
-
-Membership and Identity:
-
-\verb!in, not in, is, is not!
-
-\end{frame}
-
-
-
-\begin{frame}[fragile]{string literals}
-
-\begin{verbatim}
-'a string'
-"also a string"
-"a string with an apostophe: isn't it cool?"
-' a string with an embedded "quote" '
-""" a multi-line
-string
-all in one
-"""
-"a string with an \n escaped character"
-
-r'a "raw" string the \n comes through as a \n'
-
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{key words}
-
-{\Large A bunch:}
-
-\vspace{0.2in}
-\begin{verbatim}
-and del from not while
-as elif global or with
-assert else if pass yield
-break except import print
-class exec in raise
-continue finally is return
-def for lambda try
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{and the built-ins..}
-
-{\Large Try this:
-
-\vspace{0.2in}
-\verb+>>> dir(__builtins__)+
-
-}
-\end{frame}
-
-
-\begin{frame}[fragile]{Lab}
-
-{\large From LPTHW }
-
-\vspace{0.2in}
-\url{http://learnpythonthehardway.org/book/ex3.html}
-
-\vspace{0.2in}
-\url{http://learnpythonthehardway.org/book/ex4.html}
-
-\vspace{0.2in}
-\url{http://learnpythonthehardway.org/book/ex5.html}
-
-(and 6 -- 8 if you get bored...)
-
-\end{frame}
-
-\section{Functions}
-
-\begin{frame}[fragile]{Functions}
-
-\vfill
-{\Large What is a function?}
-
-\vfill
-{\large A function is a self-contained chunk of code}
-
-\vfill
-{\large You use them when you need the same code to run multiple times,
-or in multiple parts of the program.}
-
-\hspace{1in}{\Large (DRY) }
-
-\vfill
-{\large Or just to keep the code clean}
-
-\vfill
-{\large Functions can take and return information}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Functions}
-
-{\Large Minimal Function does nothing}
-
-\begin{verbatim}
-def ():
-
-\end{verbatim}
-
-\vspace{0.25in}
-{\Large Pass Statement (Note the indentation!)}
-\begin{verbatim}
-def ():
- pass
-\end{verbatim}
-
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: def}
-
-{\large \verb+def+ is a statement:}
-\begin{itemize}
- \item it is executed
- \item it creates a local variable
-\end{itemize}
-
-\vspace{0.2in}{\largefunction defs must be executed before the functions can be called}
-
-\pause
-\vspace{0.2in}{\largefunctions call functions -- this makes a stack -- that's all a trace back is}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: Call Stack}
-
-\begin{verbatim}
-def exceptional():
- print "I am exceptional!"
- print 1/0
-def passive():
- pass
-def doer():
- passive()
- exceptional()
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: Tracebacks}
-
-\begin{verbatim}
-I am exceptional!
-Traceback (most recent call last):
- File "functions.py", line 15, in
- doer()
- File "functions.py", line 12, in doer
- exceptional()
- File "functions.py", line 5, in exceptional
- print 1/0
-ZeroDivisionError: integer division or modulo by zero
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: return}
-
-{\Large Every function ends with a \verb+return+}
-
-\begin{verbatim}
-def five():
- return 5
-\end{verbatim}
-
-{\Large Actually simplest function}
-\begin{verbatim}
-def fun():
- return None
-\end{verbatim}
-\end{frame}
-
-\begin{frame}[fragile]{Functions: return}
-
-{\Large if you don't put \verb+return+ there, python will:}
-
-\begin{verbatim}
-In [123]: def fun():
- .....: pass
-In [124]: result = fun()
-In [125]: print result
-None
-\end{verbatim}
-
-{\Large note that the interpreter eats \verb+None+}
-
-\end{frame}
-
-
-\begin{frame}{Functions: return}
-
-\vspace{0.25in}
-{\Large Only one return statement will ever be executed.}
-
-\pause
-\vspace{0.25in}
-{\Large Ever.}
-
-\pause
-\vspace{0.25in}
-{\Large Anything after a executed return statement will never get run.}
-
-\vspace{0.25in}
-{\Large This is useful when debugging! }
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Functions: return}
-
-{\Large functions can return multiple results}
-
-\begin{verbatim}
-def fun():
- return 1,2,3
-
-In [149]: fun()
-Out[149]: (1, 2, 3)
-\end{verbatim}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: return}
-
-{\Large remember multiple assignment?}
-
-\begin{verbatim}
-In [150]: x,y,z = fun()
-
-In [151]: x
-Out[151]: 1
-
-In [152]: y
-Out[152]: 2
-
-In [153]: z
-Out[153]: 3
-\end{verbatim}
-
-\end{frame}
-
-% \begin{frame}[fragile]{Functions: return}
-
-% {\Large Actually a tuple of results...}
-
-% \begin{verbatim}
-% In [154]: t = fun()
-
-% In [155]: t
-% Out[155]: (1, 2, 3)
-
-% In [156]: type(t)
-% Out[156]: tuple
-% \end{verbatim}
-
-% {\Large Multiple assignment is really "tuple unpacking"}
-
-% \end{frame}
-
-
-\begin{frame}[fragile]{Functions: parameters}
-
-{\Large function parameters: in definition}
-
-\begin{verbatim}
-def fun(x, y, z):
- q = x + y + z
- print x, y, z, q
-\end{verbatim}
-
-{\Large x, y, z are local names -- so is q}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: arguments}
-
-{\Large function arguments: when calling}
-
-\begin{verbatim}
-def fun(x, y, z):
- print x, y, z
-\end{verbatim}
-\begin{verbatim}
-In [138]: fun(3, 4, 5)
-
-3 4 5
-\end{verbatim}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Functions: local vs. global}
-
-\begin{verbatim}
-x = 32
-y = 33
-z = 34
-def fun(y, z):
- print x, y, z
-\end{verbatim}
-\begin{verbatim}
-In [141]: fun(3,4)
-
-32 3 4
-\end{verbatim}
-{\Large x is global, y, z are local}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: local vs. global}
-
-\begin{verbatim}
-x = 3
-def f():
- y = x
- x = 5
- print x
- print y
-\end{verbatim}
-
-{\Large What happens when we call \verb+f()+?}
-
-\end{frame}
-
-\begin{frame}[fragile]{Functions: local vs. global}
-
-{\Large Gotcha!}
-
-\begin{verbatim}
-In [134]: f()
----------------------------------------------------------------------------
-UnboundLocalError Traceback (most recent call last)
-/Users/Chris/ in f()
- 1 def f():
-----> 2 y = x
- 3 x = 5
- 4 print x
- 5 print y
-\end{verbatim}
-
-{\Large you are going to assign x -- so it's local}
-
-\end{frame}
-
-\begin{frame}[fragile]{Scopes}
-
-\vspace{0.5in}
-{\LargeThere is a \verb+global+ statement}
-
-\pause
-\vspace{0.5in}
-{\LARGE Don't use it!}
-
-\end{frame}
-
-\begin{frame}[fragile]{Scopes}
-
-\vspace{0.5in}
-{\Largegood discussion of scopes:}
-
-\vspace{0.5in}
-\url{http://docs.python.org/tutorial/classes.html#python-‐scopes-‐and-‐namespaces}
-
-\end{frame}
-
-\begin{frame}[fragile]{Recursion}
-
-\vspace{0.5in}
-{\LargeRecursion is calling a function from itself.}
-
-\vspace{0.5in}
-{\LargeMax stack depth, function call overhead.}
-
-\vspace{0.5in}
-{\LargeBecause of these two(?), recursion isn't used {\bf that} often in Python.}
-
-\end{frame}
-
-\begin{frame}[fragile]{Lab: functions}
-
-{\Large write a function that:}
-\begin{itemize}
- \item takes a number and returns the square and cube of that number
- -- use variables to store the results
- \item takes a string and a number, and returns a new string containing the input string repeated the given number of times
- \item calls another function to do part of its job.
-
-\end{itemize}
-
-\end{frame}
-
-
-\section{Wrap Up}
-
-\begin{frame}{Lightning Talks}
-
-\vspace{0.5in}
-{\Large Assign times for lightning talks}
-
-\vspace{0.5in}
-\center{\Large Let's use Python for that!}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Homework}
-
-Recommended Reading:
-\begin{itemize}
- \item Think Python: Chapters 1--7 \\
- \item Dive Into Python: Chapters 1--3 \\
- \item LPTHW: ex. 1--10, 18-21 \\
-\end{itemize}
-
-\vfill
-Problems in \verb|week-01\homework.rst|
-
-\vfill
-Coding is the only way to learn to code:
-CodingBat exercises are a good way to build skills.
-\begin{itemize}
- \item visit \url{http://codingbat.com}
- \item sign up for an account and goto ‘prefs’ page and share To: \url{PythonCHB@gmailcom}
-\end{itemize}
-
-Do at least two exercises from CodingBat: Warmup-1
-
-\end{frame}
-
-\end{document}
-
-
diff --git a/slides_sources/old_versions/week-01/students.txt b/slides_sources/old_versions/week-01/students.txt
deleted file mode 100644
index 2bb8398..0000000
--- a/slides_sources/old_versions/week-01/students.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Antoun, Jo-Anne
-AuBuchon, Harlan
-Bae, Andrew
-Chan, Lawrence
-Chhen, Rithy
-Colwell, Kimberly
-Cypret, Luke
-Eaton, Sako
-Edson, Howard
-Flagg, Nate
-Gapasin, Anne-Lynn
-Grizzel, Travis
-Ivers, Brandon
-Kang, Dong
-Leblanc, Adam
-Moore, Blane
-Onen, Omer
-Parrish, Brent
-Pei, Guangyu
-Petrova, Maria
-Popish, Mario
-Rajagopalan, Sridharan
-Salkodu Parameshwar, Maitri
-Savage, Nathan
-Schmitz, Brian
-Small, Edward
-Smith, Richard
-Thach, Phuc
-Tran, Linh
-Warren, Catherine
-Werner, Steven
-Wright, Duane
diff --git a/slides_sources/old_versions/week-02/code/FizzBuzz.py b/slides_sources/old_versions/week-02/code/FizzBuzz.py
deleted file mode 100644
index d6a27c2..0000000
--- a/slides_sources/old_versions/week-02/code/FizzBuzz.py
+++ /dev/null
@@ -1,72 +0,0 @@
- #!/usr/bin/env python
-
-"""
-Fizz Buzz examples -- from most straightforward, to most compact.
-"""
-
-# basic approach:
-def fizzbuzz1(n):
- for i in range(1, n+1):
- if i%3 == 0 and i%5 == 0:
- print "FizzBuzz"
- elif i%3 == 0:
- print "Fizz"
- elif i%5 == 0:
- print "Buzz"
- else:
- print i
-
-def fizzbuzz2(n):
- """
- Why evaluate i%3 and i%5 twice?
- """
- for i in range(1, n+1):
- msg = ''
- if i%3 == 0:
- msg += "Fizz"
- if i%5 == 0:
- msg += "Buzz"
- if msg:
- print msg
- else:
- print i
-
-def fizzbuzz3(n):
- """
- use conditional expressions:
- """
- for i in range(1, n+1):
- msg = "Fizz" if i%3 == 0 else ''
- msg += "Buzz" if i%5 == 0 else ''
- print msg or i
-
-def fizzbuzz4(n):
- """
- the one liner
- """
- for i in range(1,n+1): print ( "Fizz" * (not (i%3)) + "Buzz" * (not (i%5)) ) or i
-
-def fizzbuzz_ruby(n):
- """
- This is a one-liner version inspired by the Ruby one-liner
- found here:
-
- http://www.commandercoriander.net/blog/2013/02/03/fizzbuzz-in-one-line
-
- This uses list comprehensions, and slicing, and is, well, pretty darn ugly!
-
- """
- for word in [ ("".join(["Fizz",][0:1-i%3]+["Buzz",][0:1-i%5]) or `i`) for i in range(1, n+1)]: print word
-
-
-fizzbuzz1(16)
-print
-fizzbuzz2(16)
-print
-fizzbuzz3(16)
-print
-fizzbuzz4(16)
-print
-fizzbuzz_ruby(16)
-
-
diff --git a/slides_sources/old_versions/week-02/code/codingbat.rst b/slides_sources/old_versions/week-02/code/codingbat.rst
deleted file mode 100644
index 9f3c5d7..0000000
--- a/slides_sources/old_versions/week-02/code/codingbat.rst
+++ /dev/null
@@ -1,50 +0,0 @@
-Coding Bat examples
-######################
-
-Warmup-1 > monkey_trouble
-============================
-
-We have two monkeys, a and b, and the parameters a_smile and b_smile indicate if each is smiling. We are in trouble if they are both smiling or if neither of them is smiling. Return True if we are in trouble::
-
- monkey_trouble(True, True) → True
- monkey_trouble(False, False) → True
- monkey_trouble(True, False) → False
-
-
-Warmup-1 > sleep_in
-=======================
-
-The parameter weekday is True if it is a weekday, and the parameter vacation is True if we are on vacation. We sleep in if it is not a weekday or we're on vacation. Return True if we sleep in.
-
-sleep_in(False, False) → True
-sleep_in(True, False) → False
-sleep_in(False, True) → True
-
-
-Warmup-1 > diff21
-=======================
-
-Given an int n, return the absolute difference between n and 21, except return double the absolute difference if n is over 21.
-
-diff21(19) → 2
-diff21(10) → 11
-diff21(21) → 0
-
-Warmup-1 > makes10
-======================
-
-Given 2 ints, a and b, return True if one if them is 10 or if their sum is 10.
-
-makes10(9, 10) → True
-makes10(9, 9) → False
-makes10(1, 9) → True
-
-Logic-1 > cigar_party
-======================
-
-When squirrels get together for a party, they like to have cigars. A squirrel party is successful when the number of cigars is between 40 and 60, inclusive. Unless it is the weekend, in which case there is no upper bound on the number of cigars. Return True if the party with the given values is successful, or False otherwise.
-
-cigar_party(30, False) → False
-cigar_party(50, False) → True
-cigar_party(70, True) → True
-
diff --git a/slides_sources/old_versions/week-02/code/codingbat_solutions.py b/slides_sources/old_versions/week-02/code/codingbat_solutions.py
deleted file mode 100644
index 130667a..0000000
--- a/slides_sources/old_versions/week-02/code/codingbat_solutions.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Coding Bat Example Solutions
-"""
-
-##############################
-## Warmup-1 > monkey_trouble
-
-def monkey_trouble(a_smile, b_smile):
- """
- really simple solution
- """
- if a_smile and b_smile:
- return True
- elif not a_smile and not b_smile:
- return True
- else:
- return False
-
-def monkey_trouble2(a_smile, b_smile):
- """
- slightly more sophisticated
- """
- if a_smile and b_smile or not (a_smile or b_smile):
- return True
- else:
- return False
-
-def monkey_trouble3(a_smile, b_smile):
- """
- conditional expression -- kind of ugly in this case
- """
- result = True if (a_smile and b_smile or not (a_smile or b_smile)) else False
- return result
-
-def monkey_trouble4(a_smile, b_smile):
- """
- direct return of boolean result
- """
- return a_smile and b_smile or not (a_smile or b_smile)
-
-##############################
-## Warmup-1 > sleep_in
-
-def sleep_in(weekday, vacation):
- """
- basic solution
- """
- if (not weekday) or vacation:
- return True
- else:
- return False
-
-def sleep_in2(weekday, vacation):
- """
- direct return of boolean result
- """
- return (not weekday) or vacation
-
-##################
-## Warmup-1 > diff21
-
-def diff21(n):
- """
- basic solution
- """
- if n > 21:
- return 2 * (n - 21)
- else:
- return 21 - n
-
-def diff21b(n):
- """
- direct return of conditional expression
- """
- return 2 * (n - 21) if n > 21 else 21-n
-
-
-###############
-## Warmup-1 > makes10
-
-def makes10(a, b):
- """
- Too easy to make a one-liner
- """
- return a == 10 or b == 10 or a+b == 10
-
-######################
-## Logic-1 > cigar_party
-
-def cigar_party(cigars, is_weekend):
- """
- basic solution
- """
- if is_weekend and cigars >= 40:
- return True
- elif 40 <= cigars <= 60:
- return True
- return False
-
-def cigar_party2(cigars, is_weekend):
- """
- some direct return of bool result
- """
- if is_weekend:
- return (cigars >= 40)
- else:
- return (cigars >= 40 and cigars <= 60)
-
-def cigar_party3(cigars, is_weekend):
- """
- conditional expression
- """
- return (cigars >= 40) if is_weekend else (cigars >= 40 and cigars <= 60)
diff --git a/slides_sources/old_versions/week-02/code/command_params.py b/slides_sources/old_versions/week-02/code/command_params.py
deleted file mode 100755
index 0076f3e..0000000
--- a/slides_sources/old_versions/week-02/code/command_params.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-import sys
-
-print sys.argv
-
diff --git a/slides_sources/old_versions/week-02/code/distance.py b/slides_sources/old_versions/week-02/code/distance.py
deleted file mode 100644
index 9989210..0000000
--- a/slides_sources/old_versions/week-02/code/distance.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-
-"""
-A version of TP's distance -- showing tuple unpacking
-
-"""
-
-import math
-
-something = 3
-
-# TP's version:
-def distance(x1, y1, x2, y2):
- dx = x2 - x1
- dy = y2 - y1
- dsquared = dx**2 + dy**2
- result = math.sqrt(dsquared)
- return result
-
-# my version:
-def distance2( pt1, pt2 ):
- dx = pt2[0] - pt1[0]
- dy = pt2[1] - pt1[1]
- dsquared = dx**2 + dy**2
- result = math.sqrt(dsquared)
- return result
-
-# my version:
-def distance3( (x1, y1), (x2, y2) ):
-
- dx = x2 - x1
- dy = y2 - y1
- dsquared = dx**2 + dy**2
- result = math.sqrt(dsquared)
- return result
diff --git a/slides_sources/old_versions/week-02/code/factorial.py b/slides_sources/old_versions/week-02/code/factorial.py
deleted file mode 100644
index fea9736..0000000
--- a/slides_sources/old_versions/week-02/code/factorial.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-
-def factorial(n):
- """
- computes the factorial of n
-
- :param n: an integer to compute the factorial of
-
- :returns: the factorial of n
- """
- # print "calling factorial, n=",n
- f = float(n)
- n = int(n)
- if n != f:
- print "factorial only works for integers:",
- return None
-
- if n == 0:
- return 1
- else:
- return n * factorial(n-1)
-
-
-# print "the factorial of 0 is:", factorial(0)
-# print "the factorial of 1 is:", factorial(1)
-# print "the factorial of 2 is:", factorial(2)
-# print "the factorial of 3 is:", factorial(3)
-# print "the factorial of 4 is:", factorial(4)
-
-#print "the factorial of 983 is:", factorial(983)
-
-#print "the factorial of 984 is:", factorial(984)
-
-#print "the factorial of 4L is:", factorial(4L)
-
-#print "the factorial of 1.5 is:", factorial(1.5)
-
-## checking types: -- is instance
diff --git a/slides_sources/old_versions/week-02/code/fib_solution.py b/slides_sources/old_versions/week-02/code/fib_solution.py
deleted file mode 100644
index 454d2c0..0000000
--- a/slides_sources/old_versions/week-02/code/fib_solution.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#/usr/bin/env python
-
-def fib(n):
- """
- recursive function that computes Fibonacci numbers
- """
- if n == 0:
- return 0
- elif n == 1:
- return 1
- else:
- return fib(n-1) + fib(n-2)
-
-def fib2(n):
- """
- non-recusive function that computes fibonacci numbers
- """
- if n == 0:
- return 0
- if n == 1:
- return 1
- else:
- minus_2 = 0
- minus_1 = 1
- for i in range(2, n+1):
- result = minus_2 + minus_1
- minus_2, minus_1 = minus_1, result
- return result
-
-
-print fib(0),
-print fib(1),
-print fib(2),
-print fib(3),
-print fib(4),
-print fib(5),
-print fib(6),
-print fib(7),
-
-
diff --git a/slides_sources/old_versions/week-02/homework.rst b/slides_sources/old_versions/week-02/homework.rst
deleted file mode 100644
index c423f5f..0000000
--- a/slides_sources/old_versions/week-02/homework.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-Homework: week 2 (due week 3)
-##############################
-
-Adapted from "Think Python": Chapter 6, excercise 5.
-
-
-The Ackermann function, A(m, n), is defined::
-
- A(m, n) =
- n+1 if m = 0
- A(m−1, 1) if m > 0 and n = 0
- A(m−1, A(m, n−1)) if m > 0 and n > 0.
-
-
-See http://en.wikipedia.org/wiki/Ackermann_function.
-
-Write a function named ack that evaluates Ackermann’s function.
-Use your function to evaluate ack(3, 4), which should be 125.
-
-What happens for larger values of m and n?
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-02/homework_gary.py b/slides_sources/old_versions/week-02/homework_gary.py
deleted file mode 100644
index 92d3dfb..0000000
--- a/slides_sources/old_versions/week-02/homework_gary.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Gary's solution to the ackerman function
-
-The only one that is not recursive.
-
-However, it still can't compute ack(m,n) for m,n > 3,4
- ... at least not in a reasonable time and memory
-"""
-
-
-def ack(m,n):
-
- # s is the stack to track
- s=[m, n]
- t = 1
- while True:
- if s[t-1] == 0: # m = 0
- t = t - 1
- s[t] = s[t + 1] + 1 # A (m,n) = n + 1
- elif s[t] == 0: # n = 0
- s[t] = 1
- s[t-1] = s[t-1] - 1 # A (m,n) = A (m-1, 1)
- else:
- s.insert(t + 1, s[t] - 1) # n-1 in A(m,n-1)
- s[t] = s[t - 1] # m in A(m,n-1)
- s[t - 1] = s[t - 1] - 1 # m-1 in A(m-1, A(m, n-1))
- t = t + 1 # Try to calculated A (m, n-1)
- if not t:
- break
- print "ack(%d,%d) = %d"%(m,n,s[0])
-
-ack(2, 3)
-#ack(3, 4)
-
diff --git a/slides_sources/old_versions/week-02/homework_solution.py b/slides_sources/old_versions/week-02/homework_solution.py
deleted file mode 100644
index 2420584..0000000
--- a/slides_sources/old_versions/week-02/homework_solution.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/env python
-
-"""
-Chris' Solution to The Ackermann function
-"""
-
-def ack(m,n):
- """
- Solution to the Ackerman function
-
- http://en.wikipedia.org/wiki/Ackermann_function
-
- This one simply follows the logic laid out in the definition
-
- """
-
- if m<0 or n<0:
- return "Solution is not Defined"
-
- if m == 0:
- return n+1
- elif n == 0 and m > 0:
- return ack(m-1, 1)
- else:
- return ack(m-1, ack(m, n-1))
-
-
-def ack2(m,n):
- """
- Solution to the Ackerman function
-
- http://en.wikipedia.org/wiki/Ackermann_function
-
- This one uses nested conditional expressions:
- Don't try this at home!
-
- """
-
- if m<0 or n<0:
- return "Solution is not Defined"
- else:
- return n+1 if m==0 else (
- ack2(m-1, 1) if (n == 0 and m > 0) else (
- ack2(m-1, ack2(m, n-1) )
- )
- )
-
-
-
-# tests:
-print ack(2,3)
-
-for m in range(-1, 4):
- for n in range(-1, 5):
- print " the result of ack", (m,n), "is", ack(m,n)
- print " the result of ack2", (m,n), "is", ack2(m,n)
-
-
diff --git a/slides_sources/old_versions/week-02/homework_solution_memo.py b/slides_sources/old_versions/week-02/homework_solution_memo.py
deleted file mode 100644
index dba8e41..0000000
--- a/slides_sources/old_versions/week-02/homework_solution_memo.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/env python
-
-"""
-Chris' Solution to The Ackermann function
-"""
-
-all_calls = {}
-
-num_calls = 0
-num_calls2 = 0
-
-
-def ack(m,n):
- """
- Solution to the Ackerman function
-
- http://en.wikipedia.org/wiki/Ackermann_function
-
- This one directly follows the logic laid out in the definition
-
- """
-
- # I prefer to check bounds up front:
- # this really should raise an exception,
- # but we haven't covered that yet in class.
-
- global num_calls
- num_calls += 1
-
- if m<0 or n<0:
- return "Solution is not Defined"
-
- # print "ack called with:", m, n
- if (m,n) in all_calls:
- # print "already called with:", (m,n)
- return all_calls[(m,n)]
- else:
- if m == 0:
- result = n+1
- elif n == 0 and m > 0:
- result = ack(m-1, 1)
- else:
- result = ack(m-1, ack(m, n-1))
- all_calls[(m,n)] = result
-
- return result
-
-
-def ack2(m,n):
- """
- Solution to the Ackerman function
-
- http://en.wikipedia.org/wiki/Ackermann_function
-
- This one uses nested conditional expressions:
- Don't try this at home!
-
- """
- global num_calls2
- num_calls2 += 1
-
- if m<0 or n<0:
- return "Solution is not Defined"
- else:
- return n+1 if m==0 else (
- ack2(m-1, 1) if (n == 0 and m > 0) else (
- ack2(m-1, ack2(m, n-1) )
- )
- )
-
-
-# tests:
-print "with saving intermediate results:"
-print ack(3,4)
-print "total number of calls:", num_calls
-
-print "without saving intermediate results:"
-print ack2(3,4)
-print "total number of calls:", num_calls2
-
-# for m in range(-1, 4):
-# for n in range(-1, 5):
-# print " the result of ack", (m,n), "is", ack(m,n)
-# print " the result of ack2", (m,n), "is", ack2(m,n)
-
-
diff --git a/slides_sources/old_versions/week-02/presentation-week02.pdf b/slides_sources/old_versions/week-02/presentation-week02.pdf
deleted file mode 100644
index 96b61e7..0000000
Binary files a/slides_sources/old_versions/week-02/presentation-week02.pdf and /dev/null differ
diff --git a/slides_sources/old_versions/week-02/presentation-week02.tex b/slides_sources/old_versions/week-02/presentation-week02.tex
deleted file mode 100644
index 6fc0465..0000000
--- a/slides_sources/old_versions/week-02/presentation-week02.tex
+++ /dev/null
@@ -1,948 +0,0 @@
-\documentclass{beamer}
-%\usepackage[latin1]{inputenc}
-\usetheme{Warsaw}
-\title[Intro to Python: Week 2]{Introduction to Python\\ Functions, Booleans, Modules}
-\author{Christopher Barker}
-\institute{UW Continuing Education}
-\date{October 8, 2013}
-%-------------------------------
-
-\usepackage{listings}
-\usepackage{hyperref}
-
-\begin{document}
-
-% ---------------------------------------------
-\begin{frame}
- \titlepage
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}
-\frametitle{Table of Contents}
-%\tableofcontents[currentsection]
- \tableofcontents
-\end{frame}
-
-
-\section{Review/Questions}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Review of Previous Class}
-
-\begin{itemize}
- \item Values and Types
- \item Expressions
- \item Intro to functions
-\end{itemize}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Lightning Talks}
-
-\vfill
-{\LARGE Lightning talks today:}
-
-\vfill
-{\Large
-Jo-Anne Antoun
-
-\vfill
-Omer Onen
-
-\vfill
-Ryan Small
-
-\vfill
-Catherine Warren
-}
-\vfill
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Homework review}
-
- \vfill
- {\Large Homework Questions? }
-
- \vfill
- {\Large To loop or not to loop?}
-
- \vfill
- {\Large Build up strings, then print...}
-
- \vfill
- {\Large My Solution}
-
- \vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Stuff brought up by homework}
-
- \vfill
- {\Large Bytecode and \verb|*.pyc| }
-
- \vfill
- {\Large Please send me code:
- \begin{itemize}
- \item Enclosed in an email
- \item With your name at the beginning of the filename: \verb|chris_problem1.py|
- \end{itemize}
- }
-
- \vfill
- {\Large PEP 8}
-
- \vfill
- {\Large Repeating variable names in nested loops}
-
-
-\end{frame}
-
-
-\section{Quick Intro to Basics}
-
-\begin{frame}[fragile]{Basics}
-
-\vfill
-{\LARGE It turns out you can't really do much at all without at least a container type, conditionals and looping...}
-\vfill
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{if}
-
-{\Large Making Decisions...}
-\begin{verbatim}
-if a:
- print 'a'
-elif b:
- print 'b'
-elif c:
- print 'c'
-else:
- print 'that was unexpected'
-\end{verbatim}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{if}
-
-{\Large Making Decisions...}
-\begin{verbatim}
-if a:
- print 'a'
-elif b:
- print 'b'
-
-## versus...
-
-if a:
- print 'a'
-if b:
- print 'b'
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{switch?}
-
-\vfill
-{\Large No switch/case in Python}
-
-\vfill
-{\Large use \verb|if..elif..elif..else|}
-
-\vfill
-
-(or a dictionary, or subclassing....)
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{lists}
-
-\vfill
-{\Large A way to store a bunch of stuff in order}
-
-\vfill
-{\large ``array'' in other languages}
-
-\vfill
-\begin{verbatim}
-a_list = [2,3,5,9]
-
-a_list_of_strings = ['this', 'that', 'the', 'other']
-\end{verbatim}
-
-\vfill
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{tuples}
-
-\vfill
-{\Large Another way to store an ordered list of things}
-
-\vfill
-\begin{verbatim}
-a_tuple = (2,3,4,5)
-
-a_tuple_of_strings = ('this', 'that', 'the', 'other')
-\end{verbatim}
-
-\vfill
-{\Large Often interchangeable with lists, but not always...}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{for}
-
-{\Large When you need to do something to everything in a sequence}
-
-\vfill
-\begin{verbatim}
->> a_list = [2,3,5,9]
-
->> for item in a_list:
->> print item
-2
-3
-5
-9
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{range() and for}
-
-{\Large When you need to do something a set number of times}
-
-\vfill
-\begin{verbatim}
->>> range(4)
-[0, 1, 2, 3]
->>> for i in range(6):
-... print "*",
-...
-* * * * * *
->>>
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{intricacies}
-
-\vfill
-{\Large This is enough to get you started.}
-
-\vfill
-{\Large Each of these have intricacies special to python}
-
-\vfill
-{\Large We'll get to those over the next couple classes}
-
-\vfill
-
-\end{frame}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{More on Functions}
-
-%-------------------------------
-\begin{frame}[fragile]{Functions: review}
-
-{\Large Defining a function:}
-
-\begin{verbatim}
-def fun(x, y):
- z = x+y
- return z
-\end{verbatim}
-
-{\Large x, y, z are local names}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Functions: local vs. global}
-
-\begin{verbatim}
-x = 32
-def fun(y, z):
- print x, y, z
-
-fun(3,4)
-
-32 3 4
-\end{verbatim}
-{\large x is global, y and z local}
-
-\vfill
-{\Large Use global variables mostly for constants}
-
-\end{frame}
-
-
-%----------------------------------
-\begin{frame}[fragile]{Recursion}
-
-\vfill
-{\LargeRecursion is calling a function from itself.}
-
-\vfill
-{\LargeMax stack depth, function call overhead.}
-
-\vfill
-{\LargeBecause of these two(?), recursion isn't used {\bf that} often in Python.}
-
-\vfill
-(demo: factorial)
-\end{frame}
-
-%----------------------------------
-\begin{frame}[fragile]{Tuple Unpacking}
-
-{\Large Remember: \verb| x,y = 3,4| ?}
-
-\vfill
-{\Large Really ``tuple unpacking'': \verb| (x, y) = (3, 4)|}
-
-\vfill
-{\Large This works in function arguments, too:}
-
-\begin{verbatim}
->>> def a_fun( (a, b), (c, d) ):
-... print a, b, c, d
-...
->>> t, u = (3,4), (5,6)
->>>
->>> a_fun(t, u)
-3 4 5 6
-\end{verbatim}
-(demo)
-\end{frame}
-
-
-%----------------------------------
-\begin{frame}[fragile]{Lab: more with functions}
-
-{\Large Write a function that:}
-\begin{itemize}
- \item computes the distance between two points:\\
- dist = sqrt( (x1-x2)**2 + (y1-y2)**2 )\\
- using tuple unpacking...
- \item Take some code with functions, add this to each function:\\
- \verb|print locals()|
- \item Computes the Fibonacci series with a recursive function:\\
- f(0) = 0; f(1) = 1\\
- f(n) = f(n-1) + f(n-2)\\
- 0, 1, 1, 2, 3, 5, 8, 13, 21, ...\\
- (If time: a non-recursive version)
-\end{itemize}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Lightning Talks}
-
-\vfill
-{\LARGE Lightning Talks:}
-
-\vfill
-{\Large Jo-Anne Antoun }
-
-\vfill
-{\Large Omer Onen }
-
-\vfill
-\end{frame}
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Boolean Expressions}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Truthiness}
-
-{\Large What is true or false in Python?}
-
-\begin{itemize}
- \item The Booleans: \verb+True+ and \verb+False+
- \item ``Something or Nothing''
-\end{itemize}
-
-{\small \url{http://mail.python.org/pipermail/python-dev/2002-April/022107.html} }
-
-\end{frame}
-
-% -------------------------------
-\begin{frame}[fragile]{Truthiness}
-
-{\Large Determining Truthiness:}
-
-\vfill
-{\Large \verb+bool(something)+ }
-
-\vfill
-
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Boolean Expressions}
-
-{\Large \verb+False+ }
-
-\begin{itemize}
- \item \verb+None+
- \item \verb+False+
- \item zero of any numeric type, for example, \verb+ 0, 0L, 0.0, 0j+.
- \item any empty sequence, for example, \verb+ '', (), [] +.
- \item any empty mapping, for example, \verb+{}+.
- \item instances of user-defined classes, if the class defines a
- \verb+__nonzero__() or __len__()+ method, when that method
- returns the integer zero or bool value \verb+False+.
-\end{itemize}
-
-\url{http://docs.python.org/library/stdtypes.html}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Boolean Expressions}
-
-{ \LargeAvoid: }
-
-\vspace{0.1in}
-\verb+if xx == True:+
-
-\vfill
-{ \LargeUse: }
-
-\vspace{0.1in}
-\verb+if xx:+
-
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Boolean Expressions}
-
-{\Large ``Shortcutting''}
-
-\begin{verbatim}
- if x is false,
-x or y return y,
- else return x
-
- if x is false,
-x and y return x
- else return y
-
- if x is false,
-not x return True,
- else return False
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Boolean Expressions}
-
-{\Large Stringing them together}
-
-\begin{verbatim}
- a or b or c or d
-
-a and b and c and d
-\end{verbatim}
-
-{\Large The first value that defines the result is returned}
-
-\vfill
-(demo)
-\end{frame}
-
-
-%---------------------------------------------
-\begin{frame}[fragile]{Boolean returns}
-
-{\Large From CodingBat}
-\vfill
-\begin{verbatim}
-def sleep_in(weekday, vacation):
- if weekday == True and vacation == False:
- return False
- else:
- return True
-\end{verbatim}
-
-\end{frame}
-
-
-%---------------------------------------------
-\begin{frame}[fragile]{Boolean returns}
-
-{\Large From CodingBat}
-
-%\begin{verbatim}
-%def makes10(a, b):
-% return a == 10 or b == 10 or a+b == 10
-%\end{verbatim}
-
-\begin{verbatim}
-def sleep_in(weekday, vacation):
- return not (weekday == True and vacation == False)
-\end{verbatim}
-
-or
-
-\begin{verbatim}
-def sleep_in(weekday, vacation):
- return (not weekday) or vacation
-\end{verbatim}
-
-
-\end{frame}
-
-
-% -------------------------------------------
-\begin{frame}[fragile]{bools are ints?}
-
-{\Large bool types are subclasses of integer}
-
-\begin{verbatim}
-In [1]: True == 1
-Out[1]: True
-
-In [2]: False == 0
-Out[2]: True
-\end{verbatim}
-
-{\Large It gets weirder! }
-
-\begin{verbatim}
-In [6]: 3 + True
-Out[6]: 4
-\end{verbatim}
-
-(demo)
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Conditional expression}
-
-{\large A common idiom:}
-\begin{verbatim}
-if something:
- x = a_value
-else:
- x = another_value
-\end{verbatim}
-\vfill
-{\large Also, other languages have a ``ternary operator''}\\
-\hspace{0.2in}(C family: \verb|result = a > b ? x : y ;|)
-
-\vfill
-{ \Large \verb|y = 5 if x > 2 else 3| }
-
-\vfill
-{\large PEP 308:}
-(http://www.python.org/dev/peps/pep-0308/)
-
-\end{frame}
-
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-\begin{itemize}
- \item Look up the \verb+%+ operator. What do these do?\\
- \verb| 10 % 7 == 3 | \\
- \verb| 14 % 7 == 0 |
- \item Write a program that prints the numbers from 1 to 100 inclusive.
-But for multiples of three print ``Fizz'' instead of the number and for the
-multiples of five print ``Buzz''. For numbers which are multiples of both three
-and five print ``FizzBuzz'' instead.
-
- \item Re-write a couple CodingBat exercises, using a conditional expression
-
-
- \item Re-write a couple CodingBat exercises, returning the direct boolean results\\
-\end{itemize}
-
-(use whichever you like, or the ones in: \verb|code/codingbat.rst| )
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Lightning Talks}
-
-{\LARGE Lightning Talks:}
-
-\vfill
-Ryan Small
-
-\vfill
-Catherine Warren
-
-
-\end{frame}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Code structure, modules, and namespaces}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Code Structure}
-
-{\Large Python is all about namespaces -- the ``dots'' }
-
-\vfill
-\verb|name.another_name|
-
-\vfill
-The ``dot'' indicates looking for a name in the namespace of the
-given object. It could be:
-
-\begin{itemize}
-\item name in a module
-\item module in a package
-\item attribute of an object
-\item method of an object
-\end{itemize}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{indenting and blocks}
-
-{\Large Indenting determines blocks of code }
-
-\vfill
-\begin{verbatim}
-something:
- some code
- some more code
- another block:
- code in
- that block
-\end{verbatim}
-
-\vfill
-{\Large But you need the colon too...}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{indenting and blocks}
-
-{\Large You can put a one-liner after the colon:}
-
-\vfill
-\begin{verbatim}
-In [167]: x = 12
-
-In [168]: if x > 4: print x
-12
-\end{verbatim}
-
-\vfill
-{\Large Only do this if it makes it more readable...}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Spaces and Tabs}
-
-{\Large An indent can be:}
-\begin{itemize}
- \item Any number of spaces
- \item A tab
- \item tabs and spaces:
- \begin{itemize}
- \item A tab is eight spaces (always!)
- \item Are they eight in your editor?
- \end{itemize}
-\end{itemize}
-
-\vfill
-{\LARGE Always use four spaces -- really!}
-
-\vfill
-(PEP 8)
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Spaces Elsewhere}
-
-{\Large Other than indenting -- space doesn't matter}
-
-\vfill
-\begin{verbatim}
-
-x = 3*4+12/func(x,y,z)
-
-x = 3*4 + 12 / func (x, y, z)
-
-\end{verbatim}
-
-\vfill
-{\Large Choose based on readability/coding style}
-
-\vfill
-\center{\LARGE PEP 8}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Various Brackets}
-
-{\Large Bracket types:}
-
-\begin{itemize}
- \item parentheses \verb+( )+
- \begin{itemize}
- \item tuple literal: \verb+(1,2,3)+
- \item function call: \verb+fun( arg1, arg2 )+
- \item grouping: \verb| (a + b) * c |
- \end{itemize}
- \item square brackets \verb+[ ]+
- \begin{itemize}
- \item list literal: \verb+[1,2,3]+
- \item sequence indexing: \verb+a_string[4]+
- \end{itemize}
- \item curly brackets \verb+{ }+
- \begin{itemize}
- \item dictionary literal: \verb+{"this":3, "that":6}+
- \item (we'll get to those...)
- \end{itemize}
-\end{itemize}
-
-\end{frame}
-
-
-%-----------------------------------
-\begin{frame}{modules and packages}
-
-{\Large A module is simply a namespace}
-
-\vfill
-{\Large A package is a module with other modules in it}
-
-\vfill
-{\Large The code in the module is run when it is imported}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{importing modules}
-
-\begin{verbatim}
-
-import modulename
-
-from modulename import this, that
-
-import modulename as a_new_name
-\end{verbatim}
-
-\vfill
-(demo)
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{importing from packages}
-
-\begin{verbatim}
-
-import packagename.modulename
-
-from packagename.modulename import this, that
-
-from package import modulename
-
-\end{verbatim}
-\vfill
-(demo)
-
-\vfill
-\url{http://effbot.org/zone/import-confusion.htm}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{importing from packages}
-
-\begin{verbatim}
-from modulename import *
-\end{verbatim}
-
-\vfill
-{\LARGE Don't do this!}
-\vfill
-{\Large (``Namespaces are one honking great idea...'')}
-
-\vfill
-(wxPython and numpy example...)
-
-\vfill
-Except \emph{maybe} math module
-
-\vfill
-(demo)
-\end{frame}
-
-
-%------------------------------------
-\begin{frame}[fragile]{import}
-
-\vfill
-If you don’t know the module name before execution.
-
-\vfill
-\begin{verbatim}
-__import__(module)
-\end{verbatim}
-
-\vfill
-where \verb|module| is a Python string.
-
-\vfill
-\end{frame}
-
-\begin{frame}[fragile]{modules and packages}
-
-\vfill
-{\Large The code in a module is NOT re-run when imported again
- -- it must be explicitly reloaded to be re-run}
-
-\begin{verbatim}
-import modulename
-
-reload(modulename)
-\end{verbatim}
-
-(demo)
-
-\begin{verbatim}
-import sys
-print sys.modules
-\end{verbatim}
-(demo)
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large Experiment with importing different ways:}
-\begin{verbatim}
-import math
-dir(math) # or, in ipython -- math.
-math.sqrt(4)
-
-import math as m
-m.sqrt(4)
-
-from math import *
-sqrt(4)
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large Experiment with importing different ways:}
-\begin{verbatim}
-import sys
-print sys.path
-
-import os
-print os.path
-\end{verbatim}
-{\Large You wouldn't want to import * those -- check out}
-\begin{verbatim}
-os.path.split()
-os.path.join()
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Lightning Talks}
-
-\vfill
-{\LARGE Lightning talks next Week:}
-
-\vfill
-{\Large
-Nate Flagg
-
-\vfill
-Duane Wright
-
-\vfill
-Josh Rakita
-
-\vfill
-Anyone want a slot?
-}
-\vfill
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{Homework}
-
-Recommended Reading:
-\begin{itemize}
- \item Think Python: Chapters 8, 9, 10, 11, 12
- \item String methods: \url{http://docs.python.org/library/stdtypes.html#string-methods}
- \item Dive Into Python: Chapter 3
-\end{itemize}
-
-Do:
-\begin{itemize}
- \item The problem in \verb|week-02/homework.rst|
- \item Six more CodingBat exercises.
- \item LPTHW: for extra practice with the concepts -- some of:
- \begin{description}
- \item[strings:] ex5, ex6, ex7, ex8, ex9, ex10
- \item[raw\_input(), sys.argv:] ex12, ex13, ex14 (needed for files)
- \end{description}
-\end{itemize}
-
-\vfill
-(and any labs you didn't finish in class)
-
-\end{frame}
-
-\end{document}
-
-
diff --git a/slides_sources/old_versions/week-03/code/list_lab.rst b/slides_sources/old_versions/week-03/code/list_lab.rst
deleted file mode 100644
index 8a727d5..0000000
--- a/slides_sources/old_versions/week-03/code/list_lab.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-
-List Lab
-#############
-
-Modeled after
-
-
-Examples
-===================
-
- zoo = ["giraffe", "crow"] # define a list
-
- zoo[0] # a single element
-
- zoo[0] = "zebra" # change an element
-
- zoo.append("marmot") # add element at end of list
-
- zoo = ["cat"] + zoo # add element at beginning
-
- type(raw_input("Type a string: ")) # returns str
-
- type( input("Type a number: ")) # returns int or float
-
- [x for x in zoo if len(x) > 4] # list comprehension
-
- zoo2 = zoo[:] # create a list copy
-
- zoo.pop() # delete last element
-
- del zoo[0] # delete element by index
-
- zoo.remove('crow') # delete element by value
-
- "abc"[::-1] # reverse a string: "cba"
- # Unspecified range takes all; step value of -1 reverses.
-
-Exercises
-===============
-
-1.
-----
- - Create a list that contains "Apples", "Pears", "Oranges" and "Peaches".
- - Display the list.
- - Ask the user for another fruit and add it to the end of the list.
- - Display the list.
- - Ask the user for a number and display the number back to the user and the fruit corresponding to that number (on a 1-is-first basis).
- - Add another fruit to the beginning of the list using "+" and display the list.
- - Add another fruit to the beginning of the list using insert() and display the list.
-
- - Display all the fruits that begin with "P", using a for loop.
-
-
-2. Using the list above:
--------------------------
- - Display the list.
- - Remove the last fruit from the list.
- - Display the list.
- - Ask the user for a fruit to delete and find it and delete it.
- - (Bonus: Multiply the list times two. Keep asking until a match is found. Once found, delete all occurrences.)
-
-
-3. Using the list in item 1:
- - Ask the user for input displaying a line like "Do you like apples?"
- - for each fruit in the list (making the fruit all lowercase).
- - For each "no", delete that fruit from the list.
- - Display the list.
-
-
-4. Using the list in item 1:
- - Make a copy of the list and reverse the letters in each fruit in the copy.
- - Delete the last item of the original list. Display the original list and the copy.
diff --git a/slides_sources/old_versions/week-03/code/list_lab_solution.py b/slides_sources/old_versions/week-03/code/list_lab_solution.py
deleted file mode 100644
index 872d469..0000000
--- a/slides_sources/old_versions/week-03/code/list_lab_solution.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-
-"""
-list lab solution
-"""
-
-# Create a list that contains "Apples", "Pears", "Oranges" and "Peaches".
-fruit = ["Apples", "Pears", "Oranges" and "Peaches"]
-
-# Display the list.
-print fruit
-
-# Ask the user for another fruit and add it to the end of the list.
-new_fruit = raw_input("type in a fruit name > ")
-
-fruit.append(new_fruit)
-
-# Display the list.
-print fruit
-
-# Ask the user for a number and display the number back to the user
-# and the fruit corresponding to that number (on a 1-is-first basis).
-number = input("give me a number between 1 and "+`len(fruit)`+" > ")
-
-print "you picked:", number, "--", fruit[number-1]
-
-# Add another fruit to the beginning of the list using "+".
-fruit = ['Mangoes'] + fruit
-print fruit
-
-# Add another fruit to the beginning of the list using insert().
-fruit.insert(0, 'Apricots')
-print fruit
-
-
-
-
-
diff --git a/slides_sources/old_versions/week-03/code/mail_merge_solution.py b/slides_sources/old_versions/week-03/code/mail_merge_solution.py
deleted file mode 100644
index 1ed6ff5..0000000
--- a/slides_sources/old_versions/week-03/code/mail_merge_solution.py
+++ /dev/null
@@ -1,22 +0,0 @@
-data = ( ('George', 'a goldfish'),
- ('Joe', 'several small pieces of lint'),
- ('Jennifer','a red wagon')
- )
-
-template = """
-Dear %s,
-
-Thank you so much for your gift of %s. I will treasure it
-forever. I've always wanted an excuse to get %s, and now I
-don't have to pay for it!
-
-Please enjoy this form letter as a token of my sincere appreciation.
-"""
-
-for name, gift in data:
- print 'Filling template for %s' % name
- message = template%(name, gift, gift)
- file_name = 'thank_you_%s.txt' % name.lower()
- f = open(file_name, 'w')
- f.write(message)
- f.close()
diff --git a/slides_sources/old_versions/week-03/code/module_reload.py b/slides_sources/old_versions/week-03/code/module_reload.py
deleted file mode 100644
index 446f70e..0000000
--- a/slides_sources/old_versions/week-03/code/module_reload.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-
-"""
-a really simple module to use to test reloading
-"""
-
-this = "this2"
-that = "that"
-
-def print_something():
- print "I'm printing something else"
-
diff --git a/slides_sources/old_versions/week-03/code/rot13_solution.py b/slides_sources/old_versions/week-03/code/rot13_solution.py
deleted file mode 100644
index 5dde644..0000000
--- a/slides_sources/old_versions/week-03/code/rot13_solution.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/enc python
-
-"""
-A simple function to compute rot13 encoding
-
-ROT13 encryption
-
-Applying ROT13 to a piece of text merely requires examining its alphabetic
-characters and replacing each one by the letter 13 places further along in
-the alphabet, wrapping back to the beginning if necessary
-"""
-
-## note: the string translate() method would be the high-performance solution
-
-import string
-
-# a few handy constanst:
-a = ord('a')
-z = ord('z')
-A = ord('A')
-Z = ord('Z')
-
-
-def rot13a(text):
- """
- my first solution
- """
- # loop through the letters
- new_text = []
- for c in text:
- # do upper and lower case separately
- if c in string.ascii_lowercase:
- o = ord(c) + 13
- if o > z:
- o = a-1 + o-z
- elif c in string.ascii_uppercase:
- o = ord(c) + 13
- if o > Z:
- o = A-1 + o-Z
- else:
- o = ord(c)
- new_text.append( chr(o) )
- return "".join(new_text)
-
-def rot13b(text):
- """
- A little smarter to use % to take care of the wrap-around
-
- -thanks, Howard!
- """
- # loop through the letters
- new_text = []
- for c in text:
- # do upper and lower case separately
- if c in string.ascii_lowercase:
- o = a + ( (ord(c) - a + 13)%26 )
- elif c in string.ascii_uppercase:
- o = A + ( (ord(c) - A + 13)%26 )
- else:
- o = ord(c)
- new_text.append( chr(o) )
- return "".join(new_text)
-
-## Faster if you build a translation table and use that
-## a translation table needs to be 256 characters long
-## -- all ord vales from 0 to 255
-
-## NOTE: if you didn't discover
-front = str(bytearray(range(A)))
-translate_upper = str(bytearray(range(A+13,Z+1))) + str(bytearray(range(A,A+13)))
-middle = str(bytearray(range(Z+1, a)))
-translate_lower = str(bytearray(range(a+13,z+1))) + str(bytearray(range(a,a+13)))
-back = str(bytearray(range(z+1, 256)))
-
-# build the whole thing
-table = front + translate_upper + middle + translate_lower + back
-
-def rot13c(text):
- """
- just calls .translate()
- """
- return text.translate(table)
-
-
-print rot13a("Zntargvp sebz bhgfvqr arne pbeare")
-print rot13b("Zntargvp sebz bhgfvqr arne pbeare")
-print rot13c("Zntargvp sebz bhgfvqr arne pbeare")
-
-## rot13 should be reversible:
-print rot13a(rot13b(rot13c(rot13a('This Should be the Same...'))))
-
-# ## and some timings:
-# In [2]: timeit rot13a('This is a pretty short string, but maybe long enough to test')
-# 10000 loops, best of 3: 52.2 µs per loop
-#
-# In [3]: timeit rot13b('This is a pretty short string, but maybe long enough to test')
-# 10000 loops, best of 3: 54.7 µs per loop
-#
-# In [4]: timeit rot13c('This is a pretty short string, but maybe long enough to test')
-# 1000000 loops, best of 3: 482 ns per loop
-
-
diff --git a/slides_sources/old_versions/week-03/code/string_formatting_solution.py b/slides_sources/old_versions/week-03/code/string_formatting_solution.py
deleted file mode 100644
index 3a8951b..0000000
--- a/slides_sources/old_versions/week-03/code/string_formatting_solution.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-
-"""
-String formatting lab:
-
-"""
-# Rewrite: "the first 3 numbers are: %i, %i, %i"%(1,2,3)
-# for an arbitrary number of numbers...
-
-# solution 1
-# the goal was to demonstrate dynamic building of format strings:
-
-# create the numbers
-numbers = [32, 56, 34, 12, 48, 18]
-
-# build the format string for the numbers:
-formatter = " %i," * len(numbers)
-
-formatter = formatter[:-1] # take the extra comma off the end
-
-# put it together with the rest of the string
-formatter = "the first %i numbers are: %s"%(len(numbers), formatter)
-
-# use it:
-# the format operator needs a tuple
-# tuple(seq) will make a tuple out of any sequence
-print formatter%tuple(numbers)
-
-# solution 2
-# in class, a couple people realized that str() would make a nice string from
-# a list or tuple
-
-numbers_str = str(numbers)[1:-1] # make a string, remove the brackets
-# put it together with the rest of the string
-print "the first %i numbers are: %s"%(len(numbers), numbers_str)
-
-#####
-# Write a format string that will take:
-# ( 2, 123.4567, 10000)
-# and produce:
-# 'file_002 : 123.46, 1e+04'
-#####
-
-t = (2, 123.4567, 10000)
-print "file_%03i, %10.2f, %.3g"%t
-
-# could use '%e' for the last one, too -- I like '%g' -- it does significant figures...
diff --git a/slides_sources/old_versions/week-03/presentation-week03.pdf b/slides_sources/old_versions/week-03/presentation-week03.pdf
deleted file mode 100644
index 99def2e..0000000
Binary files a/slides_sources/old_versions/week-03/presentation-week03.pdf and /dev/null differ
diff --git a/slides_sources/old_versions/week-03/presentation-week03.tex b/slides_sources/old_versions/week-03/presentation-week03.tex
deleted file mode 100644
index 774dc48..0000000
--- a/slides_sources/old_versions/week-03/presentation-week03.tex
+++ /dev/null
@@ -1,1861 +0,0 @@
-\documentclass{beamer}
-%\usepackage[latin1]{inputenc}
-\usetheme{Warsaw}
-\title[Intro to Python: Week 3]{Introduction to Python\\ Sequences, List, Tuples}
-\author{Christopher Barker}
-\institute{UW Continuing Education}
-\date{October 15, 2013}
-
-\usepackage{listings}
-\usepackage{hyperref}
-
-\begin{document}
-
-% ---------------------------------------------
-\begin{frame}
- \titlepage
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}
-\frametitle{Table of Contents}
-%\tableofcontents[currentsection]
- \tableofcontents
-\end{frame}
-
-
-\section{Review/Questions}
-
-% ---------------------------------------------
-\begin{frame}{Review of Previous Class}
-
-\begin{itemize}
- \item Recusive functions
- \item Truthiness
- \item Modules and name spaces
-\end{itemize}
-
-\vfill
-{\large New sublime theme...}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}{Note about homework}
-
-{\large About a 1/3 of you have been sending me homework to review.}
-
-\vfill
-{\large Which is jsut fine!}
-
-\vfill
-{\large But how do I know if you have learned the material?}
-
-\vfill
-{\large Final Project...}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}{Lightning Talks}
-
-\vfill
-{\LARGE Lightning talks today:}
-
-\vfill
-{\Large
-Nate Flagg
-
-\vfill
-Duane Wright
-
-\vfill
-Jo-Anne Antoun
-
-\vfill
-Josh Rakita
-
-}
-\vfill
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}{Homework review}
-
- \vfill
- {\Large Homework Questions? }
-
- \vfill
- {\Large My Solution}
-
- \vfill
- {\Large Gary's Solution}
-
-\end{frame}
-
-% ************************************
-\section {Sequences}
-
-\begin{frame}[fragile]{Sequences}
-
-{\Large Sequences are ordered collections of objects}
-
-\vfill
-{\Large They can be indexed, sliced, iterated over,...}
-
-\vfill
-{\Large They have a length: \verb+len(sequence)+}
-
-\vfill
-{\Large Common sequences (Remember Duck Typing?):}
-
-{\Large
-\begin{itemize}
- \item strings
- \item tuples
- \item lists
-\end{itemize}
-}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Indexing}
-
-{\Large square brackets for indexing: \verb+[]+}
-
-\vfill
-{\Large Indexing starts at zero}
-
-\begin{verbatim}
-In [98]: s = "this is a string"
-
-In [99]: s[0]
-Out[99]: 't'
-
-In [100]: s[5]
-Out[100]: 'i'
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Indexing}
-
-{\Large Negative indexes count from the end}
-
-\vfill
-\begin{verbatim}
-In [105]: s = "this is a string"
-
-In [106]: s[-1]
-Out[106]: 'g'
-
-In [107]: s[-6]
-Out[107]: 's'
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Slices}
-
-{\Large Slicing: Pulling a range out of a sequence}
-
-\begin{verbatim}
-sequence[start:finish]
-
-indexes for which:
-
-start <= i < finish
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Slices}
-\begin{verbatim}
-In [121]: s = "a bunch of words"
-In [122]: s[2]
-Out[122]: 'b'
-
-In [123]: s[6]
-Out[123]: 'h'
-
-In [124]: s[2:6]
-Out[124]: 'bunc'
-
-In [125]: s[2:7]
-Out[125]: 'bunch'
-\end{verbatim}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{Slices}
-
-{\Large the indexes point to the spaces between the items}
-
-\vfill
-\begin{verbatim}
- X X X X X X X X
- | | | | | | | |
- 0 1 2 3 4 5 6 7
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Slices}
-
-{\Large Slicing satisfies nifty properties:
-
-\vfill
-\begin{verbatim}
-len( seq[a:b] ) == b - a
-
-seq[a:b] + seq[b:c] == seq
-
-\end{verbatim}
-
-}
-
-\end{frame}
-
-% ------------------------------------------------
-\begin{frame}[fragile]{Slicing vs. Indexing}
-
-{\Large Indexing returns a single element}
-
-\begin{verbatim}
-In [86]: l
-Out[86]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-In [87]: type(l)
-Out[87]: list
-
-In [88]: l[3]
-Out[88]: 3
-
-In [89]: type( l[3] )
-Out[89]: int
-\end{verbatim}
-\end{frame}
-
-% ------------------------------------------------
-\begin{frame}[fragile]{Slicing vs. Indexing}
-
-{\Large Unless it's a string:}
-
-\begin{verbatim}
-In [75]: s = "a string"
-
-In [76]: s[3]
-Out[76]: 't'
-
-In [77]: type(s[3])
-Out[77]: str
-\end{verbatim}
-
-\vfill
-There is no single character type
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{Slicing vs. Indexing}
-
-{\Large Slicing returns a sequence:}
-
-\begin{verbatim}
-In [68]: l
-Out[68]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-In [69]: l[2:4]
-Out[69]: [2, 3]
-\end{verbatim}
-
-Even if it's one element long
-
-\begin{verbatim}
-In [70]: l[2:3]
-Out[70]: [2]
-
-In [71]: type(l[2:3])
-Out[71]: list
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Slicing vs. Indexing}
-
-{\Large Indexing out of range produces an error}
-\vfill
-\begin{verbatim}
-In [129]: s = "a bunch of words"
-In [130]: s[17]
-----> 1 s[17]
-IndexError: string index out of range
-\end{verbatim}
-
-\vfill
-{\Large Slicing just gives you what's there}
-
-\begin{verbatim}
-In [131]: s[10:20]
-Out[131]: ' words'
-
-In [132]: s[20:30]
-Out[132]: ''
-\end{verbatim}
-(demo)
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Multiplying and slicing}
-
-{\Large from CodingBat: Warmup-1 -- front3}
-
-\begin{verbatim}
-def front3(str):
- if len(str) < 3:
- return str+str+str
- else:
- return str[:3]+str[:3]+str[:3]
-\end{verbatim}
-
-{\Large or}
-
-\begin{verbatim}
-def front3(str):
- return str[:3] * 3
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Slicing}
-
-{\Large from CodingBat: Warmup-1 -- \verb+missing_char+ }
-
-\begin{verbatim}
-def missing_char(str, n):
- front = str[0:n]
- l = len(str)-1
- back = str[n+1:l+1]
- return front + back
-\end{verbatim}
-
-\begin{verbatim}
-def missing_char(str, n):
- return str[:n] + str[n+1:]
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Slicing}
-
-{\Large you can skip items, too}
-
-\begin{verbatim}
-In [289]: string = "a fairly long string"
-
-In [290]: string[0:15]
-Out[290]: 'a fairly long s'
-
-In [291]: string[0:15:2]
-Out[291]: 'afil ogs'
-
-In [292]: string[0:15:3]
-Out[292]: 'aallg'
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-Write some functions that:
-\begin{itemize}
- \item return a string with the first and last characters exchanged.
- \item return a string with every other character removed
- \item return a string with the first and last 4 characters removed, and every other char in between
- \item return a string reversed (just with slicing)
- \item return a string with the middle, then last, then first third in a new order
-\end{itemize}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}{Lightning Talk}
-
-{\LARGE Lightning Talks:}
-
-\vfill
-{\large Nate Flag}
-
-\vfill
-{\large Duane Wright}
-
-\end{frame}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Lists, Tuples...}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Lists}
-
- {\Large List Literals}
-
-\begin{verbatim}
->>> []
-[]
->>> list()
-[]
->>> [1, 2, 3]
-[1, 2, 3]
->>> [1, 3.14, "abc"]
-[1, 3.14, 'abc']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Lists}
-
- {\Large List ``type''}
-
- {\large \hspace{0.1in}(also constructor)}
-
-\begin{verbatim}
->>> type(list)
-
->>> list( (1,2,3) )
-[1, 2, 3]
->>> list( "a string" )
-\end{verbatim}
-
-\vfill
-{\Large Takes any sequence, tries to turn it into a list}
-
-\vfill
-{\large like \verb|int()|, \verb|float()|, etc.}
-
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Indexing}
-
- {\Large Indexing just like all sequences}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> food[2]
-'ham'
->>> food[0]
-'spam'
->>> food[42]
-Traceback (most recent call last):
- File "", line 1, in
-IndexError: list index out of range
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Mutability}
-
-{\Large Lists are mutable}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> food[1] = 'raspberries'
->>> food
-['spam', 'raspberries', 'ham']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Elements}
-
-{\Large Each element is a value, and can be in multiple lists and have multiple
-names (or no name)}
-
-\begin{verbatim}
- >>> name = 'Brian'
- >>> a = [1, 2, name]
- >>> b = [3, 4, name]
- >>> name
- 'Brian'
- >>> a
- [1, 2, 'Brian']
- >>> b
- [3, 4, 'Brian']
- >>> a[2]
- 'Brian'
- >>> b[2]
- 'Brian'
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Methods}
-
-{\Large \verb| .append(), .insert()|}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> food.append('sushi')
->>> food
-['spam', 'eggs', 'ham', 'sushi']
->>> food.insert(0, 'carrots')
->>> food
-['carrots', 'spam', 'eggs', 'ham', 'sushi']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Methods}
-
-{\large \verb| .extend()|}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> food.extend(['fish', 'chips'])
->>> food
-['spam', 'eggs', 'ham', 'fish', 'chips']
-\end{verbatim}
-
-{\large could be any sequence:}
-
-\begin{verbatim}
->>> food
->>> ['spam', 'eggs', 'ham']
->>> silverware = ('fork', 'knife', 'spoon') # a tuple
->>> food.extend(silverware)
->>> food
->>> ['spam', 'eggs', 'ham', 'fork', 'knife', 'spoon']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Methods}
-
-{\large \verb|pop(), remove() |}
-
-\begin{verbatim}
-In [203]: food = ['spam', 'eggs', 'ham', 'toast']
-In [204]: food.pop()
-Out[204]: 'toast'
-In [205]: food.pop(0)
-Out[205]: 'spam'
-In [206]: food
-Out[206]: ['eggs', 'ham']
-In [207]: food.remove('ham')
-In [208]: food
-Out[208]: ['eggs']
-\end{verbatim}
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Constructor}
-
-{\large \verb|list()| accepts any sequence and returns a list of that sequence}
-\begin{verbatim}
->>> word = 'Python '
->>> chars = []
->>> for char in word:
-... chars.append(char)
->>> chars
-['P', 'y', 't', 'h', 'o', 'n', ' ']
->>> list(word)
-['P', 'y', 't', 'h', 'o', 'n', ' ']
-\end{verbatim}
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{String to List to String}
-
-{\large If you need to change individual letters... you can do this,
-but usually \verb|somestring.replace()| will be enough }
-
-\begin{verbatim}
-In [216]: name = 'Chris'
-In [217]: lname = list(name)
-In [218]: lname[0:2] = 'K'
-In [219]: name = ''.join(lname)
-In [220]: name
-Out[220]: 'Kris'
-\end{verbatim}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Building up strings in a list}
-
-\begin{verbatim}
-In [221]: msg = []
-
-In [222]: msg.append('The first line of a message')
-
-In [223]: msg.append('The second line of a message')
-
-In [224]: msg.append('And one more line')
-
-In [225]: print '\n'.join(msg)
-The first line of a message
-The second line of a message
-And one more line
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Slicing}
-
-{\large Slicing makes a copy}
-
-\begin{verbatim}
-In [227]: food = ['spam', 'eggs', 'ham', 'sushi']
-
-In [228]: some_food = food[1:3]
-
-In [229]: some_food[1] = 'bacon'
-
-In [230]: food
-Out[230]: ['spam', 'eggs', 'ham', 'sushi']
-
-In [231]: some_food
-Out[231]: ['eggs', 'bacon']
-\end{verbatim}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Slicing}
-
-{\large Easy way to copy a whole list}
-
-\begin{verbatim}
-In [232]: food
-Out[232]: ['spam', 'eggs', 'ham', 'sushi']
-
-In [233]: food2 = food[:]
-
-In [234]: food is food2
-Out[234]: False
-
-\end{verbatim}
-
-{\Large but the copy is ``shallow''}: \
-\url{http://docs.python.org/library/copy.html}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Slicing}
-
-{\Large ``Shallow'' copy}
-
-\begin{verbatim}
-In [249]: food = ['spam', ['eggs', 'ham']]
-In [251]: food_copy = food[:]
-In [252]: food[1].pop()
-Out[252]: 'ham'
-In [253]: food
-Out[253]: ['spam', ['eggs']]
-In [256]: food.pop(0)
-Out[256]: 'spam'
-In [257]: food
-Out[257]: [['eggs']]
-In [258]: food_copy
-Out[258]: ['spam', ['eggs']]
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Name Binding}
-
-{\Large Assigning to a name does not copy:}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham', 'sushi']
->>> food_again = food
->>> food_copy = food[:]
->>> food.remove('sushi')
->>> food
-['spam', 'eggs', 'ham']
->>> food_again
-['spam', 'eggs', 'ham']
->>> food_copy
-['spam', 'eggs', 'ham', 'sushi']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Iterating}
-
-{\Large Iterating over a list}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham', 'sushi']
->>> for x in food:
-... print x
-...
-spam
-eggs
-ham
-sushi
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Processing Lists}
-
-{\Large A common pattern}
-
-\begin{verbatim}
-filtered = []
-for x in somelist:
- if should_be_included(x):
- filtered.append(x)
-del(somelist) # maybe
-\end{verbatim}
-
-{\Large you don't want to be deleting items from the list while iterating...}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Mutating Lists}
-
-{\Large if you're going to change the list, iterate over a copy for safety }
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham', 'sushi']
->>> for x in food[:]:
- ... # change the list somehow
- ...
-\end{verbatim}
-
-{\Large insidious bugs otherwise}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{operators vs methods}
-
-{\large What's the difference?}
-
-\begin{verbatim}
- >>> food = ['spam', 'eggs', 'ham']
- >>> more = ['fish', 'chips']
- >>> food = food + more
- >>> food
- ['spam', 'eggs', 'ham', 'fish', 'chips']
-
- >>> food = ['spam', 'eggs', 'ham']
- >>> more = ['fish', 'chips']
- >>> food.extend(more)
- >>> food
- ['spam', 'eggs', 'ham', 'fish', 'chips']
-\end{verbatim}
-(the operator makes a new list...)
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{in}
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> 'eggs' in food
-True
->>> 'chicken feet' in food
-False
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{reverse()}
-
-
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham']
->>> food.reverse()
->>> food
-['ham', 'eggs', 'spam']
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{sort()}
-
-\vfill
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham', 'sushi']
->>> food.sort()
->>> food
-['eggs', 'ham', 'spam', 'sushi']
-\end{verbatim}
-
-\vfill
-{\Large note:}
-
-\vfill
-\begin{verbatim}
->>> food = ['spam', 'eggs', 'ham', 'sushi']
->>> result = food.sort()
->>> print result
-None
-\end{verbatim}
-
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Sorting}
-
-{\large How should this sort?}
-
-\begin{verbatim}
->>> s
-[[2, 'a'], [1, 'b'], [1, 'c'], [1, 'a'], [2, 'c']]
-\end{verbatim}
-
-\pause
-
-\begin{verbatim}
->>> s.sort()
->>> s
-[[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'c']]
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Sorting}
-
-{\large You can specify your own compare function:}
-
-\begin{verbatim}
-In [279]: s = [[2, 'a'], [1, 'b'], [1, 'c'], [1, 'a'], [2, 'c']]
-In [281]: def comp(s1,s2):
- .....: if s1[1] > s2[1]: return 1
- .....: elif s1[1] s2[0]: return 1
- .....: elif s1[0] < s2[0]: return -1
- .....: return 0
-In [282]: s.sort(comp)
-In [283]: s
-Out[283]: [[1, 'a'], [2, 'a'], [1, 'b'], [1, 'c'], [2, 'c']]
-\end{verbatim}
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Sorting}
-
-{\Large
-Mixed types can be sorted.
-}
-\vfill
-{\center \Large
-
-``objects of different types always compare unequal, and are ordered
-consistently but arbitrarily.''
-
-}
-
-\vfill
-\url{http://docs.python.org/reference/expressions.html#not-in}
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Searching}
-
-{\Large Finding or Counting items}
-
-\begin{verbatim}
-In [288]: l = [3,1,7,5,4,3]
-
-In [289]: l.index(5)
-Out[289]: 3
-
-In [290]: l.count(3)
-Out[290]: 2
-\end{verbatim}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List Performance }
-
-\begin{itemize}
- \item indexing is fast and constant time: O(1)
- \item x in s proportional to n: O(n)
- \item visiting all is proportional to n: O(n)
- \item operating on the end of list is fast and constant time: O(1) \\
- append(), pop()
- \item operating on the front (or middle) of the list depends on n: O(n)\\
- pop(0), insert(0, v) \\
- But, reversing is fast. Also, collections.deque
-\end{itemize}
-
-\url{ http://wiki.python.org/moin/TimeComplexity}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Lists vs. Tuples}
-
-\vfill
-{\Large List or Tuples}
-
-\vfill
-{\Large
-If it needs to mutable: list
-
-\vfill
-If it needs to be immutable: tuple\\
-}
-\hspace{0.2in}{\large (dict key, safety when passing to a function) }
-
-\vfill
-{\Large Otherwise ... taste and convention}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List vs Tuple}
-
-\vfill
-{\LARGE Convention:}
-
-\vfill
-{\Large Lists are Collections (homogeneous):\\[0.1in]
--- contain values of the same type \\
--- simplifies iterating, sorting, etc
-}
-
-\vfill
-{\Large tuples are mixed types:\\[0.1in]
--- Group multiple values into one logical thing
--- Kind of like simple C structs.
-}
-\vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List vs Tuple}
-
-{\Large
-\begin{itemize}
- \item Do the same operation to each element?
- \item Small collection of values which make a single logical item?
- \item To document that these values won't change?
- \item Build it iteratively?
- \item Transform, filter, etc?
-\end{itemize}
-}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{List vs Tuple}
-
-{\Large
-\begin{itemize}
- \item Do the same operation to each element? {\bf list}
- \item Small collection of values which make a single logical item? {\bf tuple}
- \item To document that these values won't change? {\bf tuple}
- \item Build it iteratively? {\bf list}
- \item Transform, filter, etc? {\bf list}
-\end{itemize}
-}
-
-\end{frame}
-
-\begin{frame}[fragile]{List Docs}
-
-\vfill
-{\Large The list docs:}
-
-\vfill
-\url{http://docs.python.org/library/stdtypes.html#mutable-sequence-types}
-
-\vfill
-(actually any mutable sequence....)
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{tuples and commas..}
-
-{\Large Tuples don't NEED parentheses... }
-
-\begin{verbatim}
-In [161]: t = (1,2,3)
-In [162]: t
-Out[162]: (1, 2, 3)
-
-In [163]: t = 1,2,3
-In [164]: t
-Out[164]: (1, 2, 3)
-
-In [165]: type(t)
-Out[165]: tuple
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{tuples and commas..}
-
-{\Large Tuples do need commas... }
-
-\begin{verbatim}
-In [156]: t = ( 3 )
-
-In [157]: type(t)
-Out[157]: int
-
-In [158]: t = (3,)
-In [159]: t
-Out[159]: (3,)
-
-In [160]: type(t)
-Out[160]: tuple
-\end{verbatim}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-\vfill
-{\LARGE List Lab}
-
-\vfill
-\verb|week-03/code/list_lab.rst|
-
-\vfill
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}{Lightning Talk}
-
-{\LARGE Lightning Talks:}
-
-\vfill
-{\large Jo-Anne Antoun}
-
-\vfill
-{\large Josh Rakita}
-
-\end{frame}
-
-
-
-\section{Looping}
-
-%-------------------------------
-\begin{frame}[fragile]{for loops}
-
-{\Large looping through sequences
-
-\begin{verbatim}
-for x in sequence:
- do_something_with_x
-\end{verbatim}
-}
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{for loops}
-
-\begin{verbatim}
-In [170]: for x in "a string":
- .....: print x
- .....:
-a
-
-s
-t
-r
-i
-n
-g
-\end{verbatim}
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{range}
-
-{\Large looping a known number of times..}
-
-\begin{verbatim}
-In [171]: for i in range(5):
- .....: print i
- .....:
-0
-1
-2
-3
-4
-\end{verbatim}
-(you don't need to do anything with i...
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{range}
-
-{\Large \verb|range| defined similarly to indexing}
-
-\begin{verbatim}
-In [183]: range(4)
-Out[183]: [0, 1, 2, 3]
-
-In [184]: range(2,4)
-Out[184]: [2, 3]
-
-In [185]: range(2,10,2)
-Out[185]: [2, 4, 6, 8]
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{indexing?}
-
-{\Large Python only loops through a sequence -- not like C, Javascript, etc...}
-\begin{verbatim}
-for(var i=0; i= 0 on entry
-% ... # do something with x
-% x -= 1 # make progress toward 0
-%\end{verbatim}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{break}
-
-{\Large \verb|break| ends a loop early}
-
-\begin{verbatim}
-x = 0
-while True:
- print x
- if x > 2:
- break
- x = x + 1
-In [216]: run for_while.py
-0
-1
-2
-3
-\end{verbatim}
-
-\vfill
-(This is a pretty common idiom)
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{break}
-
-{\Large same way with a \verb|for| loop }
-
-\begin{verbatim}
-name = "Chris Barker"
-for c in name:
- print c,
- if c == "B":
- break
-print "I'm done"
-
-C h r i s B
-I'm done
-\end{verbatim}
-\end{frame}
-
-\begin{frame}[fragile]{continue}
-
-{\Large \verb|continue| skips to the start of the loop again}
-
-\begin{verbatim}
-print "continue in a for loop"
-name = "Chris Barker"
-for c in name:
- if c == "B":
- continue
- print c,
-print "\nI'm done"
-
-continue in a for loop
-C h r i s a r k e r
-I'm done
-\end{verbatim}
-\end{frame}
-
-\begin{frame}[fragile]{continue}
-
-{\Large \verb|continue| works for a \verb|while| loop too.}
-
-\begin{verbatim}
-print "continue in a while loop"
-x = 6
-while x > 0:
- x = x-1
- if x%2:
- continue
- print x,
-print "\nI'm done"
-
-continue in a while loop
-4 2 0
-I'm done
-\end{verbatim}
-\end{frame}
-
-\begin{frame}[fragile]{else again}
-
-{\Large \verb|else| block run if the loop finished naturally -- no \verb|break|}
-
-\begin{verbatim}
-print "else in a for loop"
-x = 5
-for i in range(5):
- print i
- if i == x:
- break
-else:
- print "else block run"
-
-\end{verbatim}
-\end{frame}
-
-\section{Fun with Strings}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Strings}
-
-{\Large A string literal creates a string type}
-
-\begin{verbatim}
-"this is a string"
-\end{verbatim}
-
-{\Large Can also use \verb|str()|}
-
-\begin{verbatim}
-In [256]: str(34)
-Out[256]: '34'
-\end{verbatim}
-{\Large or "back ticks"}
-\begin{verbatim}
-In [258]: `34`
-Out[258]: '34'
-\end{verbatim}
-(demo)
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{The String Type}
-
-{\Large Lots of nifty methods:}
-
-\begin{verbatim}
-s.lower()
-s.upper()
- ...
-s.capitalize()
-s.swapcase()
-s.title()
-\end{verbatim}
-
-\url{http://docs.python.org/library/stdtypes.html#index-23}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{The String Type}
-
-{\Large Lots of nifty methods:}
-
-\begin{verbatim}
-x in s
-s.startswith(x)
-s.endswith(x)
-...
-s.index(x)
-s.find(x)
-s.rfind(x)
-\end{verbatim}
-
-\url{http://docs.python.org/library/stdtypes.html#index-23}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{The String Type}
-
-{\Large Lots of nifty methods:}
-
-\begin{verbatim}
-s.split()
-s.join(list)
-...
-s.splitlines()
-\end{verbatim}
-
-\url{http://docs.python.org/library/stdtypes.html#index-23}
-\vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Joining Strings}
-
-{\Large The Join Method:}
-
-\vfill
-\begin{verbatim}
-In [289]: t = ("some", "words","to","join")
-
-In [290]: " ".join(t)
-Out[290]: 'some words to join'
-
-In [291]: ",".join(t)
-Out[291]: 'some,words,to,join'
-
-In [292]: "".join(t)
-Out[292]: 'somewordstojoin'
-\end{verbatim}
-
-\vfill
-(demo -- join)
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{The string module}
-
-{\Large Lots of handy constants, etc.}
-\begin{verbatim}
-string.ascii_letters
-string.ascii_lowercase
-string.ascii_uppercase
-string.letters
-string.hexdigits
-string.whitespace
-string.printable
-string.digits
-string.punctuation
-\end{verbatim}
-
-\vfill
-(and the string methods -- legacy)
-
-\vfill
-{\small \url{http://docs.python.org/2/library/string.html#module-string} }
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{String Literals}
-
-{\Large Common Escape Sequences}
-\vfill
-\begin{verbatim}
-\\ Backslash (\)
-\a ASCII Bell (BEL)
-\b ASCII Backspace (BS)
-\n ASCII Linefeed (LF)
-\r ASCII Carriage Return (CR)
-\t ASCII Horizontal Tab (TAB)
-\ooo Character with octal value ooo
-\xhh Character with hex value hh
-\end{verbatim}
-(\url{http://docs.python.org/release/2.5.2/ref/strings.html})
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Raw Strings}
-
-{\Large Escape Sequences Ignored}
-\vfill
-\begin{verbatim}
-In [408]: print "this\nthat"
-this
-that
-In [409]: print r"this\nthat"
-this\nthat
-\end{verbatim}
-
-{\Large Gotcha:}
-\begin{verbatim}
-In [415]: r"\"
-SyntaxError: EOL while scanning string literal
-\end{verbatim}
-
-\vfill
-(handy for regex, windows paths...)
-\end{frame}
-
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Character Values}
-
-{\Large Characters in strings are stored as numeric values}
-
-\vfill
-{\large ``ASCII'' values: 1-127}
-
-\vfill
-{\large ``ANSI'' values: 1-255}
-
-
-\vfill
-{\large To get the value:}
-\begin{verbatim}
-In [109]: for i in 'Chris':
- .....: print ord(i),
-67 104 114 105 115
-
-In [110]: for i in (67,104,114,105,115):
- .....: print chr(i),
-C h r i s
-\end{verbatim}
-
-\vfill
-(next week: unicode!)
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Building Strings}
-
-{\Large Please don't do this:
-
-\vfill
-\begin{verbatim}
-'Hello ' + name + '!'
-\end{verbatim}
-}
-\vfill
-(much)
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Building Strings}
-
-{\Large Do this instead:
-
-\vfill
-\begin{verbatim}
-'Hello %s!' % name
-\end{verbatim}
-
-\vfill
-much faster and safer:
-
-\vfill
-easier to modify as code gets complicated
-}
-
-\vfill
-\url{http://docs.python.org/library/stdtypes.html#string-formatting-operations}
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{String Formatting}
-
-{\Large The string format operator: \%}
-
-\begin{verbatim}
-In [261]: "an integer is: %i"%34
-Out[261]: 'an integer is: 34'
-
-In [262]: "a floating point is: %f"%34.5
-Out[262]: 'a floating point is: 34.500000'
-
-In [263]: "a string is: %s"%"anything"
-Out[263]: 'a string is: anything'
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{String Formatting}
-
-{\Large multiple arguments:}
-
-\begin{verbatim}
-In [264]: "the number %s is %i"%('five', 5)
-Out[264]: 'the number five is 5'
-
-In [266]: "the first 3 numbers are: %i, %i, %i"%(1,2,3)
-Out[266]: 'the first 3 numbers are: 1, 2, 3'
-
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{String formatting}
-
-{\Large Gotcha}
-
-\begin{verbatim}
-In [127]: "this is a string with %i formatting item"%1
-Out[127]: 'this is a string with 1 formatting item'
-
-In [128]: "string with %i formatting %s: "%2, "items"
-TypeError: not enough arguments for format string
-
-# Done right:
-In [131]: "string with %i formatting %s"%(2, "items")
-Out[131]: 'string with 2 formatting items'
-
-In [132]: "string with %i formatting item"%(1,)
-Out[132]: 'string with 1 formatting item'
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{String formatting}
-
-{\Large Named arguments}
-
-\begin{verbatim}
-'Hello %(name)s!'%{'name':'Joe'}
-'Hello Joe!'
-
-'Hello %(name)s, how are you, %(name)s!' %{'name':'Joe'}
-'Hello Joe, how are you, Joe!'
-\end{verbatim}
-\vfill
-{\Large That last bit is a dictionary (next week) }
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{String formatting}
-
-{\Large The format operator works with string variables, too:}
-
-\begin{verbatim}
-In [45]: s = "%i / %i = %i"
-
-In [46]: a, b = 12, 3
-
-In [47]: s%(a, b, a/b)
-Out[47]: '12 / 3 = 4'
-\end{verbatim}
-\vfill
-So you can dynamically build a format string
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Advanced Formatting}
-
-{\Large The format method}
-
-\begin{verbatim}
-In [14]: 'Hello {0} {1}!'.format('Joe', 'Barnes')
-Out[14]: 'Hello Joe Barnes!'
-
-In [12]: 'Hello {name}!'.format(name='Joe')
-Out[12]: 'Hello Joe!'
-\end{verbatim}
-\vfill
-{\Large pick one (probably regular string formatting): \\
- -- get comfy with it }
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large Fun with strings}
-
-\begin{itemize}
- \item Rewrite: \verb| the first 3 numbers are: %i, %i, %i"%(1,2,3)| \\
- for an arbitrary number of numbers...
- \item write a format string that will take:\\
- \verb|( 2, 123.4567, 10000)| \\
- and produce: \\
- \verb|'file_002 : 123.46, 1e+04'|
- \item Write a (really simple) mail merge program
- \item ROT13 -- see next slide
-\end{itemize}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-\vfill
-\LargeROT13 encryption
-
-\vfill
-Applying ROT13 to a piece of text merely requires examining its alphabetic
-characters and replacing each one by the letter 13 places further along in
-the alphabet, wrapping back to the beginning if necessary
-
-\begin{itemize}
- \item Implement rot13 decoding
- \item decode this message: \\
- \hspace{0.5in} Zntargvp sebz bhgfvqr arne pbeare \\
- \hspace{0.5in} (from a geo-caching hint)
-\end{itemize}
-
-\end{frame}
-
-
-
-%-------------------------------
-\begin{frame}[fragile]{Homework}
-
-{\Large Recommended Reading:}
-\begin{itemize}
- \item Think Python: Chapt. 9 -- 14
- \item Dive Into Python: Chapt. 6
- \item String methods: \url{http://docs.python.org/library/stdtypes.html#string-methods}
- \item Extra: unicode: \url{http://www.joelonsoftware.com/articles/Unicode.html}
-\end{itemize}
-
-\vfill
-{\Large Do:}
-\begin{itemize}
- \item Finish the LABs
- \item Six more CodingBat exercises.
- \item LPTHW: for extra practice with the concepts -- some of:\\
- excercises 5 -- 14
-\end{itemize}
-
-\end{frame}
-
-
-\end{document}
-
-
diff --git a/slides_sources/old_versions/week-04/code/dict_lab.html b/slides_sources/old_versions/week-04/code/dict_lab.html
deleted file mode 100644
index 725d131..0000000
--- a/slides_sources/old_versions/week-04/code/dict_lab.html
+++ /dev/null
@@ -1,395 +0,0 @@
-
-
-
-
-
-
-Dictionaries and Sets Lab
-
-
-
-
-
Dictionaries and Sets Lab
-
-
-
Examples
-
-d = {} # define a dictionary
-d = {"item": "tea", "country": "China"} # define a dictionary
-d["price"] = 1 # add an item
-del d["price"] # delete an item
-d.keys() # list of dictionary keys
-d.values() # list of dictionary values
-"tea" in ["tea", "China"] # membership...
-"coffee" in ["tea", "China"] # or lack thereof
-hex(x) # hexadecimal string for x
-[(x, x + 1) for x in range(7)] # list comprehension of two-item tuples
-dict([(x, x + 1) for x in range(7)]) # dictionary of the previous item
-"abc".count("a") # count the number of occurrences of a substring
-[x for x in range(51) if x % 5 == 0] # list comprehension for multiples of 5 under 51
-set([1,2]) # set of items in a list
-set("Hi!") # set of characters in a string
-frozenset("Hi!") # frozen set of characters in a string
-set("Hi!").issubset(set("Hi there!")) # the first set a subset of the second? Returns True
-set("Hi!").union(set(" there")) # union- Returns set(['!', ' ', 'e', 'i', 'H', 'r', 't', 'h'])
-set("Hi!").intersection(set(" there")) # intersection- Returns set([])
-x = set("Hi") # x is set(['i', 'H'])
-x.add("!") # x is set(['i', 'H', '!'])
-
-
-
-
Exercises
-
-
1.
-
Create a dictionary containing name, city, and cake for Chris from Seattle Edmonds who likes Chocolate. Display the dictionary. Delete the entry for cake. Display the dictionary. Add an entry for fruit with "Mango" and display the dictionary. Display the dictionary keys. Display the dictionary values. Display whether or not cake is a key in the dictionary (i.e. False). Display whether or not "Mango" is a value in the dictionary.
-
-
-
2.
-
Using the dict constructor and zip, build a dictionary of numbers from zero to fifteen and the hexadecimal equivalent (string is fine).
-
-
-
3.
-
Using the dictionary from item 1: Make a dictionary using the same keys but with the number of 'n's in each value.
-
-
-
4.
-
Create sets s2, s3 and s4 that contain numbers from zero through twenty divisible 2, 3 and 4. Display the sets. Display if s3 is a subset of s2 (False) and if s4 is a subset of s2 (True).
-
-
-
5.
-
Create a set with the letters in 'Python' and add 'i' to the set. Create a frozenset with the letters in 'marathon' and display the union and intersection of the two sets.
-
-
-
-
-
diff --git a/slides_sources/old_versions/week-04/code/dict_lab.rst b/slides_sources/old_versions/week-04/code/dict_lab.rst
deleted file mode 100644
index 33e472a..0000000
--- a/slides_sources/old_versions/week-04/code/dict_lab.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-Dictionaries and Sets Lab
-###############################
-
-Examples
-==============
-
-::
-
- d = {} # define a dictionary
- d = {"item": "tea", "country": "China"} # define a dictionary
- d["price"] = 1 # add an item
- del d["price"] # delete an item
- d.keys() # list of dictionary keys
- d.values() # list of dictionary values
- "tea" in ["tea", "China"] # membership...
- "coffee" in ["tea", "China"] # or lack thereof
- hex(x) # hexadecimal string for x
- [(x, x + 1) for x in range(7)] # list comprehension of two-item tuples
- dict([(x, x + 1) for x in range(7)]) # dictionary of the previous item
- "abc".count("a") # count the number of occurrences of a substring
- [x for x in range(51) if x % 5 == 0] # list comprehension for multiples of 5 under 51
- set([1,2]) # set of items in a list
- set("Hi!") # set of characters in a string
- frozenset("Hi!") # frozen set of characters in a string
- set("Hi!").issubset(set("Hi there!")) # the first set a subset of the second? Returns True
- set("Hi!").union(set(" there")) # union- Returns set(['!', ' ', 'e', 'i', 'H', 'r', 't', 'h'])
- set("Hi!").intersection(set(" there")) # intersection- Returns set([])
- x = set("Hi") # x is set(['i', 'H'])
- x.add("!") # x is set(['i', 'H', '!'])
-
-Exercises
-==================
-
-1.
-----
-Create a dictionary containing name, city, and cake for Chris from Seattle who likes Chocolate. Display the dictionary. Delete the entry for cake. Display the dictionary. Add an entry for fruit with "Mango" and display the dictionary. Display the dictionary keys. Display the dictionary values. Display whether or not cake is a key in the dictionary (i.e. False). Display whether or not "Mango" is a value in the dictionary.
-
-2.
-----
-Using the dict constructor and zip, build a dictionary of numbers from zero to fifteen and the hexadecimal equivalent (string is fine).
-
-3.
-----
-Using the dictionary from item 1: Make a dictionary using the same keys but with the number of 't's in each value.
-
-4.
-----
-Create sets s2, s3 and s4 that contain numbers from zero through twenty divisible 2, 3 and 4. Display the sets. Display if s3 is a subset of s2 (False) and if s4 is a subset of s2 (True).
-
-5.
-----
-Create a set with the letters in 'Python' and add 'i' to the set. Create a frozenset with the letters in 'marathon' and display the union and intersection of the two sets.
-
-
-
diff --git a/slides_sources/old_versions/week-04/code/students_languages.txt b/slides_sources/old_versions/week-04/code/students_languages.txt
deleted file mode 100644
index 7c93ec6..0000000
--- a/slides_sources/old_versions/week-04/code/students_languages.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-name: languages
-Barker, Chris: Python, C, C++, Shell, Fortran, Pascal
-Rakita, Joshua: C#, Java, Python, JavaScript
-Antoun, Jo-Anne: python (GIS)
-AuBuchon, Harlan: python, java
-Bae, Andrew: pascal, C, C#
-Chan, Lawrence: VB
-Chhen, Rithy: PHP, java, JS, SQL
-Colwell, Kimberly: pascal
-Cypret, Luke: bash, python, sql
-Eaton, Sako: php, sql
-Edson, Howard: SQL, C++
-Flagg, Nate: basic, pascal, C, c#, TCL
-Gapasin, Anne-Lynn: java, C#, perl, XML, assembly
-Grizzel, Travis: shell,
-Ivers, Brandon: ruby,
-Kang, Dong: Java
-Leblanc, Adam: C, C++, ADA, Java, C#
-Moore, Blane: C++, java
-Onen, Omer: matlab, skil
-Parrish, Brent: python, JS
-Pei, Guangyu (gary): C, C++
-Petrova, Maria: R, SQL
-Popish, Mario: shell
-Rajagopalan, Sridharan: C, Java, C++
-Salkodu Parameshwar, Maitri: C, C++, bash
-Savage, Nathan: py3, PHP,
-Schmitz, Brian: javascript, PHP
-Small, Edward (Ryan): python, JS
-Smith, Richard: C++, Java, XML, Shell
-Thach, Phuc: php, JS
-Tran, Linh: html, java
-Warren, Catherine: SQL
-Werner, Steven: javascript
-Wright, Duane:
diff --git a/slides_sources/old_versions/week-04/code/students_languages_solution.py b/slides_sources/old_versions/week-04/code/students_languages_solution.py
deleted file mode 100755
index 8ca97aa..0000000
--- a/slides_sources/old_versions/week-04/code/students_languages_solution.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-"""
-simple script to extract a list of languages that the students have used in the past.
-
-This script parses the text file created on the first day of class.
-"""
-
-infile = open("../../week-01/code/students.txt")
-
-languages = set() # use a set to store -- order doesn't matter, and we don't want duplicates
-
-infile.readline() # skip the first line
-for line in infile:
- langs = line.split(':')[1]
- langs = langs.split(',')
- for lang in langs:
- lang = lang.strip()
- lang = lang.lower() # case doesn't matter
- if lang:
- languages.add(lang)
-languages = list(languages) # so we can sort it
-languages.sort()
-
-print "The programming languages previously used by students are:"
-for lang in languages:
- print lang
-
-
-
-
-
diff --git a/slides_sources/old_versions/week-04/homework/kata_fourteen_t.html b/slides_sources/old_versions/week-04/homework/kata_fourteen_t.html
deleted file mode 100644
index a9b51d2..0000000
--- a/slides_sources/old_versions/week-04/homework/kata_fourteen_t.html
+++ /dev/null
@@ -1,459 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CodeKata: Kata Fourteen: Tom Swift Under Milk Wood
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- How to Become a Better Developer
-
-
-
-
-
-
-
-
-
-
-
-
-
- « Kata Sixteen: Business Rules |
- Main
- | Kata Thirteen: Counting Code Lines »
-
-
-
-
-
-
-
-
-
-
-
-
-Trigrams can be used to mutate text into new, surreal, forms. But what
-heuristics do we apply to get a reasonable result?
-
-
-
-
- As a boy, one of my treats was go to the shops on a Saturday and spend part
-of my allowance on books; for a nine-year old, I had quite a collection of
-Tom Swift and Hardy Boys. Wouldn’t it be great to be able to create
-more and more of these classic books, to be able to generate a new Tom
-Swift adventure on demand?
-
-
-OK, perhaps not. But that won’t stop us trying. I coded up a quick
-program to generate some swash-buckling scientific adventure on demand. It
-came up with:
-
-
-…it was in the wind that was what he thought was his companion. I
-think would be a good one and accordingly the ship their situation
-improved. Slowly so slowly that it beat the band! You’d think no one
-was a low voice. "Don’t take any of the elements and the
-inventors of the little Frenchman in the enclosed car or cabin completely
-fitted up in front of the gas in the house and wringing her hands.
-"I’m sure they’ll fall!"
-
-
-She looked up at them. He dug a mass of black vapor which it had
-refused to accept any. As for Mr. Swift as if it goes too high I’ll
-warn you and you can and swallow frequently. That will make the airship was
-shooting upward again and just before the raid wouldn’t have been
-instrumental in capturing the scoundrels right out of jail."
-
-
-
-
-Stylistically, it’s Victor Appleton meets Dylan Thomas. Technically,
-it’s all done with trigrams.
-
-
-Trigram analysis is very simple. Look at each set of three adjacent words
-in a document. Use the first two words of the set as a key, and remember
-the fact that the third word followed that key. Once you’ve finished,
-you know the list of individual words that can follow each two word
-sequence in the document. For example, given the input:
-
-
I wish I may I wish I might
-
-
-You might generate:
-
-
"I wish" => ["I", "I"]
- "wish I" => ["may", "might"]
- "may I" => ["wish"]
- "I may" => ["I"]
-
-
-This says that the words "I wish" are twice followed by the word
-"I", the words "wish I" are followed once by
-"may" and once by "might" and so on.
-
-
-To generate new text from this analysis, choose an arbitrary word pair as a
-starting point. Use these to look up a random next word (using the table
-above) and append this new word to the text so far. This now gives you a
-new word pair at the end of the text, so look up a potential next word
-based on these. Add this to the list, and so on. In the previous example,
-we could start with "I may". The only possible next word is
-"I", so now we have:
-
-
I may I
-
-
-The last two words are "may I", so the next word is
-"wish". We then look up "I wish", and find our choice
-is constrained to another "I".
-
-
I may I wish I
-
-
-Now we look up "wish I", and find we have a choice. Let’s
-choose "may".
-
-
I may I wish I may
-
-
-Now we’re back where we started from, with "I may."
-Following the same sequence, but choosing "might" this time, we
-get:
-
-
I may I wish I may I wish I might
-
-
-At this point we stop, as no sequence starts "I might."
-
-
-Given a short input text, the algorithm isn’t too interesting. Feed
-it a book, however, and you give it more options, so the resulting output
-can be surprising.
-
-
-For this kata, try implementing a trigram algorithm that generates a couple
-of hundred words of text using a book-sized file as input. Project Gutenberg is a good source of online
-books (Tom Swift and His Airship is here ). Be warned
-that these files have DOS line endings (carriage return followed by
-newline).
-
-
Objectives
-
-Kata’s are about trying something many times. In this one, what
-we’re experimenting with is not just the code, but the heuristics of
-processing the text. What do we do with punctuation? Paragraphs? Do we have
-to implement backtracking if we chose a next word that turns out to be a
-dead end?
-
-
-I’ll fire the signal and the fun will commence…
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TrackBack URL for this entry:http://www.typepad.com/services/trackback/6a00d83451c41c69e200d8353d46a953ef
-
Listed below are links to weblogs that reference Kata Fourteen: Tom Swift Under Milk Wood :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Dave's blog, which stuff on Ruby, Rails, general programming, careers, and other stuff.
- Where
- it all started! Have a look at the books we're publishing on all sorts
-of programming topics. If you liked the kata, you might also like
The Best of Ruby Quiz .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-04/homework/sherlock_small.txt b/slides_sources/old_versions/week-04/homework/sherlock_small.txt
deleted file mode 100644
index 992a29b..0000000
--- a/slides_sources/old_versions/week-04/homework/sherlock_small.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-One night--it was on the twentieth of March, 1888--I was
-returning from a journey to a patient (for I had now returned to
-civil practice), when my way led me through Baker Street. As I
-passed the well-remembered door, which must always be associated
-in my mind with my wooing, and with the dark incidents of the
-Study in Scarlet, I was seized with a keen desire to see Holmes
-again, and to know how he was employing his extraordinary powers.
-His rooms were brilliantly lit, and, even as I looked up, I saw
-his tall, spare figure pass twice in a dark silhouette against
-the blind. He was pacing the room swiftly, eagerly, with his head
-sunk upon his chest and his hands clasped behind him. To me, who
-knew his every mood and habit, his attitude and manner told their
-own story. He was at work again. He had risen out of his
-drug-created dreams and was hot upon the scent of some new
-problem. I rang the bell and was shown up to the chamber which
-had formerly been in part my own.
diff --git a/slides_sources/old_versions/week-04/homework/trigram_solution.py b/slides_sources/old_versions/week-04/homework/trigram_solution.py
deleted file mode 100644
index fb2759f..0000000
--- a/slides_sources/old_versions/week-04/homework/trigram_solution.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#/usr/bin/ev python
-
-"""
-Trigram.py
-
-A solution to the trigram coding Kata:
-
-http://codekata.pragprog.com/2007/01/kata_fourteen_t.html
-
-Chris Barker's Solution
-"""
-
-# infilename = "sherlock_small.txt"
-infilename = "sherlock.txt"
-
-import string
-import random
-
-# translation table for string.translate:
-# I use this to purge the punctuation..
-
-# stuff I want to keep:
-valid = string.letters + "'" # keep the contractions
-all = ''.join([chr(i) for i in range(256)])
-table = []
-for c in all:
- if c in valid:
- table.append(c)
- else:
- table.append(' ')
-table = ''.join(table)
-
-infile = open(infilename, 'r')
-# strip out the header, table of contents, etc.
-for i in range(61):
- infile.readline()
-# read the rest of the file into memory
-in_data = infile.read()
-
-# Dictionary for trigram results:
-# The keys will be all the word pairs
-# The values will be a list of the words that follow each pair
-word_pairs = {}
-
-# lower-case everything to remove that complication:
-in_data = in_data.lower()
-
-# strip out the punctuation:
-in_data = in_data.translate(table)
-
-# split into words
-words = in_data.split()
-
-# remove the bare single quotes
-# " ' " is both a quote and an apostrophe
-words = [word for word in words if word != "'"]
# loop through the words
-for i in range(len(words) - 2):
- pair = " ".join(words[i:i+2])
- follower = words[i+2]
- # setdefault() returns the value if pair is already in the dict
- # if it's not, it adds it, setting the value to a an empty list
- # then it returns the list, which we then append the following
- # word to.
- word_pairs.setdefault(pair,[]).append(follower)
-
-
-# A little reporting
-#for pair, followers in word_pairs.items():
-# if len(followers) > 1:
-# print pair, followers
-
-# create some new text
-new_text = []
-for i in range (100): # do 100 sets.
- pair = random.sample(word_pairs, 1)[0]
- follower = random.sample(word_pairs[pair], 1)[0]
- new_text.extend( (pair, follower) )
-
-new_text = " ".join(new_text)
-
-print new_text
-
diff --git a/slides_sources/old_versions/week-04/presentation-week-04.pdf b/slides_sources/old_versions/week-04/presentation-week-04.pdf
deleted file mode 100644
index 0e8034c..0000000
Binary files a/slides_sources/old_versions/week-04/presentation-week-04.pdf and /dev/null differ
diff --git a/slides_sources/old_versions/week-04/presentation-week-04.tex b/slides_sources/old_versions/week-04/presentation-week-04.tex
deleted file mode 100644
index 53fe1d3..0000000
--- a/slides_sources/old_versions/week-04/presentation-week-04.tex
+++ /dev/null
@@ -1,1062 +0,0 @@
-\documentclass{beamer}
-%\usepackage[latin1]{inputenc}
-\usetheme{Warsaw}
-\title[Intro to Python: Week 4]{Introduction to Python:\\ Dictionaries, Sets, Exceptions\\ Files and Text Processing}
-\author{Christopher Barker}
-\institute{UW Continuing Education}
-\date{October 22, 2013}
-
-\usepackage{listings}
-\usepackage{hyperref}
-
-\begin{document}
-
-% ---------------------------------------------
-\begin{frame}
- \titlepage
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}
-\frametitle{Table of Contents}
-%\tableofcontents[currentsection]
- \tableofcontents
-\end{frame}
-
-
-\section{Review/Questions}
-
-% ---------------------------------------------
-\begin{frame}{Review of Previous Class}
-
-\begin{itemize}
- \item Sequences
- \item Lists
- \item Tuples
-\end{itemize}
-
-\vfill
-{\Large Any questions?}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}{Lightning Talks}
-
-\vfill
-{\LARGE Lightning talks today:}
-
-\vfill
-{\Large ( Jo-Anne Antoun )}
-
-\vfill
-{\Large
- Sako Eaton
-
-\vfill
-Brandon Ivers
-
-\vfill
-Gary Pei
-
-\vfill
-Nathan Savage
-
-}
-\vfill
-
-\end{frame}
-
-
-% --------------------------------------------
-\begin{frame}[fragile]{Notes on Workflow}
-
- \vfill
- {\Large For more than a few lines:}
-
- \vfill
- {\large Write your code in a module}
-
- \vfill
- {\large Have a way to re-run quickly}
- \begin{itemize}
- \item Plain command line: \verb|$ python my_script.py|
- \item iPython: \verb|run my_script.py|
- \item The ``run'' button / keystroke in your IDE.
- \end{itemize}
-
- \vfill
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}{Finish Last Class...}
-
- \vfill
- {\Large More on Looping}
-
- \vfill
- {\Large Strings!}
-
- \vfill
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}{Lightning Talks}
-
-{\LARGE Lightning Talks:}
-
-\vfill
-{\Large
-Jo-Anne Antoun
-
-}
-\vfill
-
-\end{frame}
-
-
-% ##################################
-\section{Dictionaries and Sets}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary}
-
-{\Large Python calls it a \verb|dict| }
-
-\vfill
-{\Large Other languages call it:}
-\begin{itemize}
- \item dictionary
- \item associative array
- \item map
- \item hash table
- \item hash
- \item key-value pair
-\end{itemize}
-
-\vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Constructors}
-
-\begin{verbatim}
->>> {'key1': 3, 'key2': 5}
-{'key1': 3, 'key2': 5}
-
->>> dict([('key1', 3),('key2', 5)])
-{'key1': 3, 'key2': 5}
-
->>> dict(key1=3, key2= 5)
-{'key1': 3, 'key2': 5}
-
->>> d = {}
->>> d['key1'] = 3
->>> d['key2'] = 5
->>> d
-{'key1': 3, 'key2': 5}
-\end{verbatim}
-% {\Large Which to use depends on the shape of your data}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\begin{verbatim}
->>> d = {'name': 'Brian', 'score': 42}
->>> d['score']
-42
->>> d = {1: 'one', 0: 'zero'}
->>> d[0]
-'zero'
->>> d['non-existing key']
-Traceback (most recent call last):
- File "", line 1, in
-KeyError: 'non-existing key'
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-{\Large Keys can be any immutable:}
-\begin{itemize}
- \item numbers
- \item string
- \item tuples
-\end{itemize}
-
-\begin{verbatim}
-In [325]: d[3] = 'string'
-In [326]: d[3.14] = 'pi'
-In [327]: d['pi'] = 3.14
-In [328]: d[ (1,2,3) ] = 'a tuple key'
-In [329]: d[ [1,2,3] ] = 'a list key'
- TypeError: unhashable type: 'list'
-\end{verbatim}
-
-\vfill
-Actually -- any "hashable" type.
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\vfill
-{\Large hash functions convert arbitrarily large data to a small proxy (usually int)
-
-\vfill
-always return the same proxy for the same input
-
-\vfill
-MD5, SHA, etc
-\vfill
-}
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\vfill
-{\Large
-Dictionaries hash the key to an integer proxy and use it to find the key and value
-}
-\vfill
-{\Large
-Key lookup is efficient because the hash function leads directly to a bucket with a very few keys (often just one)
-}
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\vfill
-{\Large
-What would happen if the proxy changed after storing a key?
-}
-\vfill
-{\Large
-Hashability requires immutability}
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\vfill
-{\Large
-
-Key lookup is very efficient
-
-\vfill
-Same average time regardless of size
-}
-
-\vfill
-also... Python name look-ups are implemented with dict:
-
- --- its highly optimized
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Indexing}
-
-\vfill
-{\Large
-{\center
-
-key to value
-
-lookup is one way
-
-}}
-\vfill
-{\Large
-{\center
-
-value to key
-
-requires visiting the whole dict
-
-}}
-
-\vfill
-{\Large
-if you need to check dict values often, create another dict or set (up to you to keep them in sync)
-
-}
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Ordering (not)}
-
-\vfill
-{\Large
-dictionaries have no defined order
-}
-\vfill
-\begin{verbatim}
-In [352]: d = {'one':1, 'two':2, 'three':3}
-
-In [353]: d
-Out[353]: {'one': 1, 'three': 3, 'two': 2}
-
-In [354]: d.keys()
-Out[354]: ['three', 'two', 'one']
-\end{verbatim}
-\vfill
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Dictionary Iterating}
-
-{\Large \verb|for| iterates the keys}
-\vfill
-\begin{verbatim}
->>> d = {'name': 'Brian', 'score': 42}
->>> for x in d:
-... print x
-...
-score name
-\end{verbatim}
-\vfill
-{note the different order...}
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{dict keys and values}
-
-\vfill
-\begin{verbatim}
->>> d.keys()
-['score', 'name']
-
->>> d.values()
-[42, 'Brian']
-
->>> d.items()
-[('score', 42), ('name', 'Brian')]
-\end{verbatim}
-\vfill
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{dict keys and values}
-
-{\Large iterating on everything}
-\vfill
-\begin{verbatim}
->>> d = {'name': 'Brian', 'score': 42}
->>> for k, v in d.items():
-... print "%s: %s" % (k, v)
-...
-score: 42
-name: Brian
-\end{verbatim}
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Dictionary Performance }
-
-\begin{itemize}
- \item indexing is fast and constant time: O(1)
- \item x in s cpnstant time: O(1)
- \item visiting all is proportional to n: O(n)
- \item inserting is constant time: O(1)
- \item deleting is constant time: O(1)
-\end{itemize}
-
-\vfill
-\url{ http://wiki.python.org/moin/TimeComplexity}
-
-\end{frame}
-
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{ Sets }
-
-\vfill
-{\Large \verb|set| is an unordered collection of distinct values}
-
-\vfill
-{\Large Essentially a dict with only keys}
-
-\vfill
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Set Constructors}
-
-\vfill
-\begin{verbatim}
->>> set()
-set([])
->>> set([1, 2, 3])
-set([1, 2, 3])
-# as of 2.7
->>> {1, 2, 3}
-set([1, 2, 3])
->>> s = set()
->>> s.update([1, 2, 3])
->>> s
-set([1, 2, 3])
-\end{verbatim}
-\vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{ Set Properties}
-
-\vfill
-{\Large \verb|Set| members must be hashable}
-
-\vfill
-{\Large Like dictionary keys -- and for same reason (efficient lookup)}
-
-\vfill
-{\Large No indexing (unordered) }
-
-\vfill
-\begin{verbatim}
->>> s[1]
-Traceback (most recent call last):
- File "", line 1, in
-TypeError: 'set' object does not support indexing
-\end{verbatim}
-
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{ Set Methods}
-
-\begin{verbatim}
->> s = set([1])
->>> s.pop() # an arbitrary member
-1
->>> s.pop()
-Traceback (most recent call last):
- File "", line 1, in
-KeyError: 'pop from an empty set'
-
->>> s = set([1, 2, 3])
->>> s.remove(2)
->>> s.remove(2)
-Traceback (most recent call last):
- File "", line 1, in
-KeyError: 2
-\end{verbatim}
-
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{ Set Methods}
-
-\begin{verbatim}
-s.isdisjoint(other)
-
-s.issubset(other)
-
-s.union(other, ...)
-
-s.intersection(other, ...)
-
-s.difference(other, ...)
-
-s.symmetric_difference( other, ...)
-\end{verbatim}
-
-\vfill
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{ Frozen Set}
-
-\vfill
-{\Large Also \verb|frozenset|}
-
-\vfill
-{\Large immutable -- for use as a key in a dict\\
-(or another set...)}
-
-\vfill
-\begin{verbatim}
->>> fs = frozenset((3,8,5))
->>> fs.add(9)
-Traceback (most recent call last):
- File "", line 1, in
-AttributeError: 'frozenset' object has no attribute 'add'
-\end{verbatim}
-
-\vfill
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-\vfill
-{\Large Dictionary LAB:}
-
-\vfill
-{\large \verb|code/dict_lab.html (rst) |}
-
-\vfill
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}{Lightning Talks}
-
-{\LARGE Lightning Talks:}
-
-\vfill
-{\Large
- Sako Eaton
-
-\vfill
-Brandon Ivers
-}
-\vfill
-
-\end{frame}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Exceptions}
-
-%-----------------------------------
-\begin{frame}[fragile]{Exceptions}
-
-{\Large Another Branching structure:}
-\vfill
-\begin{verbatim}
-try:
- do_something()
- f = open('missing.txt')
- process(f) # never called if file missing
-except IOError:
- print "couldn't open missing.txt"
-\end{verbatim}
-\vfill
-\end{frame}
-
-\begin{frame}[fragile]{Exceptions}
-
-{\Large Never Do this:}
-\vfill
-\begin{verbatim}
-try:
- do_something()
- f = open('missing.txt')
- process(f) # never called if file missing
-except:
- print "couldn't open missing.txt"
-\end{verbatim}
-\vfill
-\end{frame}
-
-\begin{frame}[fragile]{Exceptions}
-
-{\Large Use Exceptions, rather than your own tests
-
- \hspace{0.1in} -- Don't do this:}
-
-\vfill
-\begin{verbatim}
-do_something()
-if os.path.exists('missing.txt'):
- f = open('missing.txt')
- process(f) # never called if file missing
-\end{verbatim}
-\vfill
-it will almost always work -- but the almost will drive you crazy
-\end{frame}
-
-
-\begin{frame}[fragile]{Exceptions}
-
-{\centering
-
-{\Large "easier to ask forgiveness than permission"
-\vfill
-\hfill -- Grace Hopper
-}
-}
-
-\vfill
-\url{http://www.youtube.com/watch?v=AZDWveIdqjY}
-
-(Pycon talk by Alex Martelli)
-\end{frame}
-
-
-\begin{frame}[fragile]{Exceptions}
-
-\vfill
-{\Large
-For simple scripts, let exceptions happen\\
-\vfill
-
-Only handle the exception if the code can and will do something about it
-}
-\vfill
-(much better debugging info when an error does occur)
-\end{frame}
-
-
-\begin{frame}[fragile]{Exceptions -- finally }
-
-\vfill
-\begin{verbatim}
-try:
- do_something()
- f = open('missing.txt')
- process(f) # never called if file missing
-except IOError:
- print "couldn't open missing.txt"
-finally:
- do_some_clean-up
-\end{verbatim}
-\vfill
-{\Large the \verb|finally:| clause will always run}
-\end{frame}
-
-\begin{frame}[fragile]{Exceptions -- else }
-
-\vfill
-\begin{verbatim}
-try:
- do_something()
- f = open('missing.txt')
-except IOError:
- print "couldn't open missing.txt"
-else:
- process(f) # only called if there was no exception
-\end{verbatim}
-\vfill
-{\Large Advantage:
-
-you know where the Exception came from}
-\end{frame}
-
-%--------------------------------------------
-\begin{frame}[fragile]{Exceptions -- using them }
-
-\vfill
-\begin{verbatim}
-try:
- do_something()
- f = open('missing.txt')
-except IOError as the_error:
- print the_error
- the_error.extra_info = "some more information"
- raise
-\end{verbatim}
-
-{\Large Particularly useful if you catch more than one exception:}
-
-\begin{verbatim}
-except (IOError, BufferError, OSError) as the_error:
- do_something_with (the_error)
-\end{verbatim}
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Raising Exceptions }
-
-\begin{verbatim}
-def divide(a,b):
- if b == 0:
- raise ZeroDivisionError("b can not be zero")
- else:
- return a / b
-\end{verbatim}
-\vfill
-{\Large when you call it: }
-\vfill
-\begin{verbatim}
-In [515]: divide (12,0)
-
-ZeroDivisionError: b can not be zero
-\end{verbatim}
-
-\end{frame}
-
-
-
-\begin{frame}[fragile]{Built in Exceptions}
-
-{\Large You can create your own custom exceptions}
-
-{\Large But...}
-
-\begin{verbatim}
-exp = \
- [name for name in dir(__builtin__) if "Error" in name]
-
-len(exp)
-32
-\end{verbatim}
-
-{\Large For the most part, you can/should use a built in one}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large Exceptions Lab: Improving \verb|raw_input|:}
-
-{\large
-\vfill
-The \verb|raw_input()| function can generate two exceptions:
-\verb|EOFError| or \verb|KeyboardInterrupt| on end-of-file
-(EOF) or canceled input.
-
-\vfill
-Create a wrapper function, perhaps \verb|safe_input()| that returns
-\verb|None| rather rather than raising these exceptions, when
-the user enters \verb|^C| for Keyboard Interrupt, or \verb|^D|
-(\verb|^Z| on Windows) for End Of File.
-}
-
-\vfill
-\end{frame}
-
-%-------------------------------
-\begin{frame}{Lightning Talks}
-
-{\LARGE Lightning Talks:}
-
-{\Large
-\vfill
-Gary Pei
-
-\vfill
-Nathan Savage
-}
-\vfill
-
-\end{frame}
-
-\section{File Reading and Writing}
-
-%-------------------------------
-\begin{frame}[fragile]{Files}
-
-{\Large Text Files}
-
-\begin{verbatim}
-f = open('secrets.txt')
-secret_data = f.read()
-f.close()
-\end{verbatim}
-
-{\Large \verb|secret_data| is a string}
-
-\vfill
-(can also use \verb|file()| -- \verb|open()| is preferred)
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Files}
-
-{\Large Binary Files}
-
-\begin{verbatim}
-f = open('secrets.txt', 'rb')
-secret_data = f.read()
-f.close()
-\end{verbatim}
-
-{\Large \verb|secret_data| is still a string \\[.1in]
-(with arbitrary bytes in it)}
-\vfill
-(See the \verb|struct| module to unpack binary data )
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Files}
-
-{\Large File Opening Modes}
-\vfill
-\begin{verbatim}
-f = open('secrets.txt', [mode])
-
-'r', 'w', 'a'
-'rb', 'wb', 'ab'
-r+, w+, a+
-r+b, w+b, a+b
-U
-U+
-\end{verbatim}
-\vfill
-{\Large Gotcha -- w mode always clears the file}
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Text File Notes}
-
-{\Large Text is default}
-\begin{itemize}
- \item Newlines are translated: \verb|\r\n -> \n|
- \item -- reading and writing!
- \item Use *nux-style in your code: \verb|\n|
- \item Open text files with \verb|'U'| "Universal" flag
-\end{itemize}
-
-\vfill
-{\Large Gotcha:}
-\begin{itemize}
- \item no difference between text and binary on *nix\\
- \begin{itemize}
- \item breaks on Windows
- \end{itemize}
-\end{itemize}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{File Reading}
-
-{\Large Reading Part of a file}
-
-\begin{verbatim}
-header_size = 4096
-
-f = open('secrets.txt')
-secret_data = f.read(header_size)
-f.close()
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{File Reading}
-
-{\Large Common Idioms}
-
-\begin{verbatim}
-for line in open('secrets.txt'):
- print line
-\end{verbatim}
-
-\begin{verbatim}
-f = open('secrets.txt')
-while True:
- line = f.readline()
- if not line:
- break
- do_something_with_line()
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{File Writing}
-
-\begin{verbatim}
-
-outfile = open('output.txt', 'w')
-
-for i in range(10):
- outfile.write("this is line: %i\n"%i)
-
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{File Methods}
-
-{\Large Commonly Used Methods}
-\begin{verbatim}
-
-f.read() f.readline() f.readlines()
-
-f.write(str) f.writelines(seq)
-
-f.seek(offset) f.tell()
-
-f.flush()
-
-f.close()
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{File Like Objects}
-
-{\Large File-like objects }
-\vfill
-{\large Many classes implement the file interface:}
-\vfill
-\begin{itemize}
- \item loggers
- \item \verb|sys.stdout|
- \item \verb|urllib.open()|
- \item pipes, subprocesses
- \item StringIO
-\end{itemize}
-
-\url{http://docs.python.org/library/stdtypes.html#bltin-‐file-‐objects}
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{StringIO}
-
-{\Large StringIO }
-\vfill
-\begin{verbatim}
-In [417]: import StringIO
-In [420]: f = StringIO.StringIO()
-
-In [421]: f.write("somestuff")
-
-In [422]: f.seek(0)
-
-In [423]: f.read()
-Out[423]: 'somestuff'
-\end{verbatim}
-
-{\Large handy for testing}
-\end{frame}
-
-
-\section{Paths and Directories}
-
-% ----------------------------------
-\begin{frame}[fragile]{Paths}
-
-{\Large Relative paths:}
-
-\begin{verbatim}
-secret.txt
-./secret.txt
-\end{verbatim}
-
-{\Large Absolute paths:}
-\begin{verbatim}
-/home/chris/secret.txt
-\end{verbatim}
-
-{\Large Either work with \verb|open()|, etc.}
-
-\vfill
-(working directory only makes sense with command-line programs...)
-\end{frame}
-
-% ----------------------------------
-\begin{frame}[fragile]{os.path}
-
-\begin{verbatim}
-os.getcwd() -- os.getcwdu()
-chdir(path)
-
-os.path.abspath()
-os.path.relpath()
-\end{verbatim}
-
-\end{frame}
-
-% ----------------------------------
-\begin{frame}[fragile]{os.path}
-
-\vfill
-\begin{verbatim}
-os.path.split()
-os.path.splitext()
-os.path.basename()
-os.path.dirname()
-os.path.join()
-\end{verbatim}
-
-\vfill
-(all platform independent)
-
-\end{frame}
-
-
-% ----------------------------------
-\begin{frame}[fragile]{directories}
-
-\vfill
-\begin{verbatim}
-os.listdir()
-os.mkdir()
-
-os.walk()
-
-\end{verbatim}
-
-\vfill
-(higher level stuff in \verb|shutil| module)
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large Paths and File Processing}
-
-\begin{itemize}
- \item write a program which prints the full path to all files
- in the current directory, one per line
- \item write a program which copies a file from a source, to a
- destination (without using shutil, or the OS copy command)
- \item write a program that extracts all the programming languages that the students in this class used before (\verb|code\students_languages.txt|)
- \item update mail-merge from the earlier lab to write output
- to individual files on disk
-\end{itemize}
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{Homework}
-
-{\large Recommended Reading}
-\begin{itemize}
- \item Dive Into Python: Chapt. 13,14
- \item Unicode: \url{http://www.joelonsoftware.com/articles/Unicode.html}
-\end{itemize}
-
-\vfill
-{\large Do the Labs you didn't finish in class}
-
-\vfill
-\begin{itemize}
- \item Coding Kata 14 - Dave Thomas \\
- \url{http://codekata.pragprog.com/2007/01/ kata_fourteen_t.html}
-
- \item Use The Adventures of Sherlock Holmes as input:\\
- \verb|code/sherlock.txt| (ascii)
-
- \item This is intentionally open-ended and underspecified. There are many interesting decisions to make.
-
- \item Experiment with different lengths for the lookup key. (3 words, 4 words, 3 letters, etc)
-\end{itemize}
-
-\end{frame}
-
-
-\end{document}
-
-
diff --git a/slides_sources/old_versions/week-05/code/codingbat.py b/slides_sources/old_versions/week-05/code/codingbat.py
deleted file mode 100644
index 2bb34eb..0000000
--- a/slides_sources/old_versions/week-05/code/codingbat.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Examples from: http://codingbat.com
-
-Put here so we can write unit tests for them ourselves
-"""
-
-# Python > Warmup-1 > sleep_in
-
-def sleep_in(weekday, vacation):
- return not (weekday == True and vacation == False)
-
-
diff --git a/slides_sources/old_versions/week-05/code/codingbat_unittest.py b/slides_sources/old_versions/week-05/code/codingbat_unittest.py
deleted file mode 100755
index c242e26..0000000
--- a/slides_sources/old_versions/week-05/code/codingbat_unittest.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-
-"""
-test file for codingbat module
-
-This version used unittest
-"""
-
-import unittest
-from codingbat import sleep_in
-
-class Test_sleep_in(unittest.TestCase):
-
- def test_false_false(self):
- self.assertTrue( sleep_in(False, False) )
-
- def test_true_false(self):
- self.assertFalse( sleep_in(True, False) )
-
- def test_false_true(self):
- self.assertTrue( sleep_in(False, True) )
-
- def test_true_true(self):
- self.assertTrue( sleep_in(True, True) )
-
-if __name__ == "__main__":
- unittest.main()
-
-
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-05/code/comprehension.html b/slides_sources/old_versions/week-05/code/comprehension.html
deleted file mode 100644
index 1ec91a2..0000000
--- a/slides_sources/old_versions/week-05/code/comprehension.html
+++ /dev/null
@@ -1,510 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1. Creating lists with list comprehensions
-
-
->>> feast = ['lambs', 'sloths', 'orangutans', 'breakfast cereals',
- 'fruit bats']
-
-
->>> comprehension = [delicacy.capitalize() for delicacy in feast]
-
-
-
-
What is the output of:
-
-
->>> comprehension[0]
-???
-
-
->>> comprehension[2]
-???
-
-
-
-
-
-
2. Filtering lists with list comprehensions
-
-
->>> feast = ['spam', 'sloths', 'orangutans', 'breakfast cereals',
- 'fruit bats']
-
-
->>> comprehension = [delicacy for delicacy in feast if len(delicacy) > 6]
-
-
-
-
What is the output of:
-
-
->>> len(feast)
-???
-
-
->>> len(comprehension)
-???
-
-
-
-
-
-
3. Unpacking tuples in list comprehensions
-
-
->>> list_of_tuples = [(1, 'lumberjack'), (2, 'inquisition'), (4, 'spam')]
-
-
->>> comprehension = [ skit * number for number, skit in list_of_tuples ]
-
-
-
-
What is the output of:
-
-
->>> comprehension[0]
-???
-
-
->>> len(comprehension[2])
-???
-
-
-
-
-
-
4. Double list comprehension
-
-
->>> list_of_eggs = ['poached egg', 'fried egg']
-
-
->>> list_of_meats = ['lite spam', 'ham spam', 'fried spam']
-
-
->>> comprehension = [ '{0} and {1}'.format(egg, meat) for egg in list_of_eggs for meat in list_of_meats]
-
-
-
-
What is the output of:
-
-
->>> len(comprehension)
-???
-
-
->>> comprehension[0]
-
-
-
-
-
-
5. Creating a set with set comprehension
-
-
->>> comprehension = { x for x in 'aabbbcccc'}
-
-
-
-
What is the output of:
-
-
->>> comprehension
-???
-
-
-
-
-
-
6. Creating a dictionary with dictionary comprehension
-
-
->>> dict_of_weapons = {'first': 'fear', 'second': 'surprise',
- 'third':'ruthless efficiency', 'forth':'fanatical devotion',
- 'fifth': None}
-
-
->>> dict_comprehension = { k.upper(): weapon for k, weapon in dict_of_weapons.iteritems() if weapon}
-
-
-
-
-
-
7. Count even numbers
-
This is from CodingBat "count_evens" (http://codingbat.com/prob/p189616 )
-
Using list comprehension , return the number of even ints in the given array. Note: the % "mod" operator computes the remainder, e.g. 5 % 2 is 1.
-
-count_evens([2, 1, 2, 3, 4]) → 3
-count_evens([2, 2, 0]) → 3
-count_evens([1, 3, 5]) → 0
-def count_evens(nums):
-
-
-
-
-
diff --git a/slides_sources/old_versions/week-05/code/comprehension.rst b/slides_sources/old_versions/week-05/code/comprehension.rst
deleted file mode 100644
index 418430a..0000000
--- a/slides_sources/old_versions/week-05/code/comprehension.rst
+++ /dev/null
@@ -1,112 +0,0 @@
-1. Creating lists with list comprehensions
-==========================================
- >>> feast = ['lambs', 'sloths', 'orangutans', 'breakfast cereals',
- 'fruit bats']
-
- >>> comprehension = [delicacy.capitalize() for delicacy in feast]
-
-What is the output of:
-----------------------
- >>> comprehension[0]
- ???
-
- >>> comprehension[2]
- ???
-
-2. Filtering lists with list comprehensions
-===========================================
- >>> feast = ['spam', 'sloths', 'orangutans', 'breakfast cereals',
- 'fruit bats']
-
- >>> comprehension = [delicacy for delicacy in feast if len(delicacy) > 6]
-
-What is the output of:
-----------------------
- >>> len(feast)
- ???
-
- >>> len(comprehension)
- ???
-
-
-3. Unpacking tuples in list comprehensions
-==========================================
- >>> list_of_tuples = [(1, 'lumberjack'), (2, 'inquisition'), (4, 'spam')]
-
- >>> comprehension = [ skit * number for number, skit in list_of_tuples ]
-
-What is the output of:
-----------------------
- >>> comprehension[0]
- ???
-
- >>> len(comprehension[2])
- ???
-
-4. Double list comprehension
-============================
- >>> list_of_eggs = ['poached egg', 'fried egg']
-
- >>> list_of_meats = ['lite spam', 'ham spam', 'fried spam']
-
- >>> comprehension = [ '{0} and {1}'.format(egg, meat) for egg in list_of_eggs for meat in list_of_meats]
-
-What is the output of:
-----------------------
- >>> len(comprehension)
- ???
-
- >>> comprehension[0]
-
-5. Creating a set with set comprehension
-========================================
- >>> comprehension = { x for x in 'aabbbcccc'}
-
-What is the output of:
-----------------------
-
- >>> comprehension
- ???
-
-6. Creating a dictionary with dictionary comprehension
-======================================================
- >>> dict_of_weapons = {'first': 'fear', 'second': 'surprise',
- 'third':'ruthless efficiency', 'forth':'fanatical devotion',
- 'fifth': None}
-
- >>> dict_comprehension = { k.upper(): weapon for k, weapon in dict_of_weapons.iteritems() if weapon}
-
-What is the output of:
-----------------------
->>> 'first' in dict_comprehension
- ???
-
- >>> 'FIRST' in dict_comprehension
- ???
-
- >>> len(dict_of_weapons)
- ???
-
- >>> len(dict_comprehension)
- ???
-
-
-See also: https://github.com/gregmalcolm/python_koans
-https://github.com/gregmalcolm/python_koans/blob/master/python2/koans/about_comprehension.py
-
-
-7. Count even numbers
-=====================
-This is from CodingBat "count_evens" (http://codingbat.com/prob/p189616)
-
-*Using list comprehension*, return the number of even ints in the given array. Note: the % "mod" operator computes the remainder, e.g. 5 % 2 is 1.
-
- count_evens([2, 1, 2, 3, 4]) → 3
-
- count_evens([2, 2, 0]) → 3
-
- count_evens([1, 3, 5]) → 0
-
-
- def count_evens(nums):
-
diff --git a/slides_sources/old_versions/week-05/code/hello_unicode.py b/slides_sources/old_versions/week-05/code/hello_unicode.py
deleted file mode 100644
index fce2866..0000000
--- a/slides_sources/old_versions/week-05/code/hello_unicode.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-
-hello = 'Hello '
-world = u'世界'
-
-print hello + world
-
-print u"It was nice weather today: it reached 80\u00B0"
-
-print u"Maybe it will reach 90\N{degree sign}"
-
-print u"It is extremely rare for it ever to reach 100° in Seattle"
diff --git a/slides_sources/old_versions/week-05/code/test_codingbat.py b/slides_sources/old_versions/week-05/code/test_codingbat.py
deleted file mode 100755
index 4923ebf..0000000
--- a/slides_sources/old_versions/week-05/code/test_codingbat.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-"""
-test file for codingbat module
-
-This version can be run with nose or py.test
-"""
-
-from codingbat import sleep_in
-
-def test_false_false():
- assert sleep_in(False, False)
-
-def test_true_false():
- assert not ( sleep_in(True, False) )
-
-def test_false_true():
- assert sleep_in(False, True)
-
-def test_true_true():
- assert sleep_in(True, True)
-
-
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-05/code/test_pytest_parameter.py b/slides_sources/old_versions/week-05/code/test_pytest_parameter.py
deleted file mode 100644
index 52449af..0000000
--- a/slides_sources/old_versions/week-05/code/test_pytest_parameter.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-
-"""
-pytest example of a parameterized test
-
-NOTE: there is a failure in here! can you fix it?
-
-"""
-import pytest
-
-# a (really simple) function to test
-def add(a, b):
- """
- returns the sum of a and b
- """
- return a + b
-
-# now some test data:
-
-test_data = [ ( ( 2, 3), 5),
- ( (-3, 2), -1),
- ( ( 2, 0.5), 2.5),
- ( ( "this", "that"), "this that"),
- ( ( [1,2,3], [6,7,8]), [1,2,3,6,7,8]),
- ]
-
-@pytest.mark.parametrize(("input", "result"), test_data)
-def test_add(input, result):
- assert add(*input) == result
-
diff --git a/slides_sources/old_versions/week-05/code/test_random_nose.py b/slides_sources/old_versions/week-05/code/test_random_nose.py
deleted file mode 100644
index 9e0fb4e..0000000
--- a/slides_sources/old_versions/week-05/code/test_random_nose.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-
-"""
-port of the random unit tests from the python docs to nose/py.test
-"""
-
-import random
-import nose.tools
-
-seq = range(10)
-
-def test_shuffle():
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(seq)
- seq.sort()
- print seq
- assert seq == range(8)
-
-@nose.tools.raises(TypeError)
-def test_shuffle_immutable():
- # should raise an exception for an immutable sequence
- random.shuffle( (1,2,3) )
-
-def test_choice():
- element = random.choice(seq)
- assert (element in seq)
-
-def test_sample():
- for element in random.sample(seq, 5):
- assert element in seq
-
-@nose.tools.raises(ValueError)
-def test_sample_too_large():
- random.sample(seq, 20)
diff --git a/slides_sources/old_versions/week-05/code/test_random_pytest.py b/slides_sources/old_versions/week-05/code/test_random_pytest.py
deleted file mode 100644
index 5576cc7..0000000
--- a/slides_sources/old_versions/week-05/code/test_random_pytest.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-
-"""
-port of the random unit tests from the python docs to nose/py.test
-"""
-
-import random
-import pytest
-
-
-seq = range(10)
-
-def test_shuffle():
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(seq)
- seq.sort()
- print "seq:", seq
- ## expect this to fail -- so we can see the output.
- assert seq == range(10)
-
-def test_shuffle_immutable():
- pytest.raises(TypeError, random.shuffle, (1,2,3) )
-
-def test_choice():
- element = random.choice(seq)
- assert (element in seq)
-
-def test_sample():
- for element in random.sample(seq, 5):
- assert element in seq
-
-def test_sample_too_large():
- with pytest.raises(ValueError):
- random.sample(seq, 20)
diff --git a/slides_sources/old_versions/week-05/code/text.utf16 b/slides_sources/old_versions/week-05/code/text.utf16
deleted file mode 100644
index f2fd804..0000000
Binary files a/slides_sources/old_versions/week-05/code/text.utf16 and /dev/null differ
diff --git a/slides_sources/old_versions/week-05/code/text.utf32 b/slides_sources/old_versions/week-05/code/text.utf32
deleted file mode 100644
index a713e3e..0000000
Binary files a/slides_sources/old_versions/week-05/code/text.utf32 and /dev/null differ
diff --git a/slides_sources/old_versions/week-05/code/unittest_example.py b/slides_sources/old_versions/week-05/code/unittest_example.py
deleted file mode 100644
index 6458e6c..0000000
--- a/slides_sources/old_versions/week-05/code/unittest_example.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import random
-import unittest
-
-class TestSequenceFunctions(unittest.TestCase):
-
- def setUp(self):
- self.seq = range(10)
-
- def test_shuffle(self):
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(self.seq)
- self.seq.sort()
- self.assertEqual(self.seq, range(10))
-
- # should raise an exception for an immutable sequence
- self.assertRaises(TypeError, random.shuffle, (1,2,3) )
-
- def test_choice(self):
- element = random.choice(self.seq)
- self.assertTrue(element in self.seq)
-
- def test_sample(self):
- with self.assertRaises(ValueError):
- random.sample(self.seq, 20)
- for element in random.sample(self.seq, 5):
- self.assertTrue(element in self.seq)
-
-if __name__ == '__main__':
- unittest.main()
\ No newline at end of file
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.aux b/slides_sources/old_versions/week-05/presentation-week-05.aux
deleted file mode 100644
index fb7173d..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.aux
+++ /dev/null
@@ -1,147 +0,0 @@
-\relax
-\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
-\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
-\global\let\oldcontentsline\contentsline
-\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
-\global\let\oldnewlabel\newlabel
-\gdef\newlabel#1#2{\newlabelxx{#1}#2}
-\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
-\AtEndDocument{\ifx\hyper@anchor\@undefined
-\let\contentsline\oldcontentsline
-\let\newlabel\oldnewlabel
-\fi}
-\fi}
-\global\let\hyper@last\relax
-\gdef\HyperFirstAtBeginDocument#1{#1}
-\providecommand\HyField@AuxAddToFields[1]{}
-\@writefile{toc}{\beamer@endinputifotherversion {3.10pt}}
-\@writefile{nav}{\beamer@endinputifotherversion {3.10pt}}
-\@writefile{nav}{\headcommand {\slideentry {0}{0}{1}{1/1}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {1}{1}}}
-\@writefile{nav}{\headcommand {\slideentry {0}{0}{2}{2/2}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {2}{2}}}
-\@writefile{toc}{\beamer@sectionintoc {1}{Review/Questions}{3}{0}{1}}
-\@writefile{nav}{\headcommand {\sectionentry {1}{Review/Questions}{3}{Review/Questions}{0}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {1}{2}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {1}{2}}}
-\@writefile{nav}{\headcommand {\slideentry {1}{0}{3}{3/3}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {3}{3}}}
-\@writefile{nav}{\headcommand {\slideentry {1}{0}{4}{4/4}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {4}{4}}}
-\@writefile{nav}{\headcommand {\slideentry {1}{0}{5}{5/5}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {5}{5}}}
-\@writefile{toc}{\beamer@sectionintoc {2}{Unicode}{6}{0}{2}}
-\@writefile{nav}{\headcommand {\sectionentry {2}{Unicode}{6}{Unicode}{0}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {3}{5}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {3}{5}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{6}{6/6}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {6}{6}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{7}{7/7}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {7}{7}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{8}{8/8}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {8}{8}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{9}{9/9}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {9}{9}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{10}{10/10}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {10}{10}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{11}{11/11}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {11}{11}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{12}{12/12}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {12}{12}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{13}{13/13}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {13}{13}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{14}{14/14}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {14}{14}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{15}{15/15}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {15}{15}}}
-\@writefile{nav}{\headcommand {\slideentry {2}{0}{16}{16/16}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {16}{16}}}
-\@writefile{toc}{\beamer@sectionintoc {3}{Advanced Argument Passing}{17}{0}{3}}
-\@writefile{nav}{\headcommand {\sectionentry {3}{Advanced Argument Passing}{17}{Advanced Argument Passing}{0}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {6}{16}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {6}{16}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{17}{17/17}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {17}{17}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{18}{18/18}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {18}{18}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{19}{19/19}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {19}{19}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{20}{20/20}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {20}{20}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{21}{21/21}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {21}{21}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{22}{22/22}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {22}{22}}}
-\@writefile{nav}{\headcommand {\slideentry {3}{0}{23}{23/23}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {23}{23}}}
-\@writefile{toc}{\beamer@sectionintoc {4}{List and Dict Comprehensions}{24}{0}{4}}
-\@writefile{nav}{\headcommand {\sectionentry {4}{List and Dict Comprehensions}{24}{List and Dict Comprehensions}{0}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {17}{23}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {17}{23}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{24}{24/24}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {24}{24}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{25}{25/25}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {25}{25}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{26}{26/26}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {26}{26}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{27}{27/27}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {27}{27}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{28}{28/28}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {28}{28}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{29}{29/29}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {29}{29}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{30}{30/30}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {30}{30}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{31}{31/31}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {31}{31}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{32}{32/32}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {32}{32}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{33}{33/33}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {33}{33}}}
-\@writefile{nav}{\headcommand {\slideentry {4}{0}{34}{34/34}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {34}{34}}}
-\@writefile{toc}{\beamer@sectionintoc {5}{Unit Testing}{35}{0}{5}}
-\@writefile{nav}{\headcommand {\sectionentry {5}{Unit Testing}{35}{Unit Testing}{0}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {24}{34}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {24}{34}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{35}{35/35}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {35}{35}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{36}{36/36}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {36}{36}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{37}{37/37}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {37}{37}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{38}{38/38}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {38}{38}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{39}{39/39}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {39}{39}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{40}{40/40}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {40}{40}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{41}{41/41}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {41}{41}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{42}{42/42}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {42}{42}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{43}{43/43}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {43}{43}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{44}{44/44}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {44}{44}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{45}{45/45}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {45}{45}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{46}{46/46}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {46}{46}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{47}{47/47}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {47}{47}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{48}{48/48}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {48}{48}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{49}{49/49}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {49}{49}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{50}{50/50}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {50}{50}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{51}{51/51}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {51}{51}}}
-\@writefile{nav}{\headcommand {\slideentry {5}{0}{52}{52/52}{}{0}}}
-\@writefile{nav}{\headcommand {\beamer@framepages {52}{52}}}
-\@writefile{nav}{\headcommand {\beamer@partpages {1}{52}}}
-\@writefile{nav}{\headcommand {\beamer@subsectionpages {35}{52}}}
-\@writefile{nav}{\headcommand {\beamer@sectionpages {35}{52}}}
-\@writefile{nav}{\headcommand {\beamer@documentpages {52}}}
-\@writefile{nav}{\headcommand {\def \inserttotalframenumber {52}}}
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.log b/slides_sources/old_versions/week-05/presentation-week-05.log
deleted file mode 100644
index c14318a..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.log
+++ /dev/null
@@ -1,1311 +0,0 @@
-This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011) (format=pdflatex 2011.7.3) 29 OCT 2013 17:46
-entering extended mode
- restricted \write18 enabled.
- %&-line parsing enabled.
-**presentation-week-05
-(./presentation-week-05.tex
-LaTeX2e <2009/09/24>
-Babel and hyphenation patterns for english, dumylang, nohyphenation, ge
-rman-x-2009-06-19, ngerman-x-2009-06-19, afrikaans, ancientgreek, ibycus, arabi
-c, armenian, basque, bulgarian, catalan, pinyin, coptic, croatian, czech, danis
-h, dutch, ukenglish, usenglishmax, esperanto, estonian, ethiopic, farsi, finnis
-h, french, galician, german, ngerman, swissgerman, monogreek, greek, hungarian,
- icelandic, assamese, bengali, gujarati, hindi, kannada, malayalam, marathi, or
-iya, panjabi, tamil, telugu, indonesian, interlingua, irish, italian, kurmanji,
- lao, latin, latvian, lithuanian, mongolian, mongolianlmc, bokmal, nynorsk, pol
-ish, portuguese, romanian, russian, sanskrit, serbian, serbianc, slovak, sloven
-ian, spanish, swedish, turkish, turkmen, ukrainian, uppersorbian, welsh, loaded
-.
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamer.cls
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasercs.sty
-Package: beamerbasercs 2010/06/12 (rcs-revision c3821710bb40)
-)
-Document Class: beamer 2010/06/21 development version 3.10 A class for typesett
-ing presentations (rcs-revision a6b1a8434d30)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasemodes.sty
-Package: beamerbasemodes 2010/05/01 (rcs-revision efa082c6111d)
-\beamer@tempbox=\box26
-\beamer@tempcount=\count79
-\c@beamerpauses=\count80
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasedecode.sty
-Package: beamerbasedecode 2010/05/01 (rcs-revision efa082c6111d)
-\beamer@slideinframe=\count81
-\beamer@minimum=\count82
-)
-\beamer@commentbox=\box27
-\beamer@modecount=\count83
-)
-\headheight=\dimen102
-\headdp=\dimen103
-\footheight=\dimen104
-\sidebarheight=\dimen105
-\beamer@tempdim=\dimen106
-\beamer@finalheight=\dimen107
-\beamer@animht=\dimen108
-\beamer@animdp=\dimen109
-\beamer@animwd=\dimen110
-\beamer@leftmargin=\dimen111
-\beamer@rightmargin=\dimen112
-\beamer@leftsidebar=\dimen113
-\beamer@rightsidebar=\dimen114
-\beamer@boxsize=\dimen115
-\beamer@vboxoffset=\dimen116
-\beamer@descdefault=\dimen117
-\beamer@descriptionwidth=\dimen118
-\beamer@lastskip=\skip41
-\beamer@areabox=\box28
-\beamer@animcurrent=\box29
-\beamer@animshowbox=\box30
-\beamer@sectionbox=\box31
-\beamer@logobox=\box32
-\beamer@linebox=\box33
-\beamer@sectioncount=\count84
-\beamer@subsubsectionmax=\count85
-\beamer@subsectionmax=\count86
-\beamer@sectionmax=\count87
-\beamer@totalheads=\count88
-\beamer@headcounter=\count89
-\beamer@partstartpage=\count90
-\beamer@sectionstartpage=\count91
-\beamer@subsectionstartpage=\count92
-\beamer@animationtempa=\count93
-\beamer@animationtempb=\count94
-\beamer@xpos=\count95
-\beamer@ypos=\count96
-\beamer@showpartnumber=\count97
-\beamer@currentsubsection=\count98
-\beamer@coveringdepth=\count99
-\beamer@sectionadjust=\count100
-\beamer@tocsectionnumber=\count101
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseoptions.sty
-Package: beamerbaseoptions 2010/04/27 (rcs-revision 982469101dd6)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/graphics/keyval.sty
-Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
-\KV@toks@=\toks14
-))
-\beamer@paperwidth=\skip42
-\beamer@paperheight=\skip43
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/geometry/geometry.sty
-Package: geometry 2010/09/12 v5.6 Page Geometry
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/ifpdf.sty
-Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO)
-Package ifpdf Info: pdfTeX in PDF mode is detected.
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/ifvtex.sty
-Package: ifvtex 2010/03/01 v1.5 Switches for detecting VTeX and its modes (HO)
-Package ifvtex Info: VTeX not detected.
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/ifxetex/ifxetex.sty
-Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional
-)
-\Gm@cnth=\count102
-\Gm@cntv=\count103
-\c@Gm@tempcnt=\count104
-\Gm@bindingoffset=\dimen119
-\Gm@wd@mp=\dimen120
-\Gm@odd@mp=\dimen121
-\Gm@even@mp=\dimen122
-\Gm@layoutwidth=\dimen123
-\Gm@layoutheight=\dimen124
-\Gm@layouthoffset=\dimen125
-\Gm@layoutvoffset=\dimen126
-\Gm@dimlist=\toks15
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/base/size11.clo
-File: size11.clo 2007/10/19 v1.4h Standard LaTeX file (size option)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty
-(/usr/local/texlive/2011/texmf-dist/tex/latex/graphics/graphicx.sty
-Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/graphics/graphics.sty
-Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/graphics/trig.sty
-Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/latexconfig/graphics.cfg
-File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live
-)
-Package graphics Info: Driver file: pdftex.def on input line 91.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/pdftex-def/pdftex.def
-File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/infwarerr.sty
-Package: infwarerr 2010/04/08 v1.3 Providing info/warning/message (HO)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/ltxcmds.sty
-Package: ltxcmds 2011/04/18 v1.20 LaTeX kernel commands for general use (HO)
-)
-\Gread@gobject=\count105
-))
-\Gin@req@height=\dimen127
-\Gin@req@width=\dimen128
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty
-(/usr/local/texlive/2011/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.te
-x
-\pgfutil@everybye=\toks16
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def
-\pgfutil@abb=\box34
-(/usr/local/texlive/2011/texmf-dist/tex/latex/ms/everyshi.sty
-Package: everyshi 2001/05/15 v3.00 EveryShipout Package (MS)
-))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex
-Package: pgfrcs 2010/10/25 v2.10 (rcs-revision 1.24)
-))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
-Package: pgfsys 2010/06/30 v2.10 (rcs-revision 1.37)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
-\pgfkeys@pathtoks=\toks17
-\pgfkeys@temptoks=\toks18
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.c
-ode.tex
-\pgfkeys@tmptoks=\toks19
-))
-\pgf@x=\dimen129
-\pgf@y=\dimen130
-\pgf@xa=\dimen131
-\pgf@ya=\dimen132
-\pgf@xb=\dimen133
-\pgf@yb=\dimen134
-\pgf@xc=\dimen135
-\pgf@yc=\dimen136
-\w@pgf@writea=\write3
-\r@pgf@reada=\read1
-\c@pgf@counta=\count106
-\c@pgf@countb=\count107
-\c@pgf@countc=\count108
-\c@pgf@countd=\count109
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg
-File: pgf.cfg 2008/05/14 (rcs-revision 1.7)
-)
-Package pgfsys Info: Driver file for pgf: pgfsys-pdftex.def on input line 900.
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.d
-ef
-File: pgfsys-pdftex.def 2009/05/22 (rcs-revision 1.26)
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-p
-df.def
-File: pgfsys-common-pdf.def 2008/05/19 (rcs-revision 1.10)
-)))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.
-code.tex
-File: pgfsyssoftpath.code.tex 2008/07/18 (rcs-revision 1.7)
-\pgfsyssoftpath@smallbuffer@items=\count110
-\pgfsyssoftpath@bigbuffer@items=\count111
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.
-code.tex
-File: pgfsysprotocol.code.tex 2006/10/16 (rcs-revision 1.4)
-)) (/usr/local/texlive/2011/texmf-dist/tex/latex/xcolor/xcolor.sty
-Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/latexconfig/color.cfg
-File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive
-)
-Package xcolor Info: Driver file: pdftex.def on input line 225.
-Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337.
-Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1341.
-Package xcolor Info: Model `RGB' extended on input line 1353.
-Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355.
-Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356.
-Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357.
-Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358.
-Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359.
-Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360.
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
-Package: pgfcore 2010/04/11 v2.10 (rcs-revision 1.7)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
-\pgfmath@dimen=\dimen137
-\pgfmath@count=\count112
-\pgfmath@box=\box35
-\pgfmath@toks=\toks20
-\pgfmath@stack@operand=\toks21
-\pgfmath@stack@operation=\toks22
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.
-tex
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic
-.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigo
-nometric.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.rando
-m.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.compa
-rison.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.
-code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round
-.code.tex)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.
-code.tex)))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
-\c@pgfmathroundto@lastzeros=\count113
-))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.co
-de.tex
-File: pgfcorepoints.code.tex 2010/04/09 (rcs-revision 1.20)
-\pgf@picminx=\dimen138
-\pgf@picmaxx=\dimen139
-\pgf@picminy=\dimen140
-\pgf@picmaxy=\dimen141
-\pgf@pathminx=\dimen142
-\pgf@pathmaxx=\dimen143
-\pgf@pathminy=\dimen144
-\pgf@pathmaxy=\dimen145
-\pgf@xx=\dimen146
-\pgf@xy=\dimen147
-\pgf@yx=\dimen148
-\pgf@yy=\dimen149
-\pgf@zx=\dimen150
-\pgf@zy=\dimen151
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconst
-ruct.code.tex
-File: pgfcorepathconstruct.code.tex 2010/08/03 (rcs-revision 1.24)
-\pgf@path@lastx=\dimen152
-\pgf@path@lasty=\dimen153
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage
-.code.tex
-File: pgfcorepathusage.code.tex 2008/04/22 (rcs-revision 1.12)
-\pgf@shorten@end@additional=\dimen154
-\pgf@shorten@start@additional=\dimen155
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.co
-de.tex
-File: pgfcorescopes.code.tex 2010/09/08 (rcs-revision 1.34)
-\pgfpic=\box36
-\pgf@hbox=\box37
-\pgf@layerbox@main=\box38
-\pgf@picture@serial@count=\count114
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicst
-ate.code.tex
-File: pgfcoregraphicstate.code.tex 2008/04/22 (rcs-revision 1.9)
-\pgflinewidth=\dimen156
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransform
-ations.code.tex
-File: pgfcoretransformations.code.tex 2009/06/10 (rcs-revision 1.11)
-\pgf@pt@x=\dimen157
-\pgf@pt@y=\dimen158
-\pgf@pt@temp=\dimen159
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.cod
-e.tex
-File: pgfcorequick.code.tex 2008/10/09 (rcs-revision 1.3)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.c
-ode.tex
-File: pgfcoreobjects.code.tex 2006/10/11 (rcs-revision 1.2)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathproce
-ssing.code.tex
-File: pgfcorepathprocessing.code.tex 2008/10/09 (rcs-revision 1.8)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.co
-de.tex
-File: pgfcorearrows.code.tex 2008/04/23 (rcs-revision 1.11)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.cod
-e.tex
-File: pgfcoreshade.code.tex 2008/11/23 (rcs-revision 1.13)
-\pgf@max=\dimen160
-\pgf@sys@shading@range@num=\count115
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.cod
-e.tex
-File: pgfcoreimage.code.tex 2010/03/25 (rcs-revision 1.16)
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.
-code.tex
-File: pgfcoreexternal.code.tex 2010/09/01 (rcs-revision 1.17)
-\pgfexternal@startupbox=\box39
-))
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.co
-de.tex
-File: pgfcorelayers.code.tex 2010/08/27 (rcs-revision 1.2)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretranspare
-ncy.code.tex
-File: pgfcoretransparency.code.tex 2008/01/17 (rcs-revision 1.2)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.
-code.tex
-File: pgfcorepatterns.code.tex 2009/07/02 (rcs-revision 1.3)
-)))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/pgf/utilities/xxcolor.sty
-Package: xxcolor 2003/10/24 ver 0.1
-\XC@nummixins=\count116
-\XC@countmixins=\count117
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/hyperref/hyperref.sty
-Package: hyperref 2011/04/17 v6.82g Hypertext links for LaTeX
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
-Package: hobsub-hyperref 2011/04/23 v1.4 Bundle oberdiek, subset hyperref (HO)
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty
-Package: hobsub-generic 2011/04/23 v1.4 Bundle oberdiek, subset generic (HO)
-Package: hobsub 2011/04/23 v1.4 Subsetting bundle oberdiek (HO)
-Package hobsub Info: Skipping package `infwarerr' (already loaded).
-Package hobsub Info: Skipping package `ltxcmds' (already loaded).
-Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO)
-Package ifluatex Info: LuaTeX not detected.
-Package hobsub Info: Skipping package `ifvtex' (already loaded).
-Package: intcalc 2007/09/27 v1.1 Expandable integer calculations (HO)
-Package hobsub Info: Skipping package `ifpdf' (already loaded).
-Package: etexcmds 2011/02/16 v1.5 Prefix for e-TeX command names (HO)
-Package etexcmds Info: Could not find \expanded.
-(etexcmds) That can mean that you are not using pdfTeX 1.50 or
-(etexcmds) that some package has redefined \expanded.
-(etexcmds) In the latter case, load this package earlier.
-Package: kvsetkeys 2011/04/07 v1.13 Key value parser (HO)
-Package: kvdefinekeys 2011/04/07 v1.3 Defining keys (HO)
-Package: pdftexcmds 2011/04/22 v0.16 Utilities of pdfTeX for LuaTeX (HO)
-Package pdftexcmds Info: LuaTeX not detected.
-Package pdftexcmds Info: \pdf@primitive is available.
-Package pdftexcmds Info: \pdf@ifprimitive is available.
-Package pdftexcmds Info: \pdfdraftmode found.
-Package: pdfescape 2011/04/04 v1.12 Provides string conversions (HO)
-Package: bigintcalc 2011/01/30 v1.2 Expandable big integer calculations (HO)
-Package: bitset 2011/01/30 v1.1 Data type bit set (HO)
-Package: uniquecounter 2011/01/30 v1.2 Provides unlimited unique counter (HO)
-)
-Package hobsub Info: Skipping package `hobsub' (already loaded).
-Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO)
-Package: hopatch 2011/01/30 v1.0 Wrapper for package hooks (HO)
-Package: xcolor-patch 2011/01/30 xcolor patch
-Package: atveryend 2011/04/23 v1.7 Hooks at very end of document (HO)
-Package atveryend Info: \enddocument detected (standard).
-Package: atbegshi 2011/01/30 v1.15 At begin shipout hook (HO)
-Package: refcount 2010/12/01 v3.2 Data extraction from references (HO)
-Package: hycolor 2011/01/30 v1.7 Color options of hyperref/bookmark (HO)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/oberdiek/kvoptions.sty
-Package: kvoptions 2010/12/23 v3.10 Keyval support for LaTeX options (HO)
-)
-\@linkdim=\dimen161
-\Hy@linkcounter=\count118
-\Hy@pagecounter=\count119
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/hyperref/pd1enc.def
-File: pd1enc.def 2011/04/17 v6.82g Hyperref: PDFDocEncoding definition (HO)
-)
-\Hy@SavedSpaceFactor=\count120
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/latexconfig/hyperref.cfg
-File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive
-)
-Package hyperref Info: Option `bookmarks' set `true' on input line 3905.
-Package hyperref Info: Option `bookmarksopen' set `true' on input line 3905.
-Package hyperref Info: Option `implicit' set `false' on input line 3905.
-Package hyperref Info: Hyper figures OFF on input line 4026.
-Package hyperref Info: Link nesting OFF on input line 4031.
-Package hyperref Info: Hyper index ON on input line 4034.
-Package hyperref Info: Plain pages OFF on input line 4041.
-Package hyperref Info: Backreferencing OFF on input line 4046.
-Package hyperref Info: Implicit mode OFF; no redefinition of LaTeX internals.
-Package hyperref Info: Bookmarks ON on input line 4264.
-\c@Hy@tempcnt=\count121
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/url/url.sty
-\Urlmuskip=\muskip10
-Package: url 2006/04/12 ver 3.3 Verb mode for urls, etc.
-)
-LaTeX Info: Redefining \url on input line 4617.
-\Fld@menulength=\count122
-\Field@Width=\dimen162
-\Fld@charsize=\dimen163
-Package hyperref Info: Hyper figures OFF on input line 5701.
-Package hyperref Info: Link nesting OFF on input line 5706.
-Package hyperref Info: Hyper index ON on input line 5709.
-Package hyperref Info: backreferencing OFF on input line 5716.
-Package hyperref Info: Link coloring OFF on input line 5721.
-Package hyperref Info: Link coloring with OCG OFF on input line 5726.
-Package hyperref Info: PDF/A mode OFF on input line 5731.
-LaTeX Info: Redefining \ref on input line 5771.
-LaTeX Info: Redefining \pageref on input line 5775.
-\Hy@abspage=\count123
-
-
-Package hyperref Message: Stopped early.
-
-)
-
-Package hyperref Message: Driver (autodetected): hpdftex.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/hyperref/hpdftex.def
-File: hpdftex.def 2011/04/17 v6.82g Hyperref driver for pdfTeX
-\Fld@listcount=\count124
-\c@bookmark@seq@number=\count125
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty
-Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO)
-Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2
-82.
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaserequires.sty
-Package: beamerbaserequires 2010/05/01 (rcs-revision efa082c6111d)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasecompatibility.st
-y
-Package: beamerbasecompatibility 2010/07/12 (rcs-revision 6648c3177e4e)
-) (/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasefont.sty
-Package: beamerbasefont 2010/05/10 (rcs-revision cd36e8a33c6b)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsfonts/amssymb.sty
-Package: amssymb 2009/06/22 v3.00
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsfonts/amsfonts.sty
-Package: amsfonts 2009/06/22 v3.00 Basic AMSFonts support
-\@emptytoks=\toks23
-\symAMSa=\mathgroup4
-\symAMSb=\mathgroup5
-LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
-(Font) U/euf/m/n --> U/euf/b/n on input line 96.
-)))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetranslator.sty
-Package: beamerbasetranslator 2010/06/11 (rcs-revision 85fd1cc7fc42)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/translator.sty
-Package: translator 2010/06/12 ver 1.10
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/translator-lang
-uage-mappings.tex)))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasemisc.sty
-Package: beamerbasemisc 2010/06/06 (rcs-revision bff0a9294b45)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetwoscreens.sty
-Package: beamerbasetwoscreens 2010/05/01 (rcs-revision efa082c6111d)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseoverlay.sty
-Package: beamerbaseoverlay 2010/05/07 (rcs-revision 5584dad462a9)
-\beamer@argscount=\count126
-\beamer@lastskipcover=\skip44
-\beamer@trivlistdepth=\count127
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetitle.sty
-Package: beamerbasetitle 2010/06/12 (rcs-revision 717e481ca47a)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasesection.sty
-Package: beamerbasesection 2010/06/17 (rcs-revision e0d9401bb743)
-\c@lecture=\count128
-\c@part=\count129
-\c@section=\count130
-\c@subsection=\count131
-\c@subsubsection=\count132
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseframe.sty
-Package: beamerbaseframe 2010/06/06 (rcs-revision bff0a9294b45)
-\beamer@framebox=\box40
-\beamer@frametitlebox=\box41
-\beamer@zoombox=\box42
-\beamer@zoomcount=\count133
-\beamer@zoomframecount=\count134
-\beamer@frametextheight=\dimen164
-\c@subsectionslide=\count135
-\beamer@frametopskip=\skip45
-\beamer@framebottomskip=\skip46
-\beamer@frametopskipautobreak=\skip47
-\beamer@framebottomskipautobreak=\skip48
-\beamer@envbody=\toks24
-\c@framenumber=\count136
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseverbatim.sty
-Package: beamerbaseverbatim 2010/05/01 (rcs-revision efa082c6111d)
-\beamer@verbatimfileout=\write4
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseframesize.sty
-Package: beamerbaseframesize 2010/06/27 (rcs-revision 6baa2d92e6f1)
-\beamer@splitbox=\box43
-\beamer@autobreakcount=\count137
-\beamer@autobreaklastheight=\dimen165
-\beamer@frametitletoks=\toks25
-\beamer@framesubtitletoks=\toks26
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseframecomponents.
-sty
-Package: beamerbaseframecomponents 2010/07/12 (rcs-revision 09e82992d9b1)
-\beamer@footins=\box44
-) (/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasecolor.sty
-Package: beamerbasecolor 2010/06/06 (rcs-revision d1a9b48be06d)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasenotes.sty
-Package: beamerbasenotes 2010/05/01 (rcs-revision efa082c6111d)
-\beamer@frameboxcopy=\box45
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetoc.sty
-Package: beamerbasetoc 2010/06/11 (rcs-revision 242ecaa6783b)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetemplates.sty
-Package: beamerbasetemplates 2010/05/01 (rcs-revision efa082c6111d)
-\beamer@sbttoks=\toks27
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseauxtemplates.sty
-Package: beamerbaseauxtemplates 2010/05/01 (rcs-revision efa082c6111d)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaseboxes.sty
-Package: beamerbaseboxes 2010/05/01 (rcs-revision efa082c6111d)
-\bmb@box=\box46
-\bmb@colorbox=\box47
-\bmb@boxshadow=\box48
-\bmb@boxshadowball=\box49
-\bmb@boxshadowballlarge=\box50
-\bmb@temp=\dimen166
-\bmb@dima=\dimen167
-\bmb@dimb=\dimen168
-\bmb@prevheight=\dimen169
-)
-\beamer@blockheadheight=\dimen170
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbaselocalstructure.s
-ty
-Package: beamerbaselocalstructure 2010/06/01 (rcs-revision 81f9e33f7cc2)
- (/usr/local/texlive/2011/texmf-dist/tex/latex/tools/enumerate.sty
-Package: enumerate 1999/03/05 v3.00 enumerate extensions (DPC)
-\@enLab=\toks28
-)
-\c@figure=\count138
-\c@table=\count139
-\abovecaptionskip=\skip49
-\belowcaptionskip=\skip50
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasenavigation.sty
-Package: beamerbasenavigation 2010/05/01 (rcs-revision efa082c6111d)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasetheorems.sty
-Package: beamerbasetheorems 2010/06/06 (rcs-revision 7e7cc5e53e9d)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsmath/amsmath.sty
-Package: amsmath 2000/07/18 v2.13 AMS math features
-\@mathmargin=\skip51
-
-For additional information on amsmath, use the `?' option.
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsmath/amstext.sty
-Package: amstext 2000/06/29 v2.01
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsmath/amsgen.sty
-File: amsgen.sty 1999/11/30 v2.0
-\@emptytoks=\toks29
-\ex@=\dimen171
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsmath/amsbsy.sty
-Package: amsbsy 1999/11/29 v1.2d
-\pmbraise@=\dimen172
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsmath/amsopn.sty
-Package: amsopn 1999/12/14 v2.01 operator names
-)
-\inf@bad=\count140
-LaTeX Info: Redefining \frac on input line 211.
-\uproot@=\count141
-\leftroot@=\count142
-LaTeX Info: Redefining \overline on input line 307.
-\classnum@=\count143
-\DOTSCASE@=\count144
-LaTeX Info: Redefining \ldots on input line 379.
-LaTeX Info: Redefining \dots on input line 382.
-LaTeX Info: Redefining \cdots on input line 467.
-\Mathstrutbox@=\box51
-\strutbox@=\box52
-\big@size=\dimen173
-LaTeX Font Info: Redeclaring font encoding OML on input line 567.
-LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
-\macc@depth=\count145
-\c@MaxMatrixCols=\count146
-\dotsspace@=\muskip11
-\c@parentequation=\count147
-\dspbrk@lvl=\count148
-\tag@help=\toks30
-\row@=\count149
-\column@=\count150
-\maxfields@=\count151
-\andhelp@=\toks31
-\eqnshift@=\dimen174
-\alignsep@=\dimen175
-\tagshift@=\dimen176
-\tagwidth@=\dimen177
-\totwidth@=\dimen178
-\lineht@=\dimen179
-\@envbody=\toks32
-\multlinegap=\skip52
-\multlinetaggap=\skip53
-\mathdisplay@stack=\toks33
-LaTeX Info: Redefining \[ on input line 2666.
-LaTeX Info: Redefining \] on input line 2667.
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amscls/amsthm.sty
-Package: amsthm 2009/07/02 v2.20.1
-\thm@style=\toks34
-\thm@bodyfont=\toks35
-\thm@headfont=\toks36
-\thm@notefont=\toks37
-\thm@headpunct=\toks38
-\thm@preskip=\skip54
-\thm@postskip=\skip55
-\thm@headsep=\skip56
-\dth@everypar=\toks39
-)
-\c@theorem=\count152
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/beamerbasethemes.sty
-Package: beamerbasethemes 2010/05/01 (rcs-revision efa082c6111d)
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/theme/beamerthemede
-fault.sty
-Package: beamerthemedefault 2010/06/17 (rcs-revision d02a7cf4d8ae)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/font/beamerfontthem
-edefault.sty
-Package: beamerfontthemedefault 2010/06/17 (rcs-revision d02a7cf4d8ae)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/color/beamercolorth
-emedefault.sty
-Package: beamercolorthemedefault 2010/06/17 (rcs-revision d02a7cf4d8ae)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/inner/beamerinnerth
-emedefault.sty
-Package: beamerinnerthemedefault 2010/06/17 (rcs-revision d02a7cf4d8ae)
-\beamer@dima=\dimen180
-\beamer@dimb=\dimen181
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/outer/beamerouterth
-emedefault.sty
-Package: beamerouterthemedefault 2010/06/17 (rcs-revision d02a7cf4d8ae)
-)))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/theme/beamerthemeWa
-rsaw.sty
-Package: beamerthemeWarsaw 2010/06/17 (rcs-revision d02a7cf4d8ae)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/inner/beamerinnerth
-emerounded.sty
-Package: beamerinnerthemerounded 2010/06/17 (rcs-revision d02a7cf4d8ae)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/outer/beamerouterth
-emeshadow.sty
-Package: beamerouterthemeshadow 2010/06/17 (rcs-revision d02a7cf4d8ae)
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/outer/beamerouterth
-emesplit.sty
-Package: beamerouterthemesplit 2010/06/17 (rcs-revision d02a7cf4d8ae)
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/color/beamercolorth
-emeorchid.sty
-Package: beamercolorthemeorchid 2010/06/17 (rcs-revision d02a7cf4d8ae)
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/themes/color/beamercolorth
-emewhale.sty
-Package: beamercolorthemewhale 2010/06/17 (rcs-revision d02a7cf4d8ae)
-))
-(/usr/local/texlive/2011/texmf-dist/tex/latex/listings/listings.sty
-\lst@mode=\count153
-\lst@gtempboxa=\box53
-\lst@token=\toks40
-\lst@length=\count154
-\lst@currlwidth=\dimen182
-\lst@column=\count155
-\lst@pos=\count156
-\lst@lostspace=\dimen183
-\lst@width=\dimen184
-\lst@newlines=\count157
-\lst@lineno=\count158
-\lst@maxwidth=\dimen185
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/listings/lstmisc.sty
-File: lstmisc.sty 2007/02/22 1.4 (Carsten Heinz)
-\c@lstnumber=\count159
-\lst@skipnumbers=\count160
-\lst@framebox=\box54
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/listings/listings.cfg
-File: listings.cfg 2007/02/22 1.4 listings configuration
-))
-Package: listings 2007/02/22 1.4 (Carsten Heinz)
-
-(./presentation-week-05.aux)
-\openout1 = `presentation-week-05.aux'.
-
-LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 15.
-LaTeX Font Info: ... okay on input line 15.
-
-*geometry* driver: auto-detecting
-*geometry* detected driver: pdftex
-*geometry* verbose mode - [ preamble ] result:
-* driver: pdftex
-* paper: custom
-* layout:
-* layoutoffset:(h,v)=(0.0pt,0.0pt)
-* modes: includehead includefoot
-* h-part:(L,W,R)=(28.45274pt, 307.28987pt, 28.45274pt)
-* v-part:(T,H,B)=(0.0pt, 273.14662pt, 0.0pt)
-* \paperwidth=364.19536pt
-* \paperheight=273.14662pt
-* \textwidth=307.28987pt
-* \textheight=244.6939pt
-* \oddsidemargin=-43.81725pt
-* \evensidemargin=-43.81725pt
-* \topmargin=-72.26999pt
-* \headheight=14.22636pt
-* \headsep=0.0pt
-* \topskip=11.0pt
-* \footskip=14.22636pt
-* \marginparwidth=4.0pt
-* \marginparsep=10.0pt
-* \columnsep=10.0pt
-* \skip\footins=10.0pt plus 4.0pt minus 2.0pt
-* \hoffset=0.0pt
-* \voffset=0.0pt
-* \mag=1000
-* \@twocolumnfalse
-* \@twosidefalse
-* \@mparswitchfalse
-* \@reversemarginfalse
-* (1in=72.27pt=25.4mm, 1cm=28.453pt)
-
-(/usr/local/texlive/2011/texmf-dist/tex/context/base/supp-pdf.mkii
-[Loading MPS to PDF converter (version 2006.09.02).]
-\scratchcounter=\count161
-\scratchdimen=\dimen186
-\scratchbox=\box55
-\nofMPsegments=\count162
-\nofMParguments=\count163
-\everyMPshowfont=\toks41
-\MPscratchCnt=\count164
-\MPscratchDim=\dimen187
-\MPnumerator=\count165
-\makeMPintoPDFobject=\count166
-\everyMPtoPDFconversion=\toks42
-) (/usr/local/texlive/2011/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty
-Package: epstopdf-base 2010/02/09 v2.5 Base part for package epstopdf
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/oberdiek/grfext.sty
-Package: grfext 2010/08/19 v1.1 Managing graphics extensions (HO)
-)
-Package grfext Info: Graphics extension search list:
-(grfext) [.png,.pdf,.jpg,.mps,.jpeg,.jbig2,.jb2,.PNG,.PDF,.JPG,.JPE
-G,.JBIG2,.JB2,.eps]
-(grfext) \AppendGraphicsExtensions on input line 452.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
-File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
-e
-))
-ABD: EveryShipout initializing macros
-\AtBeginShipoutBox=\box56
-Package hyperref Info: Link coloring OFF on input line 15.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/hyperref/nameref.sty
-Package: nameref 2010/04/30 v2.40 Cross-referencing by name of section
-
-(/usr/local/texlive/2011/texmf-dist/tex/generic/oberdiek/gettitlestring.sty
-Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO)
-)
-\c@section@level=\count167
-)
-LaTeX Info: Redefining \ref on input line 15.
-LaTeX Info: Redefining \pageref on input line 15.
-LaTeX Info: Redefining \nameref on input line 15.
-
-(./presentation-week-05.out) (./presentation-week-05.out)
-\@outlinefile=\write5
-\openout5 = `presentation-week-05.out'.
-
-LaTeX Font Info: Overwriting symbol font `operators' in version `normal'
-(Font) OT1/cmr/m/n --> OT1/cmss/m/n on input line 15.
-LaTeX Font Info: Overwriting symbol font `operators' in version `bold'
-(Font) OT1/cmr/bx/n --> OT1/cmss/bx/n on input line 15.
-\symnumbers=\mathgroup6
-\sympureletters=\mathgroup7
-LaTeX Font Info: Overwriting math alphabet `\mathrm' in version `normal'
-(Font) OT1/cmss/m/n --> OT1/cmr/m/n on input line 15.
-LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal'
-(Font) OT1/cmr/bx/n --> OT1/cmss/bx/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold'
-(Font) OT1/cmr/bx/n --> OT1/cmss/bx/n on input line 15.
-LaTeX Font Info: Redeclaring math alphabet \mathsf on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal'
-(Font) OT1/cmss/m/n --> OT1/cmss/m/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold'
-(Font) OT1/cmss/bx/n --> OT1/cmss/m/n on input line 15.
-LaTeX Font Info: Redeclaring math alphabet \mathit on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal'
-(Font) OT1/cmr/m/it --> OT1/cmss/m/it on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold'
-(Font) OT1/cmr/bx/it --> OT1/cmss/m/it on input line 15.
-LaTeX Font Info: Redeclaring math alphabet \mathtt on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal'
-(Font) OT1/cmtt/m/n --> OT1/cmtt/m/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold'
-(Font) OT1/cmtt/m/n --> OT1/cmtt/m/n on input line 15.
-LaTeX Font Info: Overwriting symbol font `numbers' in version `bold'
-(Font) OT1/cmss/m/n --> OT1/cmss/bx/n on input line 15.
-LaTeX Font Info: Overwriting symbol font `pureletters' in version `bold'
-(Font) OT1/cmss/m/it --> OT1/cmss/bx/it on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathrm' in version `bold'
-(Font) OT1/cmss/bx/n --> OT1/cmr/bx/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold'
-(Font) OT1/cmss/bx/n --> OT1/cmss/bx/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold'
-(Font) OT1/cmss/m/n --> OT1/cmss/bx/n on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold'
-(Font) OT1/cmss/m/it --> OT1/cmss/bx/it on input line 15.
-LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold'
-(Font) OT1/cmtt/m/n --> OT1/cmtt/bx/n on input line 15.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-basic-dictionary/translator-basic-dictionary-English.dict
-Dictionary: translator-basic-dictionary, Language: English
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-bibliography-dictionary/translator-bibliography-dictionary-English.dict
-Dictionary: translator-bibliography-dictionary, Language: English
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-environment-dictionary/translator-environment-dictionary-English.dict
-Dictionary: translator-environment-dictionary, Language: English
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-months-dictionary/translator-months-dictionary-English.dict
-Dictionary: translator-months-dictionary, Language: English
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-numbers-dictionary/translator-numbers-dictionary-English.dict
-Dictionary: translator-numbers-dictionary, Language: English
-)
-(/usr/local/texlive/2011/texmf-dist/tex/latex/beamer/translator/dicts/translato
-r-theorem-dictionary/translator-theorem-dictionary-English.dict
-Dictionary: translator-theorem-dictionary, Language: English
-)
-\c@lstlisting=\count168
-
-(./presentation-week-05.nav)
-
-LaTeX Font Warning: Font shape `OT1/cmss/m/n' in size <4> not available
-(Font) size <5> substituted on input line 20.
-
-[1{/usr/local/texlive/2011/texmf-var/fonts/map/pdftex/updmap/pdftex.map}
-
-]
-(./presentation-week-05.toc) [2
-
-] [3
-
-] [4
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [5
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-LaTeX Font Info: Try loading font information for U+msa on input line 12.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsfonts/umsa.fd
-File: umsa.fd 2009/06/22 v3.00 AMS symbols A
-)
-LaTeX Font Info: Try loading font information for U+msb on input line 12.
-
-(/usr/local/texlive/2011/texmf-dist/tex/latex/amsfonts/umsb.fd
-File: umsb.fd 2009/06/22 v3.00 AMS symbols B
-)) [6
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [7
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [8
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [9
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [10
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [11
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [12
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [13
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [14
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [15
-
-] [16
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb)
-Overfull \vbox (3.35751pt too high) detected at line 330
- []
-
-[17
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [18
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [19
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb)
-Overfull \vbox (3.35751pt too high) detected at line 389
- []
-
-[20
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb
-Overfull \hbox (26.13402pt too wide) in paragraph at lines 14--14
-[] \OT1/cmtt/m/n/10.95 print "position: %s, %s -- shape: %s, %s"%(x, y, w, h
-)[]
- []
-
-) [21
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [22
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [23
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [24
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [25
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-Overfull \hbox (14.63664pt too wide) in paragraph at lines 6--6
-[]\OT1/cmtt/m/n/10.95 [expression for variable in a_list if something_is_true][
-]
- []
-
-) [26
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [27
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb
-Overfull \hbox (3.13927pt too wide) in paragraph at lines 12--12
-[]\OT1/cmtt/m/n/10.95 [name for name in dir(__builtin__) if "Error" in name][]
-
- []
-
-) [28
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [29
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [30
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [31
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [32
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [33
-
-] [34
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [35
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [36
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [37
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-Overfull \hbox (49.70702pt too wide) in paragraph at lines 19--19
-[] \OT1/cmtt/m/n/10 # make sure the shuffled sequence does not lose any
-elements[]
- []
-
-
-Overfull \hbox (12.95734pt too wide) in paragraph at lines 19--19
-[] \OT1/cmtt/m/n/10 # should raise an exception for an immutable sequenc
-e[]
- []
-
-
-Overfull \hbox (12.95734pt too wide) in paragraph at lines 19--19
-[] \OT1/cmtt/m/n/10 self.assertRaises(TypeError, random.shuffle, (1,2,3)
-)[]
- []
-
-)
-Overfull \vbox (7.17966pt too high) detected at line 742
- []
-
-[38
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [39
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [40
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [41
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [42
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-Overfull \hbox (28.7072pt too wide) in paragraph at lines 20--20
-[] \OT1/cmtt/m/n/10 # make sure the shuffled sequence does not lose any elem
-ents[]
- []
-
-)
-Overfull \vbox (7.9463pt too high) detected at line 846
- []
-
-[43
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [44
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [45
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-Overfull \hbox (28.7072pt too wide) in paragraph at lines 18--18
-[] \OT1/cmtt/m/n/10 # make sure the shuffled sequence does not lose any elem
-ents[]
- []
-
-) [46
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [47
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [48
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-Missing character: There is no in font cmtt12!
-
-Overfull \hbox (11.33963pt too wide) in paragraph at lines 11--12
-[][]\OT1/cmtt/m/n/14.4 nosetests --with-coverage test_codingbat.py
- []
-
-) [49
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [50
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
- (./presentation-week-05.vrb) [51
-
-]
-\openout4 = `presentation-week-05.vrb'.
-
-
-(./presentation-week-05.vrb) [52
-
-]
-\tf@nav=\write6
-\openout6 = `presentation-week-05.nav'.
-
-\tf@toc=\write7
-\openout7 = `presentation-week-05.toc'.
-
-\tf@snm=\write8
-\openout8 = `presentation-week-05.snm'.
-
-Package atveryend Info: Empty hook `BeforeClearDocument' on input line 1068.
-Package atveryend Info: Empty hook `AfterLastShipout' on input line 1068.
- (./presentation-week-05.aux)
-Package atveryend Info: Executing hook `AtVeryEndDocument' on input line 1068.
-Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 1068.
-
-Package rerunfilecheck Info: File `presentation-week-05.out' has not changed.
-(rerunfilecheck) Checksum: 57794C8D06794128DF86960A8EE2428E;263.
-
-
-LaTeX Font Warning: Size substitutions with differences
-(Font) up to 1.0pt have occurred.
-
-Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 1068.
- )
-Here is how much of TeX's memory you used:
- 17056 strings out of 493633
- 316943 string characters out of 3143378
- 389869 words of memory out of 3000000
- 19761 multiletter control sequences out of 15000+200000
- 15076 words of font info for 58 fonts, out of 3000000 for 9000
- 831 hyphenation exceptions out of 8191
- 49i,19n,60p,422b,592s stack positions out of 5000i,500n,10000p,200000b,50000s
-
-<
-/usr/local/texlive/2011/texmf-dist/fonts/type1/public/amsfonts/cm/cmss8.pfb>
-Output written on presentation-week-05.pdf (52 pages, 189923 bytes).
-PDF statistics:
- 1766 PDF objects out of 2073 (max. 8388607)
- 1671 compressed objects within 17 object streams
- 110 named destinations out of 1000 (max. 500000)
- 121 words of extra memory for PDF output out of 10000 (max. 10000000)
-
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.nav b/slides_sources/old_versions/week-05/presentation-week-05.nav
deleted file mode 100644
index 93028d2..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.nav
+++ /dev/null
@@ -1,125 +0,0 @@
-\beamer@endinputifotherversion {3.10pt}
-\headcommand {\slideentry {0}{0}{1}{1/1}{}{0}}
-\headcommand {\beamer@framepages {1}{1}}
-\headcommand {\slideentry {0}{0}{2}{2/2}{}{0}}
-\headcommand {\beamer@framepages {2}{2}}
-\headcommand {\sectionentry {1}{Review/Questions}{3}{Review/Questions}{0}}
-\headcommand {\beamer@sectionpages {1}{2}}
-\headcommand {\beamer@subsectionpages {1}{2}}
-\headcommand {\slideentry {1}{0}{3}{3/3}{}{0}}
-\headcommand {\beamer@framepages {3}{3}}
-\headcommand {\slideentry {1}{0}{4}{4/4}{}{0}}
-\headcommand {\beamer@framepages {4}{4}}
-\headcommand {\slideentry {1}{0}{5}{5/5}{}{0}}
-\headcommand {\beamer@framepages {5}{5}}
-\headcommand {\sectionentry {2}{Unicode}{6}{Unicode}{0}}
-\headcommand {\beamer@sectionpages {3}{5}}
-\headcommand {\beamer@subsectionpages {3}{5}}
-\headcommand {\slideentry {2}{0}{6}{6/6}{}{0}}
-\headcommand {\beamer@framepages {6}{6}}
-\headcommand {\slideentry {2}{0}{7}{7/7}{}{0}}
-\headcommand {\beamer@framepages {7}{7}}
-\headcommand {\slideentry {2}{0}{8}{8/8}{}{0}}
-\headcommand {\beamer@framepages {8}{8}}
-\headcommand {\slideentry {2}{0}{9}{9/9}{}{0}}
-\headcommand {\beamer@framepages {9}{9}}
-\headcommand {\slideentry {2}{0}{10}{10/10}{}{0}}
-\headcommand {\beamer@framepages {10}{10}}
-\headcommand {\slideentry {2}{0}{11}{11/11}{}{0}}
-\headcommand {\beamer@framepages {11}{11}}
-\headcommand {\slideentry {2}{0}{12}{12/12}{}{0}}
-\headcommand {\beamer@framepages {12}{12}}
-\headcommand {\slideentry {2}{0}{13}{13/13}{}{0}}
-\headcommand {\beamer@framepages {13}{13}}
-\headcommand {\slideentry {2}{0}{14}{14/14}{}{0}}
-\headcommand {\beamer@framepages {14}{14}}
-\headcommand {\slideentry {2}{0}{15}{15/15}{}{0}}
-\headcommand {\beamer@framepages {15}{15}}
-\headcommand {\slideentry {2}{0}{16}{16/16}{}{0}}
-\headcommand {\beamer@framepages {16}{16}}
-\headcommand {\sectionentry {3}{Advanced Argument Passing}{17}{Advanced Argument Passing}{0}}
-\headcommand {\beamer@sectionpages {6}{16}}
-\headcommand {\beamer@subsectionpages {6}{16}}
-\headcommand {\slideentry {3}{0}{17}{17/17}{}{0}}
-\headcommand {\beamer@framepages {17}{17}}
-\headcommand {\slideentry {3}{0}{18}{18/18}{}{0}}
-\headcommand {\beamer@framepages {18}{18}}
-\headcommand {\slideentry {3}{0}{19}{19/19}{}{0}}
-\headcommand {\beamer@framepages {19}{19}}
-\headcommand {\slideentry {3}{0}{20}{20/20}{}{0}}
-\headcommand {\beamer@framepages {20}{20}}
-\headcommand {\slideentry {3}{0}{21}{21/21}{}{0}}
-\headcommand {\beamer@framepages {21}{21}}
-\headcommand {\slideentry {3}{0}{22}{22/22}{}{0}}
-\headcommand {\beamer@framepages {22}{22}}
-\headcommand {\slideentry {3}{0}{23}{23/23}{}{0}}
-\headcommand {\beamer@framepages {23}{23}}
-\headcommand {\sectionentry {4}{List and Dict Comprehensions}{24}{List and Dict Comprehensions}{0}}
-\headcommand {\beamer@sectionpages {17}{23}}
-\headcommand {\beamer@subsectionpages {17}{23}}
-\headcommand {\slideentry {4}{0}{24}{24/24}{}{0}}
-\headcommand {\beamer@framepages {24}{24}}
-\headcommand {\slideentry {4}{0}{25}{25/25}{}{0}}
-\headcommand {\beamer@framepages {25}{25}}
-\headcommand {\slideentry {4}{0}{26}{26/26}{}{0}}
-\headcommand {\beamer@framepages {26}{26}}
-\headcommand {\slideentry {4}{0}{27}{27/27}{}{0}}
-\headcommand {\beamer@framepages {27}{27}}
-\headcommand {\slideentry {4}{0}{28}{28/28}{}{0}}
-\headcommand {\beamer@framepages {28}{28}}
-\headcommand {\slideentry {4}{0}{29}{29/29}{}{0}}
-\headcommand {\beamer@framepages {29}{29}}
-\headcommand {\slideentry {4}{0}{30}{30/30}{}{0}}
-\headcommand {\beamer@framepages {30}{30}}
-\headcommand {\slideentry {4}{0}{31}{31/31}{}{0}}
-\headcommand {\beamer@framepages {31}{31}}
-\headcommand {\slideentry {4}{0}{32}{32/32}{}{0}}
-\headcommand {\beamer@framepages {32}{32}}
-\headcommand {\slideentry {4}{0}{33}{33/33}{}{0}}
-\headcommand {\beamer@framepages {33}{33}}
-\headcommand {\slideentry {4}{0}{34}{34/34}{}{0}}
-\headcommand {\beamer@framepages {34}{34}}
-\headcommand {\sectionentry {5}{Unit Testing}{35}{Unit Testing}{0}}
-\headcommand {\beamer@sectionpages {24}{34}}
-\headcommand {\beamer@subsectionpages {24}{34}}
-\headcommand {\slideentry {5}{0}{35}{35/35}{}{0}}
-\headcommand {\beamer@framepages {35}{35}}
-\headcommand {\slideentry {5}{0}{36}{36/36}{}{0}}
-\headcommand {\beamer@framepages {36}{36}}
-\headcommand {\slideentry {5}{0}{37}{37/37}{}{0}}
-\headcommand {\beamer@framepages {37}{37}}
-\headcommand {\slideentry {5}{0}{38}{38/38}{}{0}}
-\headcommand {\beamer@framepages {38}{38}}
-\headcommand {\slideentry {5}{0}{39}{39/39}{}{0}}
-\headcommand {\beamer@framepages {39}{39}}
-\headcommand {\slideentry {5}{0}{40}{40/40}{}{0}}
-\headcommand {\beamer@framepages {40}{40}}
-\headcommand {\slideentry {5}{0}{41}{41/41}{}{0}}
-\headcommand {\beamer@framepages {41}{41}}
-\headcommand {\slideentry {5}{0}{42}{42/42}{}{0}}
-\headcommand {\beamer@framepages {42}{42}}
-\headcommand {\slideentry {5}{0}{43}{43/43}{}{0}}
-\headcommand {\beamer@framepages {43}{43}}
-\headcommand {\slideentry {5}{0}{44}{44/44}{}{0}}
-\headcommand {\beamer@framepages {44}{44}}
-\headcommand {\slideentry {5}{0}{45}{45/45}{}{0}}
-\headcommand {\beamer@framepages {45}{45}}
-\headcommand {\slideentry {5}{0}{46}{46/46}{}{0}}
-\headcommand {\beamer@framepages {46}{46}}
-\headcommand {\slideentry {5}{0}{47}{47/47}{}{0}}
-\headcommand {\beamer@framepages {47}{47}}
-\headcommand {\slideentry {5}{0}{48}{48/48}{}{0}}
-\headcommand {\beamer@framepages {48}{48}}
-\headcommand {\slideentry {5}{0}{49}{49/49}{}{0}}
-\headcommand {\beamer@framepages {49}{49}}
-\headcommand {\slideentry {5}{0}{50}{50/50}{}{0}}
-\headcommand {\beamer@framepages {50}{50}}
-\headcommand {\slideentry {5}{0}{51}{51/51}{}{0}}
-\headcommand {\beamer@framepages {51}{51}}
-\headcommand {\slideentry {5}{0}{52}{52/52}{}{0}}
-\headcommand {\beamer@framepages {52}{52}}
-\headcommand {\beamer@partpages {1}{52}}
-\headcommand {\beamer@subsectionpages {35}{52}}
-\headcommand {\beamer@sectionpages {35}{52}}
-\headcommand {\beamer@documentpages {52}}
-\headcommand {\def \inserttotalframenumber {52}}
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.out b/slides_sources/old_versions/week-05/presentation-week-05.out
deleted file mode 100644
index 73ecc99..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.out
+++ /dev/null
@@ -1,5 +0,0 @@
-\BOOKMARK [2][]{Outline0.1}{Review/Questions}{}% 1
-\BOOKMARK [2][]{Outline0.2}{Unicode}{}% 2
-\BOOKMARK [2][]{Outline0.3}{Advanced Argument Passing}{}% 3
-\BOOKMARK [2][]{Outline0.4}{List and Dict Comprehensions}{}% 4
-\BOOKMARK [2][]{Outline0.5}{Unit Testing}{}% 5
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.pdf b/slides_sources/old_versions/week-05/presentation-week-05.pdf
deleted file mode 100644
index 0ecf903..0000000
Binary files a/slides_sources/old_versions/week-05/presentation-week-05.pdf and /dev/null differ
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.snm b/slides_sources/old_versions/week-05/presentation-week-05.snm
deleted file mode 100644
index e69de29..0000000
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.tex b/slides_sources/old_versions/week-05/presentation-week-05.tex
deleted file mode 100644
index 0061102..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.tex
+++ /dev/null
@@ -1,1070 +0,0 @@
-\documentclass{beamer}
-%\usepackage[latin1]{inputenc}
-\usetheme{Warsaw}
-\title[Intro to Python: Week 1]{Introduction to Python\\
-Unicode, Advanced Argument passing\\
-List and Dict Comprehensions, Testing
-}
-\author{Christopher Barker}
-\institute{UW Continuing Education}
-\date{October 29, 2013}
-
-\usepackage{listings}
-\usepackage{hyperref}
-
-\begin{document}
-
-% ---------------------------------------------
-\begin{frame}
- \titlepage
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}
-\frametitle{Table of Contents}
-%\tableofcontents[currentsection]
- \tableofcontents
-\end{frame}
-
-
-\section{Review/Questions}
-
-% ---------------------------------------------
-\begin{frame}{Review of Previous Class}
-
-\begin{itemize}
- \item Dictionaries
- \item Exceptions
- \item Files, etc.
-\end{itemize}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}{Lightning Talks}
-
-\vfill
-{\LARGE Lightning talks today:}
-
-\vfill
-{\Large
-Rithy Chhen
-
-\vfill
-Howard Edson
-
-\vfill
-Dong Kang
-
-\vfill
-Steven Werner
-
-}
-\vfill
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Homework review}
-
- \vfill
- {\Large Homework Questions? }
-
- \vfill
- {\Large My Solution}
-
- (\verb|dict.setdefault()| trick...)
-
- \vfill
-\end{frame}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Unicode}
-
-%---------------------------------
-\begin{frame}[fragile]{Unicode}
-
-{\Large I hope you all read this:}
-
-\vfill
-{\Large
-\centering
-The Absolute Minimum Every Software Developer Absolutely,
-Positively Must Know About Unicode and Character Sets (No Excuses!)
-
-}
-
-\vfill
-\url{http://www.joelonsoftware.com/articles/Unicode.html}
-
-\vfill
-{\Large If not -- go read it!}
-
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\Large
-\vfill
-
-Everything is bytes
-
-\vfill
-If it's on disk or transmitted over a network, it's bytes
-
-\vfill
-Python provides some abstractions to make it easier to deal with bytes
-
-\vfill
-}
-
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\Large
-\vfill
-
-Unicode is a biggie
-
-\vfill
-Strings vs Unicode
-}
-
-{\large (\verb|str()| vs. \verb|bytes()| vs. \verb|unicode()| ) }
-
-\vfill
-{\Large Python 2.x vs 3.x}
-
-
-\vfill
-(actually, dealing with numbers rather than bytes is big -- but we take that for granted)
-
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\Large
-\vfill
-Strings are sequences of bytes
-
-\vfill
-Unicode strings are sequences of platonic characters
-
-\vfill
-Platonic characters cannot be written to disk or network!
-}
-\vfill
-(ANSI -- one character == one byte -- so easy!)
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\Large
-\vfill
-The \verb|unicode| object lets you work with characters
-
-\vfill
-``Encoding'' is converting from a unicode object to bytes
-
-\vfill
-``Decoding'' is converting from bytes to a unicode object
-}
-
-\vfill
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\large
-\begin{verbatim}
-import codecs
-ord()
-chr()
-unichr()
-str()
-unicode()
-encode()
-decode()
-\end{verbatim}
-}
-\end{frame}
-
-\begin{frame}[fragile]{Unicode Literals}
-
-
-{\Large 1) Use unicode in your source files:}
-
-\begin{verbatim}
-# -*- coding: utf-8 -*-
-\end{verbatim}
-
-\vfill
-{\Large 2) escape the unicode characters}
-
-\begin{verbatim}
-print u"The integral sign: \u222B"
-print u"The integral sign: \N{integral}"
-\end{verbatim}
-
-{\large lots of tables of code points online:}
-
-\url{http://inamidst.com/stuff/unidata/}
-
-\vfill
-(demo: \verb|code\hello_unicode.py|)
-\end{frame}
-
-
-%---------------------------------
-\begin{frame}[fragile]{Unicode}
-
-{\Large
-Use unicode objects in all your code
-
-\vfill
-decode on input
-
-\vfill
-encode on output
-
-\vfill
-Many packages do this for you\\
-\hspace{0.25in} (XML processing, databases, ...)
-
-\vfill
-Gotcha:\\
-\hspace{0.25in} Python has a default encoding (usually ascii)
-}
-\end{frame}
-
-\begin{frame}[fragile]{Unicode}
-
-{\Large Python Docs Unicode HowTo:}
-
-\url{http://docs.python.org/howto/unicode.html}
-
-\vfill
-{\Large ``Reading Unicode from a file is therefore simple:''}
-
-\begin{verbatim}
-import codecs
-f = codecs.open('unicode.rst', encoding='utf-8')
-for line in f:
- print repr(line)
-\end{verbatim}
-
-\vfill
-{\Large Encodings Built-in to Python:}
-
-\url{http://docs.python.org/2/library/codecs.html#standard-encodings}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{Unicode LAB}
-
-\begin{itemize}
- \item Find some nifty non-ascii characters you might use.\\
- Create a unicode object with them in two different ways.
- \item In the "code" dir for this week, there are two files:\\
- \verb|text.utf16| \\
- \verb|text.utf32| \\
- read the contents into unicode objects
- \item write some of the text from the first exercise to file.
- \item read that file back in.
-\end{itemize}
-
-\vfill
-(reference: \url{http://inamidst.com/stuff/unidata/})
-
-\vfill
-NOTE: if your terminal does not support unicode -- you'll get an error trying
-to print. Try a different terminal or IDE, or google for a solution
-\end{frame}
-
-
-
-%-------------------------------
-\begin{frame}{Lightning Talk}
-
-{\LARGE Lightning Talks:}
-
-{\large
-\vfill
-Rithy Chhen
-
-\vfill
-Howard Edson
-}
-
-\end{frame}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Advanced Argument Passing}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Keyword arguments}
-
- {\Large When defining a function, you can specify only
- what you need -- any order}
-
-\begin{verbatim}
-In [151]: def fun(x,y=0,z=0):
- print x,y,z
- .....:
-
-In [152]: fun(1,2,3)
-1 2 3
-
-In [153]: fun(1, z=3)
-1 0 3
-
-In [154]: fun(1, z=3, y=2)
-1 2 3
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Keyword arguments}
-
- {\Large A Common Idiom:}
-
-\vfill
-\begin{verbatim}
-def fun(x, y=None):
- if y is None:
- do_something_different
-
- go_on_here
-\end{verbatim}
-\vfill
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Keyword arguments}
-
- {\Large Can set defaults to variables}
-
-\begin{verbatim}
-In [156]: y = 4
-
-In [157]: def fun(x=y):
- print "x is:", x
- .....:
-
-In [158]: fun()
-x is: 4
-
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Keyword arguments}
-
-{\Large Defaults are evaluated when the function is defined}
-
-\begin{verbatim}
-In [156]: y = 4
-
-In [157]: def fun(x=y):
- print "x is:", x
- .....:
-
-In [158]: fun()
-x is: 4
-
-In [159]: y = 6
-
-In [160]: fun()
-x is: 4
-\end{verbatim}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Function arguments in variables}
-
-{\Large function arguments are really just\\
- -- a tuple (positional arguments) \\
- -- a dict (keyword arguments) \\
-}
-\begin{verbatim}
-def f(x, y, w=0, h=0):
- print "position: %s, %s -- shape: %s, %s"%(x, y, w, h)
-
-position = (3,4)
-size = {'h': 10, 'w': 20}
-
->>> f( *position, **size)
-position: 3, 4 -- shape: 20, 10
-\end{verbatim}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Function parameters in variables}
-
-{\Large You can also pull in the parameters out in the function as a tuple and a dict
-}
-\begin{verbatim}
-def f(*args, **kwargs):
- print "the positional arguments are:", args
- print "the keyword arguments are:", kwargs
-
-In [389]: f(2, 3, this=5, that=7)
-the positional arguments are: (2, 3)
-the keyword arguments are: {'this': 5, 'that': 7}
-\end{verbatim}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large keyword arguments}
-\begin{itemize}
- \item Write a function that has four optional parameters\\
- (with defaults):
- \begin{itemize}
- \item foreground\_color
- \item background\_color
- \item link\_color
- \item visited\_link\_color
- \end{itemize}
- \item Have it print the colors.
- \item Call it with a couple different parameters set
- \item Have it pull the parameters out with \verb|*args, **kwargs|
-\end{itemize}
-
-\end{frame}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{List and Dict Comprehensions}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{List comprehensions}
-
-{\Large A bit of functional programming:}
-
-\begin{verbatim}
-new_list = [expression for variable in a_list]
-\end{verbatim}
-
-{\Large same as for loop:}
-
-\begin{verbatim}
-new_list = []
-for variable in a_list:
- new_list.append(expression)
-\end{verbatim}
-
-\end{frame}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{List comprehensions}
-
-{\Large More than one ``for'':}
-
-\begin{verbatim}
-new_list = \
-[exp for var in a_list for var2 in a_list2]
-\end{verbatim}
-
-{\Large same as nested for loop:}
-
-\begin{verbatim}
-new_list = []
-for var in a_list:
- for var2 in a_list2:
- new_list.append(expression)
-\end{verbatim}
-
-{\large You get the ``outer product'', i.e. all combinations.}
-
-\vfill
-(demo)
-\end{frame}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{List comprehensions}
-
-{\Large Add a conditional:}
-
-\begin{verbatim}
-new_list = \
-[expression for variable in a_list if something_is_true]
-\end{verbatim}
-
-{\Large same as for loop:}
-
-\begin{verbatim}
-new_list = []
-for variable in a_list:
- if something_is_true:
- new_list.append(expression)
-\end{verbatim}
-
-\vfill
-(demo)
-\end{frame}
-
-
-
-% ----------------------------------------------
-\begin{frame}[fragile]{List comprehensions}
-
-{\Large Examples:}
-
-\begin{verbatim}
-In [341]: [x**2 for x in range(3)]
-Out[341]: [0, 1, 4]
-
-In [342]: [x+y for x in range(3) for y in range(5,7)]
-Out[342]: [5, 6, 6, 7, 7, 8]
-
-In [343]: [x*2 for x in range(6) if not x%2]
-Out[343]: [0, 4, 8]
-\end{verbatim}
-
-\end{frame}
-
-
-% ----------------------------------------------
-\begin{frame}[fragile]{List comprehensions}
-
-{\Large Remember this from last week?}
-
-\begin{verbatim}
-[name for name in dir(__builtin__) if "Error" in name]
-
-['ArithmeticError',
- 'AssertionError',
- 'AttributeError',
- 'BufferError',
- 'EOFError',
- ....
-\end{verbatim}
-
-\end{frame}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{Set Comprehensions}
-
-{\Large You can do it with sets, too:}
-
-\begin{verbatim}
-new_set = { value for variable in a_sequence}
-\end{verbatim}
-
-{\Large same as for loop:}
-
-\begin{verbatim}
-new_set = set()
-for key in a_list:
- new_set.add(value)
-\end{verbatim}
-
-\end{frame}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{Set Comprehensions}
-
-
-\begin{verbatim}
-In [33]: s = "a fairly long string"
-
-In [34]: vowels = 'aeiou'
-
-In [35]: { l for l in s if l in vowels}
-Out[35]: set(['a', 'i', 'o'])
-\end{verbatim}
-
-\end{frame}
-
-
-
-% ----------------------------------------------
-\begin{frame}[fragile]{Dict Comprehensions}
-
-{\Large and with dicts:}
-
-\begin{verbatim}
-new_dict = { key:value for variable in a_sequence}
-\end{verbatim}
-
-{\Large same as for loop:}
-
-\begin{verbatim}
-new_dict = {}
-for key in a_list:
- new_dict[key] = value
-\end{verbatim}
-
-\end{frame}
-
-% ----------------------------------------------
-\begin{frame}[fragile]{Dict Comprehensions}
-
-{\Large Example}
-
-\begin{verbatim}
-In [340]: { i: "this_%i"%i for i in range(5) }
-Out[340]: {0: 'this_0', 1: 'this_1', 2: 'this_2',
- 3: 'this_3', 4: 'this_4'}
-\end{verbatim}
-
-\vfill
-(not as useful with the \verb|dict()| constructor...)
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-\vfill
-{\Large List and Dict comprehension lab:}
-
-\vfill
-{\large \verb|code/comprehensions.rst[html]| }
-
-\vfill
-
-\end{frame}
-
-
-%-------------------------------
-\begin{frame}{Lightning Talk}
-
-{\LARGE Lightning Talks:}
-
-{\large
-\vfill
-Dong Kang
-
-\vfill
-Steven Werner
-}
-\vfill
-\end{frame}
-
-
-\section{Unit Testing}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Unit Testing}
-
-{\LARGE Gaining Traction}
-
-\vfill
-{\Large You need to test your code somehow when you write it --
- why not preserve those tests?}
-
-\vfill
-{\Large And allow you to auto-run them later?}
-
-\vfill
-{\LARGE Test-Driven development:}\\[0.1in]
-{\Large \hspace{0.3in} Write the tests before the code}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{Unit Testing}
-
-{\LARGE My thoughts:}
-
-\vfill
-{\Large Unit testing encourages clean, decoupled design}
-
-\vfill
-{\Large If it's hard to write unit tests for -- it's not well designed}
-
-\vfill
-{\Large but...}
-
-\vfill
-{\Large ``complete'' test coverage is a fantasy}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{PyUnit}
-
-{\LARGE PyUnit: the stdlib unit testing framework}
-
-\vfill
-{\Large \verb|import unittest|}
-
-\vfill
-{\Large More or less a port of Junit from Java}
-
-\vfill
-{\Large A bit verbose: you have to write classes \& methods}
-
-\vfill
-{\large (And we haven't covered that yet!)}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{unittest example}
-
-{\small
-\begin{verbatim}
-import random
-import unittest
-
-class TestSequenceFunctions(unittest.TestCase):
-
- def setUp(self):
- self.seq = range(10)
-
- def test_shuffle(self):
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(self.seq)
- self.seq.sort()
- self.assertEqual(self.seq, range(10))
-
- # should raise an exception for an immutable sequence
- self.assertRaises(TypeError, random.shuffle, (1,2,3))
-\end{verbatim}
-}
-
-\end{frame}
-
-
-% ---------------------------------------------
-\begin{frame}[fragile]{unittest example (cont)}
-
-{\small
-\begin{verbatim}
- def test_choice(self):
- element = random.choice(self.seq)
- self.assertTrue(element in self.seq)
-
- def test_sample(self):
- with self.assertRaises(ValueError):
- random.sample(self.seq, 20)
- for element in random.sample(self.seq, 5):
- self.assertTrue(element in self.seq)
-
-if __name__ == '__main__':
- unittest.main()
-\end{verbatim}
-}
-
-\vfill
-(\verb|code/unitest_example.py|)
-
-\vfill
-\url{http://docs.python.org/library/unittest.html}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{unittest}
-
-{\Large Lots of good tutorials out there:}
-
-\vfill
-{\Large Google: ``python unittest tutorial''}
-
-\vfill
-{\Large I first learned from this one:}\\[0.1in]
-\url{http://www.diveintopython.net/unit_testing/index.html}
-
-\end{frame}
-
-% ---------------------------------------------
-\begin{frame}[fragile]{nose and pytest}
-
-{\Large Due to its Java heritage, unittest is kind of verbose}
-
-\vfill
-{\Large Also no test discovery}\\
-{\large \hspace{0.2in}(though unittest2 does add that...) }
-
-\vfill
-{\Large So folks invented nose and pytest}
-
-\end{frame}
-
-\begin{frame}[fragile]{nose}
-
-{\LARGE \verb|nose|}
-
-\vfill
-{\Large \hspace{0.2in} Is nicer testing for python}
-
-\vfill
-{\Large \hspace{0.2in} nose extends unittest to make testing easier.}
-
-\vfill
-\begin{verbatim}
- $ pip install nose
-
- $ nosetests unittest_example.py
-\end{verbatim}
-
-\vfill
-\url{http://nose.readthedocs.org/en/latest/}
-\end{frame}
-
-\begin{frame}[fragile]{nose example}
-
-{\Large The same example -- with nose}
-
-{\small
-\begin{verbatim}
-import random
-import nose.tools
-
-seq = range(10)
-
-def test_shuffle():
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(seq)
- seq.sort()
- assert seq == range(10)
-
-@nose.tools.raises(TypeError)
-def test_shuffle_immutable():
- # should raise an exception for an immutable sequence
- random.shuffle( (1,2,3) )
-\end{verbatim}
-}
-
-\end{frame}
-
-\begin{frame}[fragile]{nose example (cont) }
-
-{\small
-\begin{verbatim}
-def test_choice():
- element = random.choice(seq)
- assert (element in seq)
-
-def test_sample():
- for element in random.sample(seq, 5):
- assert element in seq
-
-@nose.tools.raises(ValueError)
-def test_sample_too_large():
- random.sample(seq, 20)
-\end{verbatim}
-}
-
-\vfill
-(\verb|code/test_random_nose.py|)
-
-\end{frame}
-
-
-\begin{frame}[fragile]{pytest}
-
-{\LARGE \verb|pytest|}
-
-\vfill
-{\Large \hspace{0.2in} A mature full-featured testing tool}
-
-\vfill
-{\Large \hspace{0.2in} Provides no-boilerplate testing}
-
-\vfill
-{\Large \hspace{0.2in} Integrates many common testing methods}
-
-\vfill
-\begin{verbatim}
- $ pip install pytest
-
- $ py.test unittest_example.py
-\end{verbatim}
-
-\vfill
-\url{http://pytest.org/latest/}
-\end{frame}
-
-\begin{frame}[fragile]{pytest example}
-
-{\Large The same example -- with pytest}
-
-{\small
-\begin{verbatim}
-import random
-import pytest
-
-seq = range(10)
-
-def test_shuffle():
- # make sure the shuffled sequence does not lose any elements
- random.shuffle(seq)
- seq.sort()
- assert seq == range(10)
-
-def test_shuffle_immutable():
- pytest.raises(TypeError, random.shuffle, (1,2,3) )
-\end{verbatim}
-}
-
-\end{frame}
-
-\begin{frame}[fragile]{pytest example (cont) }
-
-{\small
-\begin{verbatim}
-def test_choice():
- element = random.choice(seq)
- assert (element in seq)
-
-def test_sample():
- for element in random.sample(seq, 5):
- assert element in seq
-
-def test_sample_too_large():
- with pytest.raises(ValueError):
- random.sample(seq, 20)
-\end{verbatim}
-}
-
-\vfill
-(\verb|code/test_random_pytest.py|)
-
-\end{frame}
-
-
-\begin{frame}[fragile]{Parameterized Tests}
-
-{\Large A whole set of inputs and outputs to test?}
-
-\vfill
-{\Large \verb|pytest| has a nice way to do that (so does nose...)}
-
-\begin{verbatim}
-import pytest
-@pytest.mark.parametrize(("input", "expected"), [
- ("3+5", 8),
- ("2+4", 6),
- ("6*9", 42),
-])
-def test_eval(input, expected):
- assert eval(input) == expected
-\end{verbatim}
-
-\url{http://pytest.org/latest/example/parametrize.html}
-
-\vfill
-(\verb|code/test_pytest_parameter.py|)
-\end{frame}
-
-\begin{frame}[fragile]{Test Coverage}
-
-{\LARGE \verb|coverage.py |}
-
-\vfill
-{\Large Uses debugging hook to see which lines of code are actually executed
--- plugins exist for most (all?) test runners}
-
-\vfill
-{\Large \verb|pip install coverage |}
-
-\vfill
-{\Large \verb|nosetests --with-coverage test_codingbat.py|}
-
-\vfill
-\url{http://nedbatchelder.com/code/coverage/}
-\end{frame}
-
-% --------------------------
-\begin{frame}[fragile]{Coding Bat}
-
-{\LARGE Coding Bat:}
-
-\url{http://codingbat.com/python}
-
-
-\vfill
-{\Large Tells you what unit tests to write:}
-
-\url{http://codingbat.com/prob/p118406}
-
-\vfill
-{\Large We'll use them for our lab}
-
-\end{frame}
-
-%-------------------------------
-\begin{frame}[fragile]{LAB}
-
-{\Large First: get pip installed:}
-
-{\small \url{http://www.pip-installer.org/en/latest/installing.html} }
-
-\vfill
-{\Large Second: install nose and/or pytest:}
-
-{\large \verb|pip install nose| -- \verb|pip install pytest|}
-
-
-\vfill
-{\Large Unit Testing:}
-
-\begin{itemize}
- % \item unittest
- % \begin{itemize}
- % \item Pick a \url{codingbat.com} example
- % \item Write a set of unit tests using \verb|unittest|
- % (\verb|code\codingbat.py codingbat_unittest.py|)
- % \end{itemize}
- \item pytest / nose
- \begin{itemize}
- \item Test a \url{codingbat.com} with nose or pytest
- \item Try doing test-driven development
- (\verb|code\test_codingbat.py|)
- \end{itemize}
-
- \item try running \verb|coverage| on your tests
-\end{itemize}
-
-\end{frame}
-
-
-
-%-------------------------------
-\begin{frame}[fragile]{Homework}
-
-Recommended Reading:
-\begin{itemize}
- \item TP: ch 15-18
- \item LPTHW: Ex 40 - 45
- \item Dive Into Python: chapter 4, 5
-\end{itemize}
-
-Do:
-\begin{itemize}
- \item Finish (or re-factor) the Labs you didn't finish in class.
- \item Write some unit tests for a couple of the functions you've
- written for previous excercises (Or something new)
- \item Using the unit tests you jsut wrote, refactor the above functions
- using list and/or dict comprehensions.
- \item Write a script which does something useful (to you) and reads and writes
- files. Very, very small scope is good. something useful at work would
- be great, but no job secrets!
- \item Start thinking about what you want to do for your project!
-\end{itemize}
-
-
-\end{frame}
-
-
-\end{document}
-
-
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.toc b/slides_sources/old_versions/week-05/presentation-week-05.toc
deleted file mode 100644
index 3f37054..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.toc
+++ /dev/null
@@ -1,6 +0,0 @@
-\beamer@endinputifotherversion {3.10pt}
-\beamer@sectionintoc {1}{Review/Questions}{3}{0}{1}
-\beamer@sectionintoc {2}{Unicode}{6}{0}{2}
-\beamer@sectionintoc {3}{Advanced Argument Passing}{17}{0}{3}
-\beamer@sectionintoc {4}{List and Dict Comprehensions}{24}{0}{4}
-\beamer@sectionintoc {5}{Unit Testing}{35}{0}{5}
diff --git a/slides_sources/old_versions/week-05/presentation-week-05.vrb b/slides_sources/old_versions/week-05/presentation-week-05.vrb
deleted file mode 100644
index f4e79f3..0000000
--- a/slides_sources/old_versions/week-05/presentation-week-05.vrb
+++ /dev/null
@@ -1,21 +0,0 @@
-\frametitle {Homework}\par Recommended Reading:
-\begin{itemize}
- \item TP: ch 15-18
- \item LPTHW: Ex 40 - 45
- \item Dive Into Python: chapter 4, 5
-\end{itemize}
-
-Do:
-\begin{itemize}
- \item Finish (or re-factor) the Labs you didn't finish in class.
- \item Write some unit tests for a couple of the functions you've
- written for previous excercises (Or something new)
- \item Using the unit tests you jsut wrote, refactor the above functions
- using list and/or dict comprehensions.
- \item Write a script which does something useful (to you) and reads and writes
- files. Very, very small scope is good. something useful at work would
- be great, but no job secrets!
- \item Start thinking about what you want to do for your project!
-\end{itemize}
-
-
diff --git a/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.html b/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.html
deleted file mode 100644
index cf91da2..0000000
--- a/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.html
+++ /dev/null
@@ -1,511 +0,0 @@
-
-
-
-
-
-
-Calling Code
-
-
-
-
-
Calling Code
-
-
Code that can be used to call your html rendering classes
-
-
Step 1
-
-page = Html()
-
-page.append("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text")
-
-
-
-
Step 2
-
-page = Html()
-
-body = Body()
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text"))
-
-page.append(body)
-
-
-
-
Step 3
-
-page = Html()
-
-head = Head()
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text"))
-
-page.append(body)
-
-
-
-
Step 4
-
-page = Html()
-
-head = Head()
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
-page.append(body)
-
-
-
-
Step 5
-
-page = Html()
-
-head = Head()
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
-body.append(Hr())
-
-page.append(body)
-
-
-
-
Step 6
-
-page = Html()
-
-head = Head()
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
-body.append(Hr())
-
-body.append("And this is a ")
-body.append( A("http://google.com", "link") )
-body.append("to google")
-
-page.append(body)
-
-
-
-
Step 7
-
-page = Html()
-
-head = Head()
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append( H(2, "PythonClass - Class 6 example") )
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
-body.append(Hr())
-
-list = Ul(id="TheList", style="line-height:200%")
-list.append( Li("The first item in a list") )
-list.append( Li("This is the second item", style="color: red") )
-item = Li()
-item.append("And this is a ")
-item.append( A("http://google.com", "link") )
-item.append("to google")
-list.append(item)
-body.append(list)
-
-page.append(body)
-
-
-
-
Step 8
-
-page = Html()
-
-head = Head()
-head.append( Meta(charset="UTF-8") )
-head.append(Title("PythonClass = Revision 1087:"))
-
-page.append(head)
-
-body = Body()
-
-body.append( H(2, "PythonClass - Class 6 example") )
-
-body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
-body.append(Hr())
-
-list = Ul(id="TheList", style="line-height:200%")
-list.append( Li("The first item in a list") )
-list.append( Li("This is the second item", style="color: red") )
-item = Li()
-item.append("And this is a ")
-item.append( A("http://google.com", "link") )
-item.append("to google")
-list.append(item)
-body.append(list)
-
-page.append(body)
-
-
-
-
-
diff --git a/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.rst b/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.rst
deleted file mode 100644
index b8b0282..0000000
--- a/slides_sources/old_versions/week-06/code/html_render/LAB_calling_code.rst
+++ /dev/null
@@ -1,168 +0,0 @@
-Calling Code
-###############
-
-Code that can be used to call your html rendering classes
-
-Step 1
---------
-::
-
- page = Html()
-
- page.append("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text")
-
-Step 2
--------
-::
-
- page = Html()
-
- body = Body()
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text"))
-
- page.append(body)
-
-Step 3
----------
-::
-
- page = Html()
-
- head = Head()
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text"))
-
- page.append(body)
-
-Step 4
----------
-::
-
- page = Html()
-
- head = Head()
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
- page.append(body)
-
-Step 5
----------
-::
-
- page = Html()
-
- head = Head()
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
- body.append(Hr())
-
- page.append(body)
-
-Step 6
----------
-::
-
- page = Html()
-
- head = Head()
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
- body.append(Hr())
-
- body.append("And this is a ")
- body.append( A("http://google.com", "link") )
- body.append("to google")
-
- page.append(body)
-
-Step 7
----------
-::
-
- page = Html()
-
- head = Head()
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append( H(2, "PythonClass - Class 6 example") )
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
- body.append(Hr())
-
- list = Ul(id="TheList", style="line-height:200%")
- list.append( Li("The first item in a list") )
- list.append( Li("This is the second item", style="color: red") )
- item = Li()
- item.append("And this is a ")
- item.append( A("http://google.com", "link") )
- item.append("to google")
- list.append(item)
- body.append(list)
-
- page.append(body)
-
-Step 8
----------
-::
-
- page = Html()
-
- head = Head()
- head.append( Meta(charset="UTF-8") )
- head.append(Title("PythonClass = Revision 1087:"))
-
- page.append(head)
-
- body = Body()
-
- body.append( H(2, "PythonClass - Class 6 example") )
-
- body.append(P("Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text",
- style="text-align: center; font-style: oblique;"))
-
- body.append(Hr())
-
- list = Ul(id="TheList", style="line-height:200%")
- list.append( Li("The first item in a list") )
- list.append( Li("This is the second item", style="color: red") )
- item = Li()
- item.append("And this is a ")
- item.append( A("http://google.com", "link") )
- item.append("to google")
- list.append(item)
- body.append(list)
-
- page.append(body)
diff --git a/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.html b/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.html
deleted file mode 100644
index cf7c9a5..0000000
--- a/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.html
+++ /dev/null
@@ -1,492 +0,0 @@
-
-
-
-
-
-
-Instructions for html renderer exercise:
-
-
-
-
-
Instructions for html renderer exercise:
-
-
-
Goal:
-
A set of classes to render html pages. we'll try to get to all the features required to render:
-
-sample_html.html
-
-
The exercise is broken down into a number of steps -- each requiring a bit more OO concepts in Python. WE will complete a step or two, then learn a bit more about OO in Python, then do a few more steps.
-
-
-
General Instructions:
-
For each step, add the required functionality. There is example code to run your code for each step in: LAB_calling_code.rst(html) . You should be abel to run that code at each step, and then call the render() method to render your page. You may want to use sys.stdout to render to the terminal:
-
-import sys
-....
-page.render(sys.stdout)
-
-
or you can use a regular file:
-
-outfile = open('test.html', 'w')
-...
-page.render(outfile)
-
-
or use a cStringIO object (like a file, but in memory):
-
-import cStringIO
-
-...
-
-f = cStringIO.StringIO()
-
-page.render(f)
-
-# now print it to the screen:
-f.reset()
-print f.read()
-
-
-
-
Solutions:
-
There are versions of the instructors' solution to each step in code/html_render/solutions , so you can look at a solution if you get stuck, But do try to figure it out yourself, first.
-
-
-
Step 1:
-
Create an Element class for rendering an html element (xml element).
-
It should have class attributes for the tag name ("html" first) and the indentation (spaces to indent for pretty printing)
-
The constructor signature should look like:
-
-Element(content=None)
-
-
where content is a string
-
It should have an append method that can add another string to the content
-
It should have a render(file_out, ind = "") method that renders the tag
-and the strings in the content.
-
file_out could be any file-like object (i.e have a write() method ).
-
ind is a string with the indentation level in it -- i.e the amount that the tag should be indented for pretty printing (maybe 4 spaces per level).
-
The amount of indentation should be set by the class attribute: indent
-
You can test with sys.stdout to print to the console, and/or use a
-cStringIO.sStringIO object to store it in a string - or pass a file
-
You should now be able to render an html tag with text in it as contents.
-
-
-
Step 2:
-
Create a couple subclasses of Element , for a <body> tag and <p> tag. All you should have to do is override the tag class attribute (you may need to add a tag class attribute to the Element class...).
-
Now you can render a few different types of element.
-
Extend the Element.render() method so that it can render other elements
-inside the tag in addition to strings. Simple recursion should
-do it. i.e. it can call the render() method of the elements it contains.
-
Figure out a way to deal with the fact the the contents elements could be
-either simple strings or Elements with render methods...(there are a few
-ways to handle that...)
-
You should now be able to render a basic web page with an html tag around
-the whole thing, and body tag inside, and multiple <p> tags inside that,
-with text inside that.
-
-
-
Step 3:
-
Create a <head> element -- simple subclass.
-
Create a OneLineTag subclass of Element :
-
It should override the render method, to render everything on one line -- for the simple tags, like:
-
-<title> PythonClass - Class 6 example </title>
-
-
Create a Title subclass of OneLineTag class for the title.
-
You should now be able to render an html doc with a head element, with a
-title element in that, and a body element with some <P> elements and some text.
-
-
-
Step 4:
-
Extend the Element class to accept a set of attributes as keywords to the
-constructor, ie.:
-
-Element("some text content", id="TheList", style="line-height:200%")
-
-
( remember **kwargs ? )
-
The render method will need to be extended to render the attributes properly.
-
You can now render some <p> tags (and others) with attributes
-
-
-
Step 5:
-
Create a SelfClosingTag subclass of Element, to render tags like:
-
-<hr /> and <br /> (horizontal rule and line break).
-
-
You will need to override the render method to render just the one tag and
-attributes, if any.
-
Create a couple subclasses of SelfClosingTag for and <hr /> and <br />
-
-
-
Step 6:
-
Create a A class for an anchor (link) element. Its constructor should look like:
-
-A(self, link, content)
-
-
where link is the link, and content is what you see. It can be called like so:
-
-A("http://google.com", "link")
-
-
You should be able to subclass from Element , and only override the __init__ --- Calling the Element __init__ from the A __init__
-
You can now add a link to your web page.
-
-
-
Step 7:
-
Create Ul class for an unordered list (really simple subclass of Element )
-
Create Li class for an element in a list (also really simple)
-
Add a list to your web page.
-
Create a Header class -- this one should take an integer argument for the
-header level. i.e <h1>, <h2>, <h3>, called like:
-
-H(2, "The text of the header") for an <h2> header
-
-
It can subclass from OneLineTag -- overriding the __init__ , then calling the superclass __init__
-
-
-
Step 8:
-
Update the Html element class to render the "<!DOCTYPE html>" tag at the
-head of the page, before the html element.
-
You can do this by subclassing Element , overriding render() , but then
-calling the Element render from the new render.
-
Create a subclass of SelfClosingTag for <meta charset="UTF-8" /> (like
-for <hr /> and <br /> and add the meta element to the beginning of
-the head element to give your document an encoding.
-
The doctype and encoding are HTML 5 and you can check this at:
-http://validator.w3.org .
-
You now have a pretty full-featured html renderer -- play with it, add some
-new tags, etc....
-
-
-
-
diff --git a/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.rst b/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.rst
deleted file mode 100644
index 4c87d25..0000000
--- a/slides_sources/old_versions/week-06/code/html_render/LAB_instuctions.rst
+++ /dev/null
@@ -1,190 +0,0 @@
-
-Instructions for html renderer exercise:
-###########################################
-
-Goal:
-======
-
-A set of classes to render html pages. we'll try to get to all the features required to render::
-
- sample_html.html
-
-The exercise is broken down into a number of steps -- each requiring a bit more OO concepts in Python. WE will complete a step or two, then learn a bit more about OO in Python, then do a few more steps.
-
-General Instructions:
-======================
-
-For each step, add the required functionality. There is example code to run your code for each step in: ``LAB_calling_code.rst(html)``. You should be abel to run that code at each step, and then call the ``render()`` method to render your page. You may want to use sys.stdout to render to the terminal::
-
- import sys
- ....
- page.render(sys.stdout)
-
-or you can use a regular file::
-
- outfile = open('test.html', 'w')
- ...
- page.render(outfile)
-
-or use a cStringIO object (like a file, but in memory)::
-
- import cStringIO
-
- ...
-
- f = cStringIO.StringIO()
-
- page.render(f)
-
- # now print it to the screen:
- f.reset()
- print f.read()
-
-Solutions:
-============
-
-There are versions of the instructors' solution to each step in ``code/html_render/solutions``, so you can look at a solution if you get stuck, But do try to figure it out yourself, first.
-
-
-Step 1:
-=========
-
-Create an ``Element`` class for rendering an html element (xml element).
-
-It should have class attributes for the tag name ("html" first) and the indentation (spaces to indent for pretty printing)
-
-The constructor signature should look like::
-
- Element(content=None)
-
-where ``content`` is a string
-
-It should have an ``append`` method that can add another string to the content
-
-It should have a ``render(file_out, ind = "")`` method that renders the tag
-and the strings in the content.
-
-``file_out`` could be any file-like object (i.e have a ``write()`` method ).
-
-``ind`` is a string with the indentation level in it -- i.e the amount that the tag should be indented for pretty printing (maybe 4 spaces per level).
-
-The amount of indentation should be set by the class attribute: ``indent``
-
-You can test with ``sys.stdout`` to print to the console, and/or use a
-``cStringIO.sStringIO`` object to store it in a string - or pass a file
-
-You should now be able to render an html tag with text in it as contents.
-
-Step 2:
-==========
-
-Create a couple subclasses of ``Element``, for a tag and tag. All you should have to do is override the ``tag`` class attribute (you may need to add a ``tag`` class attribute to the Element class...).
-
-Now you can render a few different types of element.
-
-Extend the ``Element.render()`` method so that it can render other elements
-inside the tag in addition to strings. Simple recursion should
-do it. i.e. it can call the ``render()`` method of the elements it contains.
-
-Figure out a way to deal with the fact the the contents elements could be
-either simple strings or Elements with render methods...(there are a few
-ways to handle that...)
-
-You should now be able to render a basic web page with an html tag around
-the whole thing, and body tag inside, and multiple
tags inside that,
-with text inside that.
-
-Step 3:
-==========
-
-Create a
element -- simple subclass.
-
-Create a ``OneLineTag`` subclass of ``Element``:
-
-It should override the render method, to render everything on one line -- for the simple tags, like::
-
- PythonClass - Class 6 example
-
-Create a ``Title`` subclass of ``OneLineTag`` class for the title.
-
-You should now be able to render an html doc with a head element, with a
-title element in that, and a body element with some elements and some text.
-
-Step 4:
-===========
-
-Extend the ``Element`` class to accept a set of attributes as keywords to the
-constructor, ie.::
-
- Element("some text content", id="TheList", style="line-height:200%")
-
-( remember ``**kwargs``? )
-
-The render method will need to be extended to render the attributes properly.
-
-You can now render some
tags (and others) with attributes
-
-Step 5:
-========
-
-Create a ``SelfClosingTag`` subclass of Element, to render tags like::
-
-
and (horizontal rule and line break).
-
-You will need to override the render method to render just the one tag and
-attributes, if any.
-
-Create a couple subclasses of ``SelfClosingTag`` for and and
-
-Step 6:
-==========
-
-Create a ``A`` class for an anchor (link) element. Its constructor should look like::
-
- A(self, link, content)
-
-where link is the link, and content is what you see. It can be called like so::
-
- A("http://google.com", "link")
-
-You should be able to subclass from ``Element``, and only override the ``__init__`` --- Calling the ``Element`` ``__init__`` from the ``A __init__``
-
-You can now add a link to your web page.
-
-Step 7:
-===========
-
-Create ``Ul`` class for an unordered list (really simple subclass of ``Element``)
-
-Create ``Li`` class for an element in a list (also really simple)
-
-Add a list to your web page.
-
-Create a ``Header`` class -- this one should take an integer argument for the
-header level. i.e