Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Loops Are the Hardest

DZone's Guide to

Loops Are the Hardest

A dev who often gives workshops on D3.js to other really talented developers discusses a tendency he's noticed that surprised him.

· Web Dev Zone ·
Free Resource

Bugsnag monitors application stability, so you can make data-driven decisions on whether you should be building new features, or fixing bugs. Learn more.

There is an old truism in software engineering that 199 out of 200 job applicants can't code. Like, forget fizz buzz, can't even write a loop.

I don't know if that's true. Guess I got lucky. And I don't interview that much anyway.

But I do work with a lot of brilliant engineers in my React + D3 workshops. Go into a company, meet with a team who wants to learn some new tech, show them around for a day or two, and create a better team.

It's great.

My workshops involve a lot of coding. Practice makes perfect, and I find that a little struggle really helps the learning process.

You know, code a bit, give them a challenge, let them solve it for a few minutes, show them how it's done. It engages their brain, lets my voice rest a bit, and makes the workshop more interactive.

People love it.

Wanna know what all these brilliant, gainfully employed engineers struggle with the most?

My hardest example is a color swatch. I show them this:

<svg width="600" height="200" id="svg">
</svg>
const Component = React.Component;

// Component that draws a single color swatch
const Swatch = ({ color, width, x, y }) => (
  <rect width={width} height="20" x={x} y={y} style={{fill: color}} />
);

// Draws an entire color scale
class Colors extends Component {
  colors = d3.schemeCategory20;
  width = d3.scaleBand()
            .domain(d3.range(20));

  componentWillMount() {
    this.updateD3(this.props);
  }

  componentWillUpdate(newProps) {
    this.updateD3(newProps);
  }

  updateD3(props) {
    this.width.range([0, props.width]);
  }

  render() {
    return (
      <g>
        {d3.range(20).map(i => (
          <Swatch color={this.colors[i]} width={this.width.step()} x={this.width(i)} y="0" />
        ))}
      </g>
    )
  }
}

// Change width here
ReactDOM.render(<Colors width="300" />, document.getElementById('svg'));

See the Pen d3 color scale by Swizec Telleron CodePen.i0.

It's a row of colorful rectangles that are using D3 to get colors and React to render components in a loop.

The idea is to show workshop participants how React makes code reuse simple, that D3 doesn't have to be scary, and that all the basic JavaScript and programming concepts work great. It's just code, the same kinda code you write all day.

Then I ask them to turn this row into a checkerboard.

<svg width="600" height="600" id="svg">
</svg>
const Component = React.Component;

// Component that draws a single color swatch
const Swatch = ({ color, width, x, y }) => (
  <rect width={width} height="20" x={x} y={y} style={{fill: color}} />
);

// Draws an entire color scale
class ColorRow extends Component {
  colors = d3.schemeCategory20;
  width = d3.scaleBand()
            .domain(d3.range(20));

  componentWillMount() {
    this.updateD3(this.props);
  }

  componentWillUpdate(newProps) {
    this.updateD3(newProps);
  }

  updateD3(props) {
    this.width.range([0, props.width]);
  }

  render() {
    const { y, leftToRight } = this.props;



    return (
      <g>
        {d3.range(20).map(i => {
          const color = leftToRight ? this.colors[i] : this.colors[this.colors.length-1-i];
          return <Swatch color={color} width={this.width.step()} x={this.width(i)} y={y} />
        })}
      </g>
    )
  }
}

class Checkerboard extends Component {
  yScale = d3.scaleBand()
             .domain(d3.range(20));

  componentWillMount() {
    this.updateD3(this.props);
  }

  componentWillUpdate(newProps) {
    this.updateD3(newProps);
  }

  updateD3(props) {
    this.yScale.range([0, props.height]);
  }

  render() {
    const { width } = this.props;

    return (
      <g>
        {d3.range(20).map(i => <ColorRow width={width} y={this.yScale(i)} leftToRight={i % 2 == 0}/>)}
      </g>
    )
  }
}

// Change width here
ReactDOM.render(<Checkerboard width="300" height="300" />, document.getElementById('svg'));

See the Pen d3 color checkerboard by Swizec Teller on CodePen.i0.

And I don't think anyone has ever solved it.

We're not talking beginners here. These are hard-working, smart engineers. The kind of people who grok Redux in an afternoon. Learn React in a few hours. Keep massive engineering infrastructure working smoothly every day. The kind of software projects that would make me crap my pants. They do it every day. It's easy.

Systems, processes, really complex things. All easy. Many have forgotten more about software engineering than I ever knew.

Changing a loop into a nested loop? Impossible.

I mean, the simplest solution to my challenge is changing this:

render() {
    return (
      <g>
        {d3.range(20).map(i => (
          <Swatch color={this.colors[i]} width={this.width.step()} x={this.width(i)} y="0" />
        ))}
      </g>
    )
  }

To this:

render() {
    return (
      <g>
        {d3.range(20).map(j => d3.range(20).map(i => (
          <Swatch color={this.colors[j%2 ? i : this.colors.length-i-1]} width={this.width.step()} x={this.width(i)} y={j*20} />
        )))}
      </g>
    )
  }

Wrap the iteration in another iteration, use that to change the y coordinate. When you're on an even row, take colors from the left, take it from the right on odd rows.

That's all. A nested loop problem.

When we solve it together as a class, I usually create a <Row> component and use that in a loop. Makes nesting easier to see and makes benefits of React more apparent.

Maybe I have to change this example. Maybe loops are hard and I'm just delusional.

Do people get so used to solving huge engineering problems inside massive systems that they forget how to write code?

I know designing systems is super hard and takes a special kind of brain. It's a whole different skill. How do you make this random process talk to that other mostly random process? How do you design your architecture so 50 engineers can work together? 1000 engineers? What about 10,000?

But at the cost of forgetting how loops work?

I'm both stumped and intrigued.

Monitor application stability with Bugsnag to decide if your engineering team should be building new features on your roadmap or fixing bugs to stabilize your application.Try it free.

Topics:
web dev ,javascript loops ,nested loops ,javascript

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}