Commit c01d54f0 authored by Tapio Mäntysalo's avatar Tapio Mäntysalo
Browse files

Task 5 now draws a chart. Some polishing needed.

parent a6b89efa
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
<html lang="en"> <html lang="en">
<head> <head>
<!--Load the Google Charts AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<!-- add mocha css, to show results --> <!-- add mocha css, to show results -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
<!-- add mocha framework code --> <!-- add mocha framework code -->
...@@ -59,10 +62,84 @@ ...@@ -59,10 +62,84 @@
<p>In the final exercise of the course a predator-prey system is modeled using object oriented programming. <p>In the final exercise of the course a predator-prey system is modeled using object oriented programming.
</p> </p>
<hr> <hr>
<table>
<tbody>
<tr>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">Preys</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-x"
aria-label="positive-integer-1" aria-describedby="basic-addon1">
</div>
</td>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon2">Predators</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-y"
aria-label="positive-integer-2" aria-describedby="basic-addon2">
</div>
</td>
<td>
</td>
</tr>
<tr>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">Alpha</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-alpha"
aria-label="positive-integer-1" aria-describedby="basic-addon1">
</div>
</td>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon2">Beta</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-beta"
aria-label="positive-integer-2" aria-describedby="basic-addon2">
</div>
</td>
<td>
</td>
</tr>
<tr>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">Delta</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-delta"
aria-label="positive-integer-1" aria-describedby="basic-addon1">
</div>
</td>
<td>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon2">Gamma</span>
</div>
<input type="number" class="form-control input-task-5" placeholder="" id="input-task-5-gamma"
aria-label="positive-integer-2" aria-describedby="basic-addon2">
</div>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<p> <p>
<button type="button" class="btn btn-primary" id="btn-task-5">Answer</button> <button type="button" class="btn btn-primary" id="btn-task-5">Calculate</button>
</p> </p>
<p id="card-task-5-result"></p> <p id="card-task-5-result"></p>
<!--Div that will hold the pie chart-->
<div id="task-5-chart-area"><div id="task-5-chart-div"></div></div>
</div> </div>
</div> </div>
...@@ -106,12 +183,7 @@ ...@@ -106,12 +183,7 @@
<p class="lead">Loops and functions</p> <p class="lead">Loops and functions</p>
<hr class="my-4"> <hr class="my-4">
<p> Write a function that computes and returns the sum of all integers in the range [lower, upper] that are <p> Write a function that computes and returns the sum of all integers in the range [lower, upper] that are
divisible by d1 or d2 (or both). Lower, upper, d1 and d2 are parameters of the function; you should not divisible by d1 or d2 (or both).
assume that they have any fixed values. Performance does not matter (the problem can be solved without a
loop but it requires a bit more thinking). This exercise is a modified version of the following:
https://projecteuler.net/problem=1.
Note: You can use the remainder operator % (see javascript.info) to check whether a number is divisible
by another number: if n % d == 0, n is divisible by d.
</p> </p>
<hr> <hr>
<div class="alert alert-danger" role="alert" id="alert-task-3"> <div class="alert alert-danger" role="alert" id="alert-task-3">
...@@ -178,8 +250,7 @@ ...@@ -178,8 +250,7 @@
<h1 class="display-4">Task 2</h1> <h1 class="display-4">Task 2</h1>
<p class="lead">Loops</p> <p class="lead">Loops</p>
<hr class="my-4"> <hr class="my-4">
<p> It is a common practice to avoid using decimal numbers as loop counters because rounding errors can have <p> The task here is to simply count the
surprising effects. In this exercise we see one example of that. The task here is to simply count the
sum 0 + 0.1 + 0.2 + … + 0.9. It has been implemented as follows: <br> sum 0 + 0.1 + 0.2 + … + 0.9. It has been implemented as follows: <br>
<font face="courier"> <font face="courier">
&nbsp;let sum = 0; <br> &nbsp;let sum = 0; <br>
...@@ -190,9 +261,7 @@ ...@@ -190,9 +261,7 @@
</font> </font>
The rationale is that after adding 0.1 ten times, the value of the loop counter is 1 and the The rationale is that after adding 0.1 ten times, the value of the loop counter is 1 and the
loop should loop should
end. However, when the program is executed, it appears to never end. Fix the program so that end.
an infinite
loop is avoided and it gives the correct result.
</p> </p>
<hr> <hr>
<p> <p>
...@@ -310,7 +379,7 @@ ...@@ -310,7 +379,7 @@
$("#mocha").text(""); $("#mocha").text("");
mocha.setup('bdd'); // minimal setup mocha.setup('bdd'); // minimal setup
mocha.run(); mocha.run();
$("#dropdown-tests").hide(); $("#dropdown-tests").hide();
break; break;
} }
}); });
......
...@@ -4,7 +4,7 @@ function initTask3() { ...@@ -4,7 +4,7 @@ function initTask3() {
$("#input-task-3-2").val("4"); $("#input-task-3-2").val("4");
$("#alert-task-3").hide(); $("#alert-task-3").hide();
} }
5
// Input validation // Input validation
$(".input-task-3").keyup(function () { $(".input-task-3").keyup(function () {
$("#card-task-3-result").text(""); $("#card-task-3-result").text("");
......
function initTask5() {
const x_default = 1;
const y_default = 1;
const alpha_default = 2 / 3;
const beta_default = 1 / 3;
const delta_default = 1;
const gamma_default = 1;
$("#input-task-5-x").val(x_default);
$("#input-task-5-y").val(y_default);
$("#input-task-5-alpha").val(alpha_default);
$("#input-task-5-beta").val(beta_default);
$("#input-task-5-delta").val(delta_default);
$("#input-task-5-gamma").val(gamma_default);
}
$(".input-task-5").keyup(function () {
$("#task-5-chart-area").hide();
})
$("#btn-task-5").click(function () {
const t0_default = 0;
const delta_t = 0.001;
const simulatedTimeSpan = 20;
let x = +$("#input-task-5-x").val();
let y = +$("#input-task-5-y").val();
let alpha = +$("#input-task-5-alpha").val();
let beta = +$("#input-task-5-beta").val();
let delta = +$("#input-task-5-delta").val();
let gamma = +$("#input-task-5-gamma").val();
drawPredatorPrey(t0_default, x, y, alpha, beta, delta, gamma, delta_t, simulatedTimeSpan);
$("#task-5-chart-area").show();
})
function drawPredatorPrey(t0, x, y, alpha, beta, delta, gamma, delta_t, simulatedTimeSpan) {
google.charts.load('current', { packages: ['corechart', 'line'] });
google.charts.setOnLoadCallback(drawLineColors);
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Preys');
data.addColumn('number', 'Predators');
// Load data series
let predatorPreyObj = new predatorPrey(t0, x, y, alpha, beta, delta, gamma);
let timePoints = predatorPreyObj.getTimeSeries(delta_t, simulatedTimeSpan);
data.addRows(timePoints);
var options = {
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Population'
},
colors: ['#a52714', '#097138']
};
var chart = new google.visualization.LineChart(document.getElementById('task-5-chart-div'));
chart.draw(data, options);
}
}
class predatorPrey { class predatorPrey {
constructor(t0, x, y, alpha, beta, delta, gamma) { constructor(t0, x, y, alpha, beta, delta, gamma) {
this.t0 = t0; this.t0 = t0;
...@@ -11,23 +77,14 @@ class predatorPrey { ...@@ -11,23 +77,14 @@ class predatorPrey {
getTimeSeries(delta_t, until_t) { getTimeSeries(delta_t, until_t) {
let timeSeries = []; let timeSeries = [];
timeSeries.push(new timePoint(this.t0, this.x, this.y)); timeSeries.push([this.t0, this.x, this.y]);
for (let t = this.t0 + delta_t; t <= until_t; t += delta_t) { for (let t = this.t0 + delta_t; t <= until_t; t += delta_t) {
let xNew = this.x + delta_t * (this.alpha * this.x - this.beta * this.x * this.y); let xNew = this.x + delta_t * (this.alpha * this.x - this.beta * this.x * this.y);
let yNew = this.y + delta_t * (this.delta * this.y - this.gamma * this.y); let yNew = this.y + delta_t * (this.delta * this.x * this.y - this.gamma * this.y);
let tp = new timePoint(t, xNew, yNew);
this.x = xNew; this.x = xNew;
this.y = yNew; this.y = yNew;
timeSeries.push(tp); timeSeries.push([t, this.x, this.y]);
} }
return timeSeries; return timeSeries;
} }
} }
class timePoint {
constructor(t, x, y) {
this.t = t;
this.x = x;
this.y = y;
}
}
\ No newline at end of file
describe("Task 5", function () { describe("Task 5", function () {
it("Uses timePoint class and array", function () {
let tp = new timePoint(1, 2, 3); // This is not a very useful test :)
let tpArray = [];
tpArray.push(tp);
assert.equal(tpArray[0].t, 1);
assert.equal(tpArray[0].x, 2);
assert.equal(tpArray[0].y, 3);
});
it("Calculates predator-prey function", function () { it("Calculates predator-prey function", function () {
let pp = new predatorPrey(0, 1, 1, 2/3, 1/3, 1, 1); let pp = new predatorPrey(0, 1, 1, 2/3, 1/3, 1, 1);
let timeSeries = pp.getTimeSeries(0.1, 20); let timeSeries = pp.getTimeSeries(0.1, 20);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment