I'd like to create a custom function in Google spreadsheet (so javascript is is) to measure the level of disagreement between people who answered a survey.
Here is what I wrote:
function disagree(DISAG,otherMember) {
var otherMember = '';
var indivDisag = DISAG.localeCompare(otherMember);
return Math.abs(indivDisag);
}
The localCompare should allow me to easily get 0 (if similar) or 1 (if different), but I keep getting 1. What did I mess up?
With this basic formula, I can check the disagreement of one person with another one.
edited for clarification
Thanks for your help
Well, considering that you always set otherMember to '', I think it is expected that there's always a difference. Why don't you try:
function disagree(DISAG, otherMember) {
return Math.abs(DISAG.localeCompare(otherMember));
}
Related
I've been researching and trying different solutions to this literally all day.
** EDIT: regarding duplicate post: As I wrote below, a set timeout function has been attempted and successful around the function call. Please, before you close my question, atleast ask that what you’re describing as a duplicate hasn’t already been attempted… or in this case. INCLUDED in my original post. I’m not looking for cred, I’m looking for help. **
I have a reusable function takes in 3 params:
What to wrap,
wrap in what type of element
and the id of the new wrapping element (so I can control access it later.)
Here's a codeSandbox version to help you help me! https://codesandbox.io/s/queryselector-to-globe-jbffk0?file=/index.html
Goal: I'd like to include a querySelector within the function that takes in the id to eliminate the extra step, to ensure the selector is defined after the item is created, and to keep a cleaner code-base. The problem is I keep fighting between a function that's surrounded by parens...
Var wrap = (function(params){...})(window); to potentially give global scope to the queryselector(object ref) I'm trying to create, and a standard es6 function I'm more familiar with... Var wrap = (params) => {...};
import "./styles.css";
const item = document.querySelector(".item");
var wrap = (function (toWrap, wrapper, id) {
wrapper = wrapper || document.createElement("div");
wrapper.setAttribute("id", `${id}`);
toWrap.parentNode.appendChild(wrapper);
// Non-working auto id something to
// window.id = document.querySelector(`${id}`);
return wrapper.appendChild(toWrap);
})(window);
// How can I "store the window.id" just as if it were manually written right here in global scope?
wrap(item, "div", "itemadded");
Note: the window thing I read at: http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
Like I said, I can provide more working code/attempts to show I've made a ton of effort if anyone is wondering.
PS, I'll definitely mark the answer and give upvotes for help.
Thanks in advance!
If your still reading, I've tried simplifying even further, adding a timeout function to ensure that the function takes in toWrap correctly... idk what else to try... :(
I am trying to get deformation object to change it properties by JS, but I cannot even get it by any Spark module.
Spark AR have sample project with face distortion deformation.
https://developers.facebook.com/docs/ar-studio/tutorials-and-samples/samples/face-distortion/
You can even see in tutorial, that there is some morph object attached, which called faceDistortionPack. This object is located in assets, and I tried to get it by different ways in script, but couldn't make it. I want to write some js logic to manipulate deformations.
const Scene = require('Scene');
const Diagnostics = require('Diagnostics');
const faceMesh = Scene.root.find('facemesh_distortion');
Diagnostics.log(faceMesh); // FaceMesh: https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.facemesh
Diagnostics.log(faceMesh.deformation); // null
Diagnostics.log(faceMesh.find('faceDistortionPack')); // Exception...
// ....
I want to get 'faceDistortionPack' object to access it properties, like 'nose_z', so I can change them by JS.
Although this is a pretty old question I thought I'd answer anyway if anyone struggles with this and comes across this thread.
First of all: There's an amazing collection of helpful tips, tutorials, snippets etc. called Spark AR Community. There you can find a GitBook with an alternative, better indexed and better working version of the official script object reference. I recommend using it if you're lost in the official reference or it's not working which happens quite often. There you can see, that the BlendShapesMesh, mentioned in the previous answer is deprecated as of Spark AR v85+, so that won't help anyone. ()
So, what you are trying to achieve, if I understand it correctly, is to access the faceMesh's Blendshapes and change their value through script. What you need to do is this:
Follow the instructions in this Tutorial: https://sparkar.facebook.com/ar-studio/learn/tutorials/face-distortion-retouching/
After you applied the Blendshapes, mess around a bit with adjusting the Blendshapes, so you understand what's happening.
Add a script to your assets. You're gonna want to access the faceMesh-Object's Blendshapes' weight Property through script. That can be done by using the getBlendshapes()-Method of the Mesh-Class.
Here's a code example:
//Require Modules
const Scene = require('Scene');
const Diagnostics = require('Diagnostics');
const Reactive = require('Reactive');
//Enable async/await [part 1]
(async function () {
//Load Assets as Promise
const loadAssets = await Promise.all(
[
Scene.root.findFirst("faceMesh0"), //Put name of your facemesh here, default is faceMesh0
]
).then(function(assets){
const faceMesh = assets[0]; //Assign the facemesh from the assets-Array of the promise to a variable you can work with better
const faceMeshShapes = faceMesh.getBlendShapes(); //Access all Blendshapes of the faceMesh-Object and store them in an Array
What you have now is a variable called faceMeshShapes, that's an object with an array of Blenshapes in it. You can console log it with Diagnostics.log(faceMeshShapes) and see that there's an array called "_value" in it, that's filled with all Blendshapes as objects, that have a weight-Property, which specifies the weight of the Blendshape with a scalarValue. You can consolelog this Value by converting it with the pinLastValue()-Method of the scalarValue-Class and you can assign different values by binding it to a custom value, that you convert to a scalarValue by using the val()-Method from the Reactive-Module.
Here's an example:
Diagnostics.log(faceMeshShapes._value[0].weight.pinLastValue()); //console log the Value of the weight property's scalarValue of the Blendshape that's stored at the index 0 of the _value-Array
faceMeshShapes._value[0].weight = Reactive.val(0.5) //set the weight to 0.5
Diagnostics.log(faceMeshShapes._value[0].weight.pinLastValue()); //console log the changed value of the weight property
So basically, that's how you can access every Blendshape's weight. The index should be according to the order in which they are listed in spar AR studio, beginning with 0 for the first BlendShape. Now you can do lots of things with this value, like binding it to an animation that animates it from 0-1 or to the mouth-openess using the face-tracking module and so on.
Last but not least, don't forget any semicolons and close all brackets.
});
})(); // Enable async/await [part 2]
P.S.: It can really help sometimes to understand what's happening and how to access stuff, by console logging a list of all properties of an object. Especially since the spark AR documentation is pretty weak on that part (and pretty weak in general). You can use the following function from MDN to do that. It's nothing fancy, but it does the job and has saved me a couple of times already :)
function listAllProperties(o) {
var objectToInspect;
var result = [];
for(objectToInspect = o; objectToInspect !== null;
objectToInspect = Object.getPrototypeOf(objectToInspect)) {
result = result.concat(
Object.getOwnPropertyNames(objectToInspect)
);
}
return result;
}
The link you posted isn't live any more.
I'm guessing the below links are more relevant now for others looking into this. I animated a series of blendShapes, and these links were useful. Basically cycling through the weights of each blendShape.
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.blendshapesmesh
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.blendshape
Good Morning everybody,
I am still working on a questionnaire for illiterate people. For that I am using a Text to Speech application (thanks to #JO3-W3B-D3V)
The Problem is that the questionnaire will be developped in several languages, which means, that the text to speech application has to support several languages as well.
SpeechSynthesis.getVoices()
If I understood it correctly, the function above returns a list of all objects representing all the available voices on the current device. Now to my questions:
Is there a way to return a selection of these languages? For example, the listshould not return all 15 languages which are available on the device, but only 4 chosen ones?
Is there a way to add more languages to the device? I am using Chrome. If I understood it correctly Chromes gets the languages from Microsoft and Google. Therefore Chrome should display new language-option if I add a new language to my operation system (Windows 10). Is that assupmtion correct? I am asking because I did that already and nothing changed, so I might be missing something.
Hope my questions make sense :)
Have a great day!
Explained
Okay, so I'll answer this in two parts, considering the fact that you've kinda asked two questions, both are relatively simple & straightforward thankfully.
Question One
You've asked how to get _ chosen languages that you'd like to support, well that's simple, it's as easy as manipulating an array, within my example I've used the reduce function, fairly straightforward stuff.
P.S. For the sake of some form of consistence, I've written this snippet in a very similar fashion to the one that I wrote in the other question that you asked regarding speechSynthesis.
Assumptions
As stated within the code comments, I've written this snippet in such a way that there's no duplicated entries, i.e. within the snippet below, you will end up with a list that only contains one entity that supports the English language. In other words, you won't have both en-GB & en-US, of course you can change this, I just assumed that you'd want this type of feature, of course this is down to you & your requirements entirely.
// IIFE for the sake of it.
(function() {
"use strict";
// This is a simple list of languages that you wish to support.
var supportedLanguages = ['en', 'de', 'es', 'fr'];
var languages = [];
// This is essentially similar to jQuery's $.ready.
var ready = function(callback) {
var d = document,
s = d.readyState;
// DOMContentLoaded was fired
if (s == "complete" || s == "loaded" || s == "interactive") {
callback();
} else {
if (d.addEventListener) {
d.addEventListener("DOMContentLoaded", callback, false);
} else {
d.attachEvent("onDOMContentLoaded", callback);
}
}
};
// This is just a simple function to process whether or not you'd like to
// push a voice onto the array or not.
var shouldPush = function(array, object) {
var language = object.lang || '';
var snipped = language.substring(0, 2);
// Generate a list of all of the known languages.
var languageList = array.map(function(object) {
return object.lang;
});
// Create a list of short hand language names.
var snippedList = languageList.map(function(language) {
return language.substring(0, 2);
});
// Save having a bloated if statement, personally I find this
// more readable.
//
// Only push relevant ones, saves having any duplicated entities, i.e.
// this will not allow for both en-US & en-GB to be among the list,
// this can be altered, this is merely based on an assumption that you
// wouldn't want both en-US & en-GB, etc.
var isToPush = !snippedList.includes(snipped) &&
!languageList.includes(language) &&
supportedLanguages.includes(snipped);
// If true, push to array.
if (isToPush) {
array.push(object);
}
// Then of course return the array object.
return array;
};
// This is essentially the list of voices that you've picked to support.
var getSelectedLanguages = function() {
languages = speechSynthesis.getVoices().reduce(shouldPush, []);
};
// A starting point for this snippet.
var start = function() {
speechSynthesis.onvoiceschanged = function() {
getSelectedLanguages();
console.log(languages);
};
};
// Run the code when ready.
ready(start);
})();
Question Two
I'm not entirely sure if there's a "clean & easy" way to do this, having conducted my own research on the matter I've found that it looks like this would require some form of tinkering. One of the better sources of information that I've found is this question.
Having further looked into this question, it looks like Artyom also suggests that there's no simple way to achieve this, it looks like you can only add a language by installing the language into the operating system, so I'm lead to believe.
Conclusion
One possible idea is that you could, and I emphasise the word could possibly do this via implementing an API of your own, however I can't imagine this would be a solid or reliable implementation, as my conclusion is based on research suggests in order for an additional language to be included, the user is somewhat responsible for that, as it looks like it needs the user to have _ language installed on their OS in order for speechSynthesis to make use of _ language.
I actually find it a little odd that it appears that there's little/no formal documentation on this subject, rather I've just found mostly informal documentation, suggestions and assumptions. This could however be down to my lack of investigation, bear in mind that I've spent ~15 minutes at most looking into this issue.
Sources
A link to flaviocopes.com regarding speechSynthesis.
A link to Artyom.js, a library for speech related APIs.
A link to a previous stack overflow question similar to the second part of this question.
A link to a medium article.
MDN documentation.
A treehouse blog post.
While I may not have the answer that you desire for your second question, I hope that this entire answer has helped in some form or another! :)
I've been searching around for a simple-lightweight hashing algorithm for JavaScript. I did find this numerically-based answer on Stack Overflow here.
Unfortunately, I am unable to use this since it's numerically based and I'll need to use this hash as a unique index elsewhere in my code. Often this function returns negative numbers and that would be a big no-no (try 'hello world!'.hashCode() from the snippet linked above to see what I mean).
I've been tempted to use the md5 hashing libraries out there for JS but they're simply to bulky for my purpose and encryption libraries (such as this) are overkill.
It's worth noting that the information within this hash isn't sensitive in anyway and it wouldn't necessarily matter if it was decrypted. The purpose of this function would be to simply generate fixed-length output data that acts as a shortened reference to the original data that I would pass in.
Any help, tips and comments are much appreciated :)
The solution proposed by Kooilnc, to use the absolute value, should do the tric for you. However, if you want to use a hashing function to generate a reference, i assume that the reference you get should be unique as to match the exact element it was generated from. If this is the case, be aware of collisions. Hashing function can create hashes that are similar even though the original messages are different and we call this a collision. If i remember correctly, SHA-1 is also available for java script and is not all that bulk. Good luck
I am unable to use this since it's numerically based and I'll need to use this hash as a unique index elsewhere in my code.
Hash functions are normally numerically based and are rarely perfect (produce unique keys). I think you need something different:
function GuidGen()
{
this.items = {};
this.size = 0;
}
GuidGen.prototype.get = function(str)
{
if (!(str in this.items))
{
this.items[str] = this.size++;
}
return this.items[str];
}
// usage:
id = new GuidGen();
id.get("hello world"); // 0
id.get("spam"); // 1
id.get("eggs"); // 2
id.get("hello world"); // 0
I'm using omniture and tracking various properties to the "s" variable for tracking. The example code I'm following calls a function called s.clearVars() after each tracking event. But I get an error saying that clearVars is not a valid function. Does anyone know what I'm supposed to call to clear the tracking object? Or how to clear all properties from a javascript object.
Don't clear the entire s object, it contains a lot of functions that are listening to dom events and if you clear those, you'll lose a lot of functionality. I'm guessing you just want to clear all of the custom variables that you are populating on the page (props, evars, events, products, etc). The s.clearVars function is a "plugin" that Omniture consulting wrote that clears all of these values for you. You could contact your Omniture Account manager and ask him for the code, he may or may not give it to you, depending on whether he wants to sell you some consulting hours or if he knows what you are talking about, or you could do this yourself with a couple of simple loops:
function ClearVars(){
for (var i=0; i < 75; i++) {
s['prop'+i]='';
s['eVar'+i]='';
if(i<=5)
s['hier'+i]='';
}
svarArr = ['pageName','channel','products','events','campaign','purchaseID','state','zip','server','linkName'];
for (var i=0; i < svarArr.length ; i++) {
s[svarArr[i]]='';
}
}
Please note I haven't tested the code. Just shot it from the hip.
Small Correction to Vector Frogs (amazing) code.
The second for loop need to have i=0 to clear out the pageName variable.
Great Script V_FRog!
this will reset the entire object as per your original request:
s=s_gi(s_account);
I think the best answer for how to clear the properties off of a JS object is to just create a new object all together.
Check out this post: How to quickly clear a Javascript Object?
s = {};