1 of 93

user interfaces 2

lesson 12

January 15th, 2020

2 of 93

talking

thinking

doing

programming

workflow

software design

system architecture

performance

user interfaces

3 of 93

agenda

  • Keep talking about graphical user interfaces
  • Specifically, web development
  • Visualizations

advanced system design :: lesson 12 :: user interfaces 2

3

/ 93

4 of 93

web development

visualizations

5 of 93

frontend development

the world wide web

web technologies

web development

6 of 93

roadmap

  • The World Wide Web
  • Static websites
  • Dynamic websites
  • Web services
  • Web applications

advanced system design :: lesson 12 :: user interfaces 2

6

/ 93

7 of 93

the world wide web

  • Invented by Tim Berners-Lee in 1989
  • Organized the information on the Internet
  • HTTP, a web server and a web client (browser)
  • Mostly for academia: text and hyperlinks
  • Then, more media types, like images
  • Websites, made of web pages, written in HTML
  • Content, layout, design and a wee bit of code

advanced system design :: lesson 12 :: user interfaces 2

7

/ 93

8 of 93

static websites

  • A web server that serves static HTML
  • e.g. /index.html or /images/logo.jpg
  • Nothing more than a program, listening on port 80, reading and writing HTTP
  • Pretty quickly, web framework handling the HTTP part were developed
  • Web development becomes mostly HTML (and some Apache / NGINX)

advanced system design :: lesson 12 :: user interfaces 2

8

/ 93

9 of 93

dynamic websites

  • Not good enough: doesn't support private content and personalization
  • Getting back to programming the web server
  • New platforms (and even languages, like PHP) run code per request to generate a response
  • Example login flow:
  • GET /login returns the (static) resource login.html
  • Submitting it form sends a POST /login which runs validation code
  • An error redirects to /login; success redirects to /account
  • GET /account returns the (dynamic) resources account.html, with embedded user data

advanced system design :: lesson 12 :: user interfaces 2

9

/ 93

10 of 93

web apis

  • Running code is such a great idea, non-player characters want in on the fun
  • RESTful (and other) APIs: "bare" endpoints that send and receive "raw" data
  • Example: Xiaomi lights
  • Connect to your WiFi, register to some server (e.g. POST /register/id)
  • You now see them in your app, so you can turn them on or off (POST /id/on or /id/off)
  • The lights periodically sample the server (GET /id) and react accordingly
  • Not really, but you get the point

advanced system design :: lesson 12 :: user interfaces 2

10

/ 93

11 of 93

web applications

  • Web APIs are actually a great idea for GUIs, too
  • Truly decouples the data from the view
  • The same logic can power websites (web apps), native and mobile apps, CLIs, libraries, etc.
  • Web development turns to programming clients rather than (or in addition to) servers
  • The gist: fetch the data, and dynamically generate a website around it
  • Single Page Applications (SPAs) for a smooth and responsive experience
  • Yet more frameworks are invented: AngularJS, ReactJS, VueJS and more

advanced system design :: lesson 12 :: user interfaces 2

11

/ 93

12 of 93

summary

  • The World Wide Web: clients and servers that talk HTTP
  • Static websites: mostly about resources (HTML and routes)
  • Dynamic websites: mostly about the server (generating a response per request)
  • Web APIs: only about the server (raw data over RESTful APIs)
  • Web applications: mostly about the client (JS that fetches raw data and displays it)

advanced system design :: lesson 12 :: user interfaces 2

12

/ 93

13 of 93

frontend development

the world wide web

web technologies

web development

14 of 93

roadmap

  • HTML
  • CSS
  • JS
  • jQuery
  • Dynamic websites

advanced system design :: lesson 12 :: user interfaces 2

14

/ 93

15 of 93

html

  • HyperText Markup Language
  • Based on XML (Extensible Markup Language)
  • Tags with attributes, text, an nesting thereof
  • The root tag is html, which contains a head for metadata and a body for data
  • A lot of standard tags
  • The client renders (or otherwise consumes) them accordingly

advanced system design :: lesson 12 :: user interfaces 2

15

/ 93

16 of 93

layout and content

  • At the beginning, there was text: <p> and hypertext: <a href="url">
  • Then, there were images: <img src="url" />
  • But also, there were lists: <ul> and <ol>, and list items: <li>
  • And there were tables: <table>, with rows: <tr> and cells: <td>
  • Some basic styling was possible, like <font color="…"> or <a vlink=""> or <table width="…">
  • You may be laughing, but constraints foster creativity
  • 8-bit — that's 256 colors — Graphics Outside the Box

advanced system design :: lesson 12 :: user interfaces 2

16

/ 93

17 of 93

18 of 93

19 of 93

20 of 93

html in action

<html>

<head>

<meta charset="utf8" />

<title>Advanced System Design</title>

</head>

<body>

<h1>Advanced System Design</h1>

<p>A course about the unbearable lightness of coding.</p>

<ul>

<li><a href="/lessons">Lessons</a></li>

<li><a href="/exercises">Exercises</a></li>

<li><a href="/login">Login</a></li>

</ul>

</body>

</html>

<!doctype html>

advanced system design :: lesson 12 :: user interfaces 2

20

/ 93

21 of 93

css

  • Cascading StyleSheets
  • Selectors: what to style
  • By tag p <p>
  • By id #title <h1 id="title"> (should be unique)
  • By class .menu-link <a class="menu-link">
  • State (e.g. :hover, :focus)
  • Key-value properties: how to style it
  • selector { key: value; … }

advanced system design :: lesson 12 :: user interfaces 2

21

/ 93

22 of 93

design

  • color, background-color, font-family, font-size
  • border-width, border-color, border-style
  • width, height, margin, padding
  • display, float, position
  • transforms, animations

advanced system design :: lesson 12 :: user interfaces 2

22

/ 93

23 of 93

who runs css

  • The browser: it comes with the HTML and affects its rendering
  • On the element level: <tag style="...">
  • On the page level: <style>
  • As a separate resource: <link rel="stylesheet" href="..." />
  • Changing the entire theme/branding at once
  • CSS Zen Garden

advanced system design :: lesson 12 :: user interfaces 2

23

/ 93

24 of 93

25 of 93

css in action

body {

background-color: #f0e2c8;

}

* {

font-family: 'Josefin Sans';

}

a {

color: #629ebb;

}

li {

margin-bottom: 10px;

}

advanced system design :: lesson 12 :: user interfaces 2

25

/ 93

26 of 93

semantics

  • We can do everything with simple <div>s
  • Style heading in bold, paragraphs with margins, tables with rows and columns
  • However, using the right tags adds semantic information
  • HTML5 has a lot of them: <header>, <footer>, <nav>, <section>, <article>, <time>
  • This information is important for accessibility (e.g. screen readers)
  • But also for crawling the web, and automating it in general
  • Much easier to look for <h1>s than to infer that "this text looks more important"

advanced system design :: lesson 12 :: user interfaces 2

26

/ 93

27 of 93

not easy

  • Looks different in different browsers (damn you, IE)
  • Looks different on different screens
  • Particularly annoying in the mobile age
  • Responsive design accounts for small (phone), medium (tablet) and large (computer) screens
  • In many cases, user experience is about the 20%, not the 80%
  • So it takes a different approach — and a lot of effort
  • Example: iPhone's wonderful haptics
  • It's hard to iterate if you only get one shot

advanced system design :: lesson 12 :: user interfaces 2

27

/ 93

28 of 93

more platforms

  • Branding, storytelling, etc. is an art — but decent, functional design is common knowledge
  • Bootstrap — make stuff look decent, if similar
  • Takes care of compatibility, responsiveness, and consistency
  • Add their CSS (and JS), add the right classes to the right tags, et voilá
  • <button class="btn btn-danger">, <table class="table table-striped table-hover">
  • Doesn't presume to be right, just convenient — as opposed to Google Material Design

advanced system design :: lesson 12 :: user interfaces 2

28

/ 93

29 of 93

bootstrap in action

<head>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />

</head>

<body>

<div class="container mt-3">

<h1>Advanced System Design</h1>

<p>A course about the unbearable lightness of coding.</p>

</div>

<nav class="navbar navbar-expand-sm navbar-light bg-light">

<ul class="navbar-nav">

<li class="nav-item">

<a class="nav-link" href="/lessons">Lessons</a>

</li>

</ul>

</nav>

</body>

advanced system design :: lesson 12 :: user interfaces 2

29

/ 93

30 of 93

js

  • JavaScript is a general-purpose programming language developed by Netscape in 1995
  • Inspired by C / Java, but the name is really a marketing stunt
  • Pretty simple, if a bit quirky
  • Dynamically and weakly typed
  • Very functional (should've been Scheme) — so lots of callbacks, anonymous functions, etc.
  • The web is pretty asynchronous, so that helps
  • But be prepared to find 10 levels of nested callbacks (before async/await)
  • There are objects, but it's not exactly object-oriented (based on prototypes)

advanced system design :: lesson 12 :: user interfaces 2

30

/ 93

31 of 93

who runs js

  • The browser: it comes with the HTML, affects it rendering, and binds to its events
  • On the element level: onLoad/onClick="javascript:alert(1)"
  • On the page level: <script>
  • As a separate resources: <script src="...">
  • So yeah, the browser has an interpreter / VM to execute JS
  • V8 is actually a seriously cool project — and really fast (e.g. JIT)
  • Can be (and is) a general-purpose programming language: node.js

advanced system design :: lesson 12 :: user interfaces 2

31

/ 93

32 of 93

js in action

> var x = 1;

> x;

1

> var s = 0;

> for (var i = 0; i < 5; i++) {

s += Math.pow(i, 2);

}

> s;

30

> function inc(x) {

return x + 1;

}

> inc(1);

2

> var o = {foo: 1, bar: 2};

> o.foo;

1

> o['bar'];

2

> function runTwice(f) {

f();

f();

}

> function hello() {

console.log('Hello, world!');

}

> runTwice(hello)

Hello, world!

Hello, world!

> runTwice(function() {

console.log('I have no name.');

});

I have no name.

I have no name.

advanced system design :: lesson 12 :: user interfaces 2

32

/ 93

33 of 93

introduction to prototypes

> function Person(name) {� this.name = name;

}

> var alice = new Person('Alice');

> alice;

Person {name: 'Alice'}

> alice.hello = function() { console.log("Hello! I'm ' + this.name); };

> alice.hello();

Hello! I'm Alice

> var bob = new Person('Bob');

> bob.hello()

TypeError: bob.hello is not a function

> Person.hello = function() { … };

> bob.hello();

TypeError: bob.hello is not a function

> Person.prototype.hello = function() { … };

> bob.hello()

Hello! I'm Bob

> var charlie = Person('Charlie');

> charlie

undefined

> window.name

'Charlie'

alice.__proto__.hello = function() { … };

{}

constructor: Person(name)

{}

name: 'Alice'

__proto__

hello: [Function]

hello: [Function]

prototype

hello:

name: 'Bob'

{}

__proto__

advanced system design :: lesson 12 :: user interfaces 2

33

/ 93

34 of 93

implementing prototypes

>>> def Person(this, name):

... this.name = name

>>> alice = new(Person)('Alice')

>>> def new(f):

... if not hasattr(f, 'prototype'):

... f.prototype = Object()

... f.prototype.constructor = f

... this = Object()

... this.__proto__ = f.prototype

... def construct(*args, **kwargs):

... this.__proto__.constructor(this, *args, **kwargs)

... return this

... return construct

>>> alice.__proto__.hello = lambda this: print(f"Hello! I'm {this.name}!")

>>> alice.hello()

Hello! I'm Alice

>>> bob = new(Person)('Bob')

>>> bob.hello()

Hello! I'm Bob

>>> class Object:

... __proto__ = None

... def __getattr__(self, name):

... value = getattr(self.__proto__, name)

... if inspect.isfunction(value):

... return value.__get__(self, self.__class__)

... return value

{}

{}

__proto__

f

constructor

prototype

{}

__proto__

advanced system design :: lesson 12 :: user interfaces 2

34

/ 93

35 of 93

the dom

  • The Document Object Model (DOM) provides an interface to the browser
  • window — change the location (URL), refresh, scroll, pop-ups, etc.
  • document — select, add, remove, and modify tags
  • getElementsByTagName('p'), getElementById('title'), getElementsByClassName('menu-link')
  • querySelector('p'), querySelector('#title'), querySelector('.menu-link')
  • getAttribute('href'), setAttribute('src', 'cat.jpg')
  • style.backgroundColor = '#000000'
  • addClass('dark'), removeClass('dark') (with .dark { background-color: #000000' })

advanced system design :: lesson 12 :: user interfaces 2

35

/ 93

36 of 93

the dom in action

> var p = document.getElementById('greeting');

> p.textContent = 'Hello, world!';

> p.remove();

> var ul = document.createElement('ul');

> var li = document.createElement('li');

> var t = document.createTextNode('one');

> li.appendChild(t);

> ul.append(li);

> li2 = document.createElement('li');

> t2 = document.createTextNode('two');

> li2.appendChild(t2);

> ul.append(li2);

> document.body.append(ul);

> function hello() {

alert('Hello, world!')

}

<p id="greeting"></p>

<button onClick="hello()">Click me!</button>

advanced system design :: lesson 12 :: user interfaces 2

36

/ 93

37 of 93

a more complicated example

function onHover(image, activate) {

var src = image.getAttribute('src');

if (activate) {

var parts = src.split('.');

src = parts[0] + '-active' + parts[1];

} else {

var parts = src.split('.');

src = parts[0].substring(0, parts[0].indexOf('-'))� + parts[1];

image.setAttribute('src', src);

}

var imgs = document.getElementsByClassName('social-media-button');

for (var i = 0; i < imgs.length; i++) {

var img = imgs[i];

img.setAttribute('src', img.getAttribute('data-inactive'));

img.onmouseover = function() { this.setAttribute('src', this.getAttribute('data-active')); };

img.onmouseout = function() { this.setAttribute('src', this.getAttribute('data-inactive')); };

}

<img src="fb.png"

onMouseOver="onHover(this, true)"

onMouseOut="onHover(this, false)" />

<img class="social-media-button"

data-inactive="fb.png"

data-active="fb-active.png" />

}

advanced system design :: lesson 12 :: user interfaces 2

37

/ 93

38 of 93

a lesson in decoupling

  • HTML, CSS and JS decouples layout, design and code
  • What is there, how does it look, and what does it do
  • The line is still blurry
  • onMouseOver vs. onmouseover
  • style vs addClass

advanced system design :: lesson 12 :: user interfaces 2

38

/ 93

39 of 93

still, a mess

  • Created at by Brendan Eich in 10 days
  • One of the most popular programming languages out there, mind you
  • Says a whole lot about our world (... and not bad things, in my opinion)
  • In any case, a language people love to hate: WAT
  • There's no BDFL like Linus of Guido, so it's messy
  • People come up with a ton of ideas, and the fittest survives
  • Quite hard to keep up with all the technologies
  • Luckily, the current trend is to develop really dumbed-down solutions

advanced system design :: lesson 12 :: user interfaces 2

39

/ 93

40 of 93

jsfuck

> []

[]

> +[]

0

> ![]

false

> [] + []

''

> ![] + []

'false'

> (![] + [])[+[]]

'f'

> function f() {}

> f.constructor

Function() { [native code] }

> f['constructor']

Function() { [native code] }

> f = Function('return 42')

> f()

42

> [].filter

filter() { [native code] }

> []['filter']['constructor']('return 42')()

42

advanced system design :: lesson 12 :: user interfaces 2

40

/ 93

41 of 93

jquery to the rescue

  • jQuery is a fast, small, and feature-rich JS library
  • It makes things like DOM traversal and manipulation, event handling, animation, and AJAX simpler
  • $(selector).action(…)
  • $('p').remove() or $('.button').click(function() { … } )
  • Adds a lot of missing functionality and sanity to the language
  • Imagine Python without the standard library :[
  • Add libraries with <script src="..."> tags
  • The magical $

advanced system design :: lesson 12 :: user interfaces 2

41

/ 93

42 of 93

jquery in action

> var p = $('p');

> p.text('Hello, world!');

> p.remove();

> $('body').append(

$('<ul></ul>').append($('<li></li>', {text: 'one'}))

.append($('<li></li>', {text: 'two'}))

);

> $('img').hover(function() {

$(this).attr('src', $(this).data('active'));

}, function() {

$(this).attr('src', $(this).data('inactive'));

});

> $('img').each(function() {

$(this).attr('src', $(this).data('inactive'));

});

advanced system design :: lesson 12 :: user interfaces 2

42

/ 93

43 of 93

dynamic websites

  • We know how to write pretty decent resources
  • But how do we run the code that generates them?
  • Model-view-controller (MVC)
  • The model describes the dynamic data (a static resource has none)
  • The view describes the resource template (a static resource coincides with its template)
  • The controller is the glue that binds it together
  • In flask: @app.route(url) defines a controller, which calls render_template(path, **data)

advanced system design :: lesson 12 :: user interfaces 2

43

/ 93

44 of 93

flask in action

app = flask.Flask(__name__)

@app.route('/login')

def login():

return flask.render_template('login.html')

@app.route('/login', methods=['GET', 'POST'])

def login():

if flask.request.method == 'GET':

return flask.render_template('login.html')

username = flask.request.form['username']

password = flask.request.form['password']

token = authenticate(username, password):

if token:

redirect = flask.redirect('/account')

response = flask.make_response(redirect)

response.set_cookie('token', token)

return response

<form method="POST">

<input type="text" name="username" />

<input type="password" name="password" />

</form>

@app.route('/account')

def account():

token = flask.request.cookies.get('token')

user = get_user(token)

if not user:

return flask.redirect('/login')

return flask.render_template('account.html',� user=user)

{% if user %}

<p>Hello, {{ user.name }}!</p>

{% else %}

<a href="/login">Log in</a>

{% endif %}

return flask.redirect('/login')

advanced system design :: lesson 12 :: user interfaces 2

44

/ 93

45 of 93

a side-note on code generation

  • It's actually a very cool technique
  • Especially if you have a lot of boilerplate code
  • Like an HTML template with relatively little embedded data
  • But also, Protobuf
  • jinja2 can be used separately from flask
  • If you ever need it, it's much better than manually composing strings
  • I've done it for C and C++ code, Dockerfiles, and even Python

advanced system design :: lesson 12 :: user interfaces 2

45

/ 93

46 of 93

summary

  • A myriad of new technologies for resource development
  • HTML for the layout and content
  • CSS for the design
  • JS for the code (interactivity)
  • jQuery for sanity
  • Python (e.g. flask) for response generation
  • It's a lot
  • Learn it

advanced system design :: lesson 12 :: user interfaces 2

46

/ 93

47 of 93

frontend development

the world wide web

web technologies

web development

48 of 93

roadmap

  • Decoupling front-end from back-end
  • AJAX
  • React

advanced system design :: lesson 12 :: user interfaces 2

48

/ 93

49 of 93

the two ends

  • So far, we've been baking our business logic into HTML, CSS and JS
  • It's much harder to consume: json.loads vs. parsing a <table>
  • Luckily, the web speaks HTTP well, and we know RESTful APIs
  • Separate the frontend on the client-side, from the backend on the server-side
  • The frontend would be a bunch of HTML, CSS and JS that consumes a RESTful API
  • The backend would provide that API and implement it (flask, but without jinja2)
  • This way, the frontend and the backend are decoupled
  • Developing both makes us full-stack developers :]

advanced system design :: lesson 12 :: user interfaces 2

49

/ 93

50 of 93

ajax

  • Asynchronous Javascript + XML
  • Send an HTTP request (asynchronously, via Javascript), and get a response
  • Decouples a web-based GUI from its backend, which we'll call "the API"
  • The API is agnostic, like we discussed: it can be consumed by CLIs, GUIs and code
  • A "frontend only" web-based GUI would have all the HTML, CSS and JS, but none of the data
  • It'd fetch the data on-demand, by issuing an HTTP request to some API endpoint
  • Single Page Applications (SPAs): no refresh, smoother experience, spinners, etc.
  • But most importantly, developed independently of the API

advanced system design :: lesson 12 :: user interfaces 2

50

/ 93

51 of 93

ajax in action

function getPosts() {

$.get('/posts', function(data) {

var posts = JSON.parse(data); // or use $.getJSON

for (var i = 0; i < posts.length; i++) {

var post = posts[i];

var author = $('<td></td>', {'text': post.author});

var content = $('<td></td>', {'text': post.content});

var row = $('<tr></tr>');

row.append(author);

row.append(content);

$('#posts').append(row);

}

});

}

<table id="posts"></table>

advanced system design :: lesson 12 :: user interfaces 2

51

/ 93

52 of 93

the good, the bad, and the ugly

  • AJAX lets us decouple the frontend from the backend, which is good
  • We can have our one API consumed by CLIs, libraries and GUIs (both web-based and native)
  • What Spotify does
  • We can develop a pleasant, interactive and tailored experience
  • Alas, such code can get out of hand pretty quickly, which is bad
  • Historically, the solution was to do as much as possible server-side, on the backend
  • But with the rise of smartphones, we had more compute and less connectivity, so...
  • And we're still working with JS, which is ugly

advanced system design :: lesson 12 :: user interfaces 2

52

/ 93

53 of 93

defining the problem

  • HTML and CSS are declarative, which is great for GUIs
  • JS is imperative, which is great for code
  • But unless our system is relatively simple and static, we're back to square 1: tkinter
  • We only know the layout after having fetched the data, so we have to craft widgets manually
  • Angular: embrace the declarative approach
  • <a ng-repeat="link in links" href="{{ link.url }}">{{ link.text }}</a>
  • React: embrace the imperative approach
  • But with a twist — you can define widgets and components declaratively with JSX

advanced system design :: lesson 12 :: user interfaces 2

53

/ 93

54 of 93

jsx

  • A brilliant solution developed by Facebook as part of React
  • In short: var tag = <p>Hello, world!</p>
  • Like JS, but allows HTML tags as part of its syntax
  • Supports interpolation: var name = 'Alice'; var tag = <p>Hello, {name}</p>
  • Conditions, loops, etc. can be used as usual
  • Behind the scenes, it all gets transpiled into standard JS

advanced system design :: lesson 12 :: user interfaces 2

54

/ 93

55 of 93

jsx in action

var as = [];

for (var i = 0; i < links.length; i++) {

var a = <a href={links[i].url}>{links[i].text}</a>;

as.push(a);

}

var result = <div>{as}</div>

var result = user ? (

<p>Hello, {user.name}!</p>

) : (

<a href="/login">Log in</a>

);

advanced system design :: lesson 12 :: user interfaces 2

55

/ 93

56 of 93

react

  • A beautiful framework for building web-based user interfaces
  • Strikes a perfect balance between declarative and imperative code
  • Its game-changer is JSX, which lets you build entire apps as collections of neat components
  • Components are defined as functions that return tags, and compositions thereof
  • The root tag is injected into the actual DOM
  • A lot of other cool features: props, state, lifecycle methods
  • A lot of other cool addons: React Router, React Redux, React DevTools

advanced system design :: lesson 12 :: user interfaces 2

56

/ 93

57 of 93

react in action

function Menu() {

var links = [

{url: '/lessons', text: 'Lessons'},

{url: '/exercises', text: 'Exercises'},

{url: '/login', text: 'Login'},

];

var lis = [];

for (var i = 0; i < links.length; i++) {

var li = <li><a href={links[i].url}>{links[i].text}</a></li>;

lis.push(li);

}

return <ul>{lis}</ul>;

}

<div id="app"></div>

<script>

ReactDOM.render(<App />, document.getElementById('app'));

</script>

function App() {

return (<div>

<Menu />

<h1>Advanced System Design</h1>

<p>A course about the unbearable lightness of coding.</p>

</div>);

}

advanced system design :: lesson 12 :: user interfaces 2

57

/ 93

58 of 93

arguments

  • How do you parametrize components (e.g. pass links to a menu)?
  • When declaring a component, pass the arguments via its attributes
  • <Menu links={links} />
  • These attributes become available via the props argument (props.links)
  • Similarly, nested content is available via props.children
  • <Message><h1>Hello!</h1><p>How's it going?<p></Message>
  • Can be something like <div class="message">{props.children}</div>
  • Can also pass in callbacks, e.g. <Button onClick={callback} />

advanced system design :: lesson 12 :: user interfaces 2

58

/ 93

59 of 93

props in action

function Menu(props) {

var lis = [];

for (var i = 0; i < props.links.length; i++) {

var li = <li><a href={props.links[i].url}>{props.links[i].text}</a></li>;

lis.push(a);

}

return <ul>{lis}</ul>;

}

<Menu links={…} />

advanced system design :: lesson 12 :: user interfaces 2

59

/ 93

60 of 93

state

  • How do you keep the component's state (e.g. filter a table's results)?
  • We'd have to switch from stateless functions to stateful classes
  • A very nice progressive disclosure
  • There aren't really classes in JS, but there's syntactic sugar for them in ES6
  • The class should extend React.Component and implement the render method
  • However, it can also set its state attribute to some initial state
  • The state should be updated with the setState method, which react tracks
  • This re-renders the (virtual) DOM, changing the component accordingly

advanced system design :: lesson 12 :: user interfaces 2

60

/ 93

61 of 93

state in action

class Button extends React.Component {

state = {index: 0};

render() {

var color = this.props.colors[this.state.index];

return <button style={{backgroundColor: color}} onClick={this.toggle.bind(this)}>Click me!</button>;

}

toggle() {

var index = (this.state.index + 1) % this.props.colors.length;

this.setState({index: index}); // not this.state.index = index

}

}

click me!

click me!

click me!

click me!

advanced system design :: lesson 12 :: user interfaces 2

61

/ 93

62 of 93

flow

  • How do we integrate it with AJAX (e.g. fetch the newest posts and display them)?
  • Components have lifecycle methods, like componentDidMount and componentWillUnmount
  • We'd have to start with an empty state
  • That'd display a loading screen or a spinner
  • Once the component did mount, we can fetch the data
  • When it arrives, setting the state to it will re-render the component and reflect the change
  • Much smarter ways (e.g. React Redux) exist

advanced system design :: lesson 12 :: user interfaces 2

62

/ 93

63 of 93

flow in action

class Posts extends React.Component {

state = {posts: null}

render() {

if (!this.state.posts) {

return <div>Loading…</div>

}

return <div>{this.state.posts.map(function(post) { return <div>{post.content}</div>; })}</div>;

}

componentDidMount() {

fetch(API_ROOT + '/posts').then(function(data) {

var posts = JSON.parse(data);

this.setState({posts: posts});

}

}

}

advanced system design :: lesson 12 :: user interfaces 2

63

/ 93

64 of 93

deployment

  • Not easy to develop and to deploy if you're doing it on your own
  • Just to deploy, you'd have to transpile react to actual JS
  • It actually includes more tools, like Babel (for ES5 support) and Webpack (for bundling CSS)
  • You "compile" everything to a single HTML, with a single CSS and JS, that contains the entire app
  • This is effectively a static resource, insofar that the website doesn't generate it
  • This actually allows it to be much cheaper (storage vs. compute) and faster (CDNs)
  • I simply use create-react-app
  • npm run build packs everything up, and npm start is great for development

advanced system design :: lesson 12 :: user interfaces 2

64

/ 93

65 of 93

web development

visualizations

66 of 93

visualizations

  • There's something deeply satisfying about visualization done right
  • It just taps into our brain's most primitive pattern recognition software
  • Good visualization can be eye-opening and revolutionary
  • Bad visualization can be confusing and outrageous
  • We live in a terribly verbal world (see Bret Victor's wonderful talk)
  • Over the course of history, writing developed above all others mediums (in a feedback loop?)
  • When in fact there are so many others: auditory, tactile, kinesthetic, spatial
  • Think of the untapped potential — how much we can expand our umwelt

advanced system design :: lesson 12 :: user interfaces 2

66

/ 93

67 of 93

4 dimensional plots

  • In complex analysis, a function f ϵ ℂ → maps z = x + iy to z = x + iy; that's 4 dimensions
  • Think of the input in cartesian coordinates: (x, y)
  • Think of the output in polar coordinates: (r, θ)
  • Where 0 r < ∞ is expressed by the brightness
  • And 0 ≤ θ ≤ 360 is expressed by the hue
  • Have you ever imagined n-dimensional reality?

f(z) = z

f(z) = z3 - 1

f(z) = sin(z)

advanced system design :: lesson 12 :: user interfaces 2

67

/ 93

68 of 93

charts

interactivity

visualizations

69 of 93

roadmap

  • The challenge of data visualization
  • Various charts
  • matplotlib and plotly

advanced system design :: lesson 12 :: user interfaces 2

69

/ 93

70 of 93

visualization

  • Given some data, we'd like to visualize it
  • A list, a table, a word cloud
  • A chart: column chart, line chart, scatter plot, graph, histogram
  • An image: map, heatmap
  • A video or an interactive widget
  • Doesn't have to be limited to the visual aspect, although it usually is
  • Expressialization?

advanced system design :: lesson 12 :: user interfaces 2

70

/ 93

71 of 93

bad visualization

  • Is like bad design
  • Loaded
  • Lousy
  • Inaccurate
  • Trivial
  • OK, this one's a joke
  • Incomprehensible
  • A form of demagogy, really

advanced system design :: lesson 12 :: user interfaces 2

71

/ 93

72 of 93

chart types

  • Column chart, bar chart, pie chart
  • Mostly to show relative magnitudes or proportions
  • Line chart, area chart
  • Mostly to show time series
  • Scatter plot, bubble charts
  • Tree, graph
  • Histogram
  • Radar chart

advanced system design :: lesson 12 :: user interfaces 2

72

/ 93

73 of 93

matplotlib

  • A plotting library inspired by MatLab
  • Both high-level concepts (e.g. plot), and low-level ones (e.g. pixel)
  • Pretty old and clunky, with an awkward global state machine
  • But good enough and easy enough for most purposes — and powerful enough for the rest

advanced system design :: lesson 12 :: user interfaces 2

73

/ 93

74 of 93

matplotlib in action

>>> import matplotlib.pyplot as plt

>>> x = list(range(100))

>>> plt.plot(x, x, color='black')

>>> plt.show()

>>> plt.clf()

>>> import numpy as np

>>> x = np.linspace(0, 2, 100)

>>> plt.plot(x, x, label='linear', color='#fd4f2a')

>>> plt.plot(x, x**2, label='quadratic', color='#629ebb')

>>> plt.plot(x, x**3, label='cubic', color='#fea027')

>>> plt.xlabel('X axis')

>>> plt.ylabel('Y axis')

>>> plt.title('Lines')

>>> plt.legend()

>>> plt.show()

advanced system design :: lesson 12 :: user interfaces 2

74

/ 93

75 of 93

object-oriented matplotlib

  • I lied — there's an object-oriented interface
  • Although it's relatively obscure; data scientists make poor software engineers :[
  • A figure is the entire thing
  • It can have one or more axes — that's the box (there can be several)
  • Each axes can have one or more plots — that's the lines and shapes and drawings
  • And metadata: title, xlabel, ylabel, legend, etc.
  • Each plot is based on some data
  • And metadata: label, color, width, marker, etc.

advanced system design :: lesson 12 :: user interfaces 2

75

/ 93

76 of 93

object-oriented matplotlib in action

>>> fig = plt.figure(figsize=(8, 2.5))

>>> fig.suptitle('Lines')

>>> ax = fig.add_subplot(1, 3, 1)

>>> ax.set_title('Linear')

>>> ax.plot(x, x, color='#fd4f2a')

>>> ax = fig.add_subplot(1, 3, 2)

>>> ax.set_title('Quadratic')

>>> ax.plot(x, x**2, color='#629ebb')

>>> ax = fig.add_subplot(1, 3, 3)

>>> ax.set_title('Cubic')

>>> ax.plot(x, x**3, color='#fea027')

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

76

/ 93

77 of 93

when it's actually helpful

>>> import sklearn.datasets

>>> iris = sklearn.datasets.load_iris()

>>> sepal_length, sepal_width, petal_length, petal_width = iris.data.T

>>> type = iris.target

>>> fig = plt.figure()

>>> ax = fig.add_subplot(1, 2, 1)

>>> ax.scatter(sepal_length[type == 0], sepal_width[type == 0], color='#fd4f2a')

>>> ax.scatter(sepal_length[type == 1], sepal_width[type == 1], color='#629ebb')

>>> ax.scatter(sepal_length[type == 2], sepal_width[type == 2], color='#fea027')

>>> fig.show()

>>> ax = fig.add_subplot(1, 2, 2)

>>> ax.scatter(petal_length[type == 0], petal_width[type == 0], color='#fd4f2a')

>>> ax.scatter(petal_length[type == 1], petal_width[type == 1], color='#629ebb')

>>> ax.scatter(petal_length[type == 2], petal_width[type == 2], color='#fea027')

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

77

/ 93

78 of 93

going 3d

>>> from mpl_toolkits.mplot3d import Axes3D

>>> fig = plot.figure()

>>> ax = Axes3D(fig, elev=-150, azim=120)

>>> ax.scatter(petal_length[type == 0], petal_width[type == 0], sepal_width=[type == 0], color='#fd4f2a')

>>> ax.scatter(petal_length[type == 1], petal_width[type == 1], sepal_width=[type == 1], color='#629ebb')

>>> ax.scatter(petal_length[type == 2], petal_width[type == 2], sepal_width=[type == 2], color='#fea027')

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

78

/ 93

79 of 93

plotly

  • A charting library
  • So the focus is visualizing data in standard charts, not plotting it "mathematically"
  • plotly.express has simple, concise functions for 80% of the cases
  • Bar charts
  • Area charts
  • Pie charts
  • Bubble charts
  • Plotly is actualy much more than just a library

advanced system design :: lesson 12 :: user interfaces 2

79

/ 93

80 of 93

bar charts

>>> # magically acquire data

>>> import plotly.express as px

>>> fig = px.bar(data, x='year', y='population')

>>> fig.update_layout(title=…, yaxis_title=…, xaxis_title=…, width=…, height=…)

>>> fig.update_xaxes(tickangle=…)

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

80

/ 93

81 of 93

area charts

>>> fig = px.area(data, x='year', y='population', line_group='country', color='country')

>>> …

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

81

/ 93

82 of 93

pie charts

>>> fig = px.area(data, values='population', names='country')

>>> fig.update_traces(textposition='inside', textinfo='percent+label')

>>> fig.show()

advanced system design :: lesson 12 :: user interfaces 2

82

/ 93

83 of 93

bubble charts

>>> fig = px.area(data, x='gdp_per_capita', y='life_expectancy', size='population', color='country')

>>> …

>>> fig.show()

US

Japan

France

China

India

Nigeria

Israel

advanced system design :: lesson 12 :: user interfaces 2

83

/ 93

84 of 93

summary

  • Lots of data, lots of ways to visualize it
  • Really affects understanding, or misunderstanding
  • matplotlib is a low-level library for plotting
  • plotly is a high-level library for charting
  • It's beautiful and fun and it took me an 14-hours flight to do fuuuuuuuu

advanced system design :: lesson 12 :: user interfaces 2

84

/ 93

85 of 93

plotting

interactivity

visualizations

86 of 93

roadmap

  • The importance of interactivity
  • Interactive plots
  • Jupyter notebooks

advanced system design :: lesson 12 :: user interfaces 2

86

/ 93

87 of 93

interactivity

  • Making a system interactive dramatically decreases the gulf of execution
  • That's how human think and learn: trial and error, brainstorming, playing
  • The difference between reviewing open-source code and reverse-engineering a binary
  • So why are so few systems interactive (except Bret Victor, again)?
  • Well, it's definitely harder to make — and before software, was near impossible
  • But nowadays we have the tools, so I'd argue it's a mindset
  • Only publish the output, the solution — the rest is proprietary
  • But we're so much better together; I'm talking about Freemium, not Karma

advanced system design :: lesson 12 :: user interfaces 2

87

/ 93

88 of 93

games: the ultimate art

  • Have you ever thought how hard it is to implement a game such as World of Warcraft?
  • On an engineering level: clients, servers, rendering, multiplayer
  • Lots of security
  • Lots of AI
  • Lots and lots and lots of design, product, UX and general storytelling
  • I don't know why people keep bringing up Google Search, Facebook or Tesla as great systems
  • World of Warcraft is so much more complicated
  • Anyway — games really are the ultimate art. And I don't even play that much :[

advanced system design :: lesson 12 :: user interfaces 2

88

/ 93

89 of 93

interactive plots

  • I haven't shown it to you, but Plotly is actually interactive
  • Altair is another brilliant example, but we're really out of time
  • Here's a talk by Jake Vanderplaas, anyway

advanced system design :: lesson 12 :: user interfaces 2

89

/ 93

90 of 93

interactive python

  • Python (and code in general) is great for interactivity — you can just change it and see what happens
  • But it's a bit hard to visualize, narrate and share your interpreter session, no?
  • Enter iPython Notebook, nowadays Jupyter Notebook
  • A local web server with Python kernels
  • Exposes the Python interpreter as a website
  • Commands are sent to the server, executed by the kernel, and the results returned
  • Now that we're dealing with web, we have a lot more visualization, narration and sharing options
  • While keeping our interactivity

advanced system design :: lesson 12 :: user interfaces 2

90

/ 93

91 of 93

jupyter notebook

advanced system design :: lesson 12 :: user interfaces 2

91

/ 93

92 of 93

jupyter notebook use-cases

  • Research
  • Experiment, do whatever — except in a hybrid, web-based, interpreter/editor
  • Then tidy it up, add some description and share
  • You can export it to HTML or PDF, but then we lose the interactivity :[
  • Teaching
  • More specifically books
  • Can you imagine learning probability this way?
  • We're sharing our thought process, our evaluation function — so the sky's the limit

advanced system design :: lesson 12 :: user interfaces 2

92

/ 93

93 of 93

summary

  • Interactivity makes everything better
  • And it's relatively easy nowadays — you just have to want it
  • Jupyter Notebook is amazing
  • An excellent way to do research, to write books, and to experiment in general
  • Another example of Whorfian Refactoring :]

advanced system design :: lesson 12 :: user interfaces 2

93

/ 93