I've been trying to replicate the Discord-Famous Discord Bot Mee6's Experience Algorithm in NodeJS (the OG Bot is in Python) but every attempt im stumped by static values.
function XPValue(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
XPValue(15, 25) // This Randomizes as normal
const curLevel = Math.floor(0.5 * Math.sqrt(XPValue(15, 25))); //When put it here it becomes a static number and never changes
I don't understand how I can get the XP to randomize as I actually want it to do using the XPValue function, even though it's passed through that function it keeps a static value of 2
the issue was the variable once assign it wouldn't changed the value per execution where as using a getter fixed this issue:
const Experience = {
get random() {
var rand = Math.floor(Math.random() * 15);
return rand + (25 - 15);
}
};
credits to Zelak (PlexiDev)
Related
Each instance of my app has a different policy for paying commission to sales reps. Currently I'm using environment variables such as:
// Client 1
SALES_COMMISSION_BASIS = "PERCENTAGE"
SALES_COMMISSION_PERCENT = 15%
// Client 2
SALES_COMMISSION_BASIS = "FLAT_RATE"
SALES_COMMISSION_AMOUNT = £42
I then have a function that returns the commission calculated according to the basis
const commission = (totalFee) => {
switch (SALES_COMMISSION_BASIS) {
case "PERCENTAGE":
return (totalFee * SALES_COMMISSION_PERCENT)
break;
case "FLAT_RATE":
return (SALES_COMMISSION_AMOUNT)
break;
}
}
I could of course simplify this to always return (totalFee * SALES_COMMISSION_PERCENT + SALES_COMMISSION_AMOUNT) but this would still mean that I am including logic for percent-based commission in a flat-rate client and vice-versa, which is what I am seeking to avoid.
What I'd like to do instead is save the commission function into my environment variables.
// Client 1
SALES_COMMISSION_FUNCTION = "(totalFee) => totalFee * 0.15"
// Client 2
SALES_COMMISSION_FUNCTION = "() => 42"
While none of this is particularly language specific, it's worth noting that I'm working with an Express app in Node JS, and I'm currently using dotenv to store environment variables.
My questions are:
Is saving the function to an environment the correct approach?
How would I implement this in a NodeJS app?
I'm doing a few tutorials on CosmosDB. I've got the database set up with the Core (SQL) API, and using Node.js to interface with it. for development, I'm using the emulator.
This is the bit of code that I'm running:
const CosmosClient = require('#azure/cosmos').CosmosClient
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const options = {
endpoint: 'https://localhost:8081',
key: REDACTED,
userAgentSuffix: 'CosmosDBJavascriptQuickstart'
};
const client = new CosmosClient(options);
(async () => {
let cost = 0;
let i = 0
while (i < 2000) {
i += 1
console.log(i+" Creating record, running cost:"+cost)
let response = await client.database('TestDB').container('TestContainer').items.upsert({}).catch(console.log);
cost += response.requestCharge;
}
})()
This, without fail, stops at around iteration 1565, and doesn't continue. I've tried it with different payloads, without much difference (it may do a few more or a few less iterations, but seems to almsot always be around that number)
On the flipside, a similar .NET Core example works great to insert 10,000 documents:
double cost = 0.0;
int i = 0;
while (i < 10000)
{
i++;
ItemResponse<dynamic> resp = await this.container.CreateItemAsync<dynamic>(new { id = Guid.NewGuid() });
cost += resp.RequestCharge;
Console.WriteLine("Created item {0} Operation consumed {1} RUs. Running cost: {2}", i, resp.RequestCharge, cost);
}
So I'm not sure what's going on.
So, after a bit of fiddling, this doesn't seem to have anything to do with CosmosDB or it's library.
I was running this in the debugger, and Node would just crap out after x iterations. I noticed if I didn't use a console.log it would actually work. Also, if I ran the script with node file.js it also worked. So there seems to be some sort of issue with debugging the script while also printing to the console. Not exactly sure whats up with that, but going to go ahead and mark this as solved
I am trying to learn how to use Processing, and so am attempting to use the sound library. When running the either of the first two example programs provided at https://processing.org/tutorials/sound/, the IDE responds with this error:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'RtAudioError'
what(): RtApiWasapi::getDeviceInfo: Unable to retrieve device mix format.
Could not run the sketch (Target VM failed to initialize).
For more information, read revisions.txt and Help ? Troubleshooting.
Also, whenever I try to run a sketch using this library, along with that error, windows says
Java(TM) Platform SE binary has stopped working
Windows is collecting more information about the problem. This might take several minutes...
Could you help me to resolve this issue? I am using a windows vista computer.
This is the second example code:
/**
* Processing Sound Library, Example 2
*
* This sketch shows how to use envelopes and oscillators.
* Envelopes describe to course of amplitude over time.
* The Sound library provides an ASR envelope which stands for
* attack, sustain, release.
*
* .________
* . ---
* . ---
* . ---
* A S R
*/
import processing.sound.*;
// Oscillator and envelope
TriOsc triOsc;
Env env;
// Times and levels for the ASR envelope
float attackTime = 0.001;
float sustainTime = 0.004;
float sustainLevel = 0.2;
float releaseTime = 0.2;
// This is an octave in MIDI notes.
int[] midiSequence = {
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72
};
// Set the duration between the notes
int duration = 200;
// Set the note trigger
int trigger = 0;
// An index to count up the notes
int note = 0;
void setup() {
size(640, 360);
background(255);
// Create triangle wave and envelope
triOsc = new TriOsc(this);
env = new Env(this);
}
void draw() {
// If value of trigger is equal to the computer clock and if not all
// notes have been played yet, the next note gets triggered.
if ((millis() > trigger) && (note<midiSequence.length)) {
// midiToFreq transforms the MIDI value into a frequency in Hz which we use
//to control the triangle oscillator with an amplitute of 0.8
triOsc.play(midiToFreq(midiSequence[note]), 0.8);
// The envelope gets triggered with the oscillator as input and the times and
// levels we defined earlier
env.play(triOsc, attackTime, sustainTime, sustainLevel, releaseTime);
// Create the new trigger according to predefined durations and speed
trigger = millis() + duration;
// Advance by one note in the midiSequence;
note++;
// Loop the sequence
if (note == 12) {
note = 0;
}
}
}
// This function calculates the respective frequency of a MIDI note
float midiToFreq(int note) {
return (pow(2, ((note-69)/12.0)))*440;
}
I want a piece of code to repeat 100 times with 1 sec of delay in between. This is my code:
for(var i = 0; i < 100; i++){
setTimeout(function(){
//do stuff
},1000);
}
While this seems correct to me it is not. Instead of running "do stuff" 100 times and waiting 1 sec in between what it does is wait 1 sec and then run "do stuff" 100 times with no delay.
Anybody has any idea about this?
You can accomplish it by using setInterval().
It calls function of our choice as long as clearTimeout is called to a variable timer which stores it.
See example below with comments: (and remember to open your developer console (in chrome right click -> inspect element -> console) to view console.log).
// Total count we have called doStuff()
var count = 0;
/**
* Method for calling doStuff() 100 times
*
*/
var timer = setInterval(function() {
// If count increased by one is smaller than 100, keep running and return
if(count++ < 100) {
return doStuff();
}
// mission complete, clear timeout
clearTimeout(timer);
}, 1000); // One second in milliseconds
/**
* Method for doing stuff
*
*/
function doStuff() {
console.log("doing stuff");
}
Here is also: jsfiddle example
As a bonus: Your original method won't work because you are basically assigning 100 setTimeout calls as fast as possible. So instead of them running with one second gaps. They will run as fast as the for loop is placing them to queue, starting after 1000 milliseconds of current time.
For instance, following code shows timestamps when your approach is used:
for(var i = 0; i < 100; i++){
setTimeout(function(){
// Current time in milliseconds
console.log(new Date().getTime());
},1000);
}
It will output something like (milliseconds):
1404911593267 (14 times called with this timestamp...)
1404911593268 (10 times called with this timestamp...)
1404911593269 (12 times called with this timestamp...)
1404911593270 (15 times called with this timestamp...)
1404911593271 (12 times called with this timestamp...)
You can see the behaviour also in: js fiddle
You need to use callback, node.js is asynchronous:
function call_1000times(callback) {
var i = 0,
function do_stuff() {
//do stuff
if (i < 1000) {
i = i + 1;
do_stuff();
} else {
callback(list);
}
}
do_stuff();
}
Or, more cleaner:
setInterval(function () {
//do stuff
}, 1000);
Now that you appreciate that the for loop is iterating in a matter of milliseconds, another way to do it would be to simply adjust the setTimeout delay according to the count.
for(var i = 0; i < 100; i++){
setTimeout(function(){
//do stuff
}, i * 1000);
}
For many use-cases, this could be seen as bad. But in particular circumstances where you know that you definitely want to run code x number of times after y number of seconds, it could be useful.
It's also worth noting there are some that believe using setInterval is bad practise.
I prefer the recursive function. Call the function initially with the value of counter = 0, and then within the function check to see that counter is less than 100. If so, do your stuff, then call setTimeout with another call to doStuff but with a value of counter + 1. The function will run exactly 100 times, once per second, then quit :
const doStuff = counter => {
if (counter < 100) {
// do some stuff
setTimeout(()=>doStuff(counter + 1), 1000)
}
return;
}
doStuff(0)
Say I have a link aggregation app where users vote on links. I sort the links using hotness scores generated by an algorithm that runs whenever a link is voted on. However running it on every vote seems excessive. How do I limit it so that it runs no more than, say, every 5 minutes.
a) use cron job
b) keep track of the timestamp when the procedure was last run, and when the current timestamp - the timestamp you have stored > 5 minutes then run the procedure and update the timestamp.
var yourVoteStuff = function() {
...
setTimeout(yourVoteStuff, 5 * 60 * 1000);
};
yourVoteStuff();
Before asking why not to use setTimeinterval, well, read the comment below.
Why "why setTimeinterval" and no "why cron job?"?, am I that wrong?
First you build a receiver that receives all your links submissions.
Secondly, the receiver push()es each link (that has been received) to
a queue (I strongly recommend redis)
Moreover you have an aggregator which loops with a time interval of your desire. Within this loop each queued link should be poll()ed and continue to your business logic.
I have use this solution to a production level and I can tell you that scales well as it also performs.
Example of use;
var MIN = 5; // don't run aggregation for short queue, saves resources
var THROTTLE = 10; // aggregation/sec
var queue = [];
var bucket = [];
var interval = 1000; // 1sec
flow.on("submission", function(link) {
queue.push(link);
});
___aggregationLoop(interval);
function ___aggregationLoop(interval) {
setTimeout(function() {
bucket = [];
if(queue.length<=MIN) {
___aggregationLoop(100); // intensive
return;
}
for(var i=0; i<THROTTLE; ++i) {
(function(index) {
bucket.push(this);
}).call(queue.pop(), i);
}
___aggregationLoop(interval);
}, interval);
}
Cheers!