Skip to content

Instantly share code, notes, and snippets.

@adrianseeley
Last active August 29, 2015 13:56
Show Gist options
  • Save adrianseeley/8960336 to your computer and use it in GitHub Desktop.
Save adrianseeley/8960336 to your computer and use it in GitHub Desktop.
Let's Do Artificial Genetics - Episode 00 - Boilerplate
<html>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
// ask the DOM for our canvas element
var canvas = document.getElementById('canvas');
// set the size of our canvas element to the size of the browser window
// since we will be using this as our whole workspace we want to capitalize
// on all the available real estate
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// ask our canvas element for a 2d 'context' to draw with
var ctx = canvas.getContext('2d');
/*
Although canvas has it's own very flexible functions for drawing
virtually everything, our drawing needs are very basic and almost
never change. We add the following functions to our drawing context
so that when we do need to make quick draw calls they can be made
very clearly in a single line.
ie. ctx.Clear();
ctx.Dot(10, 10, 5, 'red');
ctx.Line(100, 100, 200, 200, 2, 'green');
ctx.Path([{x: 10, y: 10}, {x: 20, y: 25}, {x: 35, y: 100}], 3, 'blue');
We also invert the y-coordinate to make the origin (0,0) at the bottom
left corner of the canvas and (+inf,+inf) extending to the top right corner.
ie. |----+inf
| |
| |
0------|
*/
// Clears the entire canvas
ctx.Clear = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
};
// Draws a dot by defining a center (x, y), a radius (r) and a color
ctx.Dot = function (cx, cy, r, color) {
ctx.beginPath();
ctx.arc(cx, canvas.height - cy, r, 0, 2 * Math.PI, false);
ctx.fillStyle = color;
ctx.fill();
};
// Draws a dot by defining a normalized center [0->1] (x, y), a radius (r)
// and a color
ctx.nDot = function (ncx, ncy, r, color) {
ctx.Dot(ncx * canvas.width, canvas.height - (ncy * canvas.height), r, color);
};
// Draws a line by defining a starting point (x1, y1), an ending point (x2, y2),
// a line width and a color
ctx.Line = function (x1, y1, x2, y2, width, color) {
ctx.beginPath();
ctx.moveTo(x1, canvas.height - y1);
ctx.lineTo(x2, canvas.height - y2);
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.stroke();
};
// Draws a line by defining a normalized starting point [0->1] (nx1, ny1),
// a normalized ending point [0->1] (nx2, ny2), a line width and a color
ctx.nLine = function (nx1, ny1, nx2, ny2, width, color) {
ctx.Line(nx1 * canvas.width, canvas.height - (ny1 * canvas.height), nx2 * canvas.width, canvas.height - (ny2 * canvas.height), width, color);
};
// Draws a path by defining a path of [{x: 10, y: 20}, ...] points (p),
// a line width and a color
ctx.Path = function (p, width, color) {
ctx.beginPath();
ctx.moveTo(p[0].x, canvas.height - p[0].y);
for (var i = 1; i < p.length; i++) {
ctx.lineTo(p[i].x, canvas.height - p[i].y);
}
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.stroke();
};
// Draws a path by defining a path of [{nx: 0.12, ny: 0.99}, ...] normalized
// points (np), a line width and a color
ctx.nPath = function (np, width, color) {
ctx.beginPath();
ctx.moveTo(np[0].nx * canvas.width, np[0].ny * canvas.height);
for (var i = 1; i < np.length; i++) {
ctx.lineTo(np[i].nx * canvas.width, canvas.height - (np[i].ny * canvas.height));
}
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.stroke();
};
</script>
<body>
<html>

Episode 00 - Boilerplate

Introduction To Let's Do Artifical Genetics

Hi everyone, my name is Adrian Seeley, and I'm an adaptive systems researcher. Today I'm proud to introduce the new series called Let's Do Artificial Genetics, where I'll take you from virtually zero experience programming, to a full arsenal of artificially genetic structures that you can immediately start applying to real world problems. Veteran programmers and machine learning experts can still benefit from all the episodes in their entirety, although you will probably be able to progress through the first few quickly.

Now before we get started, it needs to be said that programming can be very difficult - and often cripplingly frustrating. This stops most people from even attempting to write a few lines of code, let alone become a full fledged programmer. Some of you I can save upfront by explaining there are only two kinds of problems in programming:

The first are actual code problems, like "what's a function?" or "why do I need to convert this type?". These problems have always been encountered by someone else before you, and the answer can be quickly found by typing your problem and the name of your programming language into google: "javascript reference not defined". Thanks to communities like stackoverflow.com, you can always find the answers to these problems quickly if you're willing to look and put forth the effort to actually understand the answer. The best programmers know how to leverage the power of google to fill in any blanks of knowledge they might have. Solving these kinds of problems can feel empowering, you start to get addicted to the feeling of your mind grasping and harnessing new knowledge.

The other type of problems are strictly related to getting a development environment running in the first place, or even understanding what a development environment is and why you would ever need one. Languages like Python and Ruby gladly tell the world how easy they are to learn, and how friendly they are to newcomers - but if you've ever tried to get Python or Ruby running on a windows computer, you know that it requires an intimate understanding of linux, the path, how windows is different from linux, the difference between 32 and 64 bit, and most importantly what "Error: def fun(map, def$*) -> is undefined" means, because the language installers rarely ever work properly the first time at bat, and before you even get to think about writing code you are forced to deal with a nightmare of cryptic errors that might as well be written in Egyptian hieroglyphs. These problems are the standing on the desk, waving the gun, spending the next 10 years in a straight jacket problems. They lead to common phrases like "but it works on my computer", "what do you mean I need to already have Ruby installed to install Ruby?" and "I honestly don't know what happened officer - but this blood is definitely not mine".

If the craving to feed your addiction to functional knowledge can overpower the urges to ritualistically sacrifice anything within an arms reach of your computer - congratulations you've probably got what it takes to be a programmer! To everyone else, you should probably leave now and go back to surfing Reddit.

Introduction To Genetics

Biology is a big field, genetics itself could fill a library of books with it's deep hidden complexities. We really only care about a few key features of genetics though, any further learning on the subject I leave up to you. My express apologies to anyone with an actual understanding of genetics, I do not claim to be a geneticist in any way - as I am about to make readily evident.

Basically all the living things we have knowledge of: plants, birds, fish, people - all have DNA. DNA is often referred to as a 'genetic makeup', and can be thought of like a big set of blueprints to make a living thing. Every living thing is made up of tiny cells, and each of those cells has it's own copy of the blueprints. To make it easy we can think of DNA like a little set of instructions on how to make cells, and for cells to know what they should do.

When animals sexually reproduce, they effectively mix their DNA together creating a somewhat random mix of the two parents. That works because DNA is actually made up of millions of 'genes', where each gene is one of the steps in the instruction list. When two animals mate, their genes mix together and make a new DNA - similair to both parents. This is why we look like our parents.

So quick homogenization recap: DNA is a big list of instructions that we call genes, these genes can mix and match to create fun new possibilities (also known as playing god).

Others may find it helpful to think of DNA like a recipe, where the cooking instructions are like genes. A chef can use two different recipes for the same dish to make one new recipe using ideas from both recipes, the result could be a much better recipe, or a much worse one. We refer to how good a DNA (or a recipe) is, as 'the fitness of the DNA'.

Right now a voice in the back of your head should be saying 'survival of the fittest' - a very simple description of how evolution works. Most people naively assume 'the fittest' in this context to mean the same as 'the most athletic', or 'the most muscular', when really it refers to 'the survival of those who are best suited to survive', or rather 'the survival of the most fit to survive', finally bringing us to 'the survival of the fittest' - it's easy to see how that meaning has gotten lost in modern English usage where advertising has destroyed any real meaning of the word 'fit'.

Another quick recap: genes are the building blocks that we use to make DNA, and we refer to how good a DNA is as it's fitness. It should be noted that 'fitness' is an idea used to give DNA meaningful scores and is strongly tied to artificial genetics, and not so much regular genetics - as measuring how fitness of real DNA is only really important for things like eugenics and discrimination, which are hardly the focus of any good scientist.

Luckily we are on the mad scientist side of the fence, and artificial discrimination is actually our goal - but before that, let's talk a little more about evolution. Evolution is like erosion, slow smooth changes over time leading to a totally new shape - except instead of a rock smoothing out, evolution sees life forms growing taller to better reach higher leaves on trees, or growing better shaped wings to fly faster in order to catch prey. This slow process of adapting is what makes evolution and genetics so incredibly powerful - it's almost like the environment is a big puzzle and DNA is slowly trying to solve it, coming up with better and better solutions as it goes.

In case you missed that: the environment is like a big problem and DNA is like a big problem solver.

Finally we can start talking about how this actually relates to artificial genetics. Whenever we have a certain type of problem in the programming world, we can actually write our own little artificial DNA system and 'evolve' or 'grow' a solution to our problem. Holy flip flying fuck, yes I just said we can play god and evolve a solution to our problem - but aren't we toying with the fabric of life itself? Am I not causing little fake people to lead little fake lives all to solve some trivial algorithmic problem? Actually not at all, not anywhere close - not even in the same country to close.

Even if you don't know anything about programming or how computers work, you probably know they can do mundane computations much faster than any human ever could (much, much faster). Basically artifical genetics is asking a computer to do something one way, measure how good it did, try it another way, measure if the new way was better - take the best of the two and repeat until perfect. Literally, that's it. No black magic, no heiroglyphs or virgin blood - it's actually just a fancy loop. This means that we can just as easily (albeit a lot slower) do artificial genetics by writing the instructions on paper and following them by hand - and we will actually prove this later on by doing some pen and paper genetics.

Requirements

You absolutely must have some version of Google Chrome which is powered by V8 JavaScript, the language of choice for Let's Do Artificial Genetics.

Chrome provides a first class debugger, profiler, canvas display and REPL - effectively allowing us to edit and see our code while it's running, and even to inject new code on the fly. This workflow flexibility, coupled with the powerful loose type system of JavaScript, makes Chrome the perfect candidate as a platform for artificial genetics.

Chrome's free price tag and ability to run on Linux, Mac and Windows environments helps to remove any fiscal barrier to entry for students new to Let's Do Artificial Genetics.

Recommendations

No matter what language you write code in, you will need to actually type that code somewhere in order to run it. Although Let's Do Artificial Genetics will have you writing a fair bit of exploratory code directly into the Chrome console, we will also be writing code into a saved text file as we need to make larger changes and additions to the code base.

It is possible to write code in Notepad or a similar text editor, we whole heartedly recommend you use the latest version of Sublime Text. It may take you a while to find all the helpful bits of Sublime Text, but every time you stumble upon one you will feel immediately empowered and even catered to by the brilliant features added by the masses of developers who came before us.

Although a license will cost $70 (at the time of writing this), Sublime Text provides literally countless features that are virtually indispensable when it comes to writing code effectively; By providing clear syntax highlighting, code folding, and an elegant solarized dark display, students are dramatically more likely to be successful in developing a working knowledge of artificial genetics systems and JavaScript as a whole. Sublime Text can also be used fully featured unlimitedly, with the exception of a buy me nag screen every few saves.

Transcript

Not everyone loves JavaScript as much as I do, so we will assume that everyone here has some idea what programming is all about: mainly functions, strings and basic algebra. In the event you only speak human: functions do things, strings are a bunch of letters, and basic algebra is what you would have learned in high school if you weren't smoking pot instead - but we will cross that bridge in a minute.

You're going to want to download and install Google Chrome if you don't already have it installed. We also recommend you grab the latest copy of Sublime Text, apart from chrome it's the only other piece of software we will ever be using. It's free to use with a nag screen, or a license will cost you $70 (although we would gladly pay $700 if they asked us to, it's that good).

In order to get our workspace up and running: first open up sublime text and save a brand new empty text file somewhere nice and convenient like your desktop, we are going to call ours bench.html (short for workbench). Head over to where you saved your file and it should have a nice chrome icon signifying that it's actually a webpage (thanks to the .html extension we saved it with). If you don't have a chrome icon it's probably because chrome isn't your default browser, but not to worry most operating systems will let you right click on your file and select something like "open with -> chrome" which does the same thing. After opening our file we are greeted with a very anticlimactic blank tab in chrome.

That's it, pat yourself on the back, you just established your own artificial genetics development environment! It might not look like much, but think of this tab as the blank ceiling of the Sistine Chapel waiting for you to paint a masterpiece of evolution and adaptation.

Once you come down from that rush of accomplishment, we are going to get quickly acquainted with some of the developer nooks and crannys hidden away in chrome. Start by right clicking anywhere in that big empty webpage we created, and near the bottom click on 'Inspect element'.

Welcome to the inspector pane, you should be immediately presented with the 'elements' tab which shows the actual HTML markup that is being used to display our webpage. You might be a little confused as we most definitely didn't write that HTML, but chrome could care less - providing us with any of the critical bits we left out. We don't really care about HTML though so forget about the 'elements' tab for now, and let's click on console, that's where all the cool stuff happens.

You should have a little arrow and a big empty white box, this is what we call a REPL in programming land, but more on that later. As a general rule: big empty boxes are usually hungry for code, so that's probably a good place to start. If you click anywhere inside the box you should notice that you can type almost freely. If we try mashing some keys then pressing enter: the line we typed is highlighted blue to show that chrome read it, and we are presented with an error: ReferenceError: asdfasdf is not defined. That's chrome's way of saying "I heard what you said, and it didn't make any fucking sense". Don't be scared off though, we just have to learn the magic words to make chrome do our evil bidding. But first as promised, basic algebra for people who didn't care enough to learn it the first time around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment