Skip to content

Instantly share code, notes, and snippets.

@grahamjenson
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamjenson/9163435 to your computer and use it in GitHub Desktop.
Save grahamjenson/9163435 to your computer and use it in GitHub Desktop.
First Lecture at

First Lecture for 159.707

<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/goto/deck.goto.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/menu/deck.menu.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/navigation/deck.navigation.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/status/deck.status.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/scale/deck.scale.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/themes/style/swiss.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/isagalaev/highlight.js/master/src/styles/monokai_sublime.css">
<link rel="stylesheet" href="https://rawgithub.com/imakewebthings/deck.js/master/core/deck.core.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/themes/transition/horizontal-slide.css">
<script src='http://code.jquery.com/jquery-2.0.3.js'></script>
<script src='http://code.jquery.com/ui/1.10.3/jquery-ui.js'></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/modernizr.custom.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/core/deck.core.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/menu/deck.menu.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/goto/deck.goto.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/status/deck.status.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/navigation/deck.navigation.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/scale/deck.scale.js"></script>
<script src="http://coffeescript.org/extras/coffee-script.js"></script>
<script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>
<script src="https://rawgithub.com/coreyti/showdown/master/src/showdown.js"></script>
<script src="https://rawgithub.com/coreyti/showdown/master/src/extensions/github.js"></script>
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css' />
<style>
pre {
border: 0px;
}
pre code {
font-size: .6em;
}
p {
font-size: 1.2em;
}
blockquote {
font-size: 1.2em;
}
.body {
font-family: "Lato", sans-serif;
color: #5d5d5d; }
.pull-right {
float: right;
margin: 10px; }
.pull-left {
float: left;
margin: 10px; }
</style>
</head>
<body>
<div class="deck-container">
<!-- Begin slides. Just make elements with a class of slide. -->
<section class='slide no-md'>
<h1>
159.707
<br>
<span style="font-size: .2em; color: #c00;"> Component Evolution (Graham’s thesis) and recent industry experience </span>
</h1>
</section>
<section class='slide no-md'>
<h2> About me </h2>
<ul>
<li> Graham Jenson </li>
<li> B.Sc. Hons 2008 </li>
<li> Ph.D. 2013 </li>
<li> Contracting Consultant </li>
<li> Startup </li>
<li> Marketing Enterprise Company</li>
</ul>
</section>
<section class='slide no-md'>
<h2>159.707 Advanced Software Design and Construction</h2>
<ul>
<li>25 Feb: Component Evolution (Graham’s thesis) and recent industry experience </li>
<li>4 March: Dynamic typing case study (Ruby), Convention over Configuration (RubyOnRails)</li>
<li>11 March: Design Patterns in Modern Web Applications (coffeescript, backbone, ember, angular, node.js)</li>
<li>18 March: Architecture, refurbishing/replacing legacy systems </li>
<li> 1 April: Agile Methodologies (SCRUM , Kanban) </li>
<li> 8 April: Data visualisation with D3 </li>
</ul>
</section>
<section class='slide no-md'>
<h2>Today</h2>
<ul>
<li>Ph.D. Overview</li>
<li>My Recent Work</li>
</ul>
</section>
<section class='slide no-md'>
<h1>My Ph.D.
<br>
<span style="font-size: .2em; color: #c00;"> A Study of Software Component System Evolution </span>
</h1>
</section>
<section class='slide'>
##What I am talking about
> In order to agree to talk, we just have to agree we are talking about roughly the same thing. *[The Feynman Lectures on Physics](http://www.amazon.com/gp/product/0465023827/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0465023827&linkCode=as2&tag=maor01-20), Motion, Richard Feynman, 1961.*
1. Software Components
2. Component Systems
3. Software Evolution
</section>
<section class='slide'>
## Component
A *component* is an intuitive concept, where each person has their own internal metaphor in which to describe it. Software components are:
* **lego blocks**, just clicks them together to build software
* **biological systems** where a developer puts them near each other and they communicate and self organise
* **electrical system**, where they are wired up together by a developer
* **cogs in a engine** where one connection is nothing like another and you have to put the right piece in the right place
</section>
<section class='slide'>
## Component
**Finding a definition that will satisfy all these ideas is impossible**
I think that after many such arguments Szyperski wrote that it is impossible to
> enumerate a fixed agreeable set of features that is necessary and sufficient for a natural concept such as component
</section>
<section class='slide'>
## Component
I still needed a definition for my thesis. Since there didn't exist a definition that would satisfied everyone, I decided to create my own. I chose to only define the parts of a software component I needed for my research. My definition: a software component:
1. has explicitly declared constraints for its execution environment, e.g. dependencies on (or conflicts with) other components
2. include mechanisms to automatically alter a component composition, e.g. change the components in a system without manual intervention
</section>
<section class='slide'>
## Component Systems
Some examples of component systems that fit my definition are:
* the Ubuntu operating system
* the Eclipse IDE
</section>
<section class='slide'>
## Component Systems
**Ubuntu** has control files and `apt-get`
```
Package: textEditorPackage
Version: 0.0.1.alpha
Depends: spellChecker
Conflicts: otherTextEditorPackage
```
</section>
<section class='slide'>
## Component Systems
**Eclipse** has manifest files and `P2`
```
Bundle-Name: TextEditor
Bundle-Vendor: Graham Jenson
Bundle-SymbolicName: nz.geek.textEditor
Bundle-Version: 0.0.1.alpha
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Export-Package: nz.geek.textEditor;version="0.0.1.alpha"
Require-Bundle: nz.geek.fonts
Import-Package: nz.geek.spellchecker;version>"0.0.1"
```
</section>
<section class='slide'>
## Software Evolution
> If an object has all its component parts replaced, is it the same object? *paraphrased from Plutarch, the Life of Theseus*
</section>
<section class='slide'>
## Software Evolution
> Brooks in [The Mythical Man-Month](http://www.amazon.com/gp/product/0201835959/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201835959&linkCode=as2&tag=maor01-20) states that over 90% of the cost of a system occurs after deployment
</section>
<section class='slide'>
## Software Evolution
There are two views you can take on software changing after deployment:
1. the deliberate activities a developer does to software after deployment, **software maintenance**
2. the unplanned changes that happen because of these activities, **software evolution**
</section>
<section class='slide'>
## Software Evolution
There are two views you can take on software changing after deployment:
1. the deliberate activities a developer does to software after deployment, **software maintenance**
2. the unplanned changes that happen because of these activities, **software evolution**
</section>
<section class='slide'>
## Software Evolution
Software maintenance has been formalised into types in ISO/IEC 14764 as:
1. **Adaptive Maintenance**: adapting to new system or technical requirements.
2. **Perfective Maintenance**: adapting to new user requirements.
3. **Corrective Maintenance**: fixing errors and bugs.
4. **Preventive Maintenance**: adapting to prevent future problems.
Lientz and Swanson (1980) found that 75% of the maintenance effort was on the first two types, and corrective maintenance took about 21% of the effort.
</section>
<section class='slide'>
## Software Evolution
Some [laws of software evolution](http://en.wikipedia.org/wiki/Lehman's_laws_of_software_evolution) were identified by Lehman; these are:
1. **Continuing Change**: Software systems must be continually adapted, otherwise they become progressively less satisfactory.
2. **Increasing Complexity**: As the system evolves its complexity increases unless work is done to reduce it.
3. **Self Regulation**: The system evolves with statistically determinable trends and invariances.
4. **Conservation of Organisational Stability**: The average effective activity rate to evolve a system is invariant over its lifetime.
5. **Conservation of Familiarity**: As the system evolves, its incremental growth must remain invariant to ensure users maintain mastery over the system.
6. **Continuing Growth**: The system must continually grow to maintain user satisfaction.
7. **Declining Quality**: The quality of the system will decline unless rigorously maintained.
8. **Feedback System**: The function a system performs is changed by the effect it has on its environment.
</section>
<section class='slide'>
## What does this mean for you?
>a software engineer’s objective of creating a satisfactory system is difficult, expensive, and not always achievable. Additionally, the continual evolution of a software system is necessary, and this evolution reduces quality, increases complexity, and is costly.
</section>
<section class='slide'>
##Component and Component System Evolution
>We are like sailors who on the open sea must reconstruct their ship but are never able to start afresh from the bottom. *Willard Van Orman Quine, Word and Object, 1960*
</section>
<section class='slide'>
##Component and Component System Evolution
I used to be that a developer created, a component then composed components together into a system.
**Now** the developer creates a component for the user to compose into their system
When a user is the one who composes their system, and not a developer, this breaks apart two processes:
1. the evolution of the component
2. the evolution of the component system.
</section>
<section class='slide'>
##Component and Component System Evolution
I used to be that a developer created, a component then composed components together into a system.
**Now** the developer creates a component for the user to compose into their system
When a user is the one who composes their system, and not a developer, this breaks apart two processes:
1. the evolution of the component
2. the evolution of the component system.
</section>
<section class='slide'>
##Component Evolution
**Component Evolution** is very similar to software evolution, it requires a developer.
The units of this evolution are *versions*. Using these versions, you can tell if a version of software is more or less evolved than another.
</section>
<section class='slide'>
## Component System Evolution
**Component System Evolution** (CSE) is not like software evolution. There are no versions of a system, telling if one is more evolved than another is impossible.
However, changing a component system is much more restrictive than an individual component as it must satisfy all contained component constraints. If component `a` depends on component `b`, which is noted as `a -> b`, then if `a` is installed `b` must be as well.
</section>
<section class='slide'>
##Component System Evolution
Changing a component system would be impossible for a non-technical user if it were not for tool support.
In steps **Component Dependency Resolver** (CDR)
CDR's typically **optimise** and try to minimise the amount they **change** and **out-of-dateness** of a system.
</section>
<section class='slide'>
#My Research
</section>
<section class='slide'>
##My Research
1. Hypothesis
2. Method
3. Experiments
4. Analysis
</section>
<section class='slide'>
##Hypothesis
> It is possible to reduce the negative effects of component system evolution by altering the mechanisms by which systems are changed.
I broke this down into these necessary steps I had to take:
* To develop a reproducible and controllable environment in which to measure the effects of CSE.
* To use this environment to study how systems evolve.
* To alter the mechanisms by which systems are changed and study their impact on CSE.
* To demonstrate a reduction on change and out-of-dateness using such alterations.
</section>
<section class='slide'>
##Method
**Simulation**
It lets you
1. control all the variables
2. cheaply run hundreds of experiments without interruption
3. all it takes is a little (or a lot) time on a computer.
To make a realistic simulation you need to have enough data of significant size and complexity to make the simulation realistic and non-trivial.
</section>
<section class='slide'>
##Ubuntu
> Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
First two rules of Unix:
* **Rule of Modularity**: Write simple parts connected by clean interfaces.
* **Rule of Composition**: Design programs to be connected to other programs.
</section>
<section class='slide'>
##Ubuntu
Ubuntu also has a massive sets of data to use:
1. a full history of every component in its core repository and the time it was uploaded
2. one of the largest automated surveys in the world just about what packages are popular, Ubuntu [popcon](http://popcon.ubuntu.com/)
3. millions of users who are easily accessible to collect data
4. an open and transparent community of developers and researchers all actively sharing what they are doing
</section>
<section class='slide'>
##Simulation
The biggest hurdle with simulation is making it similar enough to reality. To show a simulation is similar to reality.
> Validation is the process of determining whether a simulation is an accurate representation of the system, for the particular object of the study **Law (2005)**
</section>
<section class='slide'>
##Simulation
The method is outlined as such:
1. Formulate the problem
2. Collect information to construct a conceptual model
3. Validate the conceptual model
4. Implement the conceptual model
5. Validate the implementation
6. Design conduct and analyse experiments
7. Document and present results
</section>
<section class='slide'>
#What I created
</section>
<section class='slide'>
##What I created
> Experiment is the sole judge of scientific truth *[The Feynman Lectures on Physics](http://www.amazon.com/gp/product/0465023827/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0465023827&linkCode=as2&tag=maor01-20), Introduction, Richard Feynman, 1961.*
To answer my hypothesis I needed to answer some smaller questions:
* How can CSE be modelled?
* How can a user who changes their component system be modelled?
* How can a CSE simulation be implemented?
* How can the negative effects during CSE be reduced?
</section>
<section class='slide'>
##What I created
To answer these questions I needed to:
1. create a formal model CoSyE (Component System Evolution) that describes CSE.
2. create the CUDF\* language that is used to define documents that describe the evolution of a component system.
3. create SimUser (Simulated User), which models a user who changes their system.
4. create GJSolver which is an efficient implementation that calculates the changes made to a system as it evolves (called resolving).
5. build a simulation of the evolution of Ubuntu operating systems using CoSyE, CUDF\*, SimUser and GJSolver.
6. test two methods to reduce the out-of-dateness and change during CSE.
7. analyse the results from experiments and draw conclusions.
</section>
<section class='slide'>
##**Co**mponent **Sy**stem **E**volution (CoSyE)
To exactly describe what I am talking about, I decided to describe it as a model. The qualities I wanted from model were:
* **Abstractness** - it is a reduction of reality
* **Understandability** - it is intuitive
* **Accuracy** - it is a representation of the real system
* **Predictivness** - can be used to predict non-obvious properties
* **Inexpencive** - cheaper to study than the actual system
</section>
<section class='slide'>
##CoSyE constraints
1. **Exclusion**: Not in the system
2. **Conflict**: When two components cannot be in the system
3. **Inclusive Disjunction**: When at least one of a set of components must be in the system
4. **Dependence**: When if one component is in a system at least one of a set of other components must be in the system
5. **Exactly One**: When exactly one of a set of components must be in a system
</section>
<section class='slide'>
##CoSyE instance variables
1. A series of times
2. The set of available components at each time
3. User requests to change the system at each time
4. Sets of systems constraints at each time (can be extracted from the components that exist)
5. Optimisation criteria at each time, used to satisfy the user request
6. The initial components in the system
</section>
<section class='slide'>
##CUDF
```
preamble:
property: size: int = [0]
package: syslib
version: 1
installed: true
package: syslib
version: 2
conflicts: syslib
package: textEditor
version: 1
depends: spellChecker | spellCheckerService, syslib > 1
package: spellChecker
version: 1
size: 1
package: tpspeller
version: 1
provides: spellCheckerService
size: 2
request:
install:textEditor
```
</section>
<section class='slide'>
##CUDF\*
```
preamble: 100
property: size: int = [0]
package: syslib
version: 1
time: 50
installed: true
package: textEditor
version: 1
time: 150
depends: spellChecker | spellCheckerService, syslib > 1
...
package: tpspeller
version: 1
time: 250
provides: spellCheckerService
size: 2
request: 200, -change,-size
install:textEditor
request: 300, -size,-change
install: textEditor, tpspeller
```
</section>
<section class='slide'>
##SimUser
**Modelling a user behaviour is hard**. I mean **really hard** and it is even harder to verify. The first step though is generally talking to users, so I chose to start my modelling by doing an online survey.
*Note: Everything involving people outside your research requires ethics approval, including online surveys.*
From survey I was able to describe two type of user behaviour:
* **Progressive** behaviour prioritizes the potential risk of becoming out-of-date over the risk of introducing new problems.
* **Conservative** behaviour prioritizes the potential risk of changing the system over having less functionality and having old problems persist.
</section>
<section class='slide'>
##SimUser
1. is the probability a user requests to upgrade the system per day.
2. is the probability a user requests to install any component per day.
3. is the MOF criteria used to select an optimal system for an upgrade request.
4. is the MOF criteria used to select an optimal system for an install request.
</section>
<section class='slide'>
##SimUser
**What values should I assign these variables to get a realistic user?**
1. `apt-get` upgrade and install criteria
2. Survey Logs
3. Probability to install logs, what to install [The Ubuntu Popularity Context](http://popcon.ubuntu.com/) or **popcon** filtered by the 2399 packages from the package called `app-install-package` that contains information about popular packages to install.
</section>
<section class='slide'>
##SimUser
![](https://maorigeek.s3.amazonaws.com/uploads/users.png_1392886784.jpg)
</section>
<section class='slide'>
##Validation
1. I had discussions with project supervisors (Jens and Hans) and other stakeholders (i.e. Giovanni, Marsland, Catherine and anyone else I could).
2. I compared SimUser to responses from the survey
3. I compared generated CUDF\* documents to the supplied user logs
4. I created a virtual Ubuntu system and looked at its changing repository over a month.
</section>
<section class='slide'>
##GJSolver
> What I cannot create, I do not understand *Richard Feynman, 1988*
</section>
<section class='slide'>
##Davis-Putnam-Logemann-Loveland (DPLL)
![](https://maorigeek.s3.amazonaws.com/uploads/DPLL.png_1392882995.jpg)
</section>
<section class='slide'>
##DPLL
In this function *F* is just the set of constraints, *P* is the currently assigned variables (or partial solution) and:
1. `unit-propagate` is a particular way in which you can infer variable assignments from already inferred knowledge, e.g. you know `a=true` and you know `a -> b`, therefore `b=true`.
2. `decide` makes a guess at which variable should be true or false. If `decide` picks the right assignments all the time, then this algorithm will be really fast.
3. It is recursive, e.g. it guesses `a=true` then it calls itself to see if there is an answer where `a=true`. If there isn't then the answer must be `a=false`. If `a` cannot be true or false, then there is no answer and DPLL knows there is no solution.
</section>
<section class='slide'>
##GJSolver Optimisation
**Lexicographic-iterative-strengthening** which is another way of saying it finds a solution and keeps trying to make it better till it can't any more.
</section>
<section class='slide'>
##Verification of GJSolver
> Verification: Did I build it right
So after implementing GJSolver I needed to make sure:
1. It correctly solves component upgrade problems
2. It solves the problems at least as well as other implementations
*Mancoosi International Solver Competition* (**MISC**)
</section>
<section class='slide'>
##Validation of GJSolver
> Validation: Did I build the right thing?
To validate GJSolver and SimUser I:
1. simulated installing 200 requests of packages and compared it to the logs of apt-get users.
2. simulated updating an Ubuntu system once a day for a month and compared it to the results I collected from a virtual Ubuntu system doing the same thing.
</section>
<section class='slide'>
##Experiments
I had four questions I wanted to answer with my simulation:
1. What consequences do a user's choices have on their system (i.e. their probabilities to upgrade and install) when using the `apt-get` criteria?
2. Can the out-of-dateness of a system be reduced?
3. Can the total change of a system be reduced?
4. How do the systems of realistic users evolve?
</section>
<section class='slide'>
##Experiments
1. **Always Install** users install one component every day
2. **Always Update and Install** users install and update every day
3. **Always Upgrade** users upgrade everyday
4. **Control** users do nothing
</section>
<section class='slide'>
##Experiments
**How up to date a comopnent system is (lower is better)**:
![](https://maorigeek.s3.amazonaws.com/uploads/results.png_1392886020.jpg)
</section>
<section class='slide'>
##Experiments
**How much change a system goes through**:
![](https://maorigeek.s3.amazonaws.com/uploads/results2.png_1392886196.jpg)
</section>
<section class='slide'>
## Reducing up-to-dateness
By altering the optimisation criteria I was able to get a system about 24% more uptodate over a year of upgrading everyday.
</section>
<section class='slide'>
## Reducing Change
7 days after a package 30 instances per year, 28 days you can save yourself over 100 changes a year.
![](https://maorigeek.s3.amazonaws.com/uploads/versionreleasedistribution.png_1392885924.jpg)
</section>
<section class='slide'>
##Summary of Experiments
In addition to showing how to reduce changing by waiting before installing a component, and decreasing out-of-dateness by letting updates install new components; I also showed:
1. The majority of change during evolution is caused by a user upgrading. Installing new components increases the amount of change when upgrading.
2. Systems become out-of-date at the rate at which components evolve. Components evolve at a higher rate during release cycles.
4. Reuse decreases the rate of change during CSE. This is due to the two effects; reuse decreases the installation rate of components and this decreases the amount of components necessary to be upgraded.
5. Increasing the frequency of upgrading has depreciating returns on reducing a systems out-of-dateness. It may also increase change due to components being repeatedly upgraded if they quickly release multiple versions.
</section>
<section class='slide'>
##What I did summary
I proposed two novel ways to reduce negative effects during CSE and the tools in with which to measure the effectiveness of these techniques.
This was enough to get a Ph.D.
</section>
<section class='slide'>
## What I learnt
1. Only do a Ph.D. if you can live on ramen noodles: you are not paid much (if anything) there is a lot of stress involved and it will take a while.
2. Doing a Ph.D. will force you to learn how to give presentations, write research papers, organise conferences, in addition to all the academic things you must learn. So get good at learning things.
3. Look at what others have done, it saved me a lot of problems. If I had not found Mancoosi, or Daniel Le Berre, I would have never finished. Understanding their work allowed me to put my work in their context.
4. Writing is difficult, feedback is necessary. I had many people look at my writing and try to understand what I was saying.
5. Formalism is not for formalisms sake, but for your understanding and communication.
6. Learn to write and read mathematical notation. I believe it has helped me be a better programmer, by forcing me to think about every function I write.
6. An experiment is more powerful than any amount of words. Feynman says "Experiment is the sole judge of scientific 'truth'". If you have a repeatable experiment no one can argue with you.
7. I am much more critical of science, especially scientific reporting when they use the word prove and proof. Most of the time what they do is demonstrate something, proof is a long way off.
</section>
<section class='slide'>
#My Recent Work
</section>
<section class='slide'>
##My Recent Work
On my first day of consulting work I had to learn:
1. Ruby & Rails
2. Javascript & Coffeescript
3. sass, scss, css
4. HAML, ERB, HTML
5. git, rvm, foreman, bundler, rake, rails, capistrano, heroku
6. JQuery, Backbone, many other libraries
7. Postgres, MySQL
8. RSpec, Capybara
9. Design, UX
10. Lean Agile Development using Scrum
11. Client and Customer communication (demos, proposals)
12. Working as a full-stack developer in charge of everything
13. Starting a company, getting an accountant, tax horror
14. Airbrake, Newrelic, Google Analytics
15. Firefox, Explorer, Chrome developement debugging.
</section>
<section class='slide'>
##My Recent Work
On my first day of enterprise work, I had to learn:
1. ElasticSearch, Redis
2. Legacy System technology
3. Massive Service oriented structure
4. Third Party Integration points
5. Corporate Agile Development using Kabana
6. Enerprise Business Decions
7. Working in a large team only responcible for a slice
</section>
<section class='slide'>
##My Recent Work
Everyday I am
1. Looking for interesting things to learn
2. Trying to keep upto-date with technologies
3. Blogging about what I am learning
4. Interacting with different communities (meetup.com)
5. Entering into things (like mix and mash) that are good learning and advertising tools
</section>
<section class="slide">
<h2>Graham Jenson</h2>
<ul>
<li>Twitter: <strong>@grahamjenson</strong> </li>
<li><strong>Blog:</strong> http://maori.geek.nz/blog</li>
</ul>
</div>
</section>
<!-- deck.navigation snippet -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>
<!-- deck.status snippet -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
<!-- End extension snippets. -->
</div>
<script>
$(function() {
hljs.initHighlightingOnLoad();
$.deck('.slide');
});
(function($, deck, undefined) {
var $d = $(document);
var converter = new Showdown.converter({ extensions: ['github'] });
$d.bind('deck.init', function() {
$.each($.deck("getSlides"), function(index, value) {
var cssClass = value.attr('class');
// Prevent slides marked with no-md css class to be interpreted as markdown
if (!cssClass || cssClass.indexOf('no-md') < 0) {
value.html(converter.makeHtml(value.text()));
}
});
});
})(jQuery, 'deck');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment