2023-08-02 17:12:15 +00:00
|
|
|
'use strict';
|
|
|
|
class LuokkaAste {
|
|
|
|
#luokat = 1;
|
|
|
|
|
|
|
|
luokat() {
|
|
|
|
// Tee lista, jossa on #luokat ensimmäistä isoa kirjainta
|
|
|
|
let luokat = [];
|
|
|
|
for (let i = 0; i < this.#luokat; i++) {
|
|
|
|
luokat.push(String.fromCharCode(65 + i));
|
|
|
|
}
|
|
|
|
return luokat;
|
|
|
|
}
|
|
|
|
|
|
|
|
lisää() {
|
|
|
|
this.#luokat++;
|
|
|
|
}
|
|
|
|
|
|
|
|
poista() {
|
|
|
|
if (this.#luokat <= 1) {
|
|
|
|
throw new Error('viimeistä luokkaa ei voi poistaa asteelta');
|
|
|
|
}
|
|
|
|
this.#luokat--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class LuokkaAsteet {
|
|
|
|
asteet = [];
|
|
|
|
|
2023-08-08 14:13:11 +00:00
|
|
|
luokat() {
|
|
|
|
let luokat = [];
|
|
|
|
for (let aste = 0; aste < this.asteet.length; aste++) {
|
|
|
|
if (this.asteet[aste] !== undefined) {
|
|
|
|
for (let luokka of this.asteet[aste].luokat()) {
|
|
|
|
luokat.push(`${aste}${luokka}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return luokat;
|
|
|
|
}
|
|
|
|
|
2023-08-02 17:12:15 +00:00
|
|
|
seuraavaAste() {
|
|
|
|
// Seuraava aste on yksi suurinta listassa jo olevaa astetta isompi, tai
|
|
|
|
// 1 jos listassa ei vielä ole asteita
|
|
|
|
let aste = 1;
|
|
|
|
for (let i = 0; i < this.asteet.length; i++) {
|
|
|
|
if (this.asteet[i] !== undefined) {
|
|
|
|
aste = i + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return aste;
|
|
|
|
}
|
|
|
|
|
|
|
|
lisää(aste) {
|
|
|
|
aste ??= this.seuraavaAste()
|
|
|
|
if (this.asteet[aste] !== undefined) {
|
|
|
|
throw new Error(`luokka-aste ${aste} on jo olemassa`);
|
|
|
|
}
|
|
|
|
let asteObjekti = new LuokkaAste();
|
|
|
|
this.asteet[aste] = asteObjekti;
|
|
|
|
return aste;
|
|
|
|
}
|
|
|
|
|
|
|
|
poista(aste) {
|
|
|
|
if (this.asteet[aste] === undefined) {
|
|
|
|
throw new Error(`luokka-astetta ${aste} ei ole olemassa`);
|
|
|
|
}
|
|
|
|
this.asteet[aste] = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
muuta(vanha, uusi) {
|
|
|
|
if (vanha === uusi) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Heitä poikkeus jo ennen poistoa, jotta asteet-taulukkoon ei tule
|
|
|
|
// mitään muutoksia poikkeustilanteessa
|
|
|
|
if (this.asteet[uusi] !== undefined) {
|
|
|
|
throw new Error(`luokka-aste ${uusi} on jo olemassa`);
|
|
|
|
}
|
|
|
|
let aste = this.asteet[vanha];
|
|
|
|
this.poista(vanha);
|
|
|
|
this.asteet[uusi] = aste;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-07 15:51:11 +00:00
|
|
|
class Opettajat {
|
|
|
|
#opettajat = new Map();
|
|
|
|
|
|
|
|
opettajat() {
|
|
|
|
let lista = Array.from(this.#opettajat.entries());
|
|
|
|
lista.sort();
|
|
|
|
return lista;
|
|
|
|
}
|
|
|
|
|
|
|
|
lyhenne(lyhenne) {
|
|
|
|
return this.#opettajat.get(lyhenne);
|
|
|
|
}
|
|
|
|
|
|
|
|
lisää(lyhenne, nimi) {
|
|
|
|
if (this.#opettajat.has(lyhenne)) {
|
|
|
|
throw new Error(`opettaja on jo olemassa lyhenteellä ${lyhenne}`);
|
|
|
|
}
|
|
|
|
this.#opettajat.set(lyhenne, nimi);
|
|
|
|
}
|
|
|
|
|
|
|
|
poista(lyhenne) {
|
|
|
|
if (!this.#opettajat.delete(lyhenne)) {
|
|
|
|
throw new Error(`ei opettajaa lyhenteellä ${lyhenne}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-08 16:08:44 +00:00
|
|
|
class Tunti {
|
|
|
|
constructor(nimi, luokat, opettajaLyhenteet, kertaaViikossa) {
|
|
|
|
this.nimi = nimi;
|
2023-08-09 21:44:56 +00:00
|
|
|
this.luokat = new Joukko(luokat);
|
|
|
|
this.opettajaLyhenteet = new Joukko(opettajaLyhenteet);
|
2023-08-08 16:08:44 +00:00
|
|
|
this.kertaaViikossa = kertaaViikossa;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Tunnit {
|
|
|
|
tunnit = new Map();
|
|
|
|
#seuraavaId = 0;
|
|
|
|
|
|
|
|
lisää(nimi, luokka, opettajaLyhenne, kertaaViikossa) {
|
|
|
|
let id = this.#seuraavaId++;
|
|
|
|
this.tunnit.set(
|
|
|
|
id,
|
|
|
|
new Tunti(nimi, [luokka], [opettajaLyhenne], kertaaViikossa)
|
|
|
|
);
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
poista(id) {
|
|
|
|
if (!this.tunnit.delete(id)) {
|
|
|
|
throw new Error(`ei tuntia ID:llä ${id}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
järjestyksessä() {
|
|
|
|
let tunnit = [];
|
|
|
|
for (let [id, tunti] of this.tunnit) {
|
|
|
|
tunnit.push([id, tunti]);
|
|
|
|
}
|
|
|
|
tunnit.sort((a, b) => {
|
|
|
|
let tulos = vertaa(a[1].nimi, b[1].nimi);
|
|
|
|
// TODO: Korjaa niin, että osaa verrata okein listoja
|
|
|
|
if (tulos === 0) {
|
2023-08-09 21:44:56 +00:00
|
|
|
tulos = vertaa(a[1].luokat.alkiot(), b[1].luokat.alkiot());
|
2023-08-08 16:08:44 +00:00
|
|
|
}
|
|
|
|
// TODO: Korjaa niin, että osaa verrata okein listoja
|
|
|
|
if (tulos === 0) {
|
2023-08-09 21:44:56 +00:00
|
|
|
tulos = vertaa(a[1].opettajaLyhenteet.alkiot(), b[1].opettajaLyhenteet.alkiot());
|
2023-08-08 16:08:44 +00:00
|
|
|
}
|
|
|
|
if (tulos === 0) {
|
|
|
|
tulos = vertaa(a[1].kertaaViikossa, b[1].kertaaViikossa);
|
|
|
|
}
|
|
|
|
if (tulos === 0) {
|
|
|
|
tulos = vertaa(a[0], b[0]);
|
|
|
|
}
|
|
|
|
return tulos;
|
|
|
|
});
|
|
|
|
return tunnit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-09 21:44:56 +00:00
|
|
|
class Joukko {
|
|
|
|
#alkiot = new Map();
|
|
|
|
|
|
|
|
constructor(alkiot) {
|
|
|
|
if (alkiot !== undefined) {
|
|
|
|
for (let alkio of alkiot) {
|
|
|
|
this.#alkiot.set(alkio, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
alkiot() {
|
|
|
|
let alkiot = [];
|
|
|
|
for (let [alkio, _] of this.#alkiot) {
|
|
|
|
alkiot.push(alkio);
|
|
|
|
}
|
|
|
|
alkiot.sort();
|
|
|
|
return alkiot;
|
|
|
|
}
|
|
|
|
|
|
|
|
lisää(alkio) {
|
|
|
|
this.#alkiot.set(alkio, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
poista(alkio) {
|
|
|
|
this.#alkiot.delete(alkio);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-08 16:08:44 +00:00
|
|
|
function vertaa(a, b) {
|
|
|
|
if (a < b) {
|
|
|
|
return -1;
|
|
|
|
} else if (a > b) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-02 17:12:15 +00:00
|
|
|
testi('seuraava aste', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
assertEq('aluksi', luokkaAsteet.seuraavaAste(), 1);
|
|
|
|
luokkaAsteet.lisää();
|
|
|
|
assertEq('asteen 1 jälkeen', luokkaAsteet.seuraavaAste(), 2);
|
|
|
|
luokkaAsteet.lisää(3);
|
|
|
|
assertEq('asteiden 1 ja 3 jälkeen', luokkaAsteet.seuraavaAste(), 4);
|
|
|
|
luokkaAsteet.lisää();
|
|
|
|
assertEq('asteiden 1, 3, 4 jälkeen', luokkaAsteet.seuraavaAste(), 5);
|
|
|
|
luokkaAsteet.poista(4);
|
|
|
|
luokkaAsteet.poista(3);
|
|
|
|
assertEq('asteet 3 ja 4 poistettua', luokkaAsteet.seuraavaAste(), 2);
|
|
|
|
luokkaAsteet.muuta(1, 5);
|
|
|
|
assertEq('aste 1 muutettua 5:ksi', luokkaAsteet.seuraavaAste(), 6);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('asteiden lisääminen', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
assertEq('1. aste', luokkaAsteet.lisää(), 1);
|
|
|
|
assertEq('2. aste', luokkaAsteet.lisää(), 2);
|
|
|
|
assertEq('3. aste', luokkaAsteet.lisää(3), 3);
|
|
|
|
assertThrow('3. aste uudelleen', 'luokka-aste 3 on jo olemassa', () => {
|
|
|
|
luokkaAsteet.lisää(3);
|
|
|
|
});
|
2023-08-08 14:13:11 +00:00
|
|
|
assertEq('lisättyä', luokkaAsteet.luokat(), ['1A', '2A', '3A']);
|
2023-08-02 17:12:15 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
testi('asteiden poistaminen', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
luokkaAsteet.lisää();
|
|
|
|
luokkaAsteet.lisää();
|
|
|
|
luokkaAsteet.poista(1);
|
|
|
|
luokkaAsteet.poista(2);
|
|
|
|
assertThrow('3. asteen poisto', 'luokka-astetta 3 ei ole olemassa', () => {
|
|
|
|
luokkaAsteet.poista(3);
|
|
|
|
});
|
2023-08-08 14:13:11 +00:00
|
|
|
assertEq('poistettua', luokkaAsteet.luokat(), []);
|
2023-08-02 17:12:15 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
testi('asteiden muuttaminen', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
assertEq('lisääminen', luokkaAsteet.lisää(), 1);
|
|
|
|
luokkaAsteet.muuta(1, 5);
|
2023-08-08 14:13:11 +00:00
|
|
|
assertEq('muutettua', luokkaAsteet.luokat(), ['5A']);
|
2023-08-02 17:12:15 +00:00
|
|
|
assertThrow('poisto', 'luokka-astetta 1 ei ole olemassa', () => {
|
|
|
|
luokkaAsteet.poista(1);
|
|
|
|
});
|
|
|
|
luokkaAsteet.poista(5);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('luokkien lisääminen', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
let aste = luokkaAsteet.asteet[luokkaAsteet.lisää()];
|
2023-08-07 14:56:48 +00:00
|
|
|
assertEq('aluksi', aste.luokat(), ['A']);
|
2023-08-02 17:12:15 +00:00
|
|
|
aste.lisää();
|
|
|
|
aste.lisää();
|
2023-08-07 14:56:48 +00:00
|
|
|
assertEq('lisättyä', aste.luokat(), ['A', 'B', 'C']);
|
2023-08-02 17:12:15 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
testi('luokkien poistaminen', () => {
|
|
|
|
let luokkaAsteet = new LuokkaAsteet();
|
|
|
|
let aste = luokkaAsteet.asteet[luokkaAsteet.lisää()];
|
|
|
|
aste.lisää();
|
|
|
|
aste.lisää();
|
|
|
|
aste.poista();
|
|
|
|
aste.poista();
|
|
|
|
assertThrow('viimeisen poisto', 'viimeistä luokkaa ei voi poistaa asteelta', () => {
|
|
|
|
aste.poista();
|
|
|
|
});
|
2023-08-07 14:56:48 +00:00
|
|
|
assertEq('poistettua', aste.luokat(), ['A']);
|
2023-08-02 17:12:15 +00:00
|
|
|
});
|
2023-08-07 15:51:11 +00:00
|
|
|
|
|
|
|
testi('opettajien lisääminen', () => {
|
|
|
|
let opettajat = new Opettajat();
|
|
|
|
assertEq('aluksi', opettajat.opettajat(), []);
|
|
|
|
opettajat.lisää('MM', 'Maija Meikäläinen');
|
|
|
|
opettajat.lisää('AS', 'Aili Savolainen');
|
|
|
|
opettajat.lisää('KV', 'Kari Virtanen');
|
|
|
|
assertThrow('sama lyhenne', 'opettaja on jo olemassa lyhenteellä MM', () => {
|
|
|
|
opettajat.lisää('MM', 'Matti Meikäläinen');
|
|
|
|
});
|
|
|
|
opettajat.lisää('MaM', 'Matti Meikäläinen');
|
|
|
|
assertEq('lisättyä', opettajat.opettajat(), [
|
|
|
|
['AS', 'Aili Savolainen'],
|
|
|
|
['KV', 'Kari Virtanen'],
|
|
|
|
['MM', 'Maija Meikäläinen'],
|
|
|
|
['MaM', 'Matti Meikäläinen'],
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('opettajien poistaminen', () => {
|
|
|
|
let opettajat = new Opettajat();
|
|
|
|
opettajat.lisää('MM', 'Maija Meikäläinen');
|
|
|
|
opettajat.lisää('AS', 'Aili Savolainen');
|
|
|
|
opettajat.lisää('KV', 'Kari Virtanen');
|
|
|
|
opettajat.lisää('MaM', 'Matti Meikäläinen');
|
|
|
|
opettajat.poista('MM');
|
|
|
|
assertThrow('jo poistettu', 'ei opettajaa lyhenteellä MM', () => {
|
|
|
|
opettajat.poista('MM');
|
|
|
|
});
|
|
|
|
assertEq('poistettua', opettajat.opettajat(), [
|
|
|
|
['AS', 'Aili Savolainen'],
|
|
|
|
['KV', 'Kari Virtanen'],
|
|
|
|
['MaM', 'Matti Meikäläinen'],
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('opettajien lyhenteen', () => {
|
|
|
|
let opettajat = new Opettajat();
|
|
|
|
opettajat.lisää('MM', 'Maija Meikäläinen');
|
|
|
|
opettajat.lisää('AS', 'Aili Savolainen');
|
|
|
|
opettajat.lisää('KV', 'Kari Virtanen');
|
|
|
|
opettajat.lisää('MaM', 'Matti Meikäläinen');
|
|
|
|
assertEq('MM', opettajat.lyhenne('MM'), 'Maija Meikäläinen');
|
|
|
|
assertEq('AS', opettajat.lyhenne('AS'), 'Aili Savolainen');
|
|
|
|
assertEq('KV', opettajat.lyhenne('KV'), 'Kari Virtanen');
|
|
|
|
assertEq('MaM', opettajat.lyhenne('MaM'), 'Matti Meikäläinen');
|
|
|
|
assertEq('ZZ', opettajat.lyhenne('ZZ'), undefined);
|
|
|
|
});
|
2023-08-08 16:08:44 +00:00
|
|
|
|
|
|
|
testi('tuntien lisääminen', () => {
|
|
|
|
let tunnit = new Tunnit();
|
|
|
|
assertEq('historia', tunnit.lisää('Historia', '5B', 'KV', 1), 0);
|
|
|
|
assertEq('äidinkieli', tunnit.lisää('Äidinkieli', '1A', 'AS', 3), 1);
|
|
|
|
assertEq('historia nimi', tunnit.tunnit.get(0).nimi, 'Historia');
|
2023-08-09 21:44:56 +00:00
|
|
|
assertEq('historia luokat', tunnit.tunnit.get(0).luokat.alkiot(), ['5B']);
|
|
|
|
assertEq('historia opettajat', tunnit.tunnit.get(0).opettajaLyhenteet.alkiot(), ['KV']);
|
2023-08-08 16:08:44 +00:00
|
|
|
assertEq('historia viikossa', tunnit.tunnit.get(0).kertaaViikossa, 1);
|
|
|
|
assertEq('äidinkieli nimi', tunnit.tunnit.get(1).nimi, 'Äidinkieli');
|
2023-08-09 21:44:56 +00:00
|
|
|
assertEq('äidinkieli luokat', tunnit.tunnit.get(1).luokat.alkiot(), ['1A']);
|
|
|
|
assertEq('äidinkieli opettajat', tunnit.tunnit.get(1).opettajaLyhenteet.alkiot(), ['AS']);
|
2023-08-08 16:08:44 +00:00
|
|
|
assertEq('äidinkieli viikossa', tunnit.tunnit.get(1).kertaaViikossa, 3);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('tuntien poistaminen', () => {
|
|
|
|
let tunnit = new Tunnit();
|
|
|
|
tunnit.lisää('Historia', '5B', 'KV', 1);
|
|
|
|
tunnit.lisää('Äidinkieli', '1B', 'AS', 3);
|
|
|
|
tunnit.poista(0);
|
|
|
|
tunnit.poista(1);
|
|
|
|
assertThrow('jo poistettu', 'ei tuntia ID:llä 1', () => {
|
|
|
|
tunnit.poista(1);
|
|
|
|
});
|
|
|
|
assertEq('kuvataide', tunnit.lisää('Kuvataide', '6A', 'MM', 1), 2);
|
|
|
|
});
|
|
|
|
|
|
|
|
testi('tuntien järjestys', () => {
|
|
|
|
let tunnit = new Tunnit();
|
|
|
|
tunnit.lisää('Historia', '5B', 'KV', 1);
|
|
|
|
tunnit.lisää('Äidinkieli', '1B', 'AS', 3);
|
|
|
|
assertEq('aluksi', tunnit.järjestyksessä()[0][1].nimi, 'Historia');
|
|
|
|
tunnit.tunnit.get(1).nimi = 'Historia';
|
2023-08-09 21:44:56 +00:00
|
|
|
assertEq('sama nimi', tunnit.järjestyksessä()[0][1].luokat.alkiot(), ['1B']);
|
|
|
|
tunnit.tunnit.get(0).luokat = new Joukko(['1B']);
|
|
|
|
assertEq('sama luokka', tunnit.järjestyksessä()[0][1].opettajaLyhenteet.alkiot(), ['AS']);
|
|
|
|
tunnit.tunnit.get(0).opettajaLyhenteet = new Joukko(['AS']);
|
2023-08-08 16:08:44 +00:00
|
|
|
assertEq('sama opettaja', tunnit.järjestyksessä()[0][1].kertaaViikossa, 1);
|
|
|
|
tunnit.tunnit.get(1).kertaaViikossa = 1;
|
|
|
|
assertEq('yhtä monta kertaa viikossa', tunnit.järjestyksessä()[0][0], 0);
|
|
|
|
});
|