This commit is contained in:
louiscklaw
2025-02-01 02:01:54 +08:00
parent a767348238
commit d6e3882dd7
188 changed files with 43536 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,35 @@
-module(cw).
-import(string,[len/1, substr/3]).
-import(maps,[foreach/2]).
-export([start/0, test_find/2, ttt/5, checkMatch/3, find_patterns/2]).
checkMatch(Test, Wanted, CheckPos) when Test == Wanted ->
CheckPos -1;
checkMatch(Test, Wanted, CheckPos) when Test /= Wanted ->
"".
ttt(Data, Pattern, DataLength, PatternLength, StartPos) when StartPos >= (DataLength - (PatternLength -1)) ->
checkMatch(substr(Data,StartPos,PatternLength), Pattern, StartPos);
ttt(Data, Pattern, DataLength, PatternLength, StartPos) when StartPos < (DataLength - (PatternLength -1)) ->
[checkMatch(substr(Data,StartPos,PatternLength), Pattern, StartPos)| ttt(Data, Pattern, DataLength, PatternLength, StartPos+1)].
test_find(Data, Pattern) ->
DataLength = len(Data),
PatternLength = len(Pattern),
ttt(Data,Pattern, DataLength, PatternLength, 1).
test_helloworld(Data, []) ->
"";
test_helloworld(Data, [H|T]) ->
[test_find(Data, H) | test_helloworld(Data, T)].
find_patterns(Data, Pattern) ->
io:format(Pattern).
start() ->
io:format("~p~n",[test_helloworld("AAA",["AA"])]),
io:format("~p~n",[test_helloworld("AAA",["AA", "AC"])]),
io:format("~p~n",[test_helloworld("AAC",["AA", "AC"])]),
io:format("~p~n~n",[test_helloworld("AAAAAAAAAAAAAAACCCAAAAAAAAAAAAACCCA",["CC", "CCC"])]),
io:format("done~n").

View File

@@ -0,0 +1,9 @@
services:
ubuntu_1804:
# image: ubuntu:latest
build:
context: .
command: sleep infinity
working_dir: /app
volumes:
- .:/app

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -ex
docker compose up -d --build
docker compose exec -it ubuntu_1804 bash

View File

@@ -0,0 +1,5 @@
FROM ubuntu:latest
RUN apt update -qyy && \
apt install -qyy erlang

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
-module(for_loop).
-import(string,[len/1, substr/3]).
-export([for/4,start/0, helloworld/0]).
for(0,_, D, P) ->
[substr(D, 1, 2)];
for(N,Term, D, P) when N > 0 ->
io:fwrite("~p~n",[substr(D, 4-(N-1), 2)]),
[ok|for(N-1,"A", D, P)].
helloworld() ->
io:fwrite("~p~n",[for(4,1,"AAAA","AA")]).
start() ->
helloworld().

View File

@@ -0,0 +1,9 @@
-module(func_tryout).
-export([add/2,start/0]).
add(X,Y) ->
Z = X+Y,
io:fwrite("~w~n",[Z]).
start() ->
add(5,6).

Binary file not shown.

View File

@@ -0,0 +1,5 @@
-module(hello).
-export([hello_world/0]).
hello_world() ->
io:fwrite("hello, world\n").

View File

@@ -0,0 +1,7 @@
-module(map_tryout).
-export([hello_world/0]).
hello_world() ->
M1 = #{name=>adam,age=>24,date=>{july,29}},
io:format("M1:~p~n", [M1]),
M1.

View File

@@ -0,0 +1,18 @@
{
"name": "hk1234566",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "tests",
"gitUpdate": "git add . && git commit -m 'update Lab7 - Coursework Erlang part,' && git push",
"docker_rebuild": "docker compose up -d",
"into_backend": "docker compose exec -it ubuntu_1804 bash"
},
"scripts": {
"test": "node ./tests/test.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,7 @@
-module(record_tryout).
-export([new/2]).
-record(person, {name, age}).
new(Name, Age) ->
#person{name=Name, age=Age}.

View File

@@ -0,0 +1,9 @@
-module(recursion).
-export([fac/1,start/0]).
fac(N) when N == 0 -> 1;
fac(N) when N > 0 -> N*fac(N-1).
start() ->
X = fac(4),
io:fwrite("~w",[X]).

View File

@@ -0,0 +1,40 @@
% "AAA"
% ["AA"]
% cw:find_patterns("AAA",["AA"])
% [[0,1]]
-module(string_index_of).
-import(string,[len/1, substr/3]).
-import(maps,[foreach/2]).
-export([start/0, test_find/2, ttt/5, checkMatch/3, find_patterns/2]).
checkMatch(Test, Wanted, CheckPos) when Test == Wanted ->
CheckPos -1;
checkMatch(Test, Wanted, CheckPos) when Test /= Wanted ->
"".
ttt(Data, Pattern, DataLength, PatternLength, StartPos) when StartPos >= (DataLength - (PatternLength -1)) ->
checkMatch(substr(Data,StartPos,PatternLength), Pattern, StartPos);
ttt(Data, Pattern, DataLength, PatternLength, StartPos) when StartPos < (DataLength - (PatternLength -1)) ->
[checkMatch(substr(Data,StartPos,PatternLength), Pattern, StartPos) , ttt(Data, Pattern, DataLength, PatternLength, StartPos+1)].
test_find(Data, Pattern) ->
DataLength = len(Data),
PatternLength = len(Pattern),
ttt(Data,Pattern, DataLength, PatternLength, 1).
test_helloworld(Data, []) ->
"";
test_helloworld(Data, [H|T]) ->
[test_find(Data, H) | test_helloworld(Data, T)].
find_patterns(Data, Pattern) ->
io:format(Pattern).
start() ->
io:format("~p~n",[test_helloworld("AAA",["AA"])]),
io:format("~p~n",[test_helloworld("AAA",["AA", "AC"])]),
io:format("~p~n",[test_helloworld("AAC",["AA", "AC"])]),
io:format("~p~n~n",[test_helloworld("AAAAAAAAAAAAAAACCCAAAAAAAAAAAAACCCA",["CC", "CCC"])]),
io:format("done~n").

View File

@@ -0,0 +1,7 @@
-module(string_tryout).
-export([hello_world/0]).
hello_world() ->
M1 = #{name=>adam,age=>24,date=>{july,29}},
io:format("M1:~p~n", [M1]),
M1.

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# rm -rf hello.beam
# erlc ./hello.erl
# erl -noshell -s hello hello_world -s init stop
# rm -rf func_tryout.beam
# erlc ./func_tryout.erl
# erl -noshell -s func_tryout function_test -s init stop
# rm -rf string_index_of.beam
# erlc ./string_index_of.erl
# erl -noshell -s string_index_of start -s init stop
# rm -rf map_tryout.beam
# erlc ./map_tryout.erl
# erl -noshell -s map_tryout hello_world -s init stop
# rm -rf recursion.beam
# erlc ./recursion.erl
# erl -noshell -s recursion start -s init stop
# rm -rf func_tryout.beam
# erlc ./func_tryout.erl
# erl -noshell -s func_tryout start -s init stop
rm -rf cw.beam
erlc ./cw.erl
erl -noshell -s cw start -s init stop
# rm -rf for_loop.beam
# erlc ./for_loop.erl
# erl -noshell -s for_loop start -s init stop
# rm -rf test_list.beam
# erlc ./test_list.erl
# erl -noshell -s test_list start -s init stop
echo 'done'

View File

@@ -0,0 +1,10 @@
-module(test_list).
-import(string,[len/1, substr/3]).
-export([start/0, helloworld/0]).
helloworld() ->
Temp = [1,2,3| [] ],
io:fwrite("~p~n",[Temp]).
start() ->
helloworld().

View File

@@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# grep -rin TODO src
rm -rf delivery.zip
rm -rf delivery
rm -rf _temp
mkdir -p _temp
cp -r src _temp
cp -r tests _temp
cp -r test.sh _temp
# set -ex
7za a -tzip delivery.zip _temp
# rm -rf _temp

View File

@@ -0,0 +1,15 @@
{
"name": "hk1234566",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "tests"
},
"scripts": {
"test": "node ./tests/test.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,44 @@
# RUN
```
# https://filetransfer.io/data-package/98RLRG0M#link
chmod +x ./test.sh
./test.sh
```
# REQUIREMENTS:
<!-- REMEMBER - LOOP STRUCTURES ARE BANNED! -->
### Task 1: Frequency Counts and Sequence Matching (Week 8)
- Notes:
- The returned object MUST have the mentioned structure. Otherwise, auto-testing script will fail to award marks. The returned object MUST contain two properties frequencies and offsets, DO NOT change the name of these properties.
- The offset of a pattern is the number of characters from the start of the data string to the start of the matching sequence.
- The patterns and data can be of arbitrary lengths.
- A pattern could exist in overlapping characters, e.g. AAA contains two patterns of AA at offsets 0 and 1.
- In the supplied .zip file, you should find a JavaScript file named cw.js. This file is a template to base your implementation on. You should not modify the declared variables or the functions signatures 2/5in this file. To run the file, execute node cw.js from the command line or terminal in the programs folder.
### Task 2: Asynchronous execution using callbacks (Week9)
In this task, youve been asked to read two files; file.data, which contains lines of sequences (data) and file.pattern, which contains patterns to look for. Write a function analyse1(datafile, patternfile) that takes the names of the two files and analyses them for pattern matching and offset finding using the find() function you developed in task 1.
The function analyse1() works as the following. It asynchronously reads the contents of the file.pattern file. Once the reading is successful, it asynchronously reads the content of the file.data file and calls the find() function for each data line in the data file.
The results of analysing the files should be stored in the results1 object. This object should contain pairs of data lines from the file.data file as keys and the object returned by the find function as a value. For example, if the data file contains AAA and AAC (each in a separate line) and the pattern file contains AA and AC (each in a separate line), then the object result1 should be
```
results1 = {
AAA: { frequencies: { AA: 2, AC: 0 }, offsets: { AA: [Array], AC: [] } },
AAC: { frequencies: { AA: 1, AC: 1 }, offsets: { AA: [Array], AC: [Array] } }
}
```
In the supplied .zip file, you should find the file.pattern and file.data files. These are just sample files to use. You can create your own data and pattern files (but with the same structure) to test your code.
### Task 3: Asynchronous execution using promises (Week9)
- This task is similar to task 2. The difference is that youve been asked to use promises to process files. For this purpose, youve been asked to do the following:
- Write a function, readFilePromise(), that takes a file name and returns a promise object. The promise should read the file content and returns its contents when fulfilled. Write a function analyse2(datafile, patternfile), that reads and analyses the files for pattern matching (similar to analyse1() ). The function should use the readFilePromise to read the files contents and find() to find matches.
- The results of analysing the files should be stored in the results2 object, which has the same structure as
the object results1 described in Task2 (see above).
### Task 4: Asynchronous execution using async/await (Week9/10)
In this task, youve been asked to write analyse3(datafile, patternfile) function that is similar to analyse2(). The difference is to replace the usage of promises with the async/await. You still need to use the readFilePromise() function to return a promise when reading files.
The results of analysing the files should be stored in the results3 object, which has the same structure as the object results1 described in Task2 (see above).

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,15 @@
const fs = require("fs");
function readFileAsync(path) {
fs.readFile(path, "utf8", function (err, data) {
return data;
});
}
function processData(data) {
console.log(data);
}
let data = readFileAsync("./file.txt");
processData(data);
console.log("processing the rest of the program....");

View File

@@ -0,0 +1,10 @@
{
"ACCA": {
"frequencies": { "C": 2, "CG": 0 },
"offsets": { "C": [1, 2], "CG": [] }
},
"AACGTCGACG": {
"frequencies": { "C": 3, "CG": 3 },
"offsets": { "C": [2, 5, 8], "CG": [2, 5, 8] }
}
}

View File

@@ -0,0 +1,152 @@
"use strict"; // do not modify or delete this line
const fs = require('fs')
//Task 1
//data is a string, patterns is an array of patterns
function find(data, patterns) {
let frequencies = {};
let offsets = {};
//your implementation goes here
// initialize variables
patterns.map((pattern) => (frequencies[pattern] = 0));
patterns.map((pattern) => (offsets[pattern] = []));
// main matching loop
patterns.map((pattern, i) => {
// "AAA" => ["A","A","A"]
// => run matching starting from each characters until data.length - pattern.length + 1
// => i.e. data = "AAAA", pattern = "AA" => (4 - 2) + 1 => 3
data.split("").map((_, idx) => {
if (idx < data.length - pattern.length + 1) {
let searchResult = data.indexOf(pattern, idx);
if (searchResult > -1 && searchResult == idx) {
offsets[pattern].push(searchResult);
}
}
});
});
Object.keys(offsets).map((offset) => {
frequencies[offset] = offsets[offset].length;
});
return {
frequencies,
offsets,
};
}
//use these for results of analyse1, analyse2 and analyse3
let results1 = {};
let results2 = {};
let results3 = {};
// Task 2, Asynchronous execution using callbacks
// Write a function analyse1(datafile, patternfile)
// that takes the names of the two files and analyses them
// for pattern matching and offset finding using the
// find() function you developed in task 1.
function analyse1(dataFile, patternFile) {
//your implementation goes here
fs.readFile(dataFile, { encoding: "utf-8" }, (err, dataFileContent) => {
if (err) throw err.message;
// NOTE: input cleaning
let dataList = dataFileContent.split("\n").map((data) => data.trim());
fs.readFile(patternFile, { encoding: "utf-8" }, (err, patternFileContent) => {
if (err) throw err.message;
// NOTE: input cleaning
let patternList = patternFileContent.split("\n").map((pattern) => pattern.trim());
// main matching
dataList.map((data) => (results1[data] = find(data, patternList)));
// NOTE: print result1 show that working
console.log(results1);
});
});
}
//Task 3, Asynchronous execution using promises
// Write a function, readFilePromise(), that takes a file name and returns a promise object.
// The promise should read the file content and returns its contents when fulfilled.
const readFilePromise = (filePath) => {
//your implementation goes here
return new Promise(function (res, rej) {
fs.readFile(filePath, "utf-8", function (err, data) {
if (err) {
// reject response
rej(err);
} else {
// healthy response
res(data);
}
});
});
};
// Write a function analyse2(datafile, patternfile), that reads and analyses the files for
// pattern matching (similar to analyse1() ). The function should use the readFilePromise to read
// the files contents and find() to find matches.
function analyse2(dataFile, patternFile) {
//your implementation goes here
return Promise.all([readFilePromise(dataFile), readFilePromise(patternFile)]).then(
([dataFileContent, patternFileContent]) => {
// NOTE: input cleaning
var dataList = dataFileContent.split("\n").map((data) => data.trim());
var patternList = patternFileContent.split("\n").map((pattern) => pattern.trim());
// main matching
dataList.map((data, i) => (results2[data] = find(data, patternList)));
// NOTE: print result and show that working
console.log(results2);
}
);
}
//Task 4
// Write a function analyse3(datafile, patternfile),
// using async/await to re-implement the analyse2()
//your implementation for analyse3 goes here
async function analyse3(dataFile, patternFile) {
//your implementation goes here
var dataList = await readFilePromise(dataFile);
var patternList = await readFilePromise(patternFile);
// NOTE: input data cleaning
dataList = dataList.split("\n").map((data) => data.trim());
patternList = patternList.split("\n").map((pattern) => pattern.trim());
// main matching
dataList.map((data) => (results3[data] = find(data, patternList)));
console.log(results3);
}
//-------------------------------------------------------------------------------
//do not modify this function
function print() {
console.log("Printing results...");
Object.keys(results).forEach(function (elem) {
console.log("sequence: ", elem);
console.log("frequencies are: ", results[elem].frequencies);
console.log("offsets are: ", results[elem].offsets);
console.log("---------------------------");
});
}
//--------------- export the find function (required for the marking script)
// module.exports = { find }; //do not modify this line
module.exports = { find, analyse1, analyse2, analyse3 }; //do not modify this line

View File

@@ -0,0 +1,12 @@
AAA
AAC
ACCA
AACGTCGACG
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,9 @@
AA
AC
C
CG
TT
GG
TG
GT
CTG

View File

@@ -0,0 +1,48 @@
"use strict"; // do not modify or delete this line
//Task 1
//data is a string, patterns is an array of patterns
function find(data, patterns) {
let frequencies = {};
let offsets = {};
//your implementation goes here
}
//use these for results of analyse1, analyse2 and analyse3
const results1 = {};
const results2 = {};
const results3 = {};
//Task 2
function analyse1(dataFile, patternFile) {
//your implementation goes here
}
//Task 3
const readFilePromise = (filePath) => {
//your implementation goes here
};
function analyse2(dataFile, patternFile) {
//your implementation goes here
}
//Task 4
//your implementation for analyse3 goes here
//-------------------------------------------------------------------------------
//do not modify this function
function print() {
console.log("Printing results...");
Object.keys(results).forEach(function (elem) {
console.log("sequence: ", elem);
console.log("frequencies are: ", results[elem].frequencies);
console.log("offsets are: ", results[elem].offsets);
console.log("---------------------------");
});
}
//--------------- export the find function (required for the marking script)
module.exports = { find }; //do not modify this line

View File

@@ -0,0 +1,12 @@
AAA
AAC
ACCA
AACGTCGACG
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,9 @@
AA
AC
C
CG
TT
GG
TG
GT
CTG

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -ex
clear
node ./tests/test_task1.js
node ./tests/test_task2.js
node ./tests/test_task3.js
node ./tests/test_task4.js

View File

@@ -0,0 +1,2 @@
ACCA
AACGTCGACG

View File

@@ -0,0 +1,2 @@
C
CG

View File

@@ -0,0 +1,4 @@
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT

View File

@@ -0,0 +1,2 @@
TT
GG

View File

@@ -0,0 +1,4 @@
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,3 @@
TG
GT
CTG

View File

@@ -0,0 +1,14 @@
const cw = require("../src/cw");
// // task 1
// // frequencies: { AA: 2, AC: 0 }, offsets: { AA: [ 0, 1 ], AC: [] }
console.log(cw.find("AAA", ["AA", "AC"]));
// // { frequencies: { AA: 1, AC: 1 }, offsets: { AA: [ 0 ], AC: [ 1 ] } }
console.log(cw.find("AAC", ["AA", "AC"]));
// // {
// // frequencies: { AA: 2, AT: 1, CCA: 1 },
// // offsets: { AA: [ 2, 3 ], AT: [ 4 ], CCA: [ 0 ] }
// // }
console.log(cw.find("CCAAATT", ["AA", "AT", "CCA"]));

View File

@@ -0,0 +1,7 @@
const cw = require("../src/cw");
// // task 2
console.log("task2");
(async () => {
cw.analyse1("./src/file.data", "./src/file.pattern");
})();

View File

@@ -0,0 +1,41 @@
const cw = require("../src/cw");
// task 3
(async () => {
console.log("task3");
var test_result = await cw.analyse2("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// task 3
(async () => {
var test_result = await cw.analyse2("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// TEST CASES1
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test1/file.data", "./tests/test1/file.pattern");
console.log(test_result);
// console.log(test_result["ACCA"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["CG"]);
})();
// TEST CASES2
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test2/file.data", "./tests/test2/file.pattern");
console.log(test_result);
// console.log(test_result["TTGGTTGGTTGG"].offsets["TT"]);
})();
// TEST CASES3
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test3/file.data", "./tests/test3/file.pattern");
console.log(test_result);
// console.log(test_result["CCACTGGGGGGTT"].offsets["GT"]);
// console.log(test_result["CCCGTGGCGGTT"].offsets["GT"]);
})();

View File

@@ -0,0 +1,35 @@
const cw = require("../src/cw");
// task 4
console.log("task4");
(async () => {
var test_result = await cw.analyse3("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// TEST CASES1
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test1/file.data", "./tests/test1/file.pattern");
console.log(test_result);
// console.log(test_result["ACCA"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["CG"]);
})();
// TEST CASES2
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test2/file.data", "./tests/test2/file.pattern");
console.log(test_result);
// console.log(test_result["TTGGTTGGTTGG"].offsets["TT"]);
})();
// TEST CASES3
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test3/file.data", "./tests/test3/file.pattern");
console.log(test_result);
// console.log(test_result["CCACTGGGGGGTT"].offsets["GT"]);
// console.log(test_result["CCCGTGGCGGTT"].offsets["GT"]);
})();

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# grep -rin TODO src
rm -rf delivery-alt.zip
rm -rf delivery
rm -rf _temp
mkdir -p _temp
cp -r src _temp
cp -r tests _temp
cp -r test.sh _temp
# set -ex
7za a -tzip delivery-alt.zip _temp
rm -rf _temp

View File

@@ -0,0 +1,15 @@
{
"name": "hk1234566",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "tests"
},
"scripts": {
"test": "node ./tests/test.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,49 @@
# RUN
```
# https://filetransfer.io/data-package/98RLRG0M#link
chmod +x ./test.sh
./test.sh
```
# REQUIREMENTS:
<!-- REMEMBER - LOOP STRUCTURES ARE BANNED! -->
### Task 1: Frequency Counts and Sequence Matching (Week 8)
- Notes:
- The returned object MUST have the mentioned structure. Otherwise, auto-testing script will fail to award marks. The returned object MUST contain two properties frequencies and offsets, DO NOT change the name of these properties.
- The offset of a pattern is the number of characters from the start of the data string to the start of the matching sequence.
- The patterns and data can be of arbitrary lengths.
- A pattern could exist in overlapping characters, e.g. AAA contains two patterns of AA at offsets 0 and 1.
- In the supplied .zip file, you should find a JavaScript file named cw.js. This file is a template to base your implementation on. You should not modify the declared variables or the functions signatures 2/5in this file. To run the file, execute node cw.js from the command line or terminal in the programs folder.
### Task 2: Asynchronous execution using callbacks (Week9)
In this task, youve been asked to read two files; file.data, which contains lines of sequences (data) and file.pattern, which contains patterns to look for. Write a function analyse1(datafile, patternfile) that takes the names of the two files and analyses them for pattern matching and offset finding using the find() function you developed in task 1.
The function analyse1() works as the following. It asynchronously reads the contents of the file.pattern file. Once the reading is successful, it asynchronously reads the content of the file.data file and calls the find() function for each data line in the data file.
The results of analysing the files should be stored in the results1 object. This object should contain pairs of data lines from the file.data file as keys and the object returned by the find function as a value. For example, if the data file contains AAA and AAC (each in a separate line) and the pattern file contains AA and AC (each in a separate line), then the object result1 should be
```
results1 = {
AAA: { frequencies: { AA: 2, AC: 0 }, offsets: { AA: [Array], AC: [] } },
AAC: { frequencies: { AA: 1, AC: 1 }, offsets: { AA: [Array], AC: [Array] } }
}
```
In the supplied .zip file, you should find the file.pattern and file.data files. These are just sample files to use. You can create your own data and pattern files (but with the same structure) to test your code.
### Task 3: Asynchronous execution using promises (Week9)
- This task is similar to task 2. The difference is that youve been asked to use promises to process files. For this purpose, youve been asked to do the following:
- Write a function, readFilePromise(), that takes a file name and returns a promise object. The promise should read the file content and returns its contents when fulfilled. Write a function analyse2(datafile, patternfile), that reads and analyses the files for pattern matching (similar to analyse1() ). The function should use the readFilePromise to read the files contents and find() to find matches.
- The results of analysing the files should be stored in the results2 object, which has the same structure as
the object results1 described in Task2 (see above).
### Task 4: Asynchronous execution using async/await (Week9/10)
In this task, youve been asked to write analyse3(datafile, patternfile) function that is similar to analyse2(). The difference is to replace the usage of promises with the async/await. You still need to use the readFilePromise() function to return a promise when reading files.
The results of analysing the files should be stored in the results3 object, which has the same structure as the object results1 described in Task2 (see above).

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,15 @@
const fs = require("fs");
function readFileAsync(path) {
fs.readFile(path, "utf8", function (err, data) {
return data;
});
}
function processData(data) {
console.log(data);
}
let data = readFileAsync("./file.txt");
processData(data);
console.log("processing the rest of the program....");

View File

@@ -0,0 +1,10 @@
{
"ACCA": {
"frequencies": { "C": 2, "CG": 0 },
"offsets": { "C": [1, 2], "CG": [] }
},
"AACGTCGACG": {
"frequencies": { "C": 3, "CG": 3 },
"offsets": { "C": [2, 5, 8], "CG": [2, 5, 8] }
}
}

View File

@@ -0,0 +1,173 @@
"use strict"; // do not modify or delete this line
//Task 1
// TODO: remove me
//data is a string, patterns is an array of patterns
function find(data, patterns) {
let frequencies = {};
let offsets = {};
//your implementation goes here
const findMatch = (A, B) => A.every((t, i) => t == B[i]);
let data_length = data.length;
// run on every pattern from function input
patterns.map((pattern) => {
let pattern_length = pattern.length;
// i.e. "AAA", "AA" => check 2 times
Array(data_length - 1)
.fill("")
.map((_, offset) => {
// split from data => "AAA" => "AA"
let data_to_check = data.substr(offset, pattern_length);
// for symmetricity, do that to pattern too
let pattern_to_check = pattern;
if (findMatch(data_to_check.split(""), pattern_to_check.split(""))) {
// initialize obj if not done yet
if (frequencies[pattern] == undefined) frequencies[pattern] = 0;
if (offsets[pattern] == undefined) offsets[pattern] = [];
// update counters
offsets[pattern].push(offset);
frequencies[pattern] = frequencies[pattern] + 1;
}
});
});
return { frequencies, offsets };
}
//use these for results of analyse1, analyse2 and analyse3
let results1 = {};
let results2 = {};
let results3 = {};
// Task 2, Asynchronous execution using callbacks
// TODO: remove me
// Write a function analyse1(datafile, patternfile)
// that takes the names of the two files and analyses them
// for pattern matching and offset finding using the
// find() function you developed in task 1.
function analyse1(dataFile, patternFile) {
//your implementation goes here
const fs = require("fs");
fs.readFile(dataFile, "utf-8", (err, allData) => {
fs.readFile(patternFile, "utf-8", (err, allPattern) => {
let dataList = allData
.replace(/\r\n/g, "\n")
.split(/\n/)
.filter((d) => d != "");
let patternList = allPattern
.replace(/\r\n/g, "\n")
.split(/\n/)
.filter((p) => p != "");
let dataListLength = dataList.length;
// main matching
Array(dataListLength)
.fill("")
.map((x, i) => {
let data = dataList[i];
results1[data] = find(data, patternList);
});
// TODO: remove me
// NOTE: print result1 show that working
console.log(results1);
});
});
}
//Task 3, Asynchronous execution using promises
// TODO: remove me
// Write a function, readFilePromise(), that takes a file name and returns a promise object.
// The promise should read the file content and returns its contents when fulfilled.
const readFilePromise = (filePath) => {
//your implementation goes here
const fs = require("fs");
return new Promise((response, reject) => {
fs.readFile(filePath, "utf-8", function (err, data) {
// NOTE: if error reject without mercy
if (err) reject(err);
// NOTE: no error fall here
response(data);
});
});
};
// TODO: remove me
// Write a function analyse2(datafile, patternfile), that reads and analyses the files for
// pattern matching (similar to analyse1() ). The function should use the readFilePromise to read
// the files contents and find() to find matches.
async function analyse2(dataFile, patternFile) {
//your implementation goes here
// NOTE: read files by promise
let [contentData, contentPattern] = await Promise.all([readFilePromise(dataFile), readFilePromise(patternFile)]);
// parse file, split by line break
let listData = contentData.replace(/\r\n/g, "\n").split(/\n/);
let listPattern = contentPattern.replace(/\r\n/g, "\n").split(/\n/);
// main matching loop
listData.map((data, i) => (results2[data] = find(data, listPattern)));
// TODO: remove me
// NOTE: print result and show that working
console.log(results2);
return;
}
//Task 4
// TODO: remove me
// Write a function analyse3(datafile, patternfile),
// using async/await to re-implement the analyse2()
//your implementation for analyse3 goes here
async function analyse3(dataFile, patternFile) {
//your implementation goes here
// REF: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise
return await readFilePromise(dataFile)
.then(async (dataFileContent) => {
let patternFileContent = await readFilePromise(patternFile);
return { dataFileContent, patternFileContent };
})
.then(({ dataFileContent, patternFileContent }) => {
dataFileContent = dataFileContent.replace(/\r\n/g, "\n").split(/\n/);
patternFileContent = patternFileContent.replace(/\r\n/g, "\n").split(/\n/);
// main matching
dataFileContent.map((data) => (results3[data] = find(data, patternFileContent)));
// TODO: remove me
console.log(results3);
});
}
//-------------------------------------------------------------------------------
//do not modify this function
function print() {
console.log("Printing results...");
Object.keys(results).forEach(function (elem) {
console.log("sequence: ", elem);
console.log("frequencies are: ", results[elem].frequencies);
console.log("offsets are: ", results[elem].offsets);
console.log("---------------------------");
});
}
//--------------- export the find function (required for the marking script)
// module.exports = { find }; //do not modify this line
module.exports = { find, analyse1, analyse2, analyse3 }; //do not modify this line

View File

@@ -0,0 +1,12 @@
AAA
AAC
ACCA
AACGTCGACG
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,9 @@
AA
AC
C
CG
TT
GG
TG
GT
CTG

View File

@@ -0,0 +1,48 @@
"use strict"; // do not modify or delete this line
//Task 1
//data is a string, patterns is an array of patterns
function find(data, patterns) {
let frequencies = {};
let offsets = {};
//your implementation goes here
}
//use these for results of analyse1, analyse2 and analyse3
const results1 = {};
const results2 = {};
const results3 = {};
//Task 2
function analyse1(dataFile, patternFile) {
//your implementation goes here
}
//Task 3
const readFilePromise = (filePath) => {
//your implementation goes here
};
function analyse2(dataFile, patternFile) {
//your implementation goes here
}
//Task 4
//your implementation for analyse3 goes here
//-------------------------------------------------------------------------------
//do not modify this function
function print() {
console.log("Printing results...");
Object.keys(results).forEach(function (elem) {
console.log("sequence: ", elem);
console.log("frequencies are: ", results[elem].frequencies);
console.log("offsets are: ", results[elem].offsets);
console.log("---------------------------");
});
}
//--------------- export the find function (required for the marking script)
module.exports = { find }; //do not modify this line

View File

@@ -0,0 +1,12 @@
AAA
AAC
ACCA
AACGTCGACG
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,9 @@
AA
AC
C
CG
TT
GG
TG
GT
CTG

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -ex
clear
node ./tests/task1.js
# node ./tests/task2.js
# node ./tests/task3.js
# node ./tests/task4.js

View File

@@ -0,0 +1,14 @@
const cw = require("../src/cw");
// // task 1
// // frequencies: { AA: 2, AC: 0 }, offsets: { AA: [ 0, 1 ], AC: [] }
console.log(cw.find("AAA", ["AA", "AC"]));
// // { frequencies: { AA: 1, AC: 1 }, offsets: { AA: [ 0 ], AC: [ 1 ] } }
console.log(cw.find("AAC", ["AA", "AC"]));
// // {
// // frequencies: { AA: 2, AT: 1, CCA: 1 },
// // offsets: { AA: [ 2, 3 ], AT: [ 4 ], CCA: [ 0 ] }
// // }
console.log(cw.find("CCAAATT", ["AA", "AT", "CCA"]));

View File

@@ -0,0 +1,7 @@
const cw = require("../src/cw");
// // task 2
console.log("task2");
(async () => {
cw.analyse1("./src/file.data", "./src/file.pattern");
})();

View File

@@ -0,0 +1,41 @@
const cw = require("../src/cw");
// task 3
(async () => {
console.log("task3");
var test_result = await cw.analyse2("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// task 3
(async () => {
var test_result = await cw.analyse2("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// TEST CASES1
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test1/file.data", "./tests/test1/file.pattern");
console.log(test_result);
// console.log(test_result["ACCA"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["CG"]);
})();
// TEST CASES2
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test2/file.data", "./tests/test2/file.pattern");
console.log(test_result);
// console.log(test_result["TTGGTTGGTTGG"].offsets["TT"]);
})();
// TEST CASES3
// task 3
(async () => {
var test_result = await cw.analyse2("./tests/test3/file.data", "./tests/test3/file.pattern");
console.log(test_result);
// console.log(test_result["CCACTGGGGGGTT"].offsets["GT"]);
// console.log(test_result["CCCGTGGCGGTT"].offsets["GT"]);
})();

View File

@@ -0,0 +1,35 @@
const cw = require("../src/cw");
// task 4
console.log("task4");
(async () => {
var test_result = await cw.analyse3("./src/file.data", "./src/file.pattern");
console.log(test_result);
})();
// TEST CASES1
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test1/file.data", "./tests/test1/file.pattern");
console.log(test_result);
// console.log(test_result["ACCA"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["C"]);
// console.log(test_result["AACGTCGACG"].offsets["CG"]);
})();
// TEST CASES2
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test2/file.data", "./tests/test2/file.pattern");
console.log(test_result);
// console.log(test_result["TTGGTTGGTTGG"].offsets["TT"]);
})();
// TEST CASES3
// task 4
(async () => {
var test_result = await cw.analyse3("./tests/test3/file.data", "./tests/test3/file.pattern");
console.log(test_result);
// console.log(test_result["CCACTGGGGGGTT"].offsets["GT"]);
// console.log(test_result["CCCGTGGCGGTT"].offsets["GT"]);
})();

View File

@@ -0,0 +1,2 @@
ACCA
AACGTCGACG

View File

@@ -0,0 +1,4 @@
TTGGTTGGTTGG
CCCTTGCGGTT
CCAAGGGGGTT
CCCGGGCGGTT

View File

@@ -0,0 +1,4 @@
TTGGTTGGTTGG
CCCTGGCGGTT
CCACTGGGGGGTT
CCCGTGGCGGTT

View File

@@ -0,0 +1,3 @@
TG
GT
CTG