Skip to content

Commit

Permalink
Databench 0.7 (#10)
Browse files Browse the repository at this point in the history
* update dependencies

* update examples for Databench 0.7

* add package-lock.json
  • Loading branch information
svenkreiss committed Jan 12, 2018
1 parent 594642d commit 1eb7901
Show file tree
Hide file tree
Showing 33 changed files with 6,353 additions and 182 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Expand Up @@ -8,6 +8,9 @@ install:
# install Node 6
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 6
- node -v
# npm update
- npm install -g npm
- npm -v
# Java 8 for html5validator
- sudo apt-get install oracle-java8-installer
- sudo update-java-alternatives -s java-8-oracle
Expand All @@ -21,5 +24,5 @@ script:
- flake8
- npm run lint
- localcrawl --start http://localhost:5001 --run-delay 10.0 --run databench --log DEBUG --port 5001
- html5validator --root _crawled/ --ignore-re 'Attribute "ng-[a-z-]+" not allowed'
- html5validator --root _crawled/ --ignore-re 'Attribute "ng-[a-z-]+" not allowed' --no-langdetect
- nosetests tests
16 changes: 6 additions & 10 deletions analyses/angular/analysis.py
@@ -1,20 +1,16 @@
import databench

import math
import random
import tornado.gen


class Angular(databench.Analysis):

@tornado.gen.coroutine
def on_connect(self):
@databench.on
def connected(self):
"""Run as soon as a browser connects to this."""

inside = 0
for draws in range(1, 10000):
yield tornado.gen.sleep(0.001)

# generate points and check whether they are inside the unit circle
r1 = random.random()
r2 = random.random()
Expand All @@ -26,16 +22,16 @@ def on_connect(self):
continue

# debug
self.emit('log', {'draws': draws, 'inside': inside})
yield self.emit('log', {'draws': draws, 'inside': inside})

# calculate pi and its uncertainty given the current draws
p = inside / draws
uncertainty = 4.0 * math.sqrt(draws * p * (1.0 - p)) / draws

# send status to frontend
self.data['pi'] = {
yield self.set_state(pi={
'estimate': 4.0 * inside / draws,
'uncertainty': uncertainty,
}
})

self.emit('log', {'action': 'done'})
yield self.emit('log', {'action': 'done'})
6 changes: 3 additions & 3 deletions analyses/angular/index.html
Expand Up @@ -2,9 +2,9 @@


{% block head %}
<link rel="stylesheet" href="/_static/databench.css?v={{ databench_version }}">
<link rel="stylesheet" href="/_static/databench.css?v={{databench_version}}">
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/angular/static/analysis.css?v={{ version }}">
<link rel="stylesheet" href="/angular/static/analysis.css?v={{version}}">
{% end %}


Expand Down Expand Up @@ -61,7 +61,7 @@ <h1>


{% block footer %}
<script src="/_static/databench.js?v={{ databench_version }}"></script>
<script src="/_static/databench.js?v={{databench_version}}"></script>
<script src="/angular/static/angular_1.2.15.min.js"></script>
<script src="/angular/static/analysis.js"></script>
{% end %}
Expand Down
1 change: 0 additions & 1 deletion analyses/bagofcharsd3/analysis.js
Expand Up @@ -18,4 +18,3 @@ databench.on({ data: 'counts' }, (counts) => {


databench.connect();
databench.emit('sentence', 'type a phrase');
11 changes: 8 additions & 3 deletions analyses/bagofcharsd3/analysis.py
Expand Up @@ -3,7 +3,12 @@

class BagOfChars(databench.Analysis):

def on_sentence(self, sentence):
@databench.on
def connected(self):
yield self.sentence('type a phrase')

@databench.on
def sentence(self, sentence):
"""Takes a sentence and counts the characters."""
counts = {}
for c in sentence.lower():
Expand All @@ -13,5 +18,5 @@ def on_sentence(self, sentence):
if c not in counts:
counts[c] = sentence.count(c)

self.emit('log', counts)
self.data['counts'] = counts
yield self.emit('log', counts)
yield self.set_state(sentence=sentence, counts=counts)
19 changes: 8 additions & 11 deletions analyses/bagofcharsd3/index.html
Expand Up @@ -2,24 +2,21 @@


{% block head %}
<link rel="stylesheet" href="/_static/databench.css?version={{ databench_version }}">
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css?v={{ version }}" />
<link rel="stylesheet" href="/bagofcharsd3/static/analysis.css?v={{ version }}" />
<link rel="stylesheet" href="/_static/databench.css?v={{databench_version}}">
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css?v={{version}}" />
<link rel="stylesheet" href="/bagofcharsd3/static/analysis.css?v={{version}}" />
{% end %}


{% block analysis %}
<input type="text" class="form-control" id="sentence"
placeholder="type a phrase"
autocomplete="off" autofocus />

<input type="text" class="form-control" id="sentence" autocomplete="off" autofocus />
<svg id="viz"></svg>
{% end %}


{% block footer %}
<script src="/_static/databench.js?v={{ databench_version }}"></script>
<script src="/node_modules/d3/d3.min.js?v={{ version }}"></script>
<script src="/bagofcharsd3/static/d3charcount.js?v={{ version }}"></script>
<script src="/bagofcharsd3/static/analysis.js?v={{ version }}"></script>
<script src="/_static/databench.js?v={{databench_version}}"></script>
<script src="/node_modules/d3/d3.min.js?v={{version}}"></script>
<script src="/bagofcharsd3/static/d3charcount.js?v={{version}}"></script>
<script src="/bagofcharsd3/static/analysis.js?v={{version}}"></script>
{% end %}
53 changes: 26 additions & 27 deletions analyses/fastpi/analysis.py
Expand Up @@ -5,7 +5,6 @@
from rq import Queue
import subprocess
import time
import tornado.gen


def inside(job, draws=100):
Expand All @@ -22,29 +21,28 @@ def inside(job, draws=100):

class FastPi(databench.Analysis):

def on_workers(self, num_workers):
@databench.on
def workers(self, num_workers):
"""Spawns and terminates rqworkers as necessary."""

while num_workers > len(self.workers):
self.workers.append(subprocess.Popen(['rqworker']))
while num_workers > len(self.active_workers):
self.active_workers.append(subprocess.Popen(['rqworker']))

while num_workers < len(self.workers):
self.workers.pop().terminate()
while num_workers < len(self.active_workers):
self.active_workers.pop().terminate()

self.emit('log', {'workers': len(self.workers)})
yield self.emit('log', {'workers': len(self.active_workers)})

@tornado.gen.coroutine
def on_connect(self):
@databench.on
def connected(self):
"""Run as soon as a browser connects to this."""

self.workers = []
self.on_workers(2)
self.active_workers = []
yield self.workers(12)
q = Queue(connection=Redis())

jobs = []
for i in range(100):
jobs.append(q.enqueue(inside, i))
self.emit('log', {'enqueued_job': i})
jobs = [q.enqueue(inside, i) for i in range(100)]
yield self.emit('log', 'enqueued {} jobs'.format(len(jobs)))

draws_count = 0
inside_count = 0
Expand All @@ -53,26 +51,27 @@ def on_connect(self):
for j in finished_jobs:
draws_count += j.result[2]
inside_count += j.result[1]
self.emit('log', {
yield self.emit('log', {
'result': j.result,
'draws': draws_count,
'inside': inside_count,
})

uncertainty = 4.0 * math.sqrt(
draws_count * inside_count / draws_count *
(1.0 - inside_count / draws_count)
) / draws_count
self.data['pi'] = {
'estimate': 4.0 * inside_count / draws_count,
p = inside_count / draws_count
uncertainty = (4.0 * math.sqrt(draws_count * p * (1.0 - p)) /
draws_count)
yield self.set_state(pi={
'estimate': 4.0 * p,
'uncertainty': uncertainty,
}
})

jobs.remove(j)
yield tornado.gen.sleep(0.1)

self.emit('log', {'action': 'done'})
yield None

yield self.emit('log', {'action': 'done'})

def on_disconnect(self):
@databench.on
def disconnected(self):
# terminate all workers
self.on_workers(0)
yield self.workers(0)
6 changes: 3 additions & 3 deletions analyses/fastpi/index.html
Expand Up @@ -2,7 +2,7 @@


{% block head %}
<link rel="stylesheet" href="/_static/databench.css?version={{ databench_version }}">
<link rel="stylesheet" href="/_static/databench.css?v={{databench_version}}">
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css">
{% end %}

Expand All @@ -15,6 +15,6 @@ <h1><em>π = <span id="pi">0.0 ± 1.0</span></em></h1>


{% block footer %}
<script src="/_static/databench.js?v={{ databench_version }}"></script>
<script src="/fastpi/static/analysis.js?v={{ version }}"></script>
<script src="/_static/databench.js?v={{databench_version}}"></script>
<script src="/fastpi/static/analysis.js?v={{version}}"></script>
{% end %}
100 changes: 60 additions & 40 deletions analyses/flowers/analysis.py
Expand Up @@ -101,32 +101,54 @@ def ends(self, x=0.0, y=0.0):

class Flowers(databench.Analysis):

def __init__(self, id_=None):
super(Flowers, self).__init__(id_)
def __init__(self):
self.max_height = 0.9
self.max_width = 0.3
self.flowers = []
self.periodic_callback = tornado.ioloop.PeriodicCallback(
self.generate_flowers,
200,
)

def on_connect(self):
@databench.on
def connected(self):
"""Run as soon as a browser connects to this."""
self.data['n_flowers'] = 3
yield self.data.init({
'n_flowers': 3,

'init_size': 0.02,
'init_length': 0.05,
'init_color': 0.1,

'size_delta': (0.99, 0.02),
'length_delta': (0.99, 0.02),
'color_delta': (0.5, 0.1),
'angle_delta': (0.0, 5.0 / 57.0),
'branch_prob_per_unit': 5.0,
'branch_angle': 10.0 / 57.0,
})

self.periodic_callback.start()

self.data['init_size'] = 0.02
self.data['init_length'] = 0.05
self.data['init_color'] = 0.1
@databench.on
def n_flowers(self, value):
self.set_state(n_flowers=value)

self.data['size_delta'] = (0.99, 0.02)
self.data['length_delta'] = (0.99, 0.02)
self.data['color_delta'] = (0.5, 0.1)
self.data['angle_delta'] = (0.0, 5.0 / 57.0)
self.data['branch_prob_per_unit'] = 5.0
self.data['branch_angle'] = 10.0 / 57.0
@databench.on
def init_size(self, value):
self.set_state(init_size=value)

self.connected = True
self.generate_flowers()
@databench.on
def init_length(self, value):
self.set_state(init_length=value)

def on_disconnect(self):
self.connected = False
@databench.on
def branch_angle(self, value):
self.set_state(branch_angle=value)

@databench.on
def disconnected(self):
self.periodic_callback.stop()

def init_flowers(self):
while len(self.flowers) < self.data['n_flowers']:
Expand All @@ -145,27 +167,25 @@ def output(self):
lines += f['trunk'].lines(f['x'])
return lines

@tornado.gen.coroutine
@databench.on
def generate_flowers(self):
while self.connected:
self.init_flowers()

# remove flowers that are larger than self.max_height
heights = [max([e[1] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
self.flowers = [f for f, h in zip(self.flowers, heights)
if h < self.max_height]
# remove flowers that are wider than self.max_width
lefts = [min([e[0] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
rights = [max([e[0] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
widths = [r - l for l, r in zip(lefts, rights)]
self.flowers = [f for f, w in zip(self.flowers, widths)
if w < self.max_width]

for f in self.flowers:
f['trunk'].generate()

self.data['lines'] = self.output()
yield tornado.gen.sleep(0.15)
self.init_flowers()

# remove flowers that are larger than self.max_height
heights = [max([e[1] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
self.flowers = [f for f, h in zip(self.flowers, heights)
if h < self.max_height]
# remove flowers that are wider than self.max_width
lefts = [min([e[0] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
rights = [max([e[0] for e in f['trunk'].ends(f['x'])])
for f in self.flowers]
widths = [r - l for l, r in zip(lefts, rights)]
self.flowers = [f for f, w in zip(self.flowers, widths)
if w < self.max_width]

for f in self.flowers:
f['trunk'].generate()

yield self.set_state(lines=self.output())
8 changes: 4 additions & 4 deletions analyses/flowers/index.html
Expand Up @@ -2,7 +2,7 @@


{% block head %}
<link rel="stylesheet" href="/_static/databench.css?version={{ databench_version }}">
<link rel="stylesheet" href="/_static/databench.css?v={{databench_version}}">
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css" />
<style>
.sliders { display: flex; flex-wrap: wrap; margin: -10px 0 0 -10px; }
Expand Down Expand Up @@ -38,7 +38,7 @@


{% block footer %}
<script src="/_static/databench.js?v={{ databench_version }}"></script>
<script src="/node_modules/d3/d3.min.js?v={{ version }}"></script>
<script src="/flowers/static/analysis.js?v={{ version }}"></script>
<script src="/_static/databench.js?v={{databench_version}}"></script>
<script src="/node_modules/d3/d3.min.js?v={{version}}"></script>
<script src="/flowers/static/analysis.js?v={{version}}"></script>
{% end %}

0 comments on commit 1eb7901

Please sign in to comment.