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 @@
<html lang="en">
<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 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
<!-- add mocha framework code -->
......@@ -59,10 +62,84 @@
<p>In the final exercise of the course a predator-prey system is modeled using object oriented programming.
</p>
<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>
<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 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>
......@@ -106,12 +183,7 @@
<p class="lead">Loops and functions</p>
<hr class="my-4">
<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
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.
divisible by d1 or d2 (or both).
</p>
<hr>
<div class="alert alert-danger" role="alert" id="alert-task-3">
......@@ -178,8 +250,7 @@
<h1 class="display-4">Task 2</h1>
<p class="lead">Loops</p>
<hr class="my-4">
<p> It is a common practice to avoid using decimal numbers as loop counters because rounding errors can have
surprising effects. In this exercise we see one example of that. The task here is to simply count the
<p> The task here is to simply count the
sum 0 + 0.1 + 0.2 + … + 0.9. It has been implemented as follows: <br>
<font face="courier">
&nbsp;let sum = 0; <br>
......@@ -190,9 +261,7 @@
</font>
The rationale is that after adding 0.1 ten times, the value of the loop counter is 1 and the
loop should
end. However, when the program is executed, it appears to never end. Fix the program so that
an infinite
loop is avoided and it gives the correct result.
end.
</p>
<hr>
<p>
......@@ -310,7 +379,7 @@
$("#mocha").text("");
mocha.setup('bdd'); // minimal setup
mocha.run();
$("#dropdown-tests").hide();
$("#dropdown-tests").hide();
break;
}
});
......
......@@ -4,7 +4,7 @@ function initTask3() {
$("#input-task-3-2").val("4");
$("#alert-task-3").hide();
}
5
// Input validation
$(".input-task-3").keyup(function () {
$("#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 {
constructor(t0, x, y, alpha, beta, delta, gamma) {
this.t0 = t0;
......@@ -11,23 +77,14 @@ class predatorPrey {
getTimeSeries(delta_t, until_t) {
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) {
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 tp = new timePoint(t, xNew, yNew);
let yNew = this.y + delta_t * (this.delta * this.x * this.y - this.gamma * this.y);
this.x = xNew;
this.y = yNew;
timeSeries.push(tp);
timeSeries.push([t, this.x, this.y]);
}
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 () {
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 () {
let pp = new predatorPrey(0, 1, 1, 2/3, 1/3, 1, 1);
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