Skip to content

Commit

Permalink
Merge pull request #518 from nature-of-code/notion-update-docs
Browse files Browse the repository at this point in the history
[Notion] Update docs
  • Loading branch information
shiffman authored Oct 8, 2023
2 parents ead5398 + de4254c commit ab4b134
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 68 deletions.
15 changes: 7 additions & 8 deletions content/05_steering.html
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ <h3 id="example-53-stay-within-walls-steering-behavior">Example 5.3: “Stay Wit
} else if (this.position.y > height - offset) {
desired = createVector(this.velocity.x, -this.maxspeed);
}

// If there is non-null desired velocity, apply steering.
if (desired !== null) {
desired.normalize();
Expand Down Expand Up @@ -834,7 +834,6 @@ <h3 id="path-following-with-multiple-segments">Path Following with Multiple Segm
<figcaption></figcaption>
</figure>
<pre class="codesplit" data-code-language="javascript"> class Path {

constructor() {
this.radius = 20;
//{!1} A path is now an array of points (p5.Vector objects).
Expand All @@ -843,8 +842,8 @@ <h3 id="path-following-with-multiple-segments">Path Following with Multiple Segm

//{!4} This method allows us to add points to the path.
addPoint(x, y) {
let point = createVector(x, y);
this.points.push(point);
let pathPoint = createVector(x, y);
this.points.push(pathPoint);
}

show() {
Expand All @@ -853,17 +852,17 @@ <h3 id="path-following-with-multiple-segments">Path Following with Multiple Segm
strokeWeight(this.radius * 2);
noFill();
beginShape();
for (let i = 0; i &#x3C; this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y);
for (let pathPoint of this.points) {
vertex(pathPoint.x, pathPoint.y);
}
endShape();

//{!7} Draw a thin line for the path center.
stroke(0);
strokeWeight(1);
beginShape();
for (let i = 0; i &#x3C; this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y);
for (let pathPoint of this.points) {
vertex(pathPoint.x, pathPoint.y);
}
endShape();
}
Expand Down
4 changes: 2 additions & 2 deletions content/06_libraries.html
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ <h3 id="example-62-a-comfortable-and-cozy-p5js-sketch-that-needs-a-little-matter
}

//{!3} Display all the Box objects.
for (let i = 0; i &#x3C; boxes.length; i++) {
boxes[i].show();
for (let box of boxes) {
box.show();
}
}</pre>
<p>Right now this sketch draws fixed boxes to the screen. Here’s the challenge: how can I instead draw boxes that experience physics (calculated with Matter.js) as soon as they appear, while changing the code as little as possible?</p>
Expand Down
2 changes: 1 addition & 1 deletion content/07_ca.html
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ <h3 id="programming-an-elementary-ca">Programming an Elementary CA</h3>
}</pre>
<p>I like writing the <code>rules()</code> function this way because it describes line by line exactly what’s happening for each neighborhood configuration. However, it’s not a great solution. After all, what if a CA has four possible states (0 through 3) instead of two? Suddenly there are 64 possible neighborhood configurations. And with 10 possible states, 1,000 configurations. And just imagine programming von Neumann’s 29 possible states. I’d be stuck typing out thousands upon thousands of <code>else if</code> statements!</p>
<p>Another solution, though not quite as transparent, is to convert the neighborhood configuration (a 3-bit number) into a regular integer and use that value as the index into the ruleset array. This can be done as follows, using JavaScript’s built-in <code>parseInt()</code> function:</p>
<pre class="codesplit" data-code-language="javascript"> function rules (a, b, c) {
<pre class="codesplit" data-code-language="javascript"> function rules(a, b, c) {
// A quick way to concatenate three numbers into a string
let s = "" + a + b + c;

Expand Down
2 changes: 1 addition & 1 deletion content/08_fractals.html
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ <h3 id="drawing-the-cantor-set-with-recursion">Drawing the Cantor Set with Recur
<div data-type="example">
<h3 id="example-84-the-cantor-set">Example 8.4: The Cantor Set</h3>
<figure>
<div data-type="embed" data-p5-editor="https://editor.p5js.org/natureofcode/sketches/4OW3OCzz6" data-example-path="examples/08_fractals/8_4_cantor_set"></div>
<div data-type="embed" data-p5-editor="https://editor.p5js.org/natureofcode/sketches/4OW3OCzz6" data-example-path="examples/08_fractals/8_4_cantor_set"><img src="examples/08_fractals/8_4_cantor_set/screenshot.png"></div>
<figcaption></figcaption>
</figure>
</div>
Expand Down
18 changes: 9 additions & 9 deletions content/09_ga.html
Original file line number Diff line number Diff line change
Expand Up @@ -1136,21 +1136,21 @@ <h3 id="managing-the-population">Managing the Population</h3>

// Calculate the fitness for each rocket.
fitness() {
for (let i = 0; i &#x3C; this.population.length; i++) {
this.population[i].calculateFitness();
for (let rocket of this.population) {
rocket.calculateFitness();
}
}

// The selection method normalizes all the fitness values.
selection() {
// Sum all of the fitness values.
let totalFitness = 0;
for (let i = 0; i &#x3C; this.population.length; i++) {
totalFitness += this.population[i].fitness;
for (let rocket of this.population) {
totalFitness += rocket.fitness;
}
// Divide by the total to normalize the fitness values.
for (let i = 0; i &#x3C; this.population.length; i++) {
this.population[i].fitness /= totalFitness;
for (let rocket of this.population) {
rocket.fitness /= totalFitness;
}
}

Expand All @@ -1170,11 +1170,11 @@ <h3 id="managing-the-population">Managing the Population</h3>
this.population = newPopulation;
}</pre>
<p>There’s one more fairly significant change, however. With typing cats, a random phrase was evaluated as soon as it was created. The string of characters had no lifespan; it existed purely for the purpose of calculating its fitness. The rockets, however, need to live for a period of time before they can be evaluated—that is, they need to be given a chance to make their attempt at reaching the target. Therefore, I need to add one more method to the <code>Population</code> class that runs the physics simulation itself. This is identical to what I did in the <code>run()</code> method of a particle system: update all the particle positions and draw them.</p>
<pre class="codesplit" data-code-language="javascript"> live () {
for (let i = 0; i &#x3C; this.population.length; i++) {
<pre class="codesplit" data-code-language="javascript"> live() {
for (let rocket of this.population) {
//{!1} The run method takes care of the simulation, updates the rocket’s
// position, and draws it to the canvas.
this.population[i].run();
rocket.run();
}
}</pre>
<p>Finally, I’m ready for <code>setup()</code> and <code>draw()</code>. Here, my primary responsibility is to implement the steps of the genetic algorithm in the appropriate order by calling the methods from the <code>Population</code> class.</p>
Expand Down
9 changes: 4 additions & 5 deletions content/10_nn.html
Original file line number Diff line number Diff line change
Expand Up @@ -475,16 +475,16 @@ <h3 id="example-101-the-perceptron">Example 10.1: The Perceptron</h3>
count = (count + 1) % training.length;

// Draw all the points and color according to the output of the perceptron
for (let i = 0; i &#x3C; training.length; i++) {
let guess = perceptron.feedforward(training[i]);
for (let dataPoint of training) {
let guess = perceptron.feedforward(dataPoint);
if (guess > 0) {
fill(127);
} else {
fill(255);
}
strokeWeight(1);
stroke(0);
circle(training[i][0], training[i][1], 8);
circle(dataPoint[0], dataPoint[1], 8);
}
}</pre>
<p>In Example 10.1, the training data is visualized alongside the target solution line. Each point represents a piece of training data, and its color is determined by the perceptron's current classification—gray for <span data-type="equation">+1</span> or white for <span data-type="equation">-1</span>. I use a small learning constant (<span data-type="equation">0.0001</span>) to slow down how the system refines its classifications over time.</p>
Expand Down Expand Up @@ -855,8 +855,7 @@ <h3 id="training-the-model">Training the Model</h3>
<p>Now that I have the data in a <code>data</code> variable and a neural network initialized in the <code>classifier</code> variable, I’m ready to train the model. That process starts with adding the data to the model. And for that, it turns out I’m not quite done with preparing the data.</p>
<p>Right now, my data is neatly organized in an array of objects, each containing the <span data-type="equation">x,y</span> components of a vector and a corresponding string label. This is a very typical format for training data, but it isn’t directly consumable by ml5.js. (Sure, I could have initially organized the data into a format that ml5.js recognizes, but I’m including this extra step because it will likely be necessary when you’re using a “real” dataset that has been collected or sourced elsewhere.) To add the data to the model, I need to separate the inputs from the outputs, so the model understands which are which.</p>
<p>The ml5.js library offers a fair amount of flexibility in the kinds of formats it will accept, but I’ll choose to use arrays—one for the <code>inputs</code> and one for the <code>outputs</code>. I can use a loop to reorganize each data item and add it to the model.</p>
<pre class="codesplit" data-code-language="javascript">for (let i = 0; i &#x3C; data.length; i++) {
let item = data[i];
<pre class="codesplit" data-code-language="javascript">for (let item of data) {
// An array of 2 numbers for the inputs
let inputs = [item.x, item.y];
// A single string "label" for the output
Expand Down
6 changes: 3 additions & 3 deletions content/11_nn_ga.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ <h2 id="coding-flappy-bird">Coding Flappy Bird</h2>
// The horizontal speed of the pipe
this.velocity = 2;
}

// Draw the two pipes.
show() {
fill(0);
Expand Down Expand Up @@ -771,8 +771,8 @@ <h3 id="example-115-a-bloop-with-sensors">Example 11.5: A Bloop with Sensors</h3

//{!4} Call the sense() method for each sensor.
sense(food) {
for (let i = 0; i &#x3C; this.sensors.length; i++) {
this.sensors[i].sense(this.position, food);
for (let sensor of this.sensors) {
sensor.sense(this.position, food);
}
}

Expand Down
26 changes: 11 additions & 15 deletions content/examples/05_steering/5_6_path_segments_only/path.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,34 @@
class Path {

constructor() {
this.radius = 20;
//{!1} A Path is now an ArrayList of points (PVector objects).
//{!1} A path is now an array of points (p5.Vector objects).
this.points = [];
}

// This function allows us to add points to the path.
//{!4} This method allows us to add points to the path.
addPoint(x, y) {
let point = createVector(x, y);
this.points.push(point);
let pathPoint = createVector(x, y);
this.points.push(pathPoint);
}

//{!9} Display the path as a series of points.
show() {

// Draw thick line for radius
//{!8} Draw a thicker gray line for the path radius.
stroke(200);
strokeWeight(this.radius * 2);
noFill();
beginShape();
for (let i = 0; i < this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y);
for (let pathPoint of this.points) {
vertex(pathPoint.x, pathPoint.y);
}
endShape();

// Draw thin line for center of path
//{!7} Draw a thin line for the path center.
stroke(0);
strokeWeight(1);
noFill();
beginShape();
for (let i = 0; i < this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y);
for (let pathPoint of this.points) {
vertex(pathPoint.x, pathPoint.y);
}
endShape();
}
}
}
10 changes: 5 additions & 5 deletions content/examples/06_libraries/6_2_boxes_exercise/sketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ function draw() {
let box = new Box(mouseX, mouseY);
boxes.push(box);
}
// Display all the boxes
for (let i = 0; i < boxes.length; i++) {
boxes[i].show();

//{!3} Display all the Box objects.
for (let box of boxes) {
box.show();
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 14 additions & 12 deletions content/examples/09_ga/9_2_smart_rockets_basic/population.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,30 @@ class Population {
}

live() {
// Run every rocket
for (let i = 0; i < this.population.length; i++) {
this.population[i].run();
for (let rocket of this.population) {
//{!1} The run method takes care of the simulation, updates the rocket’s
// position, and draws it to the canvas.
rocket.run();
}
}

// Calculate fitness for each creature
// Calculate the fitness for each rocket.
fitness() {
for (let i = 0; i < this.population.length; i++) {
this.population[i].calculateFitness();
for (let rocket of this.population) {
rocket.calculateFitness();
}
}

// The selection method normalizes all the fitness values.
selection() {
// Sum all of the fitness values
// Sum all of the fitness values.
let totalFitness = 0;
for (let i = 0; i < this.population.length; i++) {
totalFitness += this.population[i].fitness;
for (let rocket of this.population) {
totalFitness += rocket.fitness;
}
// Divide by the total to normalize the fitness values
for (let i = 0; i < this.population.length; i++) {
this.population[i].fitness /= totalFitness;
// Divide by the total to normalize the fitness values.
for (let rocket of this.population) {
rocket.fitness /= totalFitness;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function draw() {
// Re-orient canvas to match traditional Cartesian plane
translate(width / 2, height / 2);
scale(1, -1);

// Draw the line
stroke(0);
strokeWeight(2);
Expand All @@ -48,17 +48,17 @@ function draw() {

//For animation, training one point at a time.
count = (count + 1) % training.length;

// Draw all the points and color according to the output of the perceptron
for (let i = 0; i < training.length; i++) {
let guess = perceptron.feedforward(training[i]);
for (let dataPoint of training) {
let guess = perceptron.feedforward(dataPoint);
if (guess > 0) {
fill(127);
} else {
fill(255);
}
strokeWeight(1);
stroke(0);
circle(training[i][0], training[i][1], 8);
circle(dataPoint[0], dataPoint[1], 8);
}
}
3 changes: 1 addition & 2 deletions content/examples/10_nn/10_2_gesture_classifier/sketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ function setup() {
classifier = ml5.neuralNetwork(options);

// Step 4: add data to the neural network
for (let i = 0; i < data.length; i++) {
let item = data[i];
for (let item of data) {
let inputs = [item.x, item.y];
let outputs = [item.label];
classifier.addData(inputs, outputs);
Expand Down

0 comments on commit ab4b134

Please sign in to comment.