BarnCamp 2011 Workshop Notes

From HacktionLab: A UK-wide network tech-activists providing meet-ups, events, workshops, national skillshare gatherings and hacklabs
Jump to navigation Jump to search

These are the notes from the many different, varied, and sometimes random workshops that took place during BarnCamp 2011

Encrypted email using Thunderbird

Disclaimer: This is a basic overview of encryption.

Why use encryption?

  • When you send an email it get bounced around several servers.
  • Anybody with admin access to the server can read you email - it's a bit like sending a postcard where anybody that handles the postcard can read you message.
  • Many email providers either choose, or are required by law, to keep emails for quite a long time. This means your postcard can be read long after it has been delivered.
  • If you are planning an action, this can be a bad thing. It can also be a bad thing if you consider your emails to be private communications.


Why & how to set up an non-corporate anonymous blogging hosting service

Why set up this type of blog services?

We heard the story of the Bristol Blogger - a political blogger who had been using a WordPress blog for a long time. They posted a blog that was critical about a person, who then complained to WordPress. WP removed the entire blog. After complaints, the blogs was restored, but the post in question was removed. The Bristol Blogger had no control over their own site, and data was removed from it.
We also heard about a Manchester based blogger who posted an item about somebody from Manchester University. WP passed on personal details about the blogger to the university.
So, the key questions are: who controls your data? Who knows who you are, and who do they pass that info onto?

Network 23 used WordPress to set up a non-corporate site that would respect people's anonymity. The approach is to deal with editorial issues on a case by case level - what the hosters want to host. So may issue take down notice - blogger has to fight own corner.
Refer to N23 terms & conditions. Editorial decisions - hierarchy & accountable. Not only place for free speech. People can go elsewhere. Is this an argument for lots of providers with different terms & conditions.

Why WP network instead of separate installs?

It is possible to set up an individual group on a single WP installation, but they don't keep it up to date.
Multi-user option available out of the box to create sub-blogs of main blog. So all blogs are running the same code - means that one update on a plugin will affect all sites using that plugin. Some plugins won't work with this set up (will only work on main blog).

How many sub blogs? Not sure, but lots.

User can Request new plugins.

How it was done

N23 were lucky to have one person who had already done similar stuff. Their key tips were:

  • Started with small number of plugins
  • Get lots of users
  • Install new plugins when people want them.

Features

Able to import from other blogs (e.g. from an existing site on WordPress.com) - useful for migration to N23.

Can there be different language options - e.g. admin interface in different languages? Seems not out of the box, but plugins may be available.

Server resources required

Lots of memory on the server

Lots of disc space if you want users to upload large and/or many video & audio.

How to make a Network 23 site

1. Use online form contact N23 asking for blog

2. Admin fills in new site form. Creates site, emails user.
- admin can access the control panel.

3. Look at plugins ...
Anti-spam - WP sites are suseptable to spam. Use wp-spamfree

Limitations for Network 23

Little space for uploaded media - people advised to use an Indymedia site that allows uploading.

Q? Anon posting on archive.org.

Can people moving from N23? Yes, using export function in settings on dashboard

Issues around domain mapping - https and SSL certificates.

Apache mod - remove IPs and replaces them, e.g. with no luck here copper.

Ways forward

Should Network 23 be the hub for anonymous WP blogs? Probably not - better if there were lots of small services, with their own rules.

Luddites and Technology

There's an audio recording of this workshop available at http://www.archive.org/details/LudditesAndTechnology-WorkshopRecordingFromBarncamp2011

The HTML 5 <canvas> element as seen through a fractal eye: a brief introduction

Years ago I was into fractals, and wrote a lot of code for the Atari ST with a friend to produce Mandelbrot and Julia sets. Recently I was excited to see that HTML 5 has an element <canvas> that allows you to draw directly in to it, so I ported the algorithm for producing Mandelbrot and Julia sets to Javascript so that I could have a play....

There is a set of slides for the workshop uploaded into the Wiki, you can download them as a PDF or original ODP: File:Fractal-talk-bc-2011.pdf or [[

What is a fractal?

A fractal is an object which has some of these properties:

  • Self-similar (the same patterns repeat themselves at different magnifications)
  • Fine structure are arbitrary small scales.
  • It can't be described by Euclidean geometry.
  • It has a simple and recursive definition.
  • It has a Hausdorff dimension which is greater than its topological dimension – I think this means that it's boundary is greater than the area that it bounds.

Types of fractals

  • Iterated Function Systems (IFS) - Cantor set, Sierpinski carpet, Sierpinski gasket, Peano curve, Koch snowflake, Harter-Heighway dragon curve, T-Square, Menger sponge
  • Strange attractors – Lorenz attractor
  • Random fractals – such as those made from Brownian motion, fractal landscapes, etc.
  • Escape-time fractals – Mandelbrot Set, Julia Set, Nova and Lyapunov fractals.

The people behind the fractals

  • Edward N Lorenz (1917-2008)
  • David Hilbert (1862-1943)
  • Wacław Sierpiński (1882-1969)
  • Gaston Julia (1893-1978)
  • Benoit Mandelbrot (1924-2010)
  • Pierre Fatou (1878-1929)

Gaston Juila

Along with Pierre Fatou, Gaston Julia predicted that some pretty interesting shapes would come out from the iteration of the equation:

Z ->Z^2 + C

For a fixed value of C, where Z and C are complex numbers. A complex number is a number that has a real part and an imaginary part and is written in the format:

C, a complex number = a + bi, where a is a real number and bi is the imaginary part.

Benôit Mandelbrot

Enter: Benoît Mandlebrot

Benoît is pronnounced 'ben-waa' and Mandlebrot is Yiddish for Almond Bread.

Born in Warsaw in 1924.

In 1979 he got hold of a big “supercomputer” at IBM and played about with writing computer programmes to plot Julia's work described many years before.

He came up with the idea of plotting a map of z => z^2 + c for every value of C in the complex plan and a miraculous pattern came out of the trusty old IBM plotter.

HTML 5

  • New HTML standard developed by the World Wide Web Consortium (W3C)
  • A hybrid of HTML 4.01 & XHTML 1.1 and a lot more.
  • HTML 4.01 was a mess
  • But XHTML 1.1 was too idealistic for folk to do interesting stuff.
  • HTML 5 is a compromise and features the exciting <video>, <audio> and <canvas> tags and features like drag-and-drop and cross-document messaging

The <canvas> element

The canvas element provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly. Great! Latest published version of HTML5 (May 2011) is available at http://www.w3.org/TR/html5/

To define <canvas> in HTML:

<canvas id="mset_canvas" width="320" height="240" style="float:left"></canvas>

And then to use it, we use JavaScript:

var canvas =     
      document.getElementById("mset_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.fillRect(ix,iy,1,1);

The Mandelbrot Set - Mandelbrot's Baby

  • Self-similar.
  • Infinitely complex.
  • A finite area enclosed by an infinite border.
  • Plethora of beautiful images.
  • Very simple equation.
  • Easy to programme.

Some hard sums

TODO!

Coding the Mandelbrot set

An algorithm

We call the following algorithm every point on our “slice” of the complex plane. Our range is from -2.5 <= x <= 0.8 and -1.25 <= iy <= 1.25.

ALGORITHM: MsetLevel (cx, cy, maxiter)

BEGIN
	x:=y:=x2:=y2:=0.0
	iter:=0
	WHILE (iter<maxiter) AND (x2 + y2 < 10000.0) DO
		temp:=x2 – y2 + cx
		y:= 2 * x * y + cy
 		x:=temp
		x2:=x * x
		y2:=y * y
		iter:=iter+1
	END WHILE
	RETURN (iter)
END 

The algorithm in JavaScript

function compute_point(x,y,cx,cy,maxiter,thresh) {
  var x2 = x * x; var y2 = y * y;
  var iter = 0;
  while ( (iter < maxiter) &&
          ( (x2 + y2) < thresh) ) {
     var temp = x2 - y2 + cx;
     y = 2 * x * y + cy;
     x = temp;
     x2 = x * x;
     y2 = y * y;
     iter++;
   }
   return iter;
}

Plotting our shape

Mset.png

… WHILE (iter<maxiter) AND (x2 + y2 < 10000.0) ....

If the sum of the squares is greater than 10000 (the threshold) then we assume the value of Z is spiralling to infinity, we break out and plot a colour depending on the number of iterations of the algorithm that it took.

If we hit maxiter (the maximum number of iterations) then plot black.

So, the black set is the orderly part that is not tending to infinity, that part that is on the inside.

The colourful part is the chaotic part, tending to infinity.

function mandelbrot() {
  var canvas = document.getElementById("mset_canvas");
  var ctx = canvas.getContext("2d");
  for (var iy = 0; iy < res_y; iy++) {
    var cy = y_min + iy * y_prop;
    for (var ix = 0; ix < res_x; ix++) {
      var cx = x_min + ix * x_prop;
      var x = 0.0; var y = 0.0;
      var iter = compute_point(x,y,cx,cy,maxiter,thresh);
      if(iter == maxiter) {
        // if we didn't get to infinity by the time we
        // used up all the iterations, then we're in the set
        // colour it black
        ctx.fillStyle = "#000000";
      } else {
        // otherwise colour it according to the number
        // of iterations it took to get to infinity (thresh)
        ctx.fillStyle = pallette[iter % num_colours];
      }
      ctx.fillRect(ix,iy,1,1);
   }
  }
}

Appendix

A Perl script to produce it using tags

#!/usr/bin/perl
#
#
# $Id: mandelbrot.pl,v 1.3 2005-03-11 17:23:26 adelayde Exp $
# Revision: $Revision: 1.3 $
# Author  : $Author: adelayde $
# Date    : $Date: 2005-03-11 17:23:26 $
#
# $Log: mandelbrot.pl,v $
# Revision 1.3  2005-03-11 17:23:26  adelayde
# Lowered res again to 320x240
#
# Revision 1.2  2005/03/11 17:13:27  adelayde
# Fixed quadratic equations
#

use CGI;

# preparar p?gina web

my $cgi = new CGI;
print $cgi->header . $cgi->start_html(-title => 'Conjunt de Mandelbrot',
				      -style=>{-src=>['/fractals/styles.css']});

print '<table border="0" cellspacing="0" cellpadding="0">';

# colors
my @pallette = ("#000033","#000066","#000099","#0000CC","#0000FF","#330000","#330033","#330066","#330099","#3300CC","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#990033","#990066","#990099","#9900CC","#9900FF","#CC0033","#CC0066","#CC00CC","#CC00FF","#FF00FF");
my $num_colours = scalar @pallette;

# M?todo MSetLSM
my $nx = 320; # resolucion en x
my $ny = 240; # resolucion en y

my $xmin = -2.5; # valor m?nimo en plano real
my $xmax = 0.8; # valor m?ximo en plano real
my $ymin = -1.25; # valor m?nimo en plano imaginario
my $ymax = 1.25; # valor m?ximo en plano imaginario
my $maxiter = 60; # n?mero m?ximo de iteraciones
my $limite = 10000.00; # l?mite considerado y valor tiende a infinidad

my $xprop = ($xmax - $xmin) / ($nx - 1);
my $yprop = ($ymax - $ymin) / ($ny - 1);

for(my $iy = 0; $iy < $ny; $iy++) {

    my $cy = $ymin + $iy * $yprop;

    print '<tr style="height: 1px;">';

    for(my $ix = 0; $ix < $nx; $ix++) {

	my $cx = $xmin + $ix * $xprop;

	# iteraci?n
	# formula es z -> z^2 + c

	my ($x, $y, $x2, $y2) = (0.0, 0.0, 0.0, 0.0);
	my $iter = 0;

	while( ($iter < $maxiter) && (($x2 + $y2) < $limite)) {

	    my $temp = $x2 - $y2 + $cx;
	    $y = 2 * $x * $y + $cy;
	    $x = $temp;
	    $x2 = $x * $x;
	    $y2 = $y * $y;

	    $iter++;
	}
	
	if ($iter == $maxiter) {
	    print '<td> </td>';
	} else {
	    print '<td style="background:' . $pallette[$iter % $num_colours] . '"> </td>';
	}
    }

    print '</tr>';

}

print '</table>' . $cgi->end_html;

exit(0);

Full coding example in HTML and JavaScript

<!DOCTYPE html>
<html>
  <head>
    <title>HTML 5 Mandelbrot set and Julia set explorer</title>
    <script type="application/x-javascript" src="fractal.js"></script>
    <style>
      h1 {
      font-size:1.2em;
      }
      
      h2 {
      font-size:1.0em;
      }
      
      p {
      font-size:0.8em;
      }
      
      address {
      font-size:0.6em;
      }
    </style>
  </head>
  <body onload="mandelbrot()" onkeypress=keycommandprocessor()>
    <h1>Mandelbrot Set > Julia Set Explorer</h1>
    <h2>written by Mike Harris, based on algorithms in The Science of Fractal Images</h2>
    <p>Click on any point in the Mandelbrot set on left to see the corresponding Julia set on the right and the co-ordinates below.</p>
    <p>colouring method: 
      <select id="method" name="method">
	<option value="lsm" selected="selected">Level Set Method (LSM)</option>
	<option value="bdm">Binary Decomposition Method (BDM)</option>
      </select>
      <button onclick="mandelbrot()">reload</button>
    </p>
    <canvas id="mset_canvas" width="480" height="320" style="float:left" onclick="setcoords(event,this);julia(event,this)"></canvas> 
    <canvas id="jset_canvas" width="480" height="320"></canvas>
    <br/>
    cx: <input type="text" value="" name="cx" id="cx" value="0.0" />
    cy: <input type="text" value="" name="cy" id="cy" value="0.0" /> <button onclick="julia(event,this)">redraw julia set</button>
   <p>There's also an archive of old Fractal work I did with Dan Grace back in the Eighties on the <a href="/fe3">Fractal Engine archive site</a>.</p>
   <hr/>
   <address>(c) 2009-2011 Mike Harris.  Free software released under GNU Public Licence.  Feel free to view the source, <a href="fractal.js">download and hack this code</a>.  Also there's a <a href="mandelbrot.pl">Perl verion that'll render the MSet using HTML table tags (run this on your own machine)</a>.</address>
  </body>
</html>
//
// JavaScript methods to draw Mandelbrot and Julia Sets
//
// Written by mike@mbharris.co.uk
//
// version 1.1 - featuring LSM and BDM methods
//
// (c) 2009-2011 Mike Harris.  
// Free software released under GNU Public Licence.
//

// set up a colour pallette for colouring the levels outside the set itself
var pallette = new Array("#000033","#000066","#000099","#0000CC","#0000FF","#330000","#330033","#330066","#330099","#3300CC","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#990033","#990066","#990099","#9900CC","#9900FF","#CC0033","#CC0066","#CC00CC","#CC00FF","#FF00FF");

var num_colours = pallette.length;

// set up of 'screen' resolution, the size of our <canvas>
var res_x = 480; // resolution in pixels of x axis
var res_y = 320; // resolution in pixels of y axis

// set up the size of our real and imaginary planes      
var x_min = -2.5;  // minimum value in real plane
var x_max = 0.8;   // maximum value in real plane
var y_min = -1.25; // minimum value in imaginary plane
var y_max = 1.25;  // maximum value in imaginary plane

// calculate the proportion in the difference between the points
// on the mathematical plane and the actual screen resolution	
var x_prop = (x_max - x_min) / (res_x -1);
var y_prop = (y_max - y_min) / (res_y -1);

var maxiter = 60;      // maximum number of iterations
var thresh = 10000.00; // threashold above which value is considered to tend to infinity
                       // the coloured bands on the outside of our Mandelbrot Set are
                       // a measure of how soon the values become unstable and hence the
                       // point on the plane is not within the set itself, not bounded by the set

function compute_point(point,cx,cy,maxiter,thresh) {
    var x2 = point.x * point.x; var y2 = point.y * point.y;
    var iter = 0;
    
    while ( (iter < maxiter) && ( (x2 + y2) < thresh) ) {
	var temp = x2 - y2 + cx;
	point.y = 2 * point.x * point.y + cy;
	point.x = temp;
	x2 = point.x * point.x;
	y2 = point.y * point.y;
	iter++;
    }
    return iter;
}

function mandelbrot() {
    var method = document.getElementById('method').value;
    switch(method) {
    case 'bdm':
	mandelbrot_bdm();
	break;
    case 'lsm':
    default:
	mandelbrot_lsm();
	break;
    }
}

// draw the mandelbrot set using the Level Set Method
function mandelbrot_lsm() {
    var canvas = document.getElementById("mset_canvas");
    var ctx = canvas.getContext("2d");
    
    for (var iy = 0; iy < res_y; iy++) {
	
	var cy = y_min + iy * y_prop;
	
	for (var ix = 0; ix < res_x; ix++) {
	    
	    var cx = x_min + ix * x_prop;
	    var point = {x:0.0,y:0.0};
	    var iter = compute_point(point,cx,cy,maxiter,thresh);
	    
	    if(iter == maxiter) {
		// if we didn't get to infinity by the time we
		// used up all the iterations, then we're in the set
		// colour it bloack
		ctx.fillStyle = "#000000";
	    } else {
		// otherwise colour it according to the number
		// of iterations it took to get to infinity (thresh)
		ctx.fillStyle = pallette[iter % num_colours];
	    }
	    ctx.fillRect(ix,iy,1,1);
	}
    }
}

// draw the mandelbrot set using the Binary Decomposition Method
function mandelbrot_bdm() {
    var canvas = document.getElementById("mset_canvas");
    var ctx = canvas.getContext("2d");
    
    for (var iy = 0; iy < res_y; iy++) {
	
	var cy = y_min + iy * y_prop;
	
	for (var ix = 0; ix < res_x; ix++) {
	    
	    var cx = x_min + ix * x_prop;
	    var point = {x:0.0,y:0.0};
	    var iter = compute_point(point,cx,cy,maxiter,thresh);
	    
	    if(iter == maxiter) {
		// if we didn't get to infinity by the time we
		// used up all the iterations, then we're in the set
		// colour it bloack
		ctx.fillStyle = "#000000";
	    } else {
		// color it depending on the angle of alpha
		var alpha = Math.atan(point.y);
		if ((alpha >= 0) && (alpha <=3)) {
		    ctx.fillStyle = "#fff";
		} else {
		    ctx.fillStyle = "#000";
		}
	    }
	    ctx.fillRect(ix,iy,1,1);
	}
    }
}

function julia() {
    var method = document.getElementById("method").value;
    switch(method) {
    case 'bdm':
	julia_bdm();
	break;
    case 'lsm':
    default:
	julia_lsm();
	break;
    }
}

function julia_lsm() {
    var canvas = document.getElementById("jset_canvas");
    var ctx = canvas.getContext("2d");
    var color_method = "lsm";

    var x_min = -2.25;
    var x_max = 2.25;
    var y_min = -1.8;
    var y_max = 1.8;
    
    var x_prop = (x_max - x_min) / (res_x -1);
    var y_prop = (y_max - y_min) / (res_y -1);
    
    // note these must use the Number object to 'cast' the
    // values to numbers (rather than strings)
    var cx = new Number(document.getElementById('cx').value);
    var cy = new Number(document.getElementById('cy').value);
    
    for (var iy = 0; iy < res_y; iy++) {
	
	var y = y_min + iy * y_prop;
	for (var ix = 0; ix < res_x; ix++) {
	    
	    var point = {x:x_min + ix * x_prop,y:y};
	    var iter = compute_point(point,cx,cy,maxiter,thresh);
	    
	    if(iter == maxiter) {
		// if we didn't get to infinity by the time we
		// used up all the iterations, then we're in the set
		// colour it bloack
		ctx.fillStyle = "#000000";
	    } else {
		// otherwise colour it according to the number
		// of iterations it took to get to infinity (thresh)
		ctx.fillStyle = pallette[iter % num_colours];
	    }
	    
	    ctx.fillRect(ix,iy,1,1);
	}
    }
}

function julia_bdm() {
    var canvas = document.getElementById("jset_canvas");
    var ctx = canvas.getContext("2d");

    var x_min = -2.25;
    var x_max = 2.25;
    var y_min = -1.8;
    var y_max = 1.8;
    
    var x_prop = (x_max - x_min) / (res_x -1);
    var y_prop = (y_max - y_min) / (res_y -1);
    
    // note these must use the Number object to 'cast' the
    // values to numbers (rather than strings)
    var cx = new Number(document.getElementById('cx').value);
    var cy = new Number(document.getElementById('cy').value);
    
    for (var iy = 0; iy < res_y; iy++) {
	
	var y = y_min + iy * y_prop;
	for (var ix = 0; ix < res_x; ix++) {
	    
	    var point = {x:x_min + ix * x_prop,y:y};
	    var iter = compute_point(point,cx,cy,maxiter,thresh);
	    	    
	    if(iter == maxiter) {
		// if we didn't get to infinity by the time we
		// used up all the iterations, then we're in the set
		// colour it bloack
		ctx.fillStyle = "#000000";
	    } else {
		// color it depending on the angle of alpha
		var alpha = Math.atan(point.y);
		if ((alpha >= 0) && (alpha <=3)) {
		    ctx.fillStyle = "#fff";
		} else {
		    ctx.fillStyle = "#000";
		}
	    }
	    
	    ctx.fillRect(ix,iy,1,1);
	}
    }
}

function setcoords(evt, obj) {
    
  var x_pos = evt.clientX - obj.offsetLeft;
  var y_pos = evt.clientY - obj.offsetTop;
  
  var cx = x_min + x_pos * x_prop;
  var cy = y_min + y_pos * y_prop;
  
  document.getElementById('cx').value = cx;
  document.getElementById('cy').value = cy;
  
}