Compare commits
34 Commits
542510f5d0
...
master
Author | SHA1 | Date | |
---|---|---|---|
4ecaa1a216 | |||
fcef1277f3 | |||
8507082995 | |||
e091a825ce | |||
8501f2f473 | |||
bfdc5dc93b | |||
d81425a781 | |||
62f9f2677d | |||
95918841b0 | |||
419e67f80a | |||
38135762f6 | |||
5c03647a4a | |||
3ee1155e1f | |||
efb36f83fc | |||
d28bd6ed1c | |||
45c5b94e63 | |||
0f1e8d5e36 | |||
57405f5aac | |||
8500f351fc | |||
268e3b6a47 | |||
a50f49d2c8 | |||
fb1a0435c1 | |||
490552f9bd | |||
07b1461635 | |||
d5c907859b | |||
f45f47b572 | |||
4daea2121b | |||
e18f58c0d0 | |||
9a62c4918f | |||
8f668a032f | |||
243b14b247 | |||
869e89188d | |||
ee767d8067 | |||
29d579b8ac |
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -2,4 +2,5 @@
|
||||
* text eol=lf
|
||||
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpg binary
|
||||
*.exe binary
|
10
.gitignore
vendored
10
.gitignore
vendored
@ -1,2 +1,10 @@
|
||||
# Racket related files
|
||||
*.bak
|
||||
.nyc_output
|
||||
|
||||
# Javascript related files
|
||||
.nyc_output
|
||||
|
||||
# Python related files
|
||||
.pytest_cache
|
||||
.coverage
|
||||
__pycache__
|
@ -8,13 +8,16 @@ function match(message, headers) {
|
||||
}
|
||||
|
||||
function body(message) {
|
||||
if (message["body"][0]["content-type"] === "text/plain") {
|
||||
return message["body"][0]["content"];
|
||||
}
|
||||
/* istanbul ignore else */
|
||||
if (message["body"][0]["content-type"] === "multipart/signed") {
|
||||
return message["body"][0]["content"][0]["content"];
|
||||
if (message["body"] !== undefined) {
|
||||
if (message["body"][0]["content-type"] === "text/plain") {
|
||||
return message["body"][0]["content"];
|
||||
}
|
||||
/* istanbul ignore else */
|
||||
if (message["body"][0]["content-type"] === "multipart/signed") {
|
||||
return message["body"][0]["content"][0]["content"];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function string(message) {
|
||||
|
@ -19,7 +19,7 @@ describe("match",
|
||||
expect(message.match(testMsg,{"Subject": "lunch"})).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe("message body",
|
||||
describe("message body",
|
||||
function () {
|
||||
it("unsigned message",
|
||||
function () {
|
||||
@ -51,6 +51,10 @@ ciao,
|
||||
Marco
|
||||
`);
|
||||
});
|
||||
it("no body",
|
||||
function() {
|
||||
expect(message.body(testMsg)).toEqual(undefined)
|
||||
});
|
||||
|
||||
});
|
||||
let fullHeaderMsg ={"headers": {
|
||||
|
178
assignments/A4/life.js
Normal file
178
assignments/A4/life.js
Normal file
@ -0,0 +1,178 @@
|
||||
// ES2015 classes based on https://eloquentjavascript.net/2nd_edition/07_elife.html
|
||||
class Vector {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
plus(other) {
|
||||
return new Vector(this.x + other.x, this.y + other.y);
|
||||
};
|
||||
};
|
||||
|
||||
class Grid {
|
||||
constructor (width, height) {
|
||||
this.space = new Array(width * height);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
};
|
||||
|
||||
isInside(vector) {
|
||||
return vector.x >= 0 && vector.x < this.width &&
|
||||
vector.y >= 0 && vector.y < this.height;
|
||||
};
|
||||
|
||||
get(vector) {
|
||||
return this.space[vector.x + this.width * vector.y];
|
||||
};
|
||||
|
||||
set(vector, value) {
|
||||
this.space[vector.x + this.width * vector.y] = value;
|
||||
};
|
||||
|
||||
forEach(f, context) {
|
||||
for (let y = 0; y < this.height; y++) {
|
||||
for (let x = 0; x < this.width; x++) {
|
||||
let value = this.space[x + y * this.width];
|
||||
if (value != null)
|
||||
f.call(context, value, new Vector(x, y));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let directions = {
|
||||
"n": new Vector( 0, -1),
|
||||
"ne": new Vector( 1, -1),
|
||||
"e": new Vector( 1, 0),
|
||||
"se": new Vector( 1, 1),
|
||||
"s": new Vector( 0, 1),
|
||||
"sw": new Vector(-1, 1),
|
||||
"w": new Vector(-1, 0),
|
||||
"nw": new Vector(-1, -1)
|
||||
};
|
||||
|
||||
function randomElement(array) {
|
||||
return array[Math.floor(Math.random() * array.length)];
|
||||
}
|
||||
|
||||
let directionNames = "n ne e se s sw w nw".split(" ");
|
||||
|
||||
function BouncingCritter() {
|
||||
this.direction = randomElement(directionNames);
|
||||
};
|
||||
|
||||
BouncingCritter.prototype.act = function(view) {
|
||||
if (view.look(this.direction) != " ")
|
||||
this.direction = view.find(" ") || "s";
|
||||
return {type: "move", direction: this.direction};
|
||||
};
|
||||
|
||||
class View {
|
||||
constructor(world, vector) {
|
||||
this.world = world;
|
||||
this.vector = vector;
|
||||
}
|
||||
look(dir) {
|
||||
let target = this.vector.plus(directions[dir]);
|
||||
if (this.world.grid.isInside(target))
|
||||
return charFromElement(this.world.grid.get(target));
|
||||
else
|
||||
return "#";
|
||||
}
|
||||
findAll(ch) {
|
||||
let found = [];
|
||||
for (let dir in directions)
|
||||
if (this.look(dir) == ch)
|
||||
found.push(dir);
|
||||
return found;
|
||||
}
|
||||
|
||||
find(ch) {
|
||||
let found = this.findAll(ch);
|
||||
if (found.length == 0) return null;
|
||||
return randomElement(found);
|
||||
}
|
||||
}
|
||||
|
||||
class World {
|
||||
constructor(map, legend) {
|
||||
let grid = new Grid(map[0].length, map.length);
|
||||
this.grid = grid;
|
||||
this.legend = legend;
|
||||
|
||||
map.forEach(function(line, y) {
|
||||
for (let x = 0; x < line.length; x++)
|
||||
grid.set(new Vector(x, y),
|
||||
World.elementFromChar(legend, line[x]));
|
||||
});
|
||||
}
|
||||
|
||||
static elementFromChar(legend, ch) {
|
||||
if (ch == " ")
|
||||
return null;
|
||||
let element = new legend[ch]();
|
||||
element.originChar = ch;
|
||||
return element;
|
||||
}
|
||||
|
||||
toString() {
|
||||
let output = "";
|
||||
for (let y = 0; y < this.grid.height; y++) {
|
||||
for (let x = 0; x < this.grid.width; x++) {
|
||||
let element = this.grid.get(new Vector(x, y));
|
||||
output += charFromElement(element);
|
||||
}
|
||||
output += "\n";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
turn () {
|
||||
let acted = [];
|
||||
this.grid.forEach(function(critter, vector) {
|
||||
if (critter.act && acted.indexOf(critter) == -1) {
|
||||
acted.push(critter);
|
||||
this.letAct(critter, vector);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
letAct(critter, vector) {
|
||||
let action = critter.act(new View(this, vector));
|
||||
if (action && action.type == "move") {
|
||||
let dest = this.checkDestination(action, vector);
|
||||
if (dest && this.grid.get(dest) == null) {
|
||||
this.grid.set(vector, null);
|
||||
this.grid.set(dest, critter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkDestination(action, vector) {
|
||||
if (directions.hasOwnProperty(action.direction)) {
|
||||
let dest = vector.plus(directions[action.direction]);
|
||||
if (this.grid.isInside(dest))
|
||||
return dest;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function charFromElement(element) {
|
||||
if (element == null)
|
||||
return " ";
|
||||
else
|
||||
return element.originChar;
|
||||
}
|
||||
|
||||
|
||||
function Wall() {};
|
||||
|
||||
exports.BouncingCritter=BouncingCritter;
|
||||
exports.Grid=Grid;
|
||||
exports.Wall=Wall;
|
||||
exports.World=World;
|
||||
exports.Vector=Vector;
|
||||
exports.View=View;
|
122
assignments/A4/moarlife.js
Normal file
122
assignments/A4/moarlife.js
Normal file
@ -0,0 +1,122 @@
|
||||
let life=require("./life.js");
|
||||
|
||||
let View=life.View;
|
||||
|
||||
let actionTypes = Object.create(null);
|
||||
|
||||
actionTypes.grow = function(critter) {
|
||||
critter.energy += 0.5;
|
||||
return true;
|
||||
};
|
||||
|
||||
actionTypes.move = function(critter, vector, action) {
|
||||
let dest = this.checkDestination(action, vector);
|
||||
if (dest == null ||
|
||||
critter.energy <= 1 ||
|
||||
this.grid.get(dest) != null)
|
||||
return false;
|
||||
critter.energy -= 1;
|
||||
this.grid.set(vector, null);
|
||||
this.grid.set(dest, critter);
|
||||
return true;
|
||||
};
|
||||
|
||||
actionTypes.eat = function(critter, vector, action) {
|
||||
let dest = this.checkDestination(action, vector);
|
||||
let atDest = dest != null && this.grid.get(dest);
|
||||
if (!atDest || atDest.energy == null)
|
||||
return false;
|
||||
critter.energy += atDest.energy;
|
||||
this.grid.set(dest, null);
|
||||
return true;
|
||||
};
|
||||
|
||||
actionTypes.reproduce = function(critter, vector, action) {
|
||||
let baby = life.World.elementFromChar(this.legend,
|
||||
critter.originChar);
|
||||
let dest = this.checkDestination(action, vector);
|
||||
if (dest == null ||
|
||||
critter.energy <= 2 * baby.energy ||
|
||||
this.grid.get(dest) != null)
|
||||
return false;
|
||||
critter.energy -= 2 * baby.energy;
|
||||
this.grid.set(dest, baby);
|
||||
return true;
|
||||
};
|
||||
|
||||
actionTypes.die = function(critter, action) {
|
||||
|
||||
}
|
||||
|
||||
class LifelikeWorld extends life.World {
|
||||
constructor(map,legend){
|
||||
super(map,legend);
|
||||
}
|
||||
letAct(critter, vector) {
|
||||
let action = critter.act(new View(this, vector));
|
||||
let handled = action &&
|
||||
action.type in actionTypes &&
|
||||
actionTypes[action.type].call(this, critter,
|
||||
vector, action);
|
||||
if (!handled) {
|
||||
critter.energy -= 0.2;
|
||||
if (critter.energy <= 0)
|
||||
this.grid.set(vector, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class Plant {
|
||||
constructor() {
|
||||
this.energy = 3 + Math.random() * 4;
|
||||
}
|
||||
|
||||
act(view) {
|
||||
if (this.energy > 15) {
|
||||
let space = view.find(" ");
|
||||
if (space)
|
||||
return {type: "reproduce", direction: space};
|
||||
}
|
||||
if (this.energy < 20)
|
||||
return {type: "grow"};
|
||||
};
|
||||
}
|
||||
|
||||
class PlantEater{
|
||||
constructor () {
|
||||
this.energy = 20;
|
||||
}
|
||||
|
||||
act(view) {
|
||||
let space = view.find(" ");
|
||||
if (this.energy > 60 && space)
|
||||
return {type: "reproduce", direction: space};
|
||||
let plant = view.find("*");
|
||||
if (plant)
|
||||
return {type: "eat", direction: plant};
|
||||
if (space)
|
||||
return {type: "move", direction: space};
|
||||
};
|
||||
}
|
||||
|
||||
class ExplodingBunnyRabbit extends PlantEater {
|
||||
constructor () {
|
||||
super()
|
||||
}
|
||||
|
||||
act(view) {
|
||||
super.act(view);
|
||||
if(this.energy > 55) {
|
||||
if (Math.random() < 0.25) {
|
||||
return {type: "die"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.LifelikeWorld=LifelikeWorld;
|
||||
exports.BouncingCritter=life.BouncingCritter;
|
||||
exports.Wall=life.Wall;
|
||||
exports.PlantEater = PlantEater;
|
||||
exports.Plant = Plant;
|
||||
exports.actionTypes = actionTypes;
|
136
assignments/A4/spec/life.spec.js
Normal file
136
assignments/A4/spec/life.spec.js
Normal file
@ -0,0 +1,136 @@
|
||||
let life=require ("../life.js");
|
||||
let plan = ["############################",
|
||||
"# # # o ##",
|
||||
"# #",
|
||||
"# ##### #",
|
||||
"## # # ## #",
|
||||
"### ## # #",
|
||||
"# ### # #",
|
||||
"# #### #",
|
||||
"# ## o #",
|
||||
"# o # o ### #",
|
||||
"# # #",
|
||||
"############################"];
|
||||
|
||||
let Vector = life.Vector;
|
||||
|
||||
describe("Grid",
|
||||
function() {
|
||||
it("initially undefined",
|
||||
function() {
|
||||
let grid = new life.Grid(5, 5);
|
||||
expect(grid.get(new life.Vector(1, 1))).toBe(undefined);
|
||||
});
|
||||
it("setting a value",
|
||||
function() {
|
||||
let grid = new life.Grid(5, 5);
|
||||
grid.set(new Vector(1, 1), "X");
|
||||
expect(grid.get(new Vector(1, 1))).toEqual("X");
|
||||
});
|
||||
it("forEach",
|
||||
function() {
|
||||
let grid = new life.Grid(5, 5);
|
||||
let test = {grid: grid, sum: 0,
|
||||
method: function () {
|
||||
this.grid.forEach(function() { this.sum++; }, this);
|
||||
}
|
||||
};
|
||||
|
||||
test.grid.set(new Vector(2,3), "#");
|
||||
test.grid.set(new Vector(3,4), "#");
|
||||
test.method();
|
||||
expect(test.sum).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("BouncingCritter",
|
||||
function() {
|
||||
let bob = null;
|
||||
beforeEach(function () {
|
||||
spyOn(Math, 'random').and.returnValue(0.5);
|
||||
bob=new life.BouncingCritter();
|
||||
});
|
||||
it("constructor",
|
||||
function() {
|
||||
expect('direction' in bob).toBe(true);
|
||||
expect(bob.direction).toBe('s');
|
||||
});
|
||||
it("act, clear path",
|
||||
function () {
|
||||
let clear = {look: function () {return " ";}};
|
||||
expect(bob.act(clear)).toEqual({type: "move", direction: "s"});
|
||||
});
|
||||
it("act, unclear path",
|
||||
function () {
|
||||
let unclear = {look: function () {return "#";}, find: function () { return "n";}};
|
||||
expect(bob.act(unclear)).toEqual({type: "move", direction: "n"});
|
||||
});
|
||||
});
|
||||
|
||||
describe("World",
|
||||
function () {
|
||||
it("roundtrip",
|
||||
function() {
|
||||
let world = new life.World(plan, {"#": life.Wall, "o": life.BouncingCritter});
|
||||
let rows = world.toString().split("\n");
|
||||
// drop blank row
|
||||
rows.pop();
|
||||
expect(rows).toEqual(plan);
|
||||
});
|
||||
it("turn",
|
||||
function () {
|
||||
let world = new life.World(plan, {"#": life.Wall, "o": life.BouncingCritter});
|
||||
let count=0;
|
||||
spyOn(world, 'letAct').and.callFake(function(critter,vector) {count++;});
|
||||
world.turn();
|
||||
expect(count).toBe(4);
|
||||
});
|
||||
it("checkDestination",
|
||||
function () {
|
||||
let world = new life.World(plan, {"#": life.Wall, "o": life.BouncingCritter});
|
||||
expect(world.checkDestination({direction: 's'},
|
||||
new life.Vector(19,1))).toEqual(new life.Vector(19,2));
|
||||
expect(world.checkDestination({direction: 'n'},
|
||||
new life.Vector(0,0))).toEqual(undefined);
|
||||
});
|
||||
it("letAct",
|
||||
function () {
|
||||
let world = new life.World(plan, {"#": life.Wall, "o": life.BouncingCritter});
|
||||
let src=new life.Vector(19,1);
|
||||
let dest=new life.Vector(19,2);
|
||||
let bob=world.grid.get(src);
|
||||
spyOn(bob,'act').and.returnValue({type: 'move', direction: 's'});
|
||||
world.letAct(bob, src);
|
||||
expect(world.grid.get(dest)).toEqual(bob);
|
||||
});
|
||||
});
|
||||
|
||||
describe("View",
|
||||
function () {
|
||||
let world = new life.World(plan, {"#": life.Wall, "o": life.BouncingCritter});
|
||||
let View=life.View;
|
||||
let position=new Vector(15,9);
|
||||
it("constructor",
|
||||
function () {
|
||||
let view=new View(world, position);
|
||||
expect(view.vector).toEqual(position);
|
||||
});
|
||||
it("look",
|
||||
function () {
|
||||
let view=new View(world, position);
|
||||
expect(view.look("s")).toBe(" ");
|
||||
});
|
||||
it("findAll",
|
||||
function () {
|
||||
let view=new View(world, position);
|
||||
let directionNames = [ 'e', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w' ];
|
||||
expect(view.findAll(" ").sort()).toEqual(directionNames);
|
||||
});
|
||||
it("find",
|
||||
function () {
|
||||
let view=new View(world, position);
|
||||
spyOn(Math, 'random').and.returnValue(0.5);
|
||||
expect(view.find(" ")).toBe('s');
|
||||
});
|
||||
|
||||
});
|
103
assignments/A4/spec/moarlife.spec.js
Normal file
103
assignments/A4/spec/moarlife.spec.js
Normal file
@ -0,0 +1,103 @@
|
||||
let life=require ("../moarlife.js");
|
||||
|
||||
let plan= ["############################",
|
||||
"##### ######",
|
||||
"## *** **##",
|
||||
"# *##** ** O *##",
|
||||
"# *** O ##** *#",
|
||||
"# O ##*** #",
|
||||
"# ##** #",
|
||||
"# O #* #",
|
||||
"#* #** O #",
|
||||
"#*** ##** O **#",
|
||||
"##**** ###*** *###",
|
||||
"############################"];
|
||||
|
||||
|
||||
describe("World",
|
||||
function () {
|
||||
let valley = new life.LifelikeWorld(plan,
|
||||
{"#": life.Wall,
|
||||
"O": life.PlantEater,
|
||||
"*": life.Plant});
|
||||
it("roundtrip",
|
||||
function() {
|
||||
let rows = valley.toString().split("\n");
|
||||
// drop blank row
|
||||
rows.pop();
|
||||
expect(rows).toEqual(plan);
|
||||
});
|
||||
});
|
||||
|
||||
describe("actionTypes",
|
||||
function () {
|
||||
it("grow",
|
||||
function () {
|
||||
let critter = new life.Plant();
|
||||
let energy = critter.energy;
|
||||
life.actionTypes.grow(critter);
|
||||
expect(critter.energy).toBeGreaterThan(energy);
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
describe("PlantEater",
|
||||
function () {
|
||||
it("constructor",
|
||||
function () {
|
||||
let pe = new life.PlantEater();
|
||||
expect('energy' in pe).toBe(true);
|
||||
expect(pe.energy).toBe(20);
|
||||
});
|
||||
it("act, reproduce",
|
||||
function () {
|
||||
let pe = new life.PlantEater();
|
||||
pe.energy = 65
|
||||
expect(pe.act({find: function (ch) { if (ch === " ") return "n"; } })).toEqual({ type: "reproduce", direction: "n" });
|
||||
|
||||
});
|
||||
it("act, eat",
|
||||
function () {
|
||||
let pe = new life.PlantEater();
|
||||
pe.energy = 20
|
||||
expect(pe.act({find: function (ch ) { if (ch === "*") return "n"; } })).toEqual({ type: "eat", direction: "n" });
|
||||
});
|
||||
it("act, move",
|
||||
function () {
|
||||
let pe = new life.PlantEater();
|
||||
expect(pe.act({find: function (ch) { if (ch === " ") return "n"; } })).toEqual({ type: "move", direction: "n" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("ExplodingBunnyRabbit",
|
||||
function () {
|
||||
it("constructor",
|
||||
function () {
|
||||
let pe = new life.ExplodingBunnyRabbit();
|
||||
expect('energy' in pe).toBe(true);
|
||||
expect(pe.energy).toBe(20);
|
||||
});
|
||||
it("act, reproduce",
|
||||
function () {
|
||||
let pe = new life.ExplodingBunnyRabbit();
|
||||
pe.energy = 65
|
||||
expect(pe.act({find: function (ch) { if (ch === " ") return "n"; } })).toEqual({ type: "reproduce", direction: "n" });
|
||||
|
||||
});
|
||||
it("act, eat",
|
||||
function () {
|
||||
let pe = new life.ExplodingBunnyRabbit();
|
||||
pe.energy = 20
|
||||
expect(pe.act({find: function (ch ) { if (ch === "*") return "n"; } })).toEqual({ type: "eat", direction: "n" });
|
||||
});
|
||||
it("act, move",
|
||||
function () {
|
||||
let pe = new life.ExplodingBunnyRabbit();
|
||||
expect(pe.act({find: function (ch) { if (ch === " ") return "n"; } })).toEqual({ type: "move", direction: "n" });
|
||||
});
|
||||
it("act, explode",
|
||||
function () {
|
||||
let pe = new life.ExplodingBunnyRabbit();
|
||||
expect(pe.act({find: function (ch) { if (ch === "O") return "n"; } })).toEqual({ type: "explode", direction: "n" });
|
||||
});
|
||||
});
|
13
assignments/A4/spec/support/jasmine.json
Normal file
13
assignments/A4/spec/support/jasmine.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"**/*[sS]pec.?(m)js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/**/*.?(m)js"
|
||||
],
|
||||
"env": {
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
}
|
28
assignments/A4/valley.js
Normal file
28
assignments/A4/valley.js
Normal file
@ -0,0 +1,28 @@
|
||||
let life=require("./moarlife.js");
|
||||
|
||||
let valley = new life.LifelikeWorld(
|
||||
["############################",
|
||||
"##### ######",
|
||||
"## *** **##",
|
||||
"# *##** ** O *##",
|
||||
"# *** O ##** *#",
|
||||
"# O ##*** #",
|
||||
"# ##** #",
|
||||
"# O #* #",
|
||||
"#* #** O #",
|
||||
"#*** ##** O **#",
|
||||
"##**** ###*** *###",
|
||||
"############################"],
|
||||
{"#": life.Wall,
|
||||
"O": life.PlantEater,
|
||||
"*": life.Plant}
|
||||
);
|
||||
|
||||
function loop () {
|
||||
valley.turn();
|
||||
console.log("\33c");
|
||||
console.log(valley.toString());
|
||||
setTimeout(function() { loop(); },250);
|
||||
}
|
||||
|
||||
loop();
|
8
assignments/A5/.idea/.gitignore
generated
vendored
Normal file
8
assignments/A5/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
8
assignments/A5/.idea/A5.iml
generated
Normal file
8
assignments/A5/.idea/A5.iml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
assignments/A5/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
assignments/A5/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
assignments/A5/.idea/misc.xml
generated
Normal file
4
assignments/A5/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (python-venv)" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
assignments/A5/.idea/modules.xml
generated
Normal file
8
assignments/A5/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/A5.iml" filepath="$PROJECT_DIR$/.idea/A5.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
assignments/A5/.idea/vcs.xml
generated
Normal file
6
assignments/A5/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
1000
assignments/A5/2014-1000.csv
Normal file
1000
assignments/A5/2014-1000.csv
Normal file
File diff suppressed because one or more lines are too long
122
assignments/A5/readcsv.py
Normal file
122
assignments/A5/readcsv.py
Normal file
@ -0,0 +1,122 @@
|
||||
def read_csv(filename):
|
||||
"""Read a CSV file, return list of rows"""
|
||||
|
||||
import csv
|
||||
with open(filename, 'rt', newline='') as f:
|
||||
reader = csv.reader(f, skipinitialspace=True)
|
||||
return [row for row in reader]
|
||||
|
||||
|
||||
def header_map(headers):
|
||||
"""
|
||||
Read a list, and convert it to a dictionary where the key is each element of the given list and the value is
|
||||
its position in the list
|
||||
:param headers: List
|
||||
:return: Dict
|
||||
"""
|
||||
|
||||
header_dict = dict()
|
||||
i = 0
|
||||
for header in headers:
|
||||
header_dict[header] = i
|
||||
i = i + 1
|
||||
return header_dict
|
||||
|
||||
|
||||
def select(table, search_items):
|
||||
"""
|
||||
Read the set in the second argument and search through the table in the first argument and return the
|
||||
columns that match the query in the search items
|
||||
:param table: List
|
||||
:param search_items: List
|
||||
:return: List
|
||||
"""
|
||||
|
||||
header_numbers = header_map(table[0])
|
||||
ret_list = list()
|
||||
columns = list()
|
||||
|
||||
for item in search_items:
|
||||
if type(item) is int: # Convert searched elements into strings if it is a number
|
||||
columns.append(header_numbers[str(item)])
|
||||
else:
|
||||
columns.append(header_numbers[item])
|
||||
columns.sort()
|
||||
for item in table:
|
||||
lst = list()
|
||||
for number in columns:
|
||||
lst.append(item[number])
|
||||
ret_list.append(lst)
|
||||
return ret_list
|
||||
|
||||
|
||||
def row2dict(hmap, row):
|
||||
"""
|
||||
Convert a row in the second argument, given the headers in the first argument to a dictionary which uses the
|
||||
headers as keys and the row data as values
|
||||
:param hmap: Dictionary
|
||||
:param row: List
|
||||
:return: Dictionary
|
||||
"""
|
||||
ret_dict = dict()
|
||||
for key in hmap:
|
||||
ret_dict[key] = row[hmap[key]]
|
||||
return ret_dict
|
||||
|
||||
|
||||
def check_row(row, query):
|
||||
"""
|
||||
Check the row in the first argument passes a query in the second argument. The second argument is a formatted
|
||||
tuple where the first element in the tuple is a column name, the second is an operation (==, <=, >=, AND,
|
||||
OR) and the third element is a condition, numeric or string matching. (ex: is age == 34, is color == blue). AND
|
||||
and OR are special in that you can pass in recursive tuples (left and right argument are tuples) that will also
|
||||
be evaluated recursively
|
||||
:param row: List
|
||||
:param query: Tuple
|
||||
:return: Boolean
|
||||
"""
|
||||
|
||||
def perform_operation(op, var, cond):
|
||||
if type(var) is str:
|
||||
if var.isnumeric():
|
||||
var = int(var)
|
||||
if type(cond) is str:
|
||||
if cond.isnumeric():
|
||||
cond = int(cond)
|
||||
|
||||
if op == '==':
|
||||
return var == cond
|
||||
elif op == '>=':
|
||||
return var >= cond
|
||||
elif op == '<=':
|
||||
return var <= cond
|
||||
elif op == 'OR':
|
||||
return perform_operation(var[1], row[var[0]], var[2]) or perform_operation(cond[1], row[cond[0]], cond[2])
|
||||
elif op == 'AND':
|
||||
return perform_operation(var[1], row[var[0]], var[2]) and perform_operation(cond[1], row[cond[0]], cond[2])
|
||||
else:
|
||||
return False
|
||||
|
||||
if type(query[0]) and type(query[2]) is tuple:
|
||||
return perform_operation(query[1], query[0], query[2])
|
||||
else:
|
||||
stringify = str(query[2])
|
||||
return perform_operation(query[1], row[str(query[0])], stringify)
|
||||
|
||||
|
||||
def filter_table(table, query):
|
||||
"""
|
||||
This function takes a table of csv values, and performs the query to filter out the rows that do not match the query
|
||||
:param table: List
|
||||
:param query: Tuple
|
||||
:return: List
|
||||
"""
|
||||
header_row = header_map(table[0])
|
||||
data_rows = table[1:]
|
||||
result = list()
|
||||
result.append(table[0])
|
||||
for row in data_rows:
|
||||
data_dict = row2dict(header_row, row)
|
||||
if check_row(data_dict, query):
|
||||
result.append(row)
|
||||
return result
|
4
assignments/A5/test1.csv
Normal file
4
assignments/A5/test1.csv
Normal file
@ -0,0 +1,4 @@
|
||||
name, age, eye colour
|
||||
Bob, 5, blue
|
||||
Mary, 27, brown
|
||||
Vij, 54, green
|
|
3
assignments/A5/test2.csv
Normal file
3
assignments/A5/test2.csv
Normal file
@ -0,0 +1,3 @@
|
||||
name, 100
|
||||
teddy, 500
|
||||
lovely, 1000
|
|
114
assignments/A5/test_readcsv.py
Normal file
114
assignments/A5/test_readcsv.py
Normal file
@ -0,0 +1,114 @@
|
||||
from readcsv import read_csv
|
||||
from readcsv import header_map
|
||||
from readcsv import select
|
||||
from readcsv import row2dict
|
||||
from readcsv import check_row
|
||||
from readcsv import filter_table
|
||||
|
||||
table = read_csv('test1.csv')
|
||||
sampledata = read_csv('2014-1000.csv')
|
||||
|
||||
|
||||
def test_read_csv():
|
||||
assert read_csv('test1.csv') == [['name', 'age', 'eye colour'],
|
||||
['Bob', '5', 'blue'],
|
||||
['Mary', '27', 'brown'],
|
||||
['Vij', '54', 'green']]
|
||||
|
||||
|
||||
def test_header_map_1():
|
||||
hmap = header_map(table[0])
|
||||
assert hmap == {'name': 0, 'age': 1, 'eye colour': 2}
|
||||
|
||||
|
||||
def test_select_1():
|
||||
assert select(table, {'name', 'eye colour'}) == [['name', 'eye colour'],
|
||||
['Bob', 'blue'],
|
||||
['Mary', 'brown'],
|
||||
['Vij', 'green']]
|
||||
|
||||
|
||||
def test_row2dict():
|
||||
hmap = header_map(table[0])
|
||||
assert row2dict(hmap, table[1]) == {'name': 'Bob', 'age': '5', 'eye colour': 'blue'}
|
||||
|
||||
|
||||
def test_check_row():
|
||||
row = {'name': 'Bob', 'age': '5', 'eye colour': 'blue'}
|
||||
assert check_row(row, ('age', '==', 5))
|
||||
assert not check_row(row, ('eye colour', '==', 5))
|
||||
assert check_row(row, ('eye colour', '==', 'blue'))
|
||||
assert check_row(row, ('age', '>=', 4))
|
||||
assert check_row(row, ('age', '<=', 1000))
|
||||
|
||||
|
||||
def test_check_row_logical():
|
||||
row = {'name': 'Bob', 'age': '5', 'eye colour': 'blue'}
|
||||
assert check_row(row, (('age', '==', 5), 'OR', ('eye colour', '==', 5)))
|
||||
assert not check_row(row, (('age', '==', 5), 'AND', ('eye colour', '==', 5)))
|
||||
|
||||
|
||||
def test_filter_table1():
|
||||
assert filter_table(table, ('age', '>=', 0)) == [['name', 'age', 'eye colour'],
|
||||
['Bob', '5', 'blue'],
|
||||
['Mary', '27', 'brown'],
|
||||
['Vij', '54', 'green']]
|
||||
|
||||
assert filter_table(table, ('age', '<=', 27)) == [['name', 'age', 'eye colour'],
|
||||
['Bob', '5', 'blue'],
|
||||
['Mary', '27', 'brown']]
|
||||
|
||||
assert filter_table(table, ('eye colour', '==', 'brown')) == [['name', 'age', 'eye colour'],
|
||||
['Mary', '27', 'brown']]
|
||||
|
||||
assert filter_table(table, ('name', '==', 'Vij')) == [['name', 'age', 'eye colour'],
|
||||
['Vij', '54', 'green']]
|
||||
|
||||
|
||||
def test_filter_table2():
|
||||
assert filter_table(table, (('age', '>=', 0), 'AND', ('age', '>=', '27'))) == [['name', 'age', 'eye colour'],
|
||||
['Mary', '27', 'brown'],
|
||||
['Vij', '54', 'green']]
|
||||
|
||||
assert filter_table(table, (('age', '<=', 27), 'AND', ('age', '>=', '27'))) == [['name', 'age', 'eye colour'],
|
||||
['Mary', '27', 'brown']]
|
||||
|
||||
assert filter_table(table, (('eye colour', '==', 'brown'),
|
||||
'OR',
|
||||
('name', '==', 'Vij'))) == [['name', 'age', 'eye colour'],
|
||||
['Mary', '27', 'brown'],
|
||||
['Vij', '54', 'green']]
|
||||
|
||||
|
||||
# Student Tests
|
||||
table2 = read_csv('test2.csv')
|
||||
hmap2 = header_map(table2[0])
|
||||
|
||||
|
||||
def test_header_map2():
|
||||
assert header_map(table2[0]) == {"name": 0, "100": 1}
|
||||
|
||||
|
||||
def test_select2():
|
||||
assert select(table2, [100]) == [["100"], ["500"], ["1000"]]
|
||||
assert select(table2, ["name"]) == [["name"], ["teddy"], ["lovely"]]
|
||||
assert select(table2, ["name", 100]) == [["name", "100"], ["teddy", "500"], ["lovely", "1000"]]
|
||||
|
||||
|
||||
def test_row2dict2():
|
||||
assert row2dict(hmap2, table2[1]) == {"name": "teddy", "100": "500"}
|
||||
assert row2dict(hmap2, table2[2]) == {"name": "lovely", "100": "1000"}
|
||||
|
||||
|
||||
def test_check_row_2():
|
||||
row = {'name': 'Bob', 'age': '5', 'eye colour': 'blue'}
|
||||
assert not check_row(row, ('age', '===', 5))
|
||||
|
||||
|
||||
def test_check_row_3():
|
||||
row = row2dict(hmap2, table2[1])
|
||||
assert check_row(row, ("100", "==", 500))
|
||||
|
||||
|
||||
def test_filter_table3():
|
||||
assert filter_table(table2, ("100", ">=", 100)) == [["name", "100"], ["teddy", "500"], ["lovely", "1000"]]
|
1752
assignments/A5/test_readcsv_bigdata.py
Normal file
1752
assignments/A5/test_readcsv_bigdata.py
Normal file
File diff suppressed because it is too large
Load Diff
32
assignments/A6/classify.m
Normal file
32
assignments/A6/classify.m
Normal file
@ -0,0 +1,32 @@
|
||||
iris = csvread("iris.csv");
|
||||
|
||||
[training, testing] = randomsplit(iris, 2/3)
|
||||
|
||||
p = 2
|
||||
cells = p^(columns(iris)-1)+1
|
||||
|
||||
minmax = ranges(iris);
|
||||
classes = minmax(2,1) - minmax(1,1) + 1;
|
||||
|
||||
votes = zeros(cells,classes);
|
||||
|
||||
for i=1:rows(training)
|
||||
label = training(i,1);
|
||||
hashval = hash(training(i,:), minmax, p);
|
||||
votes(hashval,label) += 1;
|
||||
endfor
|
||||
|
||||
classification = tally(votes)
|
||||
|
||||
correct = 0
|
||||
for i=1:rows(testing);
|
||||
hashval = hash(testing(i,:), minmax, p);
|
||||
class=classification(hashval);
|
||||
label = testing(i,1);
|
||||
if label == class
|
||||
correct += 1;
|
||||
endif
|
||||
endfor
|
||||
|
||||
display(correct/rows(testing))
|
||||
|
151
assignments/A6/iris.csv
Normal file
151
assignments/A6/iris.csv
Normal file
@ -0,0 +1,151 @@
|
||||
1,5.1,3.5,1.4,0.2
|
||||
1,4.9,3.0,1.4,0.2
|
||||
1,4.7,3.2,1.3,0.2
|
||||
1,4.6,3.1,1.5,0.2
|
||||
1,5.0,3.6,1.4,0.2
|
||||
1,5.4,3.9,1.7,0.4
|
||||
1,4.6,3.4,1.4,0.3
|
||||
1,5.0,3.4,1.5,0.2
|
||||
1,4.4,2.9,1.4,0.2
|
||||
1,4.9,3.1,1.5,0.1
|
||||
1,5.4,3.7,1.5,0.2
|
||||
1,4.8,3.4,1.6,0.2
|
||||
1,4.8,3.0,1.4,0.1
|
||||
1,4.3,3.0,1.1,0.1
|
||||
1,5.8,4.0,1.2,0.2
|
||||
1,5.7,4.4,1.5,0.4
|
||||
1,5.4,3.9,1.3,0.4
|
||||
1,5.1,3.5,1.4,0.3
|
||||
1,5.7,3.8,1.7,0.3
|
||||
1,5.1,3.8,1.5,0.3
|
||||
1,5.4,3.4,1.7,0.2
|
||||
1,5.1,3.7,1.5,0.4
|
||||
1,4.6,3.6,1.0,0.2
|
||||
1,5.1,3.3,1.7,0.5
|
||||
1,4.8,3.4,1.9,0.2
|
||||
1,5.0,3.0,1.6,0.2
|
||||
1,5.0,3.4,1.6,0.4
|
||||
1,5.2,3.5,1.5,0.2
|
||||
1,5.2,3.4,1.4,0.2
|
||||
1,4.7,3.2,1.6,0.2
|
||||
1,4.8,3.1,1.6,0.2
|
||||
1,5.4,3.4,1.5,0.4
|
||||
1,5.2,4.1,1.5,0.1
|
||||
1,5.5,4.2,1.4,0.2
|
||||
1,4.9,3.1,1.5,0.1
|
||||
1,5.0,3.2,1.2,0.2
|
||||
1,5.5,3.5,1.3,0.2
|
||||
1,4.9,3.1,1.5,0.1
|
||||
1,4.4,3.0,1.3,0.2
|
||||
1,5.1,3.4,1.5,0.2
|
||||
1,5.0,3.5,1.3,0.3
|
||||
1,4.5,2.3,1.3,0.3
|
||||
1,4.4,3.2,1.3,0.2
|
||||
1,5.0,3.5,1.6,0.6
|
||||
1,5.1,3.8,1.9,0.4
|
||||
1,4.8,3.0,1.4,0.3
|
||||
1,5.1,3.8,1.6,0.2
|
||||
1,4.6,3.2,1.4,0.2
|
||||
1,5.3,3.7,1.5,0.2
|
||||
1,5.0,3.3,1.4,0.2
|
||||
2,7.0,3.2,4.7,1.4
|
||||
2,6.4,3.2,4.5,1.5
|
||||
2,6.9,3.1,4.9,1.5
|
||||
2,5.5,2.3,4.0,1.3
|
||||
2,6.5,2.8,4.6,1.5
|
||||
2,5.7,2.8,4.5,1.3
|
||||
2,6.3,3.3,4.7,1.6
|
||||
2,4.9,2.4,3.3,1.0
|
||||
2,6.6,2.9,4.6,1.3
|
||||
2,5.2,2.7,3.9,1.4
|
||||
2,5.0,2.0,3.5,1.0
|
||||
2,5.9,3.0,4.2,1.5
|
||||
2,6.0,2.2,4.0,1.0
|
||||
2,6.1,2.9,4.7,1.4
|
||||
2,5.6,2.9,3.6,1.3
|
||||
2,6.7,3.1,4.4,1.4
|
||||
2,5.6,3.0,4.5,1.5
|
||||
2,5.8,2.7,4.1,1.0
|
||||
2,6.2,2.2,4.5,1.5
|
||||
2,5.6,2.5,3.9,1.1
|
||||
2,5.9,3.2,4.8,1.8
|
||||
2,6.1,2.8,4.0,1.3
|
||||
2,6.3,2.5,4.9,1.5
|
||||
2,6.1,2.8,4.7,1.2
|
||||
2,6.4,2.9,4.3,1.3
|
||||
2,6.6,3.0,4.4,1.4
|
||||
2,6.8,2.8,4.8,1.4
|
||||
2,6.7,3.0,5.0,1.7
|
||||
2,6.0,2.9,4.5,1.5
|
||||
2,5.7,2.6,3.5,1.0
|
||||
2,5.5,2.4,3.8,1.1
|
||||
2,5.5,2.4,3.7,1.0
|
||||
2,5.8,2.7,3.9,1.2
|
||||
2,6.0,2.7,5.1,1.6
|
||||
2,5.4,3.0,4.5,1.5
|
||||
2,6.0,3.4,4.5,1.6
|
||||
2,6.7,3.1,4.7,1.5
|
||||
2,6.3,2.3,4.4,1.3
|
||||
2,5.6,3.0,4.1,1.3
|
||||
2,5.5,2.5,4.0,1.3
|
||||
2,5.5,2.6,4.4,1.2
|
||||
2,6.1,3.0,4.6,1.4
|
||||
2,5.8,2.6,4.0,1.2
|
||||
2,5.0,2.3,3.3,1.0
|
||||
2,5.6,2.7,4.2,1.3
|
||||
2,5.7,3.0,4.2,1.2
|
||||
2,5.7,2.9,4.2,1.3
|
||||
2,6.2,2.9,4.3,1.3
|
||||
2,5.1,2.5,3.0,1.1
|
||||
2,5.7,2.8,4.1,1.3
|
||||
3,6.3,3.3,6.0,2.5
|
||||
3,5.8,2.7,5.1,1.9
|
||||
3,7.1,3.0,5.9,2.1
|
||||
3,6.3,2.9,5.6,1.8
|
||||
3,6.5,3.0,5.8,2.2
|
||||
3,7.6,3.0,6.6,2.1
|
||||
3,4.9,2.5,4.5,1.7
|
||||
3,7.3,2.9,6.3,1.8
|
||||
3,6.7,2.5,5.8,1.8
|
||||
3,7.2,3.6,6.1,2.5
|
||||
3,6.5,3.2,5.1,2.0
|
||||
3,6.4,2.7,5.3,1.9
|
||||
3,6.8,3.0,5.5,2.1
|
||||
3,5.7,2.5,5.0,2.0
|
||||
3,5.8,2.8,5.1,2.4
|
||||
3,6.4,3.2,5.3,2.3
|
||||
3,6.5,3.0,5.5,1.8
|
||||
3,7.7,3.8,6.7,2.2
|
||||
3,7.7,2.6,6.9,2.3
|
||||
3,6.0,2.2,5.0,1.5
|
||||
3,6.9,3.2,5.7,2.3
|
||||
3,5.6,2.8,4.9,2.0
|
||||
3,7.7,2.8,6.7,2.0
|
||||
3,6.3,2.7,4.9,1.8
|
||||
3,6.7,3.3,5.7,2.1
|
||||
3,7.2,3.2,6.0,1.8
|
||||
3,6.2,2.8,4.8,1.8
|
||||
3,6.1,3.0,4.9,1.8
|
||||
3,6.4,2.8,5.6,2.1
|
||||
3,7.2,3.0,5.8,1.6
|
||||
3,7.4,2.8,6.1,1.9
|
||||
3,7.9,3.8,6.4,2.0
|
||||
3,6.4,2.8,5.6,2.2
|
||||
3,6.3,2.8,5.1,1.5
|
||||
3,6.1,2.6,5.6,1.4
|
||||
3,7.7,3.0,6.1,2.3
|
||||
3,6.3,3.4,5.6,2.4
|
||||
3,6.4,3.1,5.5,1.8
|
||||
3,6.0,3.0,4.8,1.8
|
||||
3,6.9,3.1,5.4,2.1
|
||||
3,6.7,3.1,5.6,2.4
|
||||
3,6.9,3.1,5.1,2.3
|
||||
3,5.8,2.7,5.1,1.9
|
||||
3,6.8,3.2,5.9,2.3
|
||||
3,6.7,3.3,5.7,2.5
|
||||
3,6.7,3.0,5.2,2.3
|
||||
3,6.3,2.5,5.0,1.9
|
||||
3,6.5,3.0,5.2,2.0
|
||||
3,6.2,3.4,5.4,2.3
|
||||
3,5.9,3.0,5.1,1.8
|
||||
|
|
1
assignments/A6/workspace.octave-workspace
Normal file
1
assignments/A6/workspace.octave-workspace
Normal file
@ -0,0 +1 @@
|
||||
# Created by Octave 7.3.0, Wed Dec 07 23:43:44 2022 GMT <unknown@Isaac-DesktopPC>
|
9
journal/_src/posts/2022-10-19-lab-11.md
Normal file
9
journal/_src/posts/2022-10-19-lab-11.md
Normal file
@ -0,0 +1,9 @@
|
||||
Title: Lab Eleven
|
||||
Date: 2022-10-19T08:30:00
|
||||
Tags: cs2613, lab, javascript
|
||||
|
||||
Sample description
|
||||
<!-- more -->
|
||||
|
||||
## Sample Body
|
||||
Sample Body
|
9
journal/_src/posts/2022-10-24-lab-12.md
Normal file
9
journal/_src/posts/2022-10-24-lab-12.md
Normal file
@ -0,0 +1,9 @@
|
||||
Title: Lab Twelve
|
||||
Date: 2022-10-24T08:30:00
|
||||
Tags: cs2613, lab, javascript
|
||||
|
||||
Sample description
|
||||
<!-- more -->
|
||||
|
||||
## Sample Body
|
||||
Sample Body
|
9
journal/_src/posts/2022-10-26-lab-13.md
Normal file
9
journal/_src/posts/2022-10-26-lab-13.md
Normal file
@ -0,0 +1,9 @@
|
||||
Title: Lab Thirteen
|
||||
Date: 2022-10-26T08:30:00
|
||||
Tags: cs2613, lab, javascript
|
||||
|
||||
Sample description
|
||||
<!-- more -->
|
||||
|
||||
## Sample Body
|
||||
Sample Body
|
21
journal/_src/posts/2022-10-31-lab-14.md
Normal file
21
journal/_src/posts/2022-10-31-lab-14.md
Normal file
@ -0,0 +1,21 @@
|
||||
Title: Lab Fourteen
|
||||
Date: 2022-10-31T08:30:00
|
||||
Tags: cs2613, lab, python, pytest, exceptions, modules
|
||||
|
||||
In this lab I learned about python, pytest, python exceptions and modules.
|
||||
<!-- more -->
|
||||
|
||||
## Pytest
|
||||
Pytest is a python testing framework. It can show you code coverage with line counts. This is pretty similar to `nyc` from javascript. You run tests by just running `pytest` or `pytest -cov` for code coverage. Tests are defined by in a file having a function with an assert statement. Pytest will then scan your files for assert statements and run those functions to run tests. Testing in python is pretty simple, like with javascript. Racket testing is a little more abstract and confusing in my opinion.
|
||||
|
||||
## Modules
|
||||
In python functions are exported by default, in contrast to javascript. You must guard your main method with the `if __name__ =='__main__'` text so it does not run when the module is imported. You can make tests to ensure you have documentation for your functions, by checking for the imports `__doc__` variable.
|
||||
|
||||
## Indentation
|
||||
In python, blocks are defined by indentation (also known as whitespace). This sets the scope for a given statement. It can be a little confusing to tell if an if statement is in a for loop or not, but linters help.
|
||||
|
||||
## Exceptions
|
||||
Python can raise errors when things go wrong, for example diving by zero. You can catch these exceptions and handle them if you desire.
|
||||
|
||||
## FizzBuzz missing case
|
||||
You can fix the missing case just by adding another if statement above the other if statement for the fizz case.
|
0
labs/L11/deep-equal.js
Normal file
0
labs/L11/deep-equal.js
Normal file
16
labs/L11/spec/deep-equal.spec.js
Normal file
16
labs/L11/spec/deep-equal.spec.js
Normal file
@ -0,0 +1,16 @@
|
||||
describe("equal", function () {
|
||||
let obj = {here: {is: "an"}, object: 2};
|
||||
it("self", function () {
|
||||
expect(deepEqual(obj,obj)).toBe(true);
|
||||
});
|
||||
it("null", function () {
|
||||
expect(deepEqual(null,null)).toBe(true);
|
||||
});
|
||||
|
||||
it("different", function () {
|
||||
expect(deepEqual(obj, {here: 1, object: 2})).toBe(false);
|
||||
});
|
||||
it("equivalent", function () {
|
||||
expect(deepEqual(obj, {here: {is: "an"}, object: 2})).toBe(true);
|
||||
});
|
||||
});
|
13
labs/L11/spec/support/jasmine.json
Normal file
13
labs/L11/spec/support/jasmine.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"**/*[sS]pec.?(m)js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/**/*.?(m)js"
|
||||
],
|
||||
"env": {
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
}
|
0
labs/L11/spec/village.spec.js
Normal file
0
labs/L11/spec/village.spec.js
Normal file
59
labs/L11/village.js
Normal file
59
labs/L11/village.js
Normal file
@ -0,0 +1,59 @@
|
||||
const roads = [
|
||||
"Alice's House-Bob's House", "Alice's House-Cabin",
|
||||
"Alice's House-Post Office", "Bob's House-Town Hall",
|
||||
"Daria's House-Ernie's House", "Daria's House-Town Hall",
|
||||
"Ernie's House-Grete's House", "Grete's House-Farm",
|
||||
"Grete's House-Shop", "Marketplace-Farm",
|
||||
"Marketplace-Post Office", "Marketplace-Shop",
|
||||
"Marketplace-Town Hall", "Shop-Town Hall"
|
||||
];
|
||||
|
||||
function buildGraph(edges) {
|
||||
let graph = Object.create(null);
|
||||
function addEdge(from, to) {
|
||||
if (graph[from] == null) {
|
||||
graph[from] = [to];
|
||||
} else {
|
||||
graph[from].push(to);
|
||||
}
|
||||
}
|
||||
for (let [from, to] of edges.map(r => r.split("-"))) {
|
||||
addEdge(from, to);
|
||||
addEdge(to, from);
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
const roadGraph = buildGraph(roads);
|
||||
|
||||
class VillageState {
|
||||
constructor(place, parcels) {
|
||||
this.place = place;
|
||||
this.parcels = parcels;
|
||||
}
|
||||
|
||||
move(destination) {
|
||||
if (!roadGraph[this.place].includes(destination)) {
|
||||
return this;
|
||||
} else {
|
||||
let parcels = this.parcels.map(p => {
|
||||
if (p.place != this.place) return p;
|
||||
return { place: destination, address: p.address };
|
||||
}).filter(p => p.place != p.address);
|
||||
return new VillageState(destination, parcels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let first = new VillageState(
|
||||
"Post Office",
|
||||
[{ place: "Post Office", address: "Alice's House" }]
|
||||
);
|
||||
let next = first.move("Alice's House");
|
||||
|
||||
console.log(next.place);
|
||||
// → Alice's House
|
||||
console.log(next.parcels);
|
||||
// → []
|
||||
console.log(first.place);
|
||||
// → Post Office
|
13
labs/L12/spec/support/jasmine.json
Normal file
13
labs/L12/spec/support/jasmine.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"**/*[sS]pec.?(m)js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/**/*.?(m)js"
|
||||
],
|
||||
"env": {
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
}
|
28
labs/L12/spec/village.spec.js
Normal file
28
labs/L12/spec/village.spec.js
Normal file
@ -0,0 +1,28 @@
|
||||
let village = require("../village.js");
|
||||
let VillageState = village.VillageState;
|
||||
describe("roadGraph",
|
||||
function () {
|
||||
let roadGraph = village.roadGraph;
|
||||
it("Alice's house",
|
||||
() => expect(roadGraph["Alice's House"]).toEqual(["Bob's House", "Cabin", "Post Office"]));
|
||||
it("Bob's house",
|
||||
() => expect(roadGraph["Bob's House"]).toEqual(
|
||||
jasmine.objectContaining(["Alice's House"])));
|
||||
});
|
||||
|
||||
|
||||
describe("VillageState",
|
||||
function () {
|
||||
let first = new VillageState(
|
||||
"Post Office",
|
||||
[{ place: "Post Office", address: "Alice's House" }]
|
||||
);
|
||||
let next = first.move("Alice's House");
|
||||
it("next place",
|
||||
() => expect(next.place).toBe("Alice's House"));
|
||||
it("next parcels",
|
||||
() => expect(next.parcels).toEqual([]));
|
||||
it("first place",
|
||||
() => expect(first.place).toEqual("Post Office"));
|
||||
}
|
||||
);
|
48
labs/L12/village.js
Normal file
48
labs/L12/village.js
Normal file
@ -0,0 +1,48 @@
|
||||
const roads = [
|
||||
"Alice's House-Bob's House", "Alice's House-Cabin",
|
||||
"Alice's House-Post Office", "Bob's House-Town Hall",
|
||||
"Daria's House-Ernie's House", "Daria's House-Town Hall",
|
||||
"Ernie's House-Grete's House", "Grete's House-Farm",
|
||||
"Grete's House-Shop", "Marketplace-Farm",
|
||||
"Marketplace-Post Office", "Marketplace-Shop",
|
||||
"Marketplace-Town Hall", "Shop-Town Hall"
|
||||
];
|
||||
function buildGraph(edges) {
|
||||
let graph = Object.create(null);
|
||||
function addEdge(from, to) {
|
||||
if (graph[from] == null) {
|
||||
graph[from] = [to];
|
||||
} else {
|
||||
graph[from].push(to);
|
||||
}
|
||||
}
|
||||
for (let [from, to] of edges.map(r => r.split("-"))) {
|
||||
addEdge(from, to);
|
||||
addEdge(to, from);
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
const roadGraph = buildGraph(roads);
|
||||
|
||||
class VillageState {
|
||||
constructor(place, parcels) {
|
||||
this.place = place;
|
||||
this.parcels = parcels;
|
||||
}
|
||||
|
||||
move(destination) {
|
||||
if (!roadGraph[this.place].includes(destination)) {
|
||||
return this;
|
||||
} else {
|
||||
let parcels = this.parcels.map(p => {
|
||||
if (p.place != this.place) return p;
|
||||
return { place: destination, address: p.address };
|
||||
}).filter(p => p.place != p.address);
|
||||
return new VillageState(destination, parcels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.roadGraph = roadGraph;
|
||||
exports.VillageState = VillageState;
|
39
labs/L13/animation.js
Normal file
39
labs/L13/animation.js
Normal file
@ -0,0 +1,39 @@
|
||||
// let str="";
|
||||
// for (let i=0; i<60; i++) {
|
||||
// console.log('\033c');
|
||||
// str+= "*";
|
||||
// console.log(str);
|
||||
// }
|
||||
|
||||
//console.log("all done!");
|
||||
|
||||
// function loop(i,str) {
|
||||
// if (i>0) {
|
||||
// console.log("\033c");
|
||||
// console.log(str);
|
||||
// setTimeout(function() { loop(i-1, str+"*"); }, 1000);
|
||||
// }
|
||||
// }
|
||||
|
||||
// loop(20,"*");
|
||||
|
||||
// console.log("all done!");
|
||||
|
||||
function animate(iterations) {
|
||||
let i=0;
|
||||
let str="*";
|
||||
let timer = null;
|
||||
function frame() {
|
||||
|
||||
console.log('\033c');
|
||||
console.log(str);
|
||||
if (i>=iterations) {
|
||||
clearInterval(timer);
|
||||
console.log("all done!");
|
||||
}
|
||||
|
||||
}
|
||||
timer=setInterval(frame,300);
|
||||
}
|
||||
|
||||
animate(20);
|
8
labs/L14/.idea/.gitignore
generated
vendored
Normal file
8
labs/L14/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
10
labs/L14/.idea/L14.iml
generated
Normal file
10
labs/L14/.idea/L14.iml
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (python-venv)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
12
labs/L14/.idea/dataSources.xml
generated
Normal file
12
labs/L14/.idea/dataSources.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name=".coverage" uuid="af2f1fdd-3241-4470-93b5-53f58bcdd0d2">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:C:\Users\Isaac\OneDrive - University of New Brunswick\Year 3 UNB\CS2613\Git\cs2613-ishoebot\labs\L14\.coverage</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
6
labs/L14/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
labs/L14/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
labs/L14/.idea/misc.xml
generated
Normal file
4
labs/L14/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (python-venv)" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
labs/L14/.idea/modules.xml
generated
Normal file
8
labs/L14/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/L14.iml" filepath="$PROJECT_DIR$/.idea/L14.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
24
labs/L14/.idea/runConfigurations/client.xml
generated
Normal file
24
labs/L14/.idea/runConfigurations/client.xml
generated
Normal file
@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="client" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||
<module name="L14" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/client.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
24
labs/L14/.idea/runConfigurations/fizzbuzz.xml
generated
Normal file
24
labs/L14/.idea/runConfigurations/fizzbuzz.xml
generated
Normal file
@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="fizzbuzz" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||
<module name="L14" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/fizzbuzz.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
24
labs/L14/.idea/runConfigurations/humansize.xml
generated
Normal file
24
labs/L14/.idea/runConfigurations/humansize.xml
generated
Normal file
@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="humansize" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||
<module name="L14" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/humansize.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
17
labs/L14/.idea/runConfigurations/pytest.xml
generated
Normal file
17
labs/L14/.idea/runConfigurations/pytest.xml
generated
Normal file
@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="pytest" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="pytest --cov --cov-report=term-missing" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
6
labs/L14/.idea/vcs.xml
generated
Normal file
6
labs/L14/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
16
labs/L14/client.py
Normal file
16
labs/L14/client.py
Normal file
@ -0,0 +1,16 @@
|
||||
import humansize
|
||||
|
||||
|
||||
def approximate_size(size):
|
||||
"""Returns the size of a file in a human-readable format where kilobytes are 1000 bytes
|
||||
|
||||
:param size: the size of a file
|
||||
:return: string
|
||||
"""
|
||||
return humansize.approximate_size(size, False)
|
||||
|
||||
|
||||
if __name__ == '__main__': # pragma: no cover
|
||||
print(approximate_size(1_000))
|
||||
print(approximate_size(100_000_000))
|
||||
print(approximate_size(1_000_000_000))
|
8
labs/L14/divisive.py
Normal file
8
labs/L14/divisive.py
Normal file
@ -0,0 +1,8 @@
|
||||
import math
|
||||
|
||||
|
||||
def fraction(a, b):
|
||||
try:
|
||||
return a / b
|
||||
except ZeroDivisionError:
|
||||
return math.nan
|
10
labs/L14/fizzbuzz.py
Normal file
10
labs/L14/fizzbuzz.py
Normal file
@ -0,0 +1,10 @@
|
||||
if __name__ == '__main__':
|
||||
for i in range(1, 101):
|
||||
if i % 3 == 0 and i % 5 == 0:
|
||||
print("FizzBuzz")
|
||||
elif i % 3 == 0:
|
||||
print("Fizz")
|
||||
elif i % 5 == 0:
|
||||
print("Buzz")
|
||||
else:
|
||||
print(i)
|
67
labs/L14/humansize.py
Normal file
67
labs/L14/humansize.py
Normal file
@ -0,0 +1,67 @@
|
||||
"""Convert file sizes to human-readable form.
|
||||
|
||||
Available functions:
|
||||
approximate_size(size, a_kilobyte_is_1024_bytes)
|
||||
takes a file size and returns a human-readable string
|
||||
|
||||
Examples:
|
||||
>>> approximate_size(1024)
|
||||
'1.0 KiB'
|
||||
>>> approximate_size(1000, False)
|
||||
'1.0 KB'
|
||||
|
||||
"""
|
||||
|
||||
SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
|
||||
|
||||
|
||||
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
|
||||
"""Convert a file size to human-readable form.
|
||||
|
||||
Keyword arguments:
|
||||
size -- file size in bytes
|
||||
a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024
|
||||
if False, use multiples of 1000
|
||||
|
||||
Returns: string
|
||||
|
||||
"""
|
||||
if size < 0:
|
||||
raise ValueError('number must be non-negative')
|
||||
|
||||
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
|
||||
for suffix in SUFFIXES[multiple]:
|
||||
size /= multiple
|
||||
if size < multiple:
|
||||
return '{0:.1f} {1}'.format(size, suffix)
|
||||
|
||||
raise ValueError('number too large')
|
||||
|
||||
|
||||
if __name__ == '__main__': # pragma: no cover
|
||||
print(approximate_size(1000000000000, False))
|
||||
print(approximate_size(1000000000000))
|
||||
|
||||
# Copyright (c) 2009, Mark Pilgrim, All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
18
labs/L14/test_client.py
Normal file
18
labs/L14/test_client.py
Normal file
@ -0,0 +1,18 @@
|
||||
import pytest
|
||||
from client import approximate_size
|
||||
|
||||
|
||||
def test_1kb():
|
||||
assert approximate_size(1_000) == "1.0 KB"
|
||||
|
||||
|
||||
def test_100mb():
|
||||
assert approximate_size(100_000_000) == "100.0 MB"
|
||||
|
||||
|
||||
def test_1gb():
|
||||
assert approximate_size(1_000_000_000) == "1.0 GB"
|
||||
|
||||
|
||||
def test_docstring():
|
||||
assert approximate_size.__doc__ is not None
|
10
labs/L14/test_divisive.py
Normal file
10
labs/L14/test_divisive.py
Normal file
@ -0,0 +1,10 @@
|
||||
from divisive import fraction
|
||||
import math
|
||||
|
||||
|
||||
def test_fraction_int():
|
||||
assert fraction(4, 2) == 2
|
||||
|
||||
|
||||
def test_fraction_NaN():
|
||||
assert math.isnan(fraction(4, 0))
|
20
labs/L14/test_humansize.py
Normal file
20
labs/L14/test_humansize.py
Normal file
@ -0,0 +1,20 @@
|
||||
import pytest
|
||||
from humansize import approximate_size
|
||||
|
||||
|
||||
def test_1000():
|
||||
assert approximate_size(1000000000000, False) == "1.0 TB"
|
||||
|
||||
|
||||
def test_1024():
|
||||
assert approximate_size(1000000000000) == "931.3 GiB"
|
||||
|
||||
|
||||
def test_negative():
|
||||
with pytest.raises(ValueError):
|
||||
approximate_size(-1)
|
||||
|
||||
|
||||
def test_huge_number():
|
||||
with pytest.raises(ValueError):
|
||||
approximate_size(1_000_000_000_000_000_000_000_000_000_000)
|
8
labs/L15/.idea/.gitignore
generated
vendored
Normal file
8
labs/L15/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
8
labs/L15/.idea/L15.iml
generated
Normal file
8
labs/L15/.idea/L15.iml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (python-venv)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
labs/L15/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
labs/L15/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
labs/L15/.idea/misc.xml
generated
Normal file
4
labs/L15/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (python-venv)" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
labs/L15/.idea/modules.xml
generated
Normal file
8
labs/L15/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/L15.iml" filepath="$PROJECT_DIR$/.idea/L15.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
24
labs/L15/.idea/runConfigurations/globex.xml
generated
Normal file
24
labs/L15/.idea/runConfigurations/globex.xml
generated
Normal file
@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="globex" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||
<module name="L15" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="C:\Users\Isaac\Documents\CS2613-Repo\cs2613-ishoebot\labs\L15\globex.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
17
labs/L15/.idea/runConfigurations/pytest.xml
generated
Normal file
17
labs/L15/.idea/runConfigurations/pytest.xml
generated
Normal file
@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="pytest" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="pytest --cov --cov-report=term-missing" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
6
labs/L15/.idea/vcs.xml
generated
Normal file
6
labs/L15/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
22
labs/L15/globex.py
Normal file
22
labs/L15/globex.py
Normal file
@ -0,0 +1,22 @@
|
||||
import glob
|
||||
import os
|
||||
|
||||
# new_dir = os.path.expanduser("~/fcshome/cs2613/labs/test") # For lab machines
|
||||
new_dir = os.path.abspath("C:\\Users\\Isaac\\Documents\\CS2613-Repo\\cs2613-ishoebot\\labs\\L14") # For local machine
|
||||
|
||||
python_files_for = []
|
||||
|
||||
for file in glob.glob("*.py"):
|
||||
python_files_for.append(os.path.join(new_dir, file))
|
||||
|
||||
python_files_comp = [os.path.join(new_dir, file) for file in glob.glob("*.py")]
|
||||
|
||||
python_files_map = map(lambda file: os.path.join(new_dir, file), glob.glob("*.py"))
|
||||
|
||||
|
||||
if __name__ == '__main__': # pragma: no cover
|
||||
print(python_files_for)
|
||||
print()
|
||||
print(python_files_comp)
|
||||
print()
|
||||
print(list(python_files_map))
|
7
labs/L15/list2dict.py
Normal file
7
labs/L15/list2dict.py
Normal file
@ -0,0 +1,7 @@
|
||||
def list2dict(lst):
|
||||
lst_dict = dict()
|
||||
counter = 1
|
||||
for i in range(lst):
|
||||
lst_dict[counter] = i
|
||||
counter += 1
|
||||
return lst_dict
|
9
labs/L15/test_globex.py
Normal file
9
labs/L15/test_globex.py
Normal file
@ -0,0 +1,9 @@
|
||||
import globex
|
||||
|
||||
|
||||
def test_for():
|
||||
assert sorted(globex.python_files_for) == sorted(globex.python_files_comp)
|
||||
|
||||
|
||||
def test_map():
|
||||
assert sorted(globex.python_files_comp) == sorted(globex.python_files_map)
|
10
labs/L15/test_list2dict.py
Normal file
10
labs/L15/test_list2dict.py
Normal file
@ -0,0 +1,10 @@
|
||||
from list2dict import list2dict
|
||||
|
||||
|
||||
def test_empty():
|
||||
assert list2dict([]) == {}
|
||||
|
||||
|
||||
def test_abc():
|
||||
dictionary = list2dict(["a", "b", "c"])
|
||||
assert dictionary == {1: 'a', 2: 'b', 3: 'c'}
|
8
labs/L16/.idea/.gitignore
generated
vendored
Normal file
8
labs/L16/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
8
labs/L16/.idea/L16.iml
generated
Normal file
8
labs/L16/.idea/L16.iml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
12
labs/L16/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
12
labs/L16/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="E501" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
6
labs/L16/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
labs/L16/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
labs/L16/.idea/misc.xml
generated
Normal file
4
labs/L16/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="CS2613-venv" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
labs/L16/.idea/modules.xml
generated
Normal file
8
labs/L16/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/L16.iml" filepath="$PROJECT_DIR$/.idea/L16.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
labs/L16/.idea/vcs.xml
generated
Normal file
6
labs/L16/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
14
labs/L16/parse_csv.py
Normal file
14
labs/L16/parse_csv.py
Normal file
@ -0,0 +1,14 @@
|
||||
import re
|
||||
|
||||
|
||||
def split_csv(string):
|
||||
return [row.split(",") for row in string.splitlines()]
|
||||
|
||||
|
||||
def strip_quotes(string):
|
||||
strip_regex = re.compile(r'("?)*$("?)')
|
||||
search = strip_regex.search(string)
|
||||
if search:
|
||||
return search.group(1)
|
||||
else:
|
||||
return None
|
45
labs/L16/test_parse_csv.py
Normal file
45
labs/L16/test_parse_csv.py
Normal file
@ -0,0 +1,45 @@
|
||||
from parse_csv import split_csv
|
||||
from parse_csv import strip_quotes
|
||||
|
||||
test_string_1 = """OPEID,INSTNM,TUITIONFEE_OUT
|
||||
02503400,Amridge University,6900
|
||||
00100700,Central Alabama Community College,7770
|
||||
01218200,Chattahoochee Valley Community College,7830
|
||||
00101500,Enterprise State Community College,7770
|
||||
00106000,James H Faulkner State Community College,7770
|
||||
00101700,Gadsden State Community College,5976
|
||||
00101800,George C Wallace State Community College-Dothan,7710
|
||||
"""
|
||||
|
||||
table1 = [['OPEID', 'INSTNM', 'TUITIONFEE_OUT'],
|
||||
['02503400', 'Amridge University', '6900'],
|
||||
['00100700', 'Central Alabama Community College', '7770'],
|
||||
['01218200', 'Chattahoochee Valley Community College', '7830'],
|
||||
['00101500', 'Enterprise State Community College', '7770'],
|
||||
['00106000', 'James H Faulkner State Community College', '7770'],
|
||||
['00101700', 'Gadsden State Community College', '5976'],
|
||||
['00101800', 'George C Wallace State Community College-Dothan', '7710']]
|
||||
|
||||
|
||||
def test_split_1():
|
||||
assert split_csv(test_string_1) == table1
|
||||
|
||||
|
||||
test_string_2 = '''OPEID,INSTNM,TUITIONFEE_OUT
|
||||
02503400,"Amridge University",6900
|
||||
00100700,"Central Alabama Community College",7770
|
||||
01218200,"Chattahoochee Valley Community College",7830
|
||||
00101500,"Enterprise State Community College",7770
|
||||
00106000,"James H Faulkner State Community College",7770
|
||||
00101700,"Gadsden State Community College",5976
|
||||
00101800,"George C Wallace State Community College-Dothan",7710
|
||||
'''
|
||||
|
||||
|
||||
def test_split_2():
|
||||
assert split_csv(test_string_2) == table1
|
||||
|
||||
|
||||
def test_strip_quotes():
|
||||
assert strip_quotes('"hello"') == 'hello'
|
||||
assert strip_quotes('hello') == 'hello'
|
8
labs/L17/.idea/.gitignore
generated
vendored
Normal file
8
labs/L17/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
10
labs/L17/.idea/L17.iml
generated
Normal file
10
labs/L17/.idea/L17.iml
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="CS2613-venv" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
12
labs/L17/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
12
labs/L17/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="E501" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
6
labs/L17/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
labs/L17/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
labs/L17/.idea/misc.xml
generated
Normal file
4
labs/L17/.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="CS2613-venv" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
labs/L17/.idea/modules.xml
generated
Normal file
8
labs/L17/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/L17.iml" filepath="$PROJECT_DIR$/.idea/L17.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
labs/L17/.idea/vcs.xml
generated
Normal file
6
labs/L17/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
16
labs/L17/main.py
Normal file
16
labs/L17/main.py
Normal file
@ -0,0 +1,16 @@
|
||||
# This is a sample Python script.
|
||||
|
||||
# Press Shift+F10 to execute it or replace it with your code.
|
||||
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
|
||||
|
||||
|
||||
def print_hi(name):
|
||||
# Use a breakpoint in the code line below to debug your script.
|
||||
print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.
|
||||
|
||||
|
||||
# Press the green button in the gutter to run the script.
|
||||
if __name__ == '__main__':
|
||||
print_hi('PyCharm')
|
||||
|
||||
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
|
22
tests/Final/Q1 Racket/balance.rkt
Normal file
22
tests/Final/Q1 Racket/balance.rkt
Normal file
@ -0,0 +1,22 @@
|
||||
#lang racket
|
||||
(define (balance lst)
|
||||
(define (helper lst counter)
|
||||
(cond
|
||||
[(empty? lst) counter] ;;base case
|
||||
[(list? (first lst)) (helper (rest lst) counter)] ;;unwrap list
|
||||
[(eq? (first lst) 'debit) (helper (rest lst) (- counter last))] ;;if debit subtract the amount
|
||||
[(eq? (first lst) 'credit) (helper (rest lst) (+ counter last))] ;;if credit add the amount
|
||||
[else (helper (rest lst) counter)]
|
||||
)
|
||||
)
|
||||
(helper lst 0)
|
||||
)
|
||||
|
||||
;; Racket
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-equal? (balance (list (list 'credit 5))) 5)
|
||||
(check-equal? (balance (list '(debit 5))) -5)
|
||||
(check-equal? (balance '((debit 11) (credit 3))) -8)
|
||||
(check-equal? (balance '((debit 3) (credit 5))) 2)
|
||||
(check-equal? (balance '((debit 5) (credit 23) (debit 23) (credit 5))) 0))
|
0
tests/Final/Q1 Racket/balance.rkt~
Normal file
0
tests/Final/Q1 Racket/balance.rkt~
Normal file
19
tests/Final/Q2 Python/invert.py
Normal file
19
tests/Final/Q2 Python/invert.py
Normal file
@ -0,0 +1,19 @@
|
||||
def invert(lst):
|
||||
lst = list(lst) # Makes sure arugment is a list
|
||||
|
||||
#list_range = range(0, len(lst)) # Code I might have used if I used a dictionary comprehension
|
||||
|
||||
|
||||
ret_dict = dict() # Create empty dict
|
||||
counter = 0 # Create counter
|
||||
|
||||
for i in lst:
|
||||
ret_dict[i] = counter # Assign each element of list to
|
||||
# its postion in list
|
||||
|
||||
counter = counter + 1 # Increment counter
|
||||
|
||||
if (len(lst) > len(ret_dict)): # Check if the length of new dict is less than
|
||||
return None # input list, if so, there is duplicates so return none
|
||||
|
||||
return ret_dict # Return created dictionary
|
13
tests/Final/Q2 Python/test_invert.py
Normal file
13
tests/Final/Q2 Python/test_invert.py
Normal file
@ -0,0 +1,13 @@
|
||||
from invert import invert
|
||||
def test_empty():
|
||||
assert invert([]) == {}
|
||||
def test_simple():
|
||||
invert(["three","two","one"]) == {"three": 0, "two":1, "one":2}
|
||||
def test_duplicate():
|
||||
assert invert(["bob","bob"]) == None
|
||||
def test_numeric():
|
||||
assert invert(range(0,6)) == { 0:0, 1:1, 2:2, 3:3, 4:4, 5:5 }
|
||||
def test_invert():
|
||||
L=[-8,"pineapple",3]
|
||||
D=invert(L)
|
||||
assert [ L[D[j]] for j in L ] == L
|
50
tests/Final/Q3 Javascript/expression.js
Normal file
50
tests/Final/Q3 Javascript/expression.js
Normal file
@ -0,0 +1,50 @@
|
||||
class Expression {
|
||||
constructor(op, left, right) {
|
||||
this.op = op
|
||||
this.left = left
|
||||
this.right = right
|
||||
}
|
||||
|
||||
eval() {
|
||||
return evalExpression(this)
|
||||
}
|
||||
}
|
||||
|
||||
function evalExpression(expr) {
|
||||
let tempLeft
|
||||
let tempRight
|
||||
if (typeof(expr.left) === "object") { // Check if left type is another expression
|
||||
tempLeft = evalExpression(expr.left)
|
||||
}
|
||||
else {
|
||||
tempLeft = expr.left
|
||||
}
|
||||
if (typeof(expr.right) === "object") { // Check if right type is another expression
|
||||
tempRight = evalExpression(expr.right)
|
||||
}
|
||||
else {
|
||||
tempRight = expr.right
|
||||
}
|
||||
if (typeof(tempLeft) === "number" & typeof(tempRight) === "number") { // Make sure both inputs are number
|
||||
if (expr.op === "+") {
|
||||
return tempLeft + tempRight
|
||||
}
|
||||
else if(expr.op === "-") {
|
||||
return tempLeft - tempRight
|
||||
}
|
||||
else if(expr.op === "*") {
|
||||
return tempLeft * tempRight
|
||||
}
|
||||
else if(expr.op === "/") {
|
||||
return tempLeft / tempRight
|
||||
}
|
||||
else { // Case for when there is no valid provided operator
|
||||
return "Invalid operator syntax"
|
||||
}
|
||||
}
|
||||
else { //Case for when the left or right are not numbers
|
||||
return "Invalid number syntax"
|
||||
}
|
||||
}
|
||||
|
||||
exports.Expression = Expression;
|
71
tests/Final/Q3 Javascript/spec/expression.spec.js
Normal file
71
tests/Final/Q3 Javascript/spec/expression.spec.js
Normal file
@ -0,0 +1,71 @@
|
||||
Expression = require("../expression.js").Expression;
|
||||
|
||||
let six_plus_nine = new Expression('+', 6, 9);
|
||||
let six_times_nine = new Expression('*', 6, 9);
|
||||
let six_minus_nine = new Expression('-', 6, 9);
|
||||
let sixteen_div_eight = new Expression('/', 16, 8);
|
||||
let compound1 = new Expression('+', six_times_nine, six_plus_nine)
|
||||
let compound2 = new Expression('*', six_times_nine, compound1)
|
||||
let compound3 = new Expression('+', compound2, 3)
|
||||
|
||||
describe("constructor",
|
||||
function() {
|
||||
let one = new Expression("+",0,1);
|
||||
it("not null", () => expect(one).not.toBe(null));
|
||||
it("op", () => expect(one.op).toBe("+"));
|
||||
it("left", () => expect(one.left).toBe(0));
|
||||
it("right", () => expect(one.right).toBe(1));
|
||||
});
|
||||
|
||||
describe("simple",
|
||||
function() {
|
||||
it("+", () => expect(six_plus_nine.eval()).toBe(15));
|
||||
it("-", () => expect(six_minus_nine.eval()).toBe(-3));
|
||||
it("*", () => expect(six_times_nine.eval()).toBe(54));
|
||||
it("/", () => expect(sixteen_div_eight.eval()).toBe(2));
|
||||
});
|
||||
|
||||
describe("compound",
|
||||
function() {
|
||||
it("1", () => expect(compound1.eval()).toBe(69));
|
||||
it("2", () => expect(compound2.eval()).toBe(3726));
|
||||
it("3", () => expect(compound3.eval()).toBe(3729));
|
||||
});
|
||||
|
||||
describe("floating point", //Testing floating point
|
||||
function() {
|
||||
let addPointFive = new Expression("+", 0.5, 0.5)
|
||||
let timesPointFive = new Expression("*", 0.5, 10)
|
||||
let minusPointFive = new Expression("-", 10, 0.5)
|
||||
let dividePointFive = new Expression("/", 0.5, 0.1)
|
||||
|
||||
it("+", () => expect(addPointFive.eval()).toBe(1.0));
|
||||
it("*", () => expect(timesPointFive.eval()).toBe(5.0));
|
||||
it("-", () => expect(minusPointFive.eval()).toBe(9.5));
|
||||
it("/", () => expect(dividePointFive.eval()).toBe(5.0));
|
||||
});
|
||||
|
||||
|
||||
describe("bad input", //Testing bad inputs
|
||||
function() {
|
||||
let invalidStringLeft = new Expression("+", "five", 6)
|
||||
let invalidStringRight = new Expression("+", 5, "six")
|
||||
let invalidOperator = new Expression("^", 6, 9)
|
||||
|
||||
it("Invalid String on left side", () => expect(invalidStringLeft.eval()).toBe("Invalid number syntax"));
|
||||
it("Invalid String on right side", () => expect(invalidStringRight.eval()).toBe("Invalid number syntax"));
|
||||
it("invalid operator", () => expect(invalidOperator.eval()).toBe("Invalid operator syntax"));
|
||||
});
|
||||
|
||||
|
||||
describe("compound bad input", //Testing bad inputs in compound cases
|
||||
function() {
|
||||
let invalidNumber = new Expression("+", "five", 6)
|
||||
let invalidOperator = new Expression("^", 6, 9)
|
||||
|
||||
let semiValidCompound = new Expression("+", six_plus_nine, invalidNumber)
|
||||
let completlyBadCompound = new Expression("+", invalidNumber, invalidOperator)
|
||||
|
||||
it("semi-valid", () => expect(semiValidCompound.eval()).toBe("Invalid number syntax"));
|
||||
it("invalid", () => expect(completlyBadCompound.eval()).toBe("Invalid number syntax")); //Expected to be invalid number because it is the first error to be encountered
|
||||
});
|
13
tests/Final/Q3 Javascript/spec/support/jasmine.json
Normal file
13
tests/Final/Q3 Javascript/spec/support/jasmine.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"**/*[sS]pec.?(m)js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/**/*.?(m)js"
|
||||
],
|
||||
"env": {
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
}
|
71
tests/Final/tests.txt
Normal file
71
tests/Final/tests.txt
Normal file
@ -0,0 +1,71 @@
|
||||
;; Racket
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-equal? (balance (list (list 'credit 5))) 5)
|
||||
(check-equal? (balance (list '(debit 5))) -5)
|
||||
(check-equal? (balance '((debit 11) (credit 3))) -8)
|
||||
(check-equal? (balance '((debit 3) (credit 5))) 2)
|
||||
(check-equal? (balance '((debit 5) (credit 23) (debit 23) (credit 5))) 0))
|
||||
|
||||
# Python
|
||||
from invert import invert
|
||||
def test_empty():
|
||||
assert invert([]) == {}
|
||||
def test_simple():
|
||||
invert(["three","two","one"]) == {"three": 0, "two":1, "one":2}
|
||||
def test_duplicate():
|
||||
assert invert(["bob","bob"]) == None
|
||||
def test_numeric():
|
||||
assert invert(range(0,6)) == { 0:0, 1:1, 2:2, 3:3, 4:4, 5:5 }
|
||||
def test_invert():
|
||||
L=[-8,"pineapple",3]
|
||||
D=invert(L)
|
||||
assert [ L[D[j]] for j in L ] == L
|
||||
|
||||
// JavaScript
|
||||
Expression = require("../expression.js").Expression;
|
||||
|
||||
let six_plus_nine = new Expression('+', 6, 9);
|
||||
let six_times_nine = new Expression('*', 6, 9);
|
||||
let six_minus_nine = new Expression('-', 6, 9);
|
||||
let sixteen_div_eight = new Expression('/', 16, 8);
|
||||
let compound1 = new Expression('+', six_times_nine, six_plus_nine)
|
||||
let compound2 = new Expression('*', six_times_nine, compound1)
|
||||
let compound3 = new Expression('+', compound2, 3)
|
||||
|
||||
describe("constructor",
|
||||
function() {
|
||||
let one = new Expression("+",0,1);
|
||||
it("not null", () => expect(one).not.toBe(null));
|
||||
it("op", () => expect(one.op).toBe("+"));
|
||||
it("left", () => expect(one.left).toBe(0));
|
||||
it("right", () => expect(one.right).toBe(1));
|
||||
});
|
||||
|
||||
describe("simple",
|
||||
function() {
|
||||
it("+", () => expect(six_plus_nine.eval()).toBe(15));
|
||||
it("-", () => expect(six_minus_nine.eval()).toBe(-3));
|
||||
it("*", () => expect(six_times_nine.eval()).toBe(54));
|
||||
it("/", () => expect(sixteen_div_eight.eval()).toBe(2));
|
||||
});
|
||||
|
||||
describe("compound",
|
||||
function() {
|
||||
it("1", () => expect(compound1.eval()).toBe(69));
|
||||
it("2", () => expect(compound2.eval()).toBe(3726));
|
||||
it("3", () => expect(compound3.eval()).toBe(3729));
|
||||
});
|
||||
|
||||
|
||||
# Octave
|
||||
%!shared P1,P3
|
||||
%! P1=[7,5,-3];
|
||||
%! P3=[1,2,3;4,5,6;7,8,9];
|
||||
%
|
||||
%!assert(manypoly(P1,0),7,eps)
|
||||
%!assert(manypoly(P1,1),9,eps)
|
||||
%!assert(manypoly(P1,5),7+5*5-3*25,eps)
|
||||
%!assert(manypoly(P3,0),[1;4;7],eps)
|
||||
%!assert(manypoly(P3,1),[6;15;24],eps)
|
||||
%!assert(manypoly(P3,2),[1+2*2+3*4;4+5*2+6*4;7+8*2+9*4],eps)
|
21
tests/Q2/objectSum.js
Normal file
21
tests/Q2/objectSum.js
Normal file
@ -0,0 +1,21 @@
|
||||
function objectSum(obj) {
|
||||
sum = 0
|
||||
for (let number of obj){
|
||||
// Attempted to support objects
|
||||
//if (typeof(number[1]) === "number")
|
||||
// sum = sum + number[1]
|
||||
//if (typeof(number[1]) === "object")
|
||||
// sum = sum + objectSum(number[1])
|
||||
|
||||
|
||||
//Case for when the number is actually not a number (eg, recursive list)
|
||||
if (typeof(number) === "object")
|
||||
sum = sum + objectSum(number)
|
||||
//Case for when the number is a number
|
||||
if(typeof(number) === "number")
|
||||
sum = sum + number
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
exports.objectSum = objectSum
|
30
tests/Q2/spec/objectSum.spec.js
Normal file
30
tests/Q2/spec/objectSum.spec.js
Normal file
@ -0,0 +1,30 @@
|
||||
let sum=require ("../objectSum.js");
|
||||
|
||||
describe("objectSum",
|
||||
function() {
|
||||
it("List of numbers",
|
||||
function() {
|
||||
let obj = [1, 2, 3]
|
||||
expect(sum.objectSum(obj)).toBe(6);
|
||||
});
|
||||
it("Skip non numbers",
|
||||
function() {
|
||||
let obj = [1, 2, "jellyfish", 3]
|
||||
expect(sum.objectSum(obj)).toBe(6);
|
||||
});
|
||||
it("Recursive arrays",
|
||||
function() {
|
||||
let obj = [1, 2, [-6, 2, -2], 3]
|
||||
expect(sum.objectSum(obj)).toBe(0);
|
||||
});
|
||||
it("Lists",
|
||||
function() {
|
||||
let obj = {a: 1, b: 2, c: 3}
|
||||
expect(sum.objectSum(obj)).toBe(6);
|
||||
});
|
||||
it("Recursive lists",
|
||||
function() {
|
||||
let obj = [1, 2, {thing: [-6, -12], other: 6}]
|
||||
expect(sum.objectSum(obj)).toBe(-9);
|
||||
});
|
||||
});
|
13
tests/Q2/spec/support/jasmine.json
Normal file
13
tests/Q2/spec/support/jasmine.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"**/*[sS]pec.?(m)js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/**/*.?(m)js"
|
||||
],
|
||||
"env": {
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
}
|
4
tests/Q3/prefix.py
Normal file
4
tests/Q3/prefix.py
Normal file
@ -0,0 +1,4 @@
|
||||
def with_prefix(prefixes, words):
|
||||
for prefix in prefixes:
|
||||
lst = [word for word in words if word.startswith(prefix)]
|
||||
yield lst
|
41
tests/Q3/test_prefix.py
Normal file
41
tests/Q3/test_prefix.py
Normal file
@ -0,0 +1,41 @@
|
||||
from prefix import with_prefix
|
||||
|
||||
words=["apple","baby","abba"]
|
||||
a_words=["apple", "abba"]
|
||||
def test_simple():
|
||||
assert list(with_prefix(["a"],words)) == [a_words]
|
||||
def test_order():
|
||||
assert list(with_prefix(["b","a"],words)) == [["baby"], a_words]
|
||||
def test_multi():
|
||||
assert list(with_prefix(["bb","ab"],words)) == [[],["abba"]]
|
||||
|
||||
# Commented out because the solution I am submitting is not using regex
|
||||
#def test_regex1():
|
||||
# assert list(with_prefix(["[a-z]b"], words)) == [ ["abba"] ]
|
||||
#def test_regex2():
|
||||
# assert list(with_prefix([".*a$"], words)) == [ ["abba"] ]
|
||||
|
||||
def test_gen():
|
||||
gen = with_prefix(["b"],words)
|
||||
assert next(gen) == ["baby"]
|
||||
|
||||
|
||||
|
||||
|
||||
def test_gen2(): #Testing out of order prefixes, with generator syntax
|
||||
gen = with_prefix(["b", "a"], words)
|
||||
assert next(gen) == ["baby"]
|
||||
assert next(gen) == ["apple", "abba"]
|
||||
|
||||
def test_gen3(): #Testing out returning the same number of elements as words, out of order
|
||||
gen = with_prefix(["bab", "abb", "app"], words)
|
||||
assert next(gen) == ["baby"]
|
||||
assert next(gen) == ["abba"]
|
||||
assert next(gen) == ["apple"]
|
||||
|
||||
|
||||
words2 = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "z"]
|
||||
def test_gen4(): #Testing a long word and one letter word
|
||||
gen = with_prefix(["a", "z"], words2)
|
||||
assert next(gen) == ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
|
||||
assert next(gen) == ["z"]
|
32
tests/practice/Q3/practice_questions.py
Normal file
32
tests/practice/Q3/practice_questions.py
Normal file
@ -0,0 +1,32 @@
|
||||
def is_word(word):
|
||||
counter = 0
|
||||
for l in word:
|
||||
if (counter % 2) == 0: #zero is vowel, one is constanant
|
||||
if l == 'a' or l == 'e' or l == 'i' or l == 'o' or l == 'u':
|
||||
counter = counter + 1
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if l == 'b' or l == 'k' or l == 'p' or l == 't' or l == 'z':
|
||||
counter = counter + 1
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def cycle(lst):
|
||||
while True:
|
||||
yield lst
|
||||
x = lst[0]
|
||||
lst = lst[1:]
|
||||
lst.append(x)
|
||||
|
||||
class Skippy:
|
||||
def __init__(self, lst, offset)
|
||||
self.lst = lst
|
||||
self.offset = offset
|
||||
self.counter = 0
|
||||
|
||||
def __next__(self)
|
||||
if self.counter > length(self.lst)
|
||||
self.counter = 0
|
||||
|
37
tests/practice/Q3/test_practice_questions.py
Normal file
37
tests/practice/Q3/test_practice_questions.py
Normal file
@ -0,0 +1,37 @@
|
||||
from practice_questions import is_word
|
||||
|
||||
def test_match():
|
||||
assert is_word("akataka") == True
|
||||
assert is_word("ububu") == True
|
||||
assert is_word("ikekezaza") == True
|
||||
|
||||
def test_extra():
|
||||
assert is_word("akatakaa") == False
|
||||
assert is_word("uububu") == False
|
||||
|
||||
def test_bad_letter():
|
||||
assert is_word("yakataka") == False
|
||||
assert is_word("akatakala") == False
|
||||
|
||||
def test_consonant_start():
|
||||
assert is_word("kakataka") == False
|
||||
assert is_word("bububu") == False
|
||||
|
||||
|
||||
from practice_questions import cycle
|
||||
def test_small():
|
||||
lst = [1,2,3]
|
||||
g = cycle(lst)
|
||||
assert next(g) == lst
|
||||
assert next(g) == [2,3,1]
|
||||
assert next(g) == [3,1,2]
|
||||
|
||||
def test_big():
|
||||
n = 5000
|
||||
lst = list(range(n))
|
||||
g = cycle(lst)
|
||||
for j in range(n):
|
||||
lst2 = next(g)
|
||||
assert lst2[0] == n-1
|
||||
lst3 = next(g)
|
||||
assert lst3==lst
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user