-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
executable file
·24 lines (21 loc) · 24 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html><html lang="en"><head><title>Use Pyramid Like a Pro</title><meta charset="utf-8"/><meta name="viewport" content="width=792, user-scalable=no"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><link rel="stylesheet" href="theme/styles/screen.css"/><link rel="stylesheet" href="pygment_style.css"/><link rel="stylesheet" href="font-awesome/css/font-awesome.min.css"/><link rel="shortcut icon" href="pylons.ico"/><style>@font-face{font-family:Love Ya Like A Sister, cursive;src:url(fonts/LoveYaLikeASister.ttf) format(truetype)}@font-face{font-family:Ubuntu Mono;src:url(fonts/UbuntuMono-R.ttf) format(truetype)}@font-face{font-family:Ubuntu;src:url(fonts/Ubuntu-R.ttf) format(truetype)}mark{padding-left:8px;padding-right:8px;border-radius:6px;color:red}.red{color:#e00100}.blue{color:#124a7e}.list{background:#3f4144 url(pictures/linen.png)}.list a{border-bottom:.1em solid;color:#124a7e}.list .slide:after{font-family:Love Ya Like A Sister, cursive;color:rgb(56.465%, 42.981%, 1.966%);text-shadow:2px 2px #000}.list .slide:target:before{box-shadow:0 0 0 1px rgb(95.119%, 72.404%, 3.313%), 0 0 0 10px #f8c836, 0 20px 50px rgba(42, 43, 45, .6)}@media (max-width:$break){.list .slide:target:before{box-shadow:0 0 0 1px rgb(95.119%, 72.404%, 3.313%), 0 0 0 10px #f8c836, 0 20px 50px rgba(42, 43, 45, .6)}}.list .slide:target:after{text-shadow:0 1px 1px rgba(42, 43, 45, .6);color:#f8c836}img.photo_border{box-shadow:0 0 0 2px rgba(0, 0, 0, .6), 0 0 0 14px #fff, 0 0 0 18px rgba(0, 0, 0, .1), 6px 6px 8px 17px #555}.caption h1{color:#f8c836;text-shadow:6px 6px #000}.caption{color:#f8c836;text-shadow:3px 3px #000}.badge a{background:none}.text-center{text-align:center}.slide a{color:#124a7e;border-bottom:none;text-decoration:none}.slide a:hover{text-decoration:underline}.smaller-font{font-size:smaller}.white-text{color:#fff}.comment{color:#999}.slide#Cover{border-top:none}.slide#Cover h2{font-family:Ubuntu, sans-serif;margin:30px 0 0;color:#fff;text-shadow:3px 3px #000;font-size:2em}.slide#Cover h2 .a{color:#F33}.slide#Cover p{font-family:Ubuntu, sans-serif;margin:0 0 0;font-size:1.25em}.slide#Cover p a{color:#fff}.slide#Cover p a:hover{color:#FF3}.slide#Cover p .social{font-size:3em}.slide#Cover p.author{font-size:1.1em;text-shadow:2px 2px #000;margin:10px 0 0;font-style:italic}.slide{border-top:6px solid #f8c836}.slide p.note{color:#e00100}.slide blockquote p{font-size:2em}.slide h2{color:rgb(9.559%, 39.297%, 66.912%)}.slide h2 img{vertical-align:text-top}.slide.shout h2{padding-bottom:30px}.slide.shout h2 mark{margin-top 16px}h2 mark.mark{line-height:1.4;padding-left:80px;padding-right:80px}.slide li{2.2em}.Picture h2{color:#fff}#SeeMore{font-style:normal}#SeeMore h2{font-size:6.25em}#SeeMore img{width:.72em;height:.72em}.shout.medium h2{font-size:7.5em}.shout.small h2{font-size:5.625em}.shout.x-small h2{font-size:4em}.shout.x-small h2 mark{line-height:1.4}.slide i.icon{text-indent:0;font-style:normal}.slide i.icon.alien{color:#999}.linenodiv{margin-right:.6em}.slide pre code{font-size:1.2em;font-family:Ubuntu Mono, sans-serif}.slide pre code.bigger{font-size:1.3em}</style></head><body class="list"><header class="caption"><h1>Use Pyramid Like a Pro</h1><p>Keith Yang</p></header><section id="Cover" class="slide cover"><div><h2>Use Pyramid</h2><h2>Like <span class="a">a </span>Pro</h2><p class="author"><a href="http://quest.keitheis.org">Keith Yang</a></p><p><span class="white-text">@keitheis </span></p><img src="pictures/pyramid-aliens2-1920X1200.jpg" width="100%" title="Pyramid Aliens Picture by Felix LaFlamme" alt="Pyramid Aliens Picture by Felix LaFlamme"/><!-- Designed and done by Felix LaFlamme, http://www.felixlaflamme.com/ -->
</div></section><section class="slide"><div><h2><span class="red pull-right">@keitheis</span>Keith Yang</h2><ul><li>architect.py in <a href="http://www.biideal.com/"><img src="pictures/biideal_logo.png" alt="biideal logo" title="biideal"/></a></li><li>Organizer/Coordinator in <a href="http://taipei.python.org.tw/"><img src="pictures/taipei.py.logo.png" alt="Taipei.py Logo" title="Taipei.py"/></a></li><li>Web Lead in <a href="http://tw.pycon.org/2013/">PyCon Taiwan 2013</a></li></ul></div></section><section class="slide"><div><div class="pull-right"><a href="http://www.biideal.com/"><img src="pictures/biideal_logo.png" alt="biideal logo" title="biideal"/></a></div><h2>Some fun fact</h2><ul><li>New EC Startup <i class="red icon icon-shopping-cart"></i></li><li class="next"><i class="red icon icon-rotate-right"></i> Re-built on Nov.2012, Apr. 2013 online</li><li class="next">Agile style <i class="red icon icon-magic"></i></li><li class="next">Powered by <img src="pylons.ico" alt=""/> Pyramid</li></ul></div></section><section class="slide"><div><div class="pull-right"><a href="http://taipei.python.org.tw/"><img src="pictures/taipei.py.logo.png" alt="Taipei.py Logo" title="Taipei.py"/></a></div><h2>Taipei.py</h2><ul><li>Monthly Meetup</li><li class="next">to Weekly Meetup</li></ul><p class="note next">Taipei.py 的奇幻漂流</p></div></section><section class="slide shout"><div><h2><a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html"><img src="pictures/pyramid-logo.png" alt="Pyramid Official"/></a><br/>Core</h2></div></section><section class="slide shout medium"><div><h2>Choice <i class="icon icon-hand-left"></i><br/><span class="next">Like</span><br/><span class="next">Human Being</span></h2></div></section><section class="slide"><div><h2>Being What? <span class="next">Alien? <i class="alien icon icon-github"></i></span></h2><ol><li>Know your future</li><li>Know your scale</li><li>Know your tool sets</li><li>Know your team, goal, and time frames</li></ol><p class="note next">from future import everything</p></div></section><section class="slide"><div><h2>Choose <span class="next">What? <i class="icon icon-hand-left icon-spin"></i></span></h2><ol><li><code>Web Framework(s)</code></li><li>
<code>SQL</code>
<code>NoSQL</code>
<code>ORM</code>
<code>Query Helper</code>
<code>ALL REDIS?</code>
</li><li><code>Message Queues</code> and/or <code>Background Workers</code></li><li>
<code>Template</code>
<code>Session</code>
<code>API?</code>
<code>RESTful</code>
<code>RESTlike</code>
</li></ol><p class="note next">Too many to choose but usually or eventually you have to</p></div></section><section class="slide shout medium"><div><h2>Architecture,<br/>Architecture,<br/>Architecture.</h2></div></section><section class="slide shout"><div><h2>That's why<br/><mark class="mark next">Flexibility</mark><br/>Counts</h2></div></section><section class="slide"><div><h2>The Power of Pyramid (<a href="http://www.pylonsproject.org/">Pylons Project</a>)</h2><ol><li>Flexibility: from minimal to full stack <span class="next"><code>seriously ready</code></span></li><li><a href="http://www.slideshare.net/rachbelaid/pyramid-views-20820325" title="Pyramid views">Views config & varies routes</a></li><li><a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation">Add-ons and friends</a></li><li>Reliability, Agilibility, Simplicity and <code>Community</code> </li><li class="next"><code>Fun</code> to learn</li></ol></div></section><section class="slide shout small"><div><h2>Python 3<br/>Ready<br/>from Pyramid 1.3</h2></div></section><section class="slide"><div><h2>What Pyramid is <mark>NOT</mark>
</h2><p>Not the first web framework<br/>you should learn together with<br/>your first programming language (e.g. Python).</p></div></section><section class="slide"><div><h2>Rumors</h2><p><i>“Use NoSQL and you will be good with schema free.”</i></p><p>Imagine a type free programming language,<br/>which <code>int(“0”) + str(1)</code> will be so fine. </p></div></section><section class="slide"><div><h2>Rumors (cont.)</h2><p><i>“Why you should use this web framework”</i></p><p>Said, Django, Flask, Web2py, Bottle, Rails, ...<br/>all the excellent choices. </p><p class="note next">Also known as「不要欺騙小孩子」 <i class="icon icon-hand-up"></i><br/><span class="next comment smaller-font">課本上有寫「政黨體質的健全、民主、清廉與執政能力關係人民的幸福」</span></p></div></section><section class="slide shout"><div><h2>I say:<br/>“Just use Python”</h2><img src="pictures/pythocat.png" width="28%" alt="pythocat icon on github" class="pull-right"/><p class="note next"><i class="icon icon-remove"></i> 不解釋。</p></div></section><section class="slide"><div><h2>Fundamental Pyramid School</h2><p><ul><li>Understand Pyramid Request</li><li>Separated logic of views, data and business</li></ul></p><p class="note next">For any MVC-like Framework<br/>M or C is not for business logic</p></div></section><section class="slide"><div><h2>Fundamental Pyramid School (cont.)</h2><ul><li>Super powerful Views</li><li>Flexible Routes</li><li>Context driven</li></ul></div></section><section class="slide"><div><h2>Database: to SQL</h2><ul><li>Postgres, professional or enthusiastic</li><li>MariaDB, new MySQL candidates, or lazy at first</li><li>SQLite for development, personal app, or no production-level needed</li></ul></div></section><section class="slide"><div><h2>Database: to NoSQL</h2><ul><li>To name a few:<ul><li>MongoDB, Riak, Cassandra, Redis, Hadoop, ...</li></ul></li><li>When you arrived here you'll learn these class. <br/>Before that, just keep calm on them.</li></ul></div></section><section class="slide"><div><h2>Database: None</h2><h2><mark class="next">Perfect</mark></h2><p class="note">No default binding ORM, no bother.</p></div></section><section class="slide"><div><h2>To ORM</h2><ul><li>SQLAlchemy ORM</li><li>Read <a href="http://doc.ponyorm.com/#what-is-pony-orm">What is Pony ORM?¶</a></li><li>Django ORM (not really a choice here)<img src="pictures/mango_fotor.jpg" alt="" title="台灣愛文芒果" class="pull-right"/></li><li><a href="http://peewee.readthedocs.org/">Peewee</a> Django ORM like</li><li>MongoEngine, MongoKit, Ming, ...</li></ul><p class="note pull-right next">Have you tried Taiwan Mango?</p></div></section><section class="slide"><div><h2>Not to ORM</h2><ul><li>SQLAlchemy Core</li><li><a href="http://mosql.mosky.tw/">MoSQL </a>v0.2 by <a href="http://mosky.tw/">mosky</a>, also on <a href="https://github.com/moskytw/mosql"><i class="icon icon-github"></i></a> <span class="next">(yesterday v0.1.6)</span></li><li>Pure SQL Dialects: hard code driver Query<br/>(sqlite3, psycopg2, mysql-python, ...)</li><li>Pure NoSQL Dialects</li></ul></div></section><section class="slide"><div><h2>Templates: Mako or Jinja2</h2><ul><li>Mako - pythonic<span class="next">, or not, depending on you with its nature</span><br/>by Mike Bayer (author of Alembic)</li><li>Jinja2<br/>by <a href="http://lucumr.pocoo.org/">Armin Ronacher</a>, also Flask author<ol><li>Elegant</li><li>Strict, more or less, magic</li></ol></li></ul></div></section><section class="slide"><div><h2>Templates (cont.) - Plim</h2><ol><li>by Maxim Avanov <a href="https://github.com/2nd"><i class="alien icon icon-github"></i></a></li><li>Ported from Slim template</li><li>Clean HTML usage</li><li>Built on Mako</li><li><code>Fun</code><span class="next">and half hell on debug mode</span></li></ol><p class="note">Guess what? <span class="next">You'll learn how to guess by using it <i class="icon icon-meh"></i></span></p></div></section><section class="slide"><div><h2>Templates (cont.) - Plim</h2><div class="source"><pre><code><span class="o">-</span><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'apple'</span><span class="p">,</span> <span class="s">'banana'</span><span class="p">,</span> <span class="s">'pineapple'</span><span class="p">]</span></code><code> <span class="n">tr</span></code><code> <span class="o">-</span><span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'juice'</span><span class="p">,</span> <span class="s">'muffin'</span><span class="p">,</span> <span class="s">'pie'</span><span class="p">]</span></code><code> <span class="n">td</span> <span class="err">$</span><span class="p">{</span><span class="n">row</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()}</span> <span class="err">$</span><span class="p">{</span><span class="n">col</span><span class="p">}</span></code></pre></div><p class="note next">
That's all. No </blah blah things>.
</p></div></section><section class="slide"><div><h2>Templates (cont.) - Chameleon</h2><p>ZPT, Kid or Genshi lovers should give it a look</p><div class="source"><pre><code><span class="nt"><tr</span> <span class="na">tal:repeat=</span><span class="s">"row 'apple', 'banana', 'pineapple'"</span><span class="nt">></span></code><code> <span class="nt"><td</span> <span class="na">tal:repeat=</span><span class="s">"col 'juice', 'muffin', 'pie'"</span><span class="nt">></span></code><code> <span class="cp">${</span><span class="n">row</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span><span class="cp">}</span> <span class="cp">${</span><span class="n">col</span><span class="cp">}</span></code><code> <span class="nt"></td></span></code><code><span class="nt"></tr></span></code></pre></div></div></section><section class="slide"><div><h2>Too many to introduce (again)</h2><ul><li>Celery, Python RQ</li><li>RebbitMQ, ZeroMQ</li><li>Redis, memcached</li><li>Beaker, retools (both by <code>Ben Bangert</code>, Pylons 1 author)</li></ul><p class="note next">Pylons 2? You got it: Pyramid.</p></div></section><section class="slide"><div><h2>Oh, Sentry</h2><ul><li>by David Cramer (our Keynote speaker) </li><li>Awesome error events handle </li><li>Host by yourself or <a href="https://getsentry.com/">getsentry.com</a></li></ul></div></section><section class="slide"><div><h2>My better practices</h2><p><ul><li>Separate the (DB) models and behaviors.</li><li class="next">Reproduce-able development database (Fixtures)</li><li class="next">Development mode optimization</li><li class="next"><a href="https://github.com/2nd/plim" title="Python port of Ruby's Slim template language built on top of the Mako Templates.">Plim template</a></li></ul></p><p class="note">Double-edged swords <i class="icon icon-cut"></i> use them carefully. </p></div></section><section class="slide"><div><h2>My better practices (cont.)</h2><p><ul><li>Explicit architecture (lib, tasks, schemas ... folders)<br/>with explicit nameing</li><li class="next">Focus on a utc module handles datetime & timezone</li><li class="next">Fundamental doc: README and doc/**/*.rst</li><li class="next">Avoid mess sys or deploy stuff in code repository<br/>if possible</li></ul></p></div></section><section class="slide shout"><div><h2>Minimal Viable <span class="red">Code <i class="icon icon-code smaller"></i></span></h2></div></section><section class="slide"><div><h2>My worser lesson 1</h2><div class="source"><pre><code><span class="k">def</span> <span class="nf">ugly_customized_routes</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">resource_route</span><span class="p">,</span></code><code> <span class="n">path</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span></code><code> <span class="n">actions</span><span class="o">=</span><span class="s">"ICRUD"</span><span class="p">,</span></code><code> <span class="n">resource_name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span></code><code> <span class="o">...</span></code></pre></div><p class="note">Not aesthetic route helper</p></div></section><section class="slide"><div><h2>My worser lesson 2</h2><div class="source"><pre><code><span class="k">print</span><span class="p">(</span><span class="s">"This is too embarrassing to print"</span><span class="p">)</span></code></pre></div><p class="note">Lacking CI tests <i title="meh!" class="icon icon-meh"></i></p></div></section><section class="slide"><div><h2>Debug mode</h2><div class="smaller-font"></div><div class="source"><pre><code><span class="k">if</span> <span class="n">debug_notfound_route</span><span class="p">:</span></code><code> <span class="kn">from</span> <span class="nn">.views.notfound</span> <span class="kn">import</span> <span class="p">(</span></code><code> <span class="n">NotFoundDebugView</span> <span class="k">as</span> <span class="n">NotFoundView</span></code><code> <span class="p">)</span></code><code><span class="k">else</span><span class="p">:</span></code><code> <span class="kn">from</span> <span class="nn">.views.notfound</span> <span class="kn">import</span> <span class="n">NotFoundView</span></code><code><span class="n">config</span><span class="o">.</span><span class="n">add_notfound_view</span><span class="p">(</span><span class="n">NotFoundView</span><span class="p">)</span></code></pre></div></div></section><section class="slide cover"><div><img src="pictures/debugtoolbar.png" width="100%" alt="Debugtoolbar"/></div></section><section class="slide"><div><h2>SQL Master</h2><img src="pictures/debug_sql.png" width="100%" alt="SQL on Debugtoolbar" class="photo_border"/></div></section><section class="slide"><div><h2>Logging in the flow</h2><img src="pictures/debug_log.png" width="100%" alt="Logging on Debugtoolbar" class="photo_border"/></div></section><section class="slide"><div><h2>Debug Debugtoolbar</h2><div class="source"><pre><code><span class="c"># Disable development performance killer</span></code><code><span class="n">debugtoolbar</span><span class="o">.</span><span class="n">panels</span> <span class="o">=</span></code><code> <span class="n">pyramid_debugtoolbar</span><span class="o">.</span><span class="n">panels</span><span class="o">.</span><span class="n">sqla</span><span class="o">.</span><span class="n">SQLADebugPanel</span></code><code> <span class="o">...</span></code><code> <span class="c">#pyramid_debugtoolbar.panels.introspection.IntrospectionDebugPanel</span></code><code> <span class="c">#pyramid_debugtoolbar.panels.tweens.TweensDebugPanel</span></code><code> <span class="c">#pyramid_debugtoolbar.panels.routes.RoutesDebugPanel</span></code></pre></div></div></section><section class="slide"><div><h2>Before your first <mark>release</mark></h2><p><span class="icon-stack"><i class="icon blue icon-sign-blank icon-stack-base"></i><i class="icon icon-terminal icon-light"></i></span> Practice</p><ul><li>Pshell (the force on production, use it carefully)</li><li>Play Pyramid scripts</li><li>Alembic Database Migration scripts (if using SQLAlchemy)</li></ul></div></section><section class="slide shout medium"><div><h2>Save <i class="red icon icon-ambulance"></i><br/>Your Self<br/>In Time</h2></div></section><section class="slide"><div><h2>Feel the power of Alembic</h2><ul><li>by <a href="http://techspot.zzzeek.org/">Mike Bayer (author of SQLAlchemy)</a></li><li>Use op and sa instead your defined Models</li><div class="source"><pre><code><span class="kn">from</span> <span class="nn">alembic</span> <span class="kn">import</span> <span class="n">op</span></code><code><span class="kn">import</span> <span class="nn">sqlalchemy</span> <span class="kn">as</span> <span class="nn">sa</span></code></pre></div></ul><p class="note next">Because YMWV (Your model WILL vary) between revisions.</p></div></section><section class="slide shout x-small"><div><h2>alembic -c dev.ini <br/>revision <mark>--autogenerate</mark><br/>-m "magic hour" </h2></div></section><section class="slide"><div><h2>Encourage Refactor and Clean Code</h2><ul><li class="next">Feature development helps some.</li><li class="next">Clean code, testing and refactor helps <mark>everyone.</mark></li></ul></div></section><section class="slide"><div><h2>From Web app to API</h2><ul><li>Reusable permission control</li><li>Customized API render (extra work on JSON response)</li></ul><div class="source"><pre><code><span class="nd">@view_defaults</span><span class="p">(</span><span class="n">renderer</span><span class="o">=</span><span class="s">'api'</span><span class="p">,</span> <span class="n">permission</span><span class="o">=</span><span class="s">'account'</span><span class="p">)</span></code><code><span class="k">class</span> <span class="nc">APIResourceView</span><span class="p">(</span><span class="n">APIBaseView</span><span class="p">,</span> <span class="n">APIPagingMixin</span><span class="p">):</span></code><code> <span class="o">...</span></code></pre></div></div></section><section class="slide"><div><h2>From Web app to API (cont.)</h2><ul><li>Views for API Forbidden and NotFound</li></ul><div class="source"><pre><code><span class="n">config</span><span class="o">.</span><span class="n">add_forbidden_view</span><span class="p">(</span></code><code> <span class="n">APIForbiddenView</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="s">'/api/'</span><span class="p">)</span></code><code><span class="n">config</span><span class="o">.</span><span class="n">add_notfound_view</span><span class="p">(</span></code><code> <span class="n">APINotFoundView</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="s">'/api/'</span><span class="p">)</span></code></pre></div><p class="note">(no months or years needed for working)</p></div></section><section class="slide"><div><h2>API V2 Routes Ready</h2><div class="source"><pre><code><span class="kn">from</span> <span class="nn">.api.routes</span> <span class="kn">import</span> <span class="n">api_routes</span></code><code><span class="n">config</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="n">api_routes</span><span class="p">,</span> <span class="s">'/api/v1'</span><span class="p">)</span></code></pre></div><div class="source"><pre><code><span class="kn">from</span> <span class="nn">.api.v1.routes</span> <span class="kn">import</span> <span class="n">api_routes</span> <span class="k">as</span> <span class="n">api_v1_routes</span></code><code><span class="n">config</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="n">api_v1_routes</span><span class="p">,</span> <span class="s">'/api/v1'</span><span class="p">)</span></code><code><span class="kn">from</span> <span class="nn">.api.routes</span> <span class="kn">import</span> <span class="n">api_routes</span> <span class="k">as</span> <span class="n">api_v2_routes</span></code><code><span class="n">config</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="n">api_v2_routes</span><span class="p">,</span> <span class="s">'/api/v2'</span><span class="p">)</span></code></pre></div></div></section><section class="slide"><div><figure><blockquote><h2>哭吧你</h2></blockquote></figure><figcaption>現在每個人可獲得1 Pyramid。</figcaption><hr/><p class="text-center">更彈性。<span class="comment">要怎樣就怎樣。</span><br/>更多元。<span class="comment">做不完的決定。</span><br/>更多頁。<span class="comment">為什麼不立即開始讀讀不完的文件呢?</span></p><p class="next"><span class="comment pull-right"># flickr 梗</span></p></div></section><section id="more_on_pylons" class="slide"><div><h2>Much More</h2><p><a href="http://www.pylonsproject.org"><img src="pictures/pylons-logo.png" alt="Pylons Project"/></a><br/><i class="icon icon-twitter"></i> @pylons</p></div></section><section id="thank_you" class="slide shout"><div><div class="pull-right"><img src="pictures/pycontw2013-logo.png" alt="PyCon Taiwan 2013"/></div><h2><br/><br/>Thank You <i class="red icon icon-thumbs-up"></i></h2></div></section><p class="badge"><a href="https://github.com/keitheis/use-pyramid-like-a-pro">Fork me on Github</a></p><!-- To hide progress bar from entire presentation just remove "progress" element. -->
<div class="progress"><div></div></div><script src="shower/shower.min.js">
</script><script>
document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')</script><!-- Copyright © 2013 Keih Yang, keitheis.org -->
</body></html>