Creativity in Programming

@sarah_edo

For fun and $profit$

 

Sarah Drasner

#CreativeCode

(504) BAYOU-AT

What does it mean to be creative?

Programming is Creative

function fizzBuzz() {
  for (var i = 1; i <= 100; i++) {
    if (i%5 === 0 && i%3 === 0) {
      print('FizzBuzz');
    } else if (i % 3 === 0) {
      print ('Fizz');
    } else if (i % 5 === 0) {
      print ('Buzz');
    } else {
      print (i);
    }
  }
}

vs

for(i=0;i<50;)console.log(++i,i%3?'':'fizz',i%5?'':'buzz')

Important for your business

why?

  1. Hewlett-Packard: invested over $2 billion in R&D in 1999, and generated more than 1,300 patent applications. Net revenue: $42.37 billion. 
  2. Frito-Lay: cost savings over a four-year period of almost $600 million due to creativity training programs
  3. CEOs look creativity over any other quality -survey of more than 1,500 CEOs across 33 industries and 60 countries

Sources: 1. HP 2000 Annual report 2. VanGundy, 2004, 3. IBM Survey

Important for you

Flow

  • Complete immersion in tasks
  • Shares traits with hyperfocus
  • Loss of self-reflective conciousness
  • Subjective experience of time is altered

Happiest points in life

Photos by #WOCinTech

Fighting Burnout

Not just about resting?

Experiencing flow can give a lift to other activities

Using your brain in different ways strengthens it

  • Our neural pathways become set
  • Thinking about varied and new subjects increases plasticity
  • Flow plus varied thinking can cause reduced stress and happiness while programming for other tasks

Push yourself a little each time

*though too much at a time won't work

This demo.

How?

  • Questioning the base premises

  • Impose artificial bounds

  • Repurposing

  • Combining

  • Freedom

  • Use open source as a tool

Questioning the Base Premises

1

  • “Let’s spend more money.”
  • “Why don’t we spend more money, but on fewer vendors? We’ll reduce the number of vendors. We’ll place larger orders to some vendors, and we’ll get better price breaks.”
  • += $1 million dollars a year savings, based upon a one-hour creativity session.

 

Linear Thinking

Lateral Thinking

“We reduce costs by spending less money.”

source: Tanner, Igniting Innovation

Ethernet

Token Ring Networks

Ethernet

React

Questioned:

  • What if we write inline JavaScript?
  • What if we don't use the DOM?
  • What if we create a syntax that replaces our use for HTML?

You don't have x in CSS

  • What if we have variables?
  • What if we have for loops?
  • What if we can use mixins to pass in parameters like functions for DRYer code?

This shaped our specs. 

Impose artificial bounds

2

HSLA

Generative color is easier with HSLA because it's a little more human-readable

background: hsl(($i - 1)*($color / $color-frequency), 80%, 60%);

This demo.

This demo.

function combination() {
  var combo2 = "hsl(+=5%, +=2%, -=10%)";

  tl.to(body, 1, {
      backgroundColor: combo2
    }, "sated");
  tl.to(mult, 2, {
      fill: combo2
    }, "sated");
  ...

  return tl;
}

Artificial Physics

update: function (dt) {
    // friction opposes the direction of velocity
    var acceleration = -Math.sign(this.vx) * friction;
    // distance = velocity * time + 0.5 * acceleration * (time ^ 2)
    this.x += this.vx * dt + 0.5 * acceleration * (dt ^ 2);
   ...
}

Hack Physics and JavaScript by Rachel Smith

The Nature of Code, JS Stroll

This demo.

Recursion

...
if (length < 6) return;
cx.save();
cx.translate(0, length);
cx.rotate(-angle);
branch({length: length*scale, angle: angle, scale:scale});
...

Check a boundary

Or call itself again

This demo.

This demo.

Altering one expected thing

Works for comedy!

I haven’t slept for 10 days…

because that would be too long.

I used to do drugs.

I still do, but I used to, too.

Mitch Hedberg

This demo

Repurposing

3

This pen.

SVG

React

Request Animation Frame

GreenSock

CSS

Web technologies

const HeartMeter = React.createClass({
  render() {
    return (
      <div>
        <svg className="heartmeter" xmlns="http://www.w3.org/2000/svg" width="250" height="50" viewBox="0 0 1741.8 395.6">
          <path d="M1741.8 197.7c0 109.3-89 197.8-198.8 197.8a198.6 198.6 0 0 1-158.5-78.4H11.2A11.2 11.2 0 0 1 0 305.9V89.5a11.2 11.2 0 0 1 11.2-11.1h1373.4A198.8 198.8 0 0 1 1543 0c109.8 0 198.8 88.5 198.8 197.7z" fill="#000"/>
          <path d="M1591.8 127c-18.3 0-34.1 14.8-41.4 30.3-7.3-15.5-23.1-30.3-41.4-30.3a45.7 45.7 0 0 0-45.7 45.5c0 51.1 51.8 64.5 87.1 115.1 33.4-50.2 87.1-65.6 87.1-115.1a45.7 45.7 0 0 0-45.7-45.5z" fill="#b29968"/>
          <rect x="68.2" y="140.8" width={this.props.score} height="101.55" fill="#9391aa"/>
        </svg>
      </div>
    )
  }
});

Request Animation Frame

(function getCoords() {    
  let tCoords = tC1.getBoundingClientRect(),
      txCoords = txC1.getBoundingClientRect(),
      mCoords = mC1.getBoundingClientRect(),
      elCoords = ele1.getBoundingClientRect();

  function intersectRect(a, b) {
    return Math.max(a.left, b.left + 40) < Math.min(a.right, b.right - 40) &&
           Math.max(a.top, b.top + 40) < Math.min(a.bottom, b.bottom - 40);
  }

  // can't do if/else because sometimes they both come out at once
  // and one of them will be ignored
  if (intersectRect(tCoords, elCoords)) {
    getHitTestIncrease();
  } 
  if (intersectRect(txCoords, elCoords)) {
    getHitTestDecrease();
  } 
  if (intersectRect(mCoords, elCoords)) {
    getHitTestMargarita();
  }

  requestAnimationFrame(getCoords);
}());

GSAP for Animation

  _flyBy: function(el, amt, name, delay) {
    if (this.props._isGameOver()) return;
    ...

    TweenMax.fromTo(el, amt, {
      rotation:0, 
      y:randY, 
      x:window.innerWidth + 200
    }, {
      x: -200,
      y:randY,
      rotation: 360,
      delay: delay, 
      onComplete:this._flyBy,
      onCompleteParams:[el, amt, name, delay],
      ease: Power1.easeInOut
    });
  },

History of Generative Art/Music

  • Mozart- Musical Dice Game
  • John Cage - Ambient Noises
  • Max Ernst - Automatism
  • Sol Lewitt- Wall Drawings
//balloon
function balloonGrow(){
  var balloon = $("#balloon")[0];
  var radius = balloon.getAttribute("r");
  var cySet = balloon.getAttribute("cy");
  balloon.setAttribute('r', parseInt(radius) + 10);
  balloon.setAttribute('cy', parseInt(cySet) - 10);
  if (parseInt(radius) > 125) {
    ion.sound.play("balloon-pop3");
    var balloonTl = new TimelineMax();
    balloonTl.add("pop");
    balloonTl.to("#balloon", 0.05, {
      scale: 5,
      opacity: 0,
      transformOrigin: "50% 50%",
      ease: Circ.easeOut
    }, "pop");
    ...
    setTimeout(function(){
      balloon.setAttribute("r", "45");
      balloon.setAttribute("cy", "233.5");
    }, 200);
  }
}

Touch on Mobile

Jake Albaugh

This demo.

This demo.

You already know this :)

Combining

4

Flow

Flow for our users too

Mapping- cognitive leaks

You're on a trip exploring a city

You want to build out the day of activities

Lonely Planet

but...

Google Maps

Let's empower the user

This demo.

DorisLeBot

By Brendan Dawes

Another Combination:

Creatures from Tweets

  • Commissioned by Bright for Twitter France
  • Real-time tweets
  • Created from properties: color from years on twitter, following more than followed had larger antennae
  • Bots are cubes

3d printing

FWA Site of the Day, 16th February 2015

Freedom

5

Umm....

Functional Programming

  • Pure: Avoids changing-state and mutable data
  • Eliminates side effects
  • Expressions or declarations instead of statements

"Object-Oriented Programming makes code understandable by encapsulating moving parts

 

 

-Michael Feather

Functional Programming

makes code understandable by minimizing moving parts"

Imperative

var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
 
// the triangle
context.beginPath();
context.moveTo(100, 100);
context.lineTo(100, 200);
context.lineTo(200, 200);
context.closePath();
 
// the outline
context.lineWidth = 5;
context.strokeStyle = '#747C92';
context.stroke();
 
// the fill color
context.fillStyle = "#A1E8AF";
context.fill();
var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
 
// the triangle
function drawTri(size, amt) {
  var amt = amt * 10;
  context.beginPath();
  context.moveTo(0, 0);
  context.lineTo(0, size*amt);
  context.lineTo(size*amt, size*amt);
  context.closePath();
}

//call it
drawTri(1, 10);
 
// the outline
context.lineWidth = 5;
context.strokeStyle = '#747C92';
context.stroke();
 
// the fill color
context.fillStyle = "#A1E8AF";
context.fill();
var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
 
// the triangle
function drawTri(size, amt) {
  var amt = amt * 10;
  context.beginPath();
  context.moveTo(0, 0);
  context.lineTo(0, size*amt);
  context.lineTo(size*amt, size*amt);
  context.closePath();
}

//call it
drawTri(1, 10);
 
function appearance(stWidth, stColor, fillColor) {
  // the outline
  context.lineWidth = stWidth;
  context.strokeStyle = stColor;
  context.stroke();
	 
  // the fill color
  context.fillStyle = fillColor;
  context.fill();
}

//call it
appearance(5,'#747C92', '#A1E8AF');
var makeSpiral = function(value) {
  if (value > 0) {
    drawTri(value/10, 1);
    appearance(5, '#747C92', 'hsl(' + value/2 + ', ' + (40 + (value/40)) + '%, 77%)');

    return makeSpiral(value - 1);

  } else {
    return value;
  }
};

makeSpiral(1000);

^ES6! ^

Destructured Objects as Parameters

Template Literals

// the triangle
function drawTri(
  { size = 1, 
    amt = 1,
    stWidth = 5, 
    stColor = '#747C92', 
    fillColor = '#A1E8AF'
  } = {}) {
  var amt = amt * 10;
  
  //draw the triangle
  context.beginPath();
  context.moveTo(0, 0);
  ...

  // the outline
  context.lineWidth = stWidth;
  ...
}
function makeSpiral(value) {
  if (value > 0) {
    
  //call the function to draw it
  drawTri({ 
    size: value/10, 
    amt: 1, 
    fillColor: `hsl(${value/2}, ${40 + (value/40)}%, 77%)`
  });
    
  //call makeSpiral again and change it
  return makeSpiral(value - 1);

  } else {
    return value;
  }
};
makeSpiral(1000);

Constraints are good!

Not the wrong ones.

  • Custom Abstractions
  • Ability to use in a multitude of fashions
  • Less brittle
  • Move things around easily without worry

Make use of open source for tools

5

Aframe-React

This repo

This demo

Aframe

class App extends React.Component {
  render () {
    ...
    for (let i = 0; i < 30; i++) {
      ...
      items.push(<Entity geometry="primitive: box; depth: 1.5; height: 1.5; width: 6" 
                    material={{color: updateColor}}
                    position={randoPos}
                    pivot="0 0.5 0"
                    key={i}>
                    <Animation attribute="rotation" 
                               dur="12000" 
                               to={updateRot}/>
                    ...
                 </Entity>);
    }
    return (
      <Scene>
        ...

       {items}
      </Scene>
    );
  }
}

This demo.

function flame() {
  var tl = new TimelineMax();

  tl.add("begin");
  tl.fromTo(blurNode, 2.5, {
    attr: {
      stdDeviation: 9
    }
  }, {
    attr: {
      stdDeviation: 3
    }
  }, "begin");
  var num = 9;
  for (var i = 1; i <= num; i++) {
    tl.to(fStable, 1, {
      morphSVG: {
        shape: "#f" + i
      },
      opacity: ((Math.random() * 0.7) + 0.7),
      ease: Linear.easeNone
    }, "begin+=" + i);
  }
 

More than one way of working

function solve(data) {

  var size = data.length;
  var last = size - 4;    

  var path = "M" + [data[0], data[1]];

  for (var i = 0; i < size - 2; i +=2) {

    var x0 = i ? data[i - 2] : data[0];
    var y0 = i ? data[i - 1] : data[1];

    var x1 = data[i + 0];
    var y1 = data[i + 1];

    var x2 = data[i + 2];
    var y2 = data[i + 3];

    var x3 = i !== last ? data[i + 4] : x2;
    var y3 = i !== last ? data[i + 5] : y2;

    var cp1x = (-x0 + 6 * x1 + x2) / 6;
    var cp1y = (-y0 + 6 * y1 + y2) / 6;

    var cp2x = (x1 + 6 * x2 - x3) / 6;
    var cp2y = (y1 + 6 * y2 - y3) / 6;
   
    path += "C" + [cp1x, cp1y, cp2x, cp2y, x2, y2];
  } 

  return path;
}

Catmull-Rom Spline

Article about history in computer science.

var poly = document.querySelector("polyline");
var path = document.querySelector("path");

var points = [
  100,350,  
  200,100,
  300,350,
  400,150,
  500,350,
  600,200,
  700,350
];

poly.setAttribute("points", points);
path.setAttribute("d", solve(points));
var points = [
  100,350,  
  200,150,
  300,350,
  400,120,
  500,350,
  600,180,
  700,350
];
var points = [
  100,350,  
  200,100,
  300,350,
  400,150,
  500,350,
  600,200,
  700,350
];

This pen.

Social Coding Sites Help You Learn

Fun. Remember fun?

Codepen

JS Fiddle

Dabblet

  • Questioning the base premises

  • Impose artificial bounds

  • Repurposing

  • Combining

  • Freedom

  • Use open source as a tool

Creativity!

🌋

🌋

Impact

with Val Head

🎉

#CreativeCode

(504) BAYOU-AT

1-5

5 is high

Thank you!

@sarah_edo on twitter