Compare commits
22 Commits
490552f9bd
...
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 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -3,3 +3,4 @@
|
|||||||
|
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
|
*.exe binary
|
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>
|
@ -1,9 +1,21 @@
|
|||||||
Title: Lab Fourteen
|
Title: Lab Fourteen
|
||||||
Date: 2022-10-31T08:30:00
|
Date: 2022-10-31T08:30:00
|
||||||
Tags: cs2613, lab, python
|
Tags: cs2613, lab, python, pytest, exceptions, modules
|
||||||
|
|
||||||
Sample description
|
In this lab I learned about python, pytest, python exceptions and modules.
|
||||||
<!-- more -->
|
<!-- more -->
|
||||||
|
|
||||||
## Sample Body
|
## Pytest
|
||||||
Sample Body
|
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.
|
2
labs/L14/.idea/L14.iml
generated
2
labs/L14/.idea/L14.iml
generated
@ -4,7 +4,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.10 (python-venv)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
2
labs/L14/.idea/misc.xml
generated
2
labs/L14/.idea/misc.xml
generated
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (L14)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (python-venv)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</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>
|
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)
|
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
|
1
utils/python-pytest-script.txt
Normal file
1
utils/python-pytest-script.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
pytest --cov --cov-report=term-missing
|
BIN
utils/python-requirements.txt
Normal file
BIN
utils/python-requirements.txt
Normal file
Binary file not shown.
Reference in New Issue
Block a user