Getting a 'random' value from a module in node.js - javascript

Let's say I have a file that looks like this:
var random_nr = Math.floor(Math.random()*array.length);
var x = array[random_nr];
// do some things
exports.random_array_member = x
Now, if I 'require' this in another file, I will always get the same result as long as I don't restart my server, presumably because of caching?
What is the best way to run this code and get a random value, while not including the code into my main file?

The code you have shown is only executed once. The result from that code is then stored as a variable, ready to be exported to whatever file needs it.
Instead, you need to "call" the code at the moment you need a random variable:
exports.random_array_member = function(){
var random_nr = Math.floor(Math.random()*array.length);
return array[random_nr];
}
Now, instead of accessing exports.random_array_member, you call exports.random_array_member() in your other files.

Lets play with getters
random.js
var array = [1, 2, 3, 4, 5];
module.exports = {
get random_array_member() {
return array[Math.floor(Math.random()*array.length)]
}
}
consumer.js
var r = require('./random')
console.log(r.random_array_member)
console.log(r.random_array_member)
console.log(r.random_array_member)

Related

Read from 2 Different file to be 2 dimensional array Javascript

How to read two .txt files and turn these 2 files to a 2d array?
I already have a code like this :
var fs = require('fs')
file = './text1.txt'
fs.readFile(file,'utf-8', (e,d) => {
textByLine = d.split('\r\n');
console.log("test : " + textByLine[1])
})
source
I succeeded to store the file in a 1d array but now I have 2 files and I want to store them in a 2d array.
How to do this?
Thank you
You can have a variable at top with an empty array, after you read the files and push that result to that variable , like this:
const 2dArray = [];
const fillArray = (path)=> {
fs.readFile(path,'utf-8', (e,d) => {
2dArray.push(d.split('\r\n')) // the result is already an array.
});
});
after that you can call each file like this :
// read the files and push the result to the variable 2dArray
fillArray('./text1.txt');
fillArray('./text2.txt');
//you can read the 1st result of your 1st file array like this
const firstPartOfArray = 2dArray[0][0]; // text1 first result value
if you don't need to have the result files in order i strongly recommend to use async function.
also you can use thinks like fs-jetpack package to handle this, or glob

How to save strings to SPECIFIC location in p5.js

Here I have a code that I was playing around with.
It loads a string within my file and saves an unimportant one.
var file = "1";
var result;
var meString;
var splitMeString;
function preload() {
result = loadStrings("assets/save/"+file+".txt");
}
function setup() {
createCanvas(1000,650);
}
function draw() {
meString = result+'';
splitMeString = splitTokens(meString, ',');
text(meString,20,20);
console.log(splitMeString[2]);
}
function mousePressed(){
saveStrings("happy");
}
but how would I save a string to a specific location? Say I wanted to overwrite the file ("file")?
Questions like these are best answered by looking in the reference.
According to the reference, the saveStrings() function can take three arguments:
Syntax
saveStrings(list,filename,[extension])
Parameters
list String[]: string array to be written
filename String: filename for output
extension String: the filename's extension
So it sounds like you're looking for something like this:
saveStrings(yourArray, "file", "txt");
Also note that the third argument is optional, so this should also work:
saveStrings(yourArray, "file");
If you use the functions storeItem() and getItem() you can save strings to your program, this won't save it to a specific file embedded in your code but it will save it to your code. You can call whatever you stored in storeItem() with getItem()even after you close out of the tab. If you need any more info on it you can find it on the reference page here.
Hope this helps!

nodejs: run module in sandbox

I have this turn-based NodeJs gaming app in which developers (anyone) can submit a player-robot. My NodeJS app will load all players and let them play against each other. Because I don't know anything about the code submitted I need to run it inside a sandbox.
For example, the following untrusted code might look like this:
let history = [];
export default class Player {
constructor () {
this.history = [];
}
move (info) {
this.history.push(info);
}
done(result) {
history.push({result: result, history: this.history});
}
}
Now, in my main app I would like to do something like
import Player1 from 'sandbox/player1';
import Player2 from 'sandbox/player2';
....
for (let outer = 0; outer < 10; outer ++) {
let player1 = creeateSandboxedInstance(Player1);
let player2 = creeateSandboxedInstance(Player2);
for(let inner = 0; inner < 1000000; inner ++) {
...
let move1 = player1.move();
let move2 = player2.doMove();
...
}
}
What I would like the sandbox/creeateSandboxedInstance environment to take care of is:
Player class should not give access to the filesystem / internet
Player class should not have access to app global variables
Any state should be reseted (like class variables)
probably more things :)
I think that I should use the vm module. Something like this probably:
var vm = require('vm');
var script = new vm.Script('function move(info){ ... } ...', {conext});
var sandbox = script.runInNewContext();
script.move(..); // or
sandbox.move(..);
However, I cannot get it to work such that I can call the move method. Is something like even possible ?
Don't do this yourself. Use an existing library. There are quite a few issues you have to deal with if you were to write it yourself. For example: How do you handle a user writing a never ending for-loop?
How to run untrusted code serverside?
If you are planning on writing it yourself then yes, you will need the vm module.
By passing in an empty "sandbox" you have removed all global variables.
script.runInNewContext({});
Next you'll need to figure out how you want to handle the never ending for-loop. You'll have to create a new process to handle this scenario. Do you create 1 process to manage ALL untrusted code? If you do then you'll have to kill ALL untrusted code if a single script hangs. Do you create a new process for each untrusted code? If you do then you won't be happy with performance. Creating a new process can take a second or two. You could require the child process to "notify" the main process it's still alive. If it fails to notify within 5 seconds (or whatever your threshold is, kill the process). Note: script.runInNewContext does contain an option that lets you specify a "timeout" (if the code takes longer than X seconds - throw an exception), but the problem with that is it allows async code (according to another Stackoverflow post), although you could defend against that by not introducing setTimeout, setInterval, or setImmediate into the scope. However, even if you set it to 1 second, NO other code can run during that second in that process. So if you have 1000 scripts to run, it could take up to 1000 seconds (16 minutes) to run them all. At least running each in their own process will let them run in parallel.
Here's an example of why the timeout option won't work for you:
var script = new vm.Script('move = function move(info) { for(var i = 0; i < 100000; i++) { console.log(i); } }');
var sandbox = { move: null, console: console };
var result = script.runInNewContext(sandbox, { timeout: 1 });
sandbox.move('woah');
Next you'll need to figure out how to communicate from your main process, into a child process and then into the vm. I'm not going to get into communicating between processes as you can find that pretty easily. So, by calling script.runInNewContext you are executing the code right then and there. Which lets you set global variables:
var script = new vm.Script('move = function move(info) { console.log("test: " + info); }');
var sandbox = { move: null, console: console };
var result = script.runInNewContext(sandbox);
sandbox.move('success');

Javascript OOP events

I want to create an object that can parse a certain filetype. I've looked at some of the files in the File API and I want my object to work about the same. So basically, what I want is this:
A function, called CustomFileParser. I want to be able to use it as the following:
var customFileParser = new CustomFileParser();
customFileParser.parsed = paresed;
customFileParser.progress = progress;
customFileParser.parse(file);
function parsed(event){
//The file is loaded, you can do stuff with it here.
}
function progess(event){
//The file load has progressed, you can do stuff with it here.
}
So I was thinking on how to define this object, but I'm not sure how to define these events and how I should do this.
function customFileParser(){
this.parse = function(){
//Do stuff here and trigger event when it's done...
}
}
However, I'm not sure how to define these events, and how I can do this. Anyone can give me a hand?
Javscript is prototype-based OOP language, not class-based like most other popular languages. Therefore, the OOP constructs are a bit different from what you might be used to. You should ignore most websites that try to implement class-based inheritance in JS, since that's not how the language is meant to be used.
The reason people are doing it because they are used to the class-based system and are usually not even aware that are alternatives to that, so instead of trying to learn the correct way, they try to implement the way that they are more familiar with, which usually results in loads and loads of hacks or external libraries that are essentially unnecessary.
Just use the prototype.
function CustomFileParser(onParsed, onProgress) {
// constructor
this.onParsed = onParsed;
this.onProgress = onProgress;
};
CustomFileParser.prototype.parse = function(file) {
// parse the file here
var event = { foo: 'bar' };
this.onProgress(event);
// finish parsing
this.onParsed(event);
};
And you can use it like so
function parsed(event) {
alert(event);
}
function progress(event) {
alert(event);
}
var customFileParser = new CustomFileParser(parsed, progress);
var file = ''; // pseudo-file
customFileParser.parse(file);
From what it sounds to me i think you need your program to look like this
function customFileParser( onparse , progress){
this.onparse = onparse;
this.progressStatus = 0;
this.progress = progress;
this.parser = function (chunk)
}
this.parse = function(){
// Do stuff of parsing
// Determine how much data is it
// Now make a function that parses a bit of data in every run
// Keep on calling the function till the data is getting parsed
// THat function should also increase the percentage it think this can be done via setTimeout.
// After every run of the semi parser function call the progress via something like
this.parser();
if(progressStatus <100){
this.progress(this.progressStatus);
}else{
this.parsed();
}
}
}
and u can create instance of that object like
var dark = new customFileParser( function () { // this tells what to
do what parsed is complete } , function (status) { // this tells what
to do with the progress status } ) ;
using the method i suggested. you can actually define different methods for all the instances of the object you have !

Try to use node.js, fs.read

This is how I am calling fs.read, but I'm continually getting an error. Is there something wrong here with my syntax?
The error on the command line is: "errorCode": -1,
var fs = IMPORTS.require('fs'),
sys = IMPORTS.require("sys")
var file= this.filename,
start= parseInt(offsetStart),
end= parseInt(offsetEnd);
bufSize = 64 * 1024;
fs.open(file,'r',0666,function(err,fd) {
fs.read(fd,bufSize,0,end,start,function(err,str,count) {
result = { reply:str,
reply2:count
};}); });
It might help if you explain what you are doing here. Why are you opening a file and what are you trying to read from it?
If it is a textfile it may be simpler to use a ReadStream something like this:
inp = fs.createReadStream('sample.txt');
inp.setEncoding('utf8');
inptext = '';
inp.on('data', function (data) {
inptext += data;
});
inp.on('end', function (close) {
console.log(inptext);
});
You might want to look at your code and ask yourself where the data in your return statement goes. If you really want to use a callback chain, you might try passing in an empty object, and then fill that with data, so that you don't have to worry about sending the data back up the callback chain.
if you expect up to 100k and the buffer is 64k, and the image is offset, could it be getting the first 57K of something starting around 7k?
What happens if the bufSize is 256 * 1024?
Can the values of offsetStart and offsetEnd be displayed or dumped? They seem worth knowing.
Also, is the second value really an offset, or is it a length?

Categories