Finding mode and median in Javascript error - mode

I have been working on a coderbyte problem for the past two days. I thought I finally had it buy for some reason this I keep getting an error.
function comparemedianandmode(arr){
function findmode(arr){
mapping = {};
mode = 0;
for(var i = 0; i < arr.length; i++){
if(!mapping[arr[i]]){
mapping[arr[i]] = 0;
}
mapping[arr[i]] += 1;
}
for(prop in mapping){
if(mapping[prop] > mode){
var mode = parseInt(prop);
}
}
}
function findmedian(arr){
arr.sort(function(a,b){return a - b});
if(arr.length % 2 === 0){
var median = (arr[(arr.length/2)-1] + arr[arr.length/2])/2;
}
else{
var median = arr[(arr.length - 1)/2];
}
}
var answer = (median === mode) ? 1 : 0;
return answer
}
When I try comparemedianandmode([1,2,3,3,3,4,5]) I get the following error:
ReferenceError: median is not defined
Must be something simple, but I can't seem to figure it out
EDIT
New Code:
function comparemedianandmode(arr){
var mode;
var median;
function findmode(arr){
mapping = {};
for(var i = 0; i < arr.length; i++){
if(!mapping[arr[i]]){
mapping[arr[i]] = 0;
}
mapping[arr[i]] += 1;
}
for(prop in mapping){
if(mapping[prop] > mode){
var mode = parseInt(prop);
}
}
}
var median
function findmedian(arr){
var median
arr.sort(function(a,b){return a - b});
if(arr.length % 2 === 0){
median = (arr[(arr.length/2)-1] + arr[arr.length/2])/2;
}
else{
median = arr[(arr.length - 1)/2];
}
}
var answer = (median === mode) ? 1 : 0;
return answer
}
comparemedianandmode([1,2,3,3,3,4,5])
=> 1

Declaring a variable with var will limit its scope to the function in which it is being declared. You are declaring median that way inside findmedian() but then trying to access median outside of that function in the line that is assigning a value to answer.
Remove var from the lines where you are assigning median a value. At the top of comparemedianandmode() (your outermost function), declare median:
var median;
You have a function within a function, and that inner function is where you are declaring median but then you are trying to use it outside that inner function in this line:
var answer = (median === mode) ? 1 : 0;
Incidentally, you will have to do the same for mode.
Here's what it will look like after all that:
function comparemedianandmode(arr){
var median;
var mode;
function findmode(arr){
mapping = {};
mode = 0;
for(var i = 0; i < arr.length; i++){
if(!mapping[arr[i]]){
mapping[arr[i]] = 0;
}
mapping[arr[i]] += 1;
}
for(prop in mapping){
if(mapping[prop] > mode){
mode = parseInt(prop);
}
}
}
function findmedian(arr){
arr.sort(function(a,b){return a - b});
if(arr.length % 2 === 0){
median = (arr[(arr.length/2)-1] + arr[arr.length/2])/2;
} else {
median = arr[(arr.length - 1)/2];
}
}
answer = (median === mode) ? 1 : 0;
return answer;
}
console.log(comparemedianandmode([1,2,3,3,3,4,5]));

Related

Setting Base Cases for Recursive Function

class Solution {
//given a location on the matrix, this function recursively find the deepest possible depth, which is the length of a side of a found square
private int isSquare(int row_index, int col_index, int depth, char[][] matrix) {
int last_row = row_index + depth;
int last_col = col_index + depth;
if (row_index >= matrix.length || col_index >= matrix[0].length) {
return 0;
}
if (last_row >= matrix.length || last_col >= matrix[0].length) {
return 0;
}
for (int i = col_index; i < last_col; i++) {
if (matrix[row_index][i] != '1') {
return 0;
}
}
for (int i = row_index; i < last_row; i++ ) {
if (matrix[i][col_index] != '1') {
return 0;
}
}
return Math.max(depth, isSquare(row_index, col_index, depth + 1, matrix));
}
public int maximalSquare(char[][] matrix) {
int max = 0;
for (int row = 0; row < matrix.length; row ++) {
for (int col = 0; col <matrix[0].length; col ++) {
int curr_depth = isSquare(row, col, 1, matrix);
if (curr_depth > max) {
max = curr_depth;
}
}
};
return max * max;
}
}
Hi, I was working on LeetCode 221, and it seems like that my solution is not passing test cases with output 1, where the biggest square on the given matrix is just 1 x 1. To me it looks like those depth 1 cases are not passing the two for loops in function isSquare, which is supposed to catch 0s in the square.
I tried LC debugging tool but it did not help much, and my base cases seem fine to me. Please let me know what is going on here. For the problem, https://leetcode.com/problems/maximal-square/
One of the depth 1 test cases that I am failing is below.
Input:
[["0","1"],["1","0"]]
Output:
0
Expected:
1

ZigZag path onMouseDrag with paper.js

Hi im tryign to create a zigzag path using Path.js's onMouseDrag function but getting in to a bit of a muddle here is a sketch
and code
var path
var zigzag
var length
var count
var delta=[]
tool.fixedDistance= 20
function onMouseDown(event){
path= new Path()
path.add(event.point)
zigzag= new Path()
}
function onMouseDrag(event){
event.delta += 90
path.add(event.delta)
delta.push(event.delta)
}
function onMouseUp(event){
length= path.segments.length
zigzag= new Path()
zigzag.add(event.point)
console.log(delta)
delta.forEach(( zig , i) => {
zigzag.add(i % 2 == 0 ? zig + 20 : zig - 20)
})
zigzag.selected= true
}
Based on my previous answer, here is a sketch demonstrating a possible way to do it.
let line;
let zigZag;
function onMouseDown(event) {
line = new Path({
segments: [event.point, event.point],
strokeColor: 'black'
});
zigZag = createZigZagFromLine(line);
}
function onMouseDrag(event) {
line.lastSegment.point = event.point;
if (zigZag) {
zigZag.remove();
}
zigZag = createZigZagFromLine(line);
}
function createZigZagFromLine(line) {
const zigZag = new Path({ selected: true });
const count = 20, length = line.length;
for (let i = 0; i <= count; i++) {
const offset = i / count * length;
const normal = i === 0 || i === count
? new Point(0, 0)
: line.getNormalAt(offset) * 30;
const point = line.getPointAt(offset).add(i % 2 == 0 ? normal
: -normal);
zigZag.add(point);
}
return zigZag;
}

Why can't I increment global variable

I created a variable q outside of any function. From within my function I am attempting to simply increment it with a ++. Will this increment the global q or is this simply appending the value to a local variable? As you can see in the code sample below I am attempting to use the value of the global variable (which I intend to be updated during each execution of this script) to set a variable which should trigger this function via .change. The function is initially trigger (when q = 1) however it is not trigger when a selection is made from the dropdown box with id = "selectedId2" which is leading me to believe that q has retained a value of 1 though I successfully incremented it when the function was ran prior. Any advise of how I can increment the variable "q" for each iteration of this script would be greatly appreciated.
if (q === 1) {
selectedDiv = '#selectId1';
selectedDiv2 = '#selectId2';
}
if (q === 2) {
selectedDiv = '#selectedId2';
selectedDiv2 = '#selectedId3';
}
if (q === 3) {
selectedDiv = '#selectedId3';
selectedDiv2 = '#selectedId4';
}
if (q === 4) {
selectedDiv = '#selectedId4';
selectedDiv2 = '#selectedId5';
}
if (q === 5) {
selectedDiv = '#selectedId5';
selectedDiv2 = '#selectedId6';
}
$(selectedDiv).change(function () {
if (q == 1) {
var pullDownDivs = '#2';
}
if (q == 2) {
var pullDownDivs = '#3';
}
if (q == 3) {
var pullDownDivs = '#4';
}
if (dropDownSelectJoined != null) {
var dropDownSelectJoined = dropDownSelectJoined + ", " + $(selectedDiv).val();
}
else {
var dropDownSelectJoined = $(selectedDiv).val();
}
var SelArea = $(selectedDiv).val();
if (SelArea != 0) {
var url = '#Url.Action("NetworkSubForm")';
q++;
$.post(url, { RemovedAreaId: $('#RemovedAreaId').val(), selectedNetworkId: $('#SelectedNetworkId').val(), dropDownSelectJoined: dropDownSelectJoined },
function (data) {
var productDropdown = $(selectedDiv2);
productDropdown.empty();
productDropdown.append("<option>-- Select Area --</option>");
for (var i = 0; i < data.length; i++) {
productDropdown.append($('<option></option>').val(data[i].Value).html(data[i].Text));
}
});
$(pullDownDivs).show();
$(pullDownDivs).html();
}
else {
$(pullDownDivs).hide();
$(pullDownDivs).html();
}
});
I don't know what the rest of your code looks like, but you can see this kind of behavior due to "shadowing":
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
q++;
console.log(q);
}
Repeatedly calling handler will output 1 each time since you are redefining a local q within handler. However, the outer q remains unchanged. But if you did this:
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
window.q++;
console.log(window.q);
}
The global q will be updated since you are explicitly referencing it by doing window.q.

Handling class attribute assignments in Polymaps

I'm a social science person increasingly getting into web programming for data vis work so apologies if this question is dumb. I'm working on a polymaps implementation to visualize country level data over time. I reads in json temporal data and a geojson world map and spits out a quantile chloropleth map that iterates over monthly entries. The heart of this is a country formating function that binds a colorbrewer class to the country geojson objects (see below). This works find for the animation portion. The problem is that I am using a custom d3 layer that displays the date of the data currently displayed and acts as a mouseover control to stop the animation and choose a date or to choose a date once the animation is through. It does this by creating an blank svg element that uses the d3.scale() function to round mouse input to an integer that matches the index of the month desired. I've front loaded all the other calculations on load so that the only thing that happens at mouse over is the change of svg class (this is basically the same as Tom Carden's wealth of nations implementation on Bostock's d3 page here). Unfortunately, this still overloads the browser pretty quickly. Is there another way to do this that I'm totally missing? I admit im new to geojson so maybe some way to construct an array of classes with in the class attribute of the geojson object? Thanks a ton of any help.
function foo(local, geojson){
for(var x=0;x<geojson.length;x++){
var n = geojson[x].data.properties.name;
n$(geojson[x].element)
.attr("class", geojson[x].data.formats[local])
.add("svg:title");
}
}
EDIT: I'm adding the full script below.
<meta charset="utf-8">
<script src="scripts/d3.v3.js"></script>
<script src="scripts/polymaps.js"></script>
<script src="scripts/nns.js"></script>
<script>
//Polymaps namespace
var po = org.polymaps;
//Chart dimensions
var margin = {top: 20, right: 20, bottom: 20, left: 20};
var w = 960 - margin.right;
var h = 500 - margin.top - margin.bottom;
// Create the map object, add it to #map div
var map = po.map()
.container(d3.select("#map").append("svg:svg").attr("width", w + margin.left + margin.right).attr("height",h +margin.top + margin.bottom).node())
.center({lat: 28, lon: 0})
.zoom(1.85)
.zoomRange([1.5, 4.5])
.add(po.interact());
// Add the CloudMade image tiles as a base layer…
map.add(po.image()
.url(po.url("http://{S}tile.cloudmade.com"
+ "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register
+ "/20760/256/{Z}/{X}/{Y}.png")
.hosts(["a.", "b.", "c.", ""])));
//Import contribution data
d3.json("assets/contributionsTCC1990-1991.json", function(data){
//find length of json data object and loop over it at interval
var dataLength = Object.keys(data).length;
//Create date key/value array using construtor
function date_array_constructor() {
var dateArray = {};
for(var i = 0; i < dataLength; i++) {
var d = i + 1;
dateArray[d] = data[i].date;
}
return dateArray;
}
var dateArray = date_array_constructor();
// Insert date label/control layer and add SVG elements that take on attributes determined by load function
var labelLayer = d3.select("#map svg").insert("svg:g");
map.add(po.geoJson()
.url("assets/world.json")
.tile(false)
.zoom(3)
.on("load", load));
map.container().setAttribute("class", "Blues");
map.add(po.compass()
.pan("none"));
function find_max(data, dataLength) {
var max = 0;
for(var i in data) {
if(data[i] > max) {
max = data[i] + 1;
}
}
return max;
}
function max_array_constructor(data, dataLength) {
var maxArray = {};
for(var i=0;i<dataLength;i++) {
var d = i+1;
maxArray[d] = find_max(data[i].contributions);
}
return maxArray;
}
var maxArray = max_array_constructor(data, dataLength);
function contribution_array_constructor(data, dataLength, tccName, feature) {
var contributions = {};
//iterate over date entries
for(var i=0;i<dataLength;i++) {
//contribution iterator
contributions[i+1] = 0;
for(x in data[i].contributions){
if(x == tccName) {
contributions[i+1] = data[i].contributions[x];
}
}
}
return contributions;
}
function format_array_constructor(data, dataLength, maxArray, feature) {
var formats = {};
// console.log(feature.data.contributions);
//iterate over date entries
for(var i=0;i<dataLength;i++) {
var percentile = feature.data.contributions[i+1] / maxArray[i+1];
if(percentile != 0){
var v = "q" + ((~~(percentile*7)) + 2) + "-" + 9;
}else{
var v = "countries";
}
formats[i+1] = v;
}
return formats;
}
///////////////////////////////
//load function
///////////////////////////////
function load(e) {
//Bind geojson and json
var geojson = e.features;
console.log(geojson);
geojson.dates = dateArray;
for(var x = 0; x < geojson.length; x++) {
// var tccID = geojson[x].data.id;
var tccName = geojson[x].data.properties.name;
geojson[x].data.contributions = contribution_array_constructor(data, dataLength, tccName, geojson[x]);
geojson[x].data.formats = format_array_constructor(data, dataLength, maxArray, geojson[x]);
}
//Insert date label
var dateLabel = labelLayer.append("text")
.attr("class", "date label")
.attr("text-anchor", "end")
.attr("x", w-670)
.attr("y", h )
.text(dateArray[1]);
//Add interactive overlay for date label
var box = dateLabel.node().getBBox();
var overlay = labelLayer.append("rect")
.attr("class", "overlay")
.attr("x", box.x)
.attr("y", box.y)
.attr("opacity",0)
.attr("width", box.width)
.attr("height", box.height)
.on("mouseover",enable_interaction);
function country_class_constructor(local, geojson){
for(var x=0;x<geojson.length;x++){
var n = geojson[x].data.properties.name;
n$(geojson[x].element)
.attr("class", geojson[x].data.formats[local])
.add("svg:title");
}
}
function foo(local, geojson){
for(var x=0;x<geojson.length;x++){
var n = geojson[x].data.properties.name;
n$(geojson[x].element)
.attr("class", geojson[x].data.formats[local])
.add("svg:title");
}
}
//incrementor function
function incrementor(local, geojson, dateArray) {
setTimeout(function() {
//set date label to current iteration
d3.transition(dateLabel).text(dateArray[local]);
//construct country classes
country_class_constructor(local, geojson);
// console.log(geojson);
}, 500*local);
}
///////////////////////////////
//Increment on load
///////////////////////////////
country_class_constructor(1, geojson)
for(var i=1; i< dataLength; i++) {
//Set incrementer as local variable
var local = i+1;
var timer = incrementor(local, geojson, dateArray);
}
///////////////////////////////
//interaction element
///////////////////////////////
function enable_interaction(){
var dateScale = d3.scale.linear()
.domain([1,Object.keys(dateArray).length])
.range([box.x + 10, box.x + box.width - 10])
.clamp(true);
timer = null;
overlay
.on("mouseover", mouse_over)
.on("mouseout",mouse_out)
.on("mousemove",mouse_move)
.on("touchmove",mouse_move);
function mouse_over() {
dateLabel.classed("active", true);
}
function mouse_out() {
dateLabel.classed("active", false);
}
function mouse_move() {
update_map(dateScale.invert(d3.mouse(this)[0]),data);
// displayYear(dateScale.invert(d3.mouse(this)[0]));
}
function update_map(userInput) {
var date = Math.floor(userInput);
d3.transition(dateLabel).text(dateArray[date]);
// console.log(date);
// country_class_constructor(date, geojson);
foo(date, geojson);
}
}
}
});
</script>
Edit 2: I forgot to add the JSON format. See below for two months of data:
[
{"date":"11/90",
"contributions":{
"Algeria":7,
"Argentina":39,
"Australia":41,
"Austria":967,
"Bangladesh":5,
"Belgium":4,
"Brazil":27,
"Canada":1002,
"Chile":7,
"China":5,
"Colombia":12,
"Czech Republic":6,
"Denmark":374,
"Ecuador":21,
"Fiji":719,
"Finland":992,
"France":525,
"Germany":13,
"Ghana":892,
"Hungary":15,
"India":40,
"Indonesia":5,
"Ireland":814,
"Italy":79,
"Jordan":6,
"Kenya":7,
"Malaysia":15,
"Nepal":851,
"Netherlands":15,
"New Zealand":22,
"Nigeria":2,
"Norway":924,
"Poland":165,
"Republic of the Congo":6,
"Russia":35,
"Senegal":4,
"Serbia":17,
"Spain":63,
"Sweden":738,
"Switzerland":5,
"Turkey":2,
"United Kingdom":769,
"United States":33,
"Uruguay":10,
"Venezuela":23,
"Zambia":6
}
},
{"date":"12/90",
"contributions":{
"Algeria":7,
"Argentina":39,
"Australia":41,
"Austria":967,
"Bangladesh":5,
"Belgium":4,
"Brazil":27,
"Canada":1002,
"Chile":7,
"China":5,
"Colombia":12,
"Czech Republic":6,
"Denmark":374,
"Ecuador":21,
"Fiji":719,
"Finland":992,
"France":525,
"Germany":13,
"Ghana":892,
"Hungary":15,
"India":40,
"Indonesia":5,
"Ireland":814,
"Italy":79,
"Jordan":6,
"Kenya":7,
"Malaysia":15,
"Nepal":851,
"Netherlands":15,
"New Zealand":22,
"Nigeria":2,
"Norway":924,
"Poland":165,
"Republic of the Congo":6,
"Russia":35,
"Senegal":4,
"Serbia":17,
"Spain":63,
"Sweden":738,
"Switzerland":5,
"Turkey":2,
"United Kingdom":769,
"United States":33,
"Uruguay":10,
"Venezuela":23,
"Zambia":6
}
}
]
After hours of debugging, it turns out that the nns.js library was causing me problems. Each iteration of the animation was creating a new set of DOM objects which started to max out the browser at 25,000. The solution was to use nss to create the initial state and then using the following function to change the class of each svg element.
function country_class_constructor(local, geojson){
for(var x=0;x<geojson.length;x++){
var n = geojson[x].data.properties.name;
element = document.getElementById(n);
element.className["animVal"] = geojson[x].data.formats[local];
element.className["baseVal"] = geojson[x].data.formats[local];
}

j script runtime error: object requiered

I am working on the platform confirmit, which creates online surveys. This is a script node that results in the runtime error "object required", I would be grateful if you could help me fix it.. It is supposed to check whether certain codes hold 1 or 2 in the questions q2b and q3a (questions are referenced with the function f() - f(question id)[code]) - the
'//skip ?' part. Then it recodes a maximum of four of the codes into another question (h_q4) for further use.
var flag1 : boolean = false;
var flag2 : boolean = false;
//null
for(var i: int=0; i <9; i++)
{
var code = i+1;
f("h_q4")[code].set(null);
}
f("h_q4")['95'].set(null);
//skip ?
for(var k: int=1; k <16; k+=2)
{
var code = k;
if(f("q2b")[code].none("1", "2"))
flag1;
else
{
flag1 = 0;
break;
}
}
if(f("q3a")['1'].none("1", "2"))
flag2;
if(flag1 && flag2)
f("h_q4")['95'].set("1");
//recode
else
{
var fromForm = f("q2b");
var toForm = f("h_q4");
const numberOfItems : int = 4;
var available = new Set();
if(!flag1)
{
for( i = 1; i < 16; i+=2)
{
var code = i;
if(f("q2b")[i].any("1", "2"))
available.add(i);
}
}
if(!flag2)
{
available.add("9");
}
var selected = new Set();
if(available.size() <= numberOfItems)
{
selected = available;
}
else
{
while(selected.size() < numberOfItems)
{
var codes = available.members();
var randomNumber : float = Math.random()*codes.length;
var randomIndex : int = Math.floor(randomNumber);
var selectedCode = codes[randomIndex];
available.remove(selectedCode);
selected.add(selectedCode);
}
}
var codes = fromForm.domainValues();
for(var i = 0;i<codes.length;i++)
{
var code = codes[i];
if(selected.inc(code))
{
toForm[code].set("1");
}
else
{
toForm[code].set("0");
}
}
}
the first part of the code (//null) empties the 'recepient' question to ease testing
.set(), .get(), .any(), .none() are all valid

Resources