I wrote this script based on information I read here on Stack. It calls data from an API and is supposed to convert the directional degrees to cardinal. When I run it, I get no output. There is no error when I inspect the page. I found no syntax errors when I ran it through Fiddle.
I thought I could simply substitute a number (I tried 45) for num and get the script to run to no avail so I could use an expert eye. Thank you.
var settings = {
"url": "https://api.stormglass.io/v1/weather/point?lat=40.370181&lng=-73.934193&key=...",
"method": "GET",
"timeout": 0,
};
$.ajax(settings)
.fail(function(a,b,c) { console.log(a.responseJSON) })
.done(function(response) {
console.log(response);
variconwndr24 = function degToCompass(num) {
var num = response.hours[17].windDirection[1].value;;
while (num < 0) num += 360;
while (num >= 360) num -= 360;
val = Math.round((num - 11.25) / 22.5);
arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE",
"SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
];
return arr[Math.abs(val)];
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
First off, try something like this instead:
var settings = {
"url": "https://api.stormglass.io/v1/weather/point?lat=40.370181&lng=-73.934193&key=xdvfd",
"method": "GET",
"timeout": 0,
};
$.ajax(settings).done(function(response) {
console.log(response);
var degrees = response.hours[17].windDirection[1].value;
variconwndr24 = degToCompass(degrees);
console.log(variconwndr24);
return variconwndr24;
});
function degToCompass(num) {
while (num < 0) num += 360;
while (num >= 360) num -= 360;
val = Math.round((num - 11.25) / 22.5);
arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE",
"SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
];
console.log(arr[Math.abs(val)]);
return arr[Math.abs(val)];
}
In the way you did it, degToCompass never actually gets called, and the num argument becomes redundant because you immediately redefine it.
The main problem is in the callback function for done. You're defining a function degToCompass, but that function is never called. Additionally, you're re-defining a parameter for the function that you passed. No point in passing num as a parameter if you just overwrite it. Instead just pass response's desired value as the parameter. Also, for the sake of readability and maintenance, try breaking this up like this :
const arr = [
"N",
"NNE",
"NE",
"ENE",
"E",
"ESE",
"SE",
"SSE",
"S",
"SSW",
"SW",
"WSW",
"W",
"WNW",
"NW",
"NNW"
];
var settings =
{
"url": "https://api.stormglass.io/v1/weather/point?lat=40.370181&lng=-73.934193&key=...",
"method": "GET",
"timeout": 0,
};
function degToCompass(num)
{
while (num < 0)
{
num += 360;
}
while (num >= 360)
{
num -= 360;
}
val = Math.round((num - 11.25) / 22.5);
return arr[Math.abs(val)];
}
function faiureCallback(a, b, c)
{
console.log(a.responseJSON);
}
function doneCallback(response)
{
// Do some stuff
var num = response.hours[17].windDirection[1].value;;
return degToCompass(num)
}
$.ajax(settings)
.fail(faiureCallback)
.done(doneCallback);
Related
edit: I think I've fixed the 2d array bit... I forgot brackets()
edit number 2: the if didn't work because I used a single = sign setting j to 0 every loop (: using == fixed the issue. oh the joys of coding!
first post.
I'm trying to code a fretboard which I will modify and add to over time but I'm having problems.
I can render the frets, strings and circles fine, even the notes on the circles, but getting the base note to show is a pain.
I have commented out the problem lines, near the bottom of the code. The if function causes p5.js to freeze, the 2d array doesn't seem to get defined even though I push an array into the empty array.
help?
let stringNumber = 6;
let fretNumber = 22;
let notes = ["a", "a#", "b", "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#"]
let baseNotes = [7, 0, 5, 10, 2, 7];
let fretboardWidth = 0;
let fretboardHeight = 0;
function setup() {
createCanvas(600, 800);
}
function draw() {
background(0,100,100);
fretboardWidth = width - 100;
fretboardHeight = height -100
renderFrets();
renderStrings();
renderCircles();
createNotes();
}
function renderFrets() {
for(i=1; i <= fretNumber; i++){
line(0, fretboardHeight / (fretNumber + 1) * i, fretboardWidth, fretboardHeight / (fretNumber + 1) * i);
}
}
function renderStrings() {
for(i=1; i <= stringNumber; i++){
line(fretboardWidth / (stringNumber +1) * i, 0, fretboardWidth / (stringNumber +1) * i, fretboardHeight);
}
}
function renderCircles() {
for(i = 1; i <= stringNumber; i++){
for(j = 1; j <= fretNumber; j++){
circle(fretboardWidth / (stringNumber+1) * i, fretboardHeight / (fretNumber+1) * j, 20);
}
}
}
function createNotes() {
let strings = [];
let gstring = [];
for(i=0; i < stringNumber; i++){
for(j=0; j <= fretNumber; j++) {
gstring.push(notes[(baseNotes[i] + j) % 12]);
// if(j=0){
// text(gstring[j], fretboardWidth / 7 * (i+1) - 4, fretboardHeight / (fretNumber+1) * j + 3);
// }
// else{
text(gstring[j], fretboardWidth / 7 * (i+1) - 4, fretboardHeight / (fretNumber+1) * j + 3);
// }
}
strings.push[gstring];
gstring = [];
}
text(strings[0][0], fretboardWidth / 7 * (i+1) - 4, 10);
}
Fixed this!
needed double = sign in the if function to check values are equal rather than setting the value to create an infinite loop
forgot normal brackets when adding to an array.
Here's what I am trying: I have an object and I'm trying increment the values by 0.01 & 1 using setInterval
my object
var data = {
timer: {
"num": "0.1",
"perfection": "0",
}
}
here num value has to be increased by 0.1 & perfection value by 1 and if perfection's value reaches 100 then it has to stop using set interval
var data = {
timer: {
"num": "0.0",
"perfection": "0"
}
}
var info = [];
var maxValue=101;
setInterval(loop,2000)
function loop(){
for(var i = 0; i < maxValue; i++) {
data['timer']['perfection'] = i;
console.log(data)
}
}
unable to increment values of the object
The original values are strings, so these (ideally) need to be numbers to be able to increment.
var data = {
timer: {
"num": 0.0,
"perfection": 0
}
}
You can then increment with
data.timer.perfection += 1
The next issue you'll have is when to stop the setInterval - this can be done with clearInterval using the return value of the original setInterval.
Updated code:
var data = {
timer: {
"num": 0.0,
"perfection": 0
}
}
// reduced values for demo purpose
var maxValue = 10;
var intervalId = setInterval(loop, 200)
function loop() {
data.timer.num += 0.1
data.timer.perfection += 1
if (data.timer.perfection >= maxValue) {
clearInterval(intervalId);
console.log(data)
}
}
You don't need a for loop, you need just a variable keeping track of how many times setInterval called the function to increment, when it reaches 100, use clearInterval() on the variable that holds the interval.
Using just data['timer']['perfection'] = i; will not increment data.timer.num it will just set the data.timer.perfection to the exact same value as i. You need to explicitely increment both properties, see below
Also, I changed the values on the object to numbers, if you can't do this, you'll need to parse the values, otherwise it will concatenate ("0" + 1 = "01")
var data = {
timer: {
"num": 0.0,
"perfection": 0
}
}
var i = 0;
var maxValue = 100;
var interval = setInterval(increment, 100)
function increment(){
data.timer.perfection += 1;
data.timer.num += 0.1;
console.clear()
console.log(data)
i++;
if (i >= maxValue) {
clearInterval(interval)
console.log("finish")
}
}
And as you can see, the JS decimal value can be a little "broken", because adding 0.1 may make your num to be something like 0.299999999 instead of 0.3, for example. (further read: How to deal with floating point number precision in JavaScript?)
I'm new to ElasticSearch and i'm trying to make an weighted average in my index.
My data looks like this:
data = [{"id": 344,"q28": 1},{"id": 344,"q28": 1},{"id": 344,"q28": 2}, ...]
"q28": can be equal to 1,2,3 or 4
Example in JavaScript:
var data = [{"id": 344,"q28": 1},{"id": 344,"q28": 1},{"id": 344,"q28": 2}]
function calcWeightAverage(res) {
var score = 0
for (var i in res) {
if (res[i].q28 == 1)
score += 100
else if (res[i].q28 == 2)
score += 50
else if (res[i].q28 == 3)
score += 25
else if (res[i].q28 == 4)
score += 0
}
return score / res.length
}
console.log(calcWeightAverage(data)) // output 83.333...
Can you help me with to find a query that would calculate the weighted average of q28 directly in ElasticSearch ?
Thank you !
UPDATE 1
I'm close, see: "https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html"
To test it, i created a file in config/scripts/my_script.groovy
1 + my_var
Then you have to restart ElasticSearch and make this query:
GET /_search
{
"script_fields": {
"my_field": {
"script": {
"file": "my_script",
"params": {
"my_var": 2
}
}
}
}
}
It's working, now i have to work on the script.
How can i loop in all my data to do something like my javascript function ?
Just to help you with a shorter Javascript part for the average.
function calcWeightAverage(res) {
return res.reduce(function (r, a) {
return r + ({ 1: 100, 2: 50, 3: 25, 4: 0 }[a.q28] || 0);
}, 0) / res.length;
}
var data = [{ id: 344, q28: 1 }, { id: 344, q28: 1 }, { id: 344, q28: 2 }];
console.log(calcWeightAverage(data));
I'm new to coding and I've been searching for hours and haven't really found a definitive answer to my problem. A few suggestions have been close to what I want to achieve which I think has helped a little but still not getting the outcome I want.
I've been using codepen.io a lot for seeing an instant output to my code as opposed to jsfiddle, just because I prefer how it works.
This is the code in question:
var x;
var y;
var z;
var arrayFiller;
var betaArray = new Object(256);
betaArray[0] = 0 + " " + 0;
for(var i=1; i<256; i++)
{
x = i;
y = x % 16;
x = x / 16;
x = Math.floor(x);
z = x % 16;
x = i;
arrayFiller = z + "" + y + " ";
$(
function()
{
var hexDerp =
{
'0' : "0",
'1' : "1",
'2' : "2",
'3' : "3",
'4' : "4",
'5' : "5",
'6' : "6",
'7' : "7",
'8' : "8",
'9' : "9",
'10': "A",
'11': "B",
'12': "C",
'13': "D",
'14': "E",
'15': "F"
};
var hexDerp1 = /(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15)/g;
var arrayFillerHex = arrayFiller.replace
(
hexDerp1,
function(s)
{
if(s in hexDerp)
{
return hexDerp[s];
}
}
);
}
);
betaArray[i] = arrayFiller;
document.write(betaArray[i]);
}
My apologies if it is poorly formatted, I find this to be the clearest method for myself.
The bit that currently doesn't work is the function part which is an amalgamation of what I've found in order to replace the 10-15 with a-f.
There may be other ways of getting this inputted and outputted, but I want to keep this for what I am going to end up using this for.
tl;dr: what I wanted to do with this code, is get an array that is 256 elements large, and populate the elements with the hexadecimal version of the element number, to later be used in a unique alphabet that I am making.
You can convert decimal numbers to hexadecimal numbers using this:
(anyNumber).toString(16);
I'm using Highcharts to generate a line chart.
And I'm having a problem with numberFormat:
var test = 15975000;
numberFormat(test, 0,',','.');
the result is: 15.975.000
But I want to transform 1000 to 1k, 100000 to 100k, 1000000 to 1m like this.
How can I deal with this problem?
numberFormat is available in Highcharts object.
Highcharts.numberFormat(test, 0,',','.');
Example http://jsfiddle.net/DaBYc/1/
yAxis: {
labels: {
formatter: function () {
return Highcharts.numberFormat(this.value,0);
}
}
},
Write your own formatter (see this example).
formatter: function() {
result = this.value;
if (this.value > 1000000) { result = Math.floor(this.value / 1000000) + "M" }
else if (this.value > 1000) { result = Math.floor(this.value / 1000) + "k" }
return result;
}
See also: How to format numbers similar to Stack Overflow reputation format
You just need to do that:
labels: {
formatter: function() {
return abbrNum(this.value,2); // Need to call the function for each value shown by the chart
}
},
Here is the Function used to transform the data to be inserted on javascript:
function abbrNum(number, decPlaces) {
// 2 decimal places => 100, 3 => 1000, etc
decPlaces = Math.pow(10,decPlaces);
// Enumerate number abbreviations
var abbrev = [ "k", "m", "b", "t" ];
// Go through the array backwards, so we do the largest first
for (var i=abbrev.length-1; i>=0; i--) {
// Convert array index to "1000", "1000000", etc
var size = Math.pow(10,(i+1)*3);
// If the number is bigger or equal do the abbreviation
if(size <= number) {
// Here, we multiply by decPlaces, round, and then divide by decPlaces.
// This gives us nice rounding to a particular decimal place.
number = Math.round(number*decPlaces/size)/decPlaces;
// Handle special case where we round up to the next abbreviation
if((number == 1000) && (i < abbrev.length - 1)) {
number = 1;
i++;
}
// Add the letter for the abbreviation
number += abbrev[i];
// We are done... stop
break;
}
}
return number;
}
Hope this works =)
In case you want to format a Highstock chart:
tooltip: {
pointFormatter: function() {
var result = this.y;
let header = '<table>';
let body = '<tr><td style = "color: ' + this.series.color + ';padding:0">'
+ this.series.name + ': </td><td style = "padding:0"><b>';
if (result > 1000000) {
result = Math.floor(result / 1000000) + "M"
}
else if (result > 1000) {
result = Math.floor(result / 1000) + "k"
}
return header + body + result + '</b></td></tr></table>';
}
},
I had trouble finding a way of adding Millions and Thousands while not hampering the data grouping functionality or the date.