问:
Scoping with Nested Functions in Python
This question is similar to others asked on here, but after reading the answers I'm not grasping it and would appreciate further guidance.

While sketching new code I find myself adding a lot of statements like:

```<code>print('var=')
pprint(var)
</code>```

It became tedious always writing that, so I thought I could make it into a function.  Since I want to print the variable name on the preceding line, I tried:

```<code>def dbp(var):
    eval('print(\'{0}=\')'.format(var))
    eval('pprint({0})'.format(var))
</code>```

so then I do do things like:

```<code>foo = 'bar'
dbp('foo')
</code>```

which prints

```<code>foo=
'bar'
</code>```

This is all great, but when I go to use it in a function things get messed up.  For example, doing

```<code>def f():
    a = ['123']
    dbp('a')
f()
</code>```

raises a NameError (NameError: name 'a' is not defined).

My expectation was that dbp() would have read access to anything in f()'s scope, but clearly it doesn't.  Can someone explain why?

Also, better ways of printing a variable's name followed by its formatted contents are also appreciated.

答:
first of all, id like to say that eval is a high security risk for whoever is going to be running that code.

However, if you absolutely must, you can do this.

```<code>def dbp(var):
    env = {'var': var}

    # Adding global variables to the enviroment
    env.update(globals())

    eval("print('{0}=')".format(var))
    eval('pprint(var)', env)

def f():
    a = ['123']
    dbp('a')
</code>```

you can then do

```<code>>>> f()
a=
'a'
</code>```

Title: Scoping with Nested Functions in Python

Body:
This question is similar to others asked on here, but after reading the answers I'm not grasping it and would appreciate further guidance.

While sketching new code I find myself adding a lot of statements like:

print('var=')
pprint(var)

It became tedious always writing that, so I thought I could make it into a function.  Since I want to print the variable name on the preceding line, I tried:

def dbp(var):
    eval('print(\'{0}=\')'.format(var))
    eval('pprint({0})'.format(var))

so then I do do things like:

foo = 'bar'
dbp('foo')

which prints

foo=
'bar'

This is all great, but when I go to use it in a function things get messed up.  For example, doing

def f():
    a = ['123']
    dbp('a')
f()

raises a NameError (NameError: name 'a' is not defined).

My expectation was that dbp() would have read access to anything in f()'s scope, but clearly it doesn't.  Can someone explain why?

Also, better ways of printing a variable's name followed by its formatted contents are also appreciated.

Body:
first of all, id like to say that eval is a high security risk for whoever is going to be running that code.

However, if you absolutely must, you can do this.

def dbp(var):
    env = {'var': var}

    # Adding global variables to the enviroment
    env.update(globals())

    eval("print('{0}=')".format(var))
    eval('pprint(var)', env)

def f():
    a = ['123']
    dbp('a')

you can then do

>>> f()
a=
'a'


来源: stackexchange

答:
You really should look at other ways to doing this.

The logging module is a really good habit to get into, and you can turn off and on debug output.

Python 3.6 has f'' strings so you would simplify this to:

```<code>pprint(f'var=\n{var}`)`
</code>```

However, here's an example (not recommended) using locals():

```<code>In []:
def dbp(var, l):
    print('{}='.format(var))
    pprint(l[var])

def f():
    a = 1
    dbp('a', locals())
f()

Out[]:
a=
1
</code>```

ContentLicense: CC BY-SA 3.0

Title: Scoping with Nested Functions in Python

Body:
You really should look at other ways to doing this.

The logging module is a really good habit to get into, and you can turn off and on debug output.

Python 3.6 has f'' strings so you would simplify this to:

pprint(f'var=\n{var}`)`

However, here's an example (not recommended) using locals():

In []:
def dbp(var, l):
    print('{}='.format(var))
    pprint(l[var])

def f():
    a = 1
    dbp('a', locals())
f()

Out[]:
a=
1


问:
Binary Search in Javascript
I'm trying to implement a binary search algorithm in JavaScript.  Things seem okay, but my return statements appear to be returning undefined. Can anybody tell me what's wrong here?

Fiddle: http://jsfiddle.net/2mBdL/

```<code>var a = [
    1,
    2,
    4,
    6,
    1,
    100,
    0,
    10000,
    3
];

a.sort(function (a, b) {
    return a - b;
});

console.log('a,', a);

function binarySearch(arr, i) {
    var mid = Math.floor(arr.length / 2);
    console.log(arr[mid], i);

    if (arr[mid] === i) {
        console.log('match', arr[mid], i);
        return arr[mid];
    } else if (arr[mid] < i && arr.length > 1) {
        console.log('mid lower', arr[mid], i);
        binarySearch(arr.splice(mid, Number.MAX_VALUE), i);
    } else if (arr[mid] > i && arr.length > 1) {
        console.log('mid higher', arr[mid], i);
        binarySearch(arr.splice(0, mid), i);
    } else {
        console.log('not here', i);
        return -1;
    }

}
var result = binarySearch(a, 100);
console.log(result);
</code>```

答:
  ?  .

Binary searches implemented right (without modifying the array, making shallow copies of the array, or other absurdities) have an average complexity around O(k*log2(n)) (where k is constant representing needless overhead). Say you have an array of 1024 elements, and the constant k is 1 in this case. With a linear search, the average complexity would be O(k*n/2)=O(1*1024/2)=O(512). With a binary search, you would have a complexity of O(k*log2(n))=O(1*log2(1024))=O(1*10)=O(10). Now, say that you make both the linear search algorithm 25% faster and the binary search algorithm 25% faster. Now, k is 0.75 for both algorithms. The complexity of the linear search decreases to O(384) (a gain of 128 performance points), whereas the binary search decreases to O(7.5) (a gain of only 2.5 performance points). This minimal gain from optimizing the binary search method is because the binary search method is already so fast. Therefore, any sane person should be more inclined to optimize the rest of their program before they try to optimize their binary search algorithm. Despite this clear line of reasoning, I eventually gave into temptations and optimized the binary search function to the absolute limits of JavaScript engineering.

To start off the performance maxima, let us first investigate the initial function I started with. This function may be much slower than the ones shown further down the page (it's still much faster than any other answer posted here), but it should be much less confusing.

const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at "+compactBS(sArr, s);

function compactBS(array, searchedValue, ARG_start, ARG_len){
  // `void 0` is shorthand for `undefined`
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? array.length|0 : start+(ARG_len|0)|0;
  var offset = 0;

  for (var i=30; i >= 0; i=i-1|0) {
    offset = start + ((1<<i) - 1|0)|0;
    if (offset < len) {
      start = start + ((array[offset] < searchedValue) << i) | 0;
    }
  }

  if (array[start|0] !== searchedValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }
  return start |0;
}```
</div>
</div>
</p>
<p>The return value of the above function is as follows.</p>
<ul>
<li>If the value was found, then it returns the index of the value.</li>
<li>If the value was not found, then it returns <code>-1 - nearestIndex</code> where the nearestIndex is the index found which is the closest number <= index and capped at 0.</li>
<li>If the array is not sorted within the specified range, then it will return some meaningless number.</li>
</ul>
<p>And now, then, unroll it, precompute it, make it fast, nice and good, just like that:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at index "+goodBinarySearch(sArr, s);

function goodBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0;

  if ((offset = start + 0x3fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 30) | 0;
  }
  if ((offset = start + 0x1fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 29) | 0;
  }
  if ((offset = start + 0x0fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 28) | 0;
  }
  if ((offset = start + 0x07ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 27) | 0;
  }
  if ((offset = start + 0x03ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 26) | 0;
  }
  if ((offset = start + 0x01ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 25) | 0;
  }
  if ((offset = start + 0x00ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 24) | 0;
  }
  if ((offset = start + 0x007fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 23) | 0;
  }
  if ((offset = start + 0x003fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 22) | 0;
  }
  if ((offset = start + 0x001fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 21) | 0;
  }
  if ((offset = start + 0x000fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 20) | 0;
  }
  if ((offset = start + 0x0007ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 19) | 0;
  }
  if ((offset = start + 0x0003ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 18) | 0;
  }
  if ((offset = start + 0x0001ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 17) | 0;
  }
  if ((offset = start + 0x0000ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 16) | 0;
  }
  if ((offset = start + 0x00007fff|0) < len) {
    start = start + ((array[offset] < sValue) << 15) | 0;
  }
  if ((offset = start + 0x00003fff|0) < len) {
    start = start + ((array[offset] < sValue) << 14) | 0;
  }
  if ((offset = start + 0x00001fff|0) < len) {
    start = start + ((array[offset] < sValue) << 13) | 0;
  }
  if ((offset = start + 0x00000fff|0) < len) {
    start = start + ((array[offset] < sValue) << 12) | 0;
  }
  if ((offset = start + 0x000007ff|0) < len) {
    start = start + ((array[offset] < sValue) << 11) | 0;
  }
  if ((offset = start + 0x000003ff|0) < len) {
    start = start + ((array[offset] < sValue) << 10) | 0;
  }
  if ((offset = start + 0x000001ff|0) < len) {
    start = start + ((array[offset] < sValue) << 9) | 0;
  }
  if ((offset = start + 0x000000ff|0) < len) {
    start = start + ((array[offset] < sValue) << 8) | 0;
  }
  if ((offset = start + 0x0000007f|0) < len) {
    start = start + ((array[offset] < sValue) << 7) | 0;
  }
  if ((offset = start + 0x0000003f|0) < len) {
    start = start + ((array[offset] < sValue) << 6) | 0;
  }
  if ((offset = start + 0x0000001f|0) < len) {
    start = start + ((array[offset] < sValue) << 5) | 0;
  }
  if ((offset = start + 0x0000000f|0) < len) {
    start = start + ((array[offset] < sValue) << 4) | 0;
  }
  if ((offset = start + 0x00000007|0) < len) {
    start = start + ((array[offset] < sValue) << 3) | 0;
  }
  if ((offset = start + 0x00000003|0) < len) {
    start = start + ((array[offset] < sValue) << 2) | 0;
  }
  if ((offset = start + 0x00000001|0) < len) {
    start = start + ((array[offset] < sValue) << 1) | 0;
  }
  if (start < len) {
    start = start + ((array[start] < sValue) << 0) | 0;
  }

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }
  return start |0;
}</code>```

To further optimize performance, we can interleave the if-statements and use bitwise manipulations to make the last three checks branchless like so:

const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at index "+fastBinarySearch(sArr, s);

function fastBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0, nCB = 0;

  if ((start + 0x00007fff|0) < len) {
    if ((start + 0x007fffff|0) < len) {
      if ((start + 0x07ffffff|0) < len) {
        if ((start + 0x1fffffff|0) < len) {
          if ((offset = start + 0x3fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 30) | 0;
          }
          if ((offset = start + 0x1fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 29) | 0;
          }
        }
        if ((offset = start + 0x0fffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 28) | 0;
        }
        if ((offset = start + 0x07ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 27) | 0;
        }
      }
      if ((start + 0x01ffffff|0) < len) {
        if ((offset = start + 0x03ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 26) | 0;
        }
        if ((offset = start + 0x01ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 25) | 0;
        }
      }
      if ((offset = start + 0x00ffffff|0) < len) {
        start = start + ((array[offset] < sValue) << 24) | 0;
      }
      if ((offset = start + 0x007fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 23) | 0;
      }
    }
    if ((start + 0x0007ffff|0) < len) {
      if ((start + 0x001fffff|0) < len) {
        if ((offset = start + 0x003fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 22) | 0;
        }
        if ((offset = start + 0x001fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 21) | 0;
        }
      }
      if ((offset = start + 0x000fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 20) | 0;
      }
      if ((offset = start + 0x0007ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 19) | 0;
      }
    }
    if ((start + 0x0001ffff|0) < len) {
      if ((offset = start + 0x0003ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 18) | 0;
      }
      if ((offset = start + 0x0001ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 17) | 0;
      }
    }
    if ((offset = start + 0x0000ffff|0) < len) {
      start = start + ((array[offset] < sValue) << 16) | 0;
    }
    if ((offset = start + 0x00007fff|0) < len) {
      start = start + ((array[offset] < sValue) << 15) | 0;
    }
  }
  if ((start + 0x0000007f|0) < len) {
    if ((start + 0x000007ff|0) < len) {
      if ((start + 0x00001fff|0) < len) {
        if ((offset = start + 0x00003fff|0) < len) {
          start = start + ((array[offset] < sValue) << 14) | 0;
        }
        if ((offset = start + 0x00001fff|0) < len) {
          start = start + ((array[offset] < sValue) << 13) | 0;
        }
      }
      if ((offset = start + 0x00000fff|0) < len) {
        start = start + ((array[offset] < sValue) << 12) | 0;
      }
      if ((offset = start + 0x000007ff|0) < len) {
        start = start + ((array[offset] < sValue) << 11) | 0;
      }
    }
    if ((start + 0x000001ff|0) < len) {
      if ((offset = start + 0x000003ff|0) < len) {
        start = start + ((array[offset] < sValue) << 10) | 0;
      }
      if ((offset = start + 0x000001ff|0) < len) {
        start = start + ((array[offset] < sValue) << 9) | 0;
      }
    }
    if ((offset = start + 0x000000ff|0) < len) {
      start = start + ((array[offset] < sValue) << 8) | 0;
    }
    if ((offset = start + 0x0000007f|0) < len) {
      start = start + ((array[offset] < sValue) << 7) | 0;
    }
  }
  if ((start + 0x00000007|0) < len) {
    if ((start + 0x0000001f|0) < len) {
      if ((offset = start + 0x0000003f|0) < len) {
        start = start + ((array[offset] < sValue) << 6) | 0;
      }
      if ((offset = start + 0x0000001f|0) < len) {
        start = start + ((array[offset] < sValue) << 5) | 0;
      }
    }
    if ((offset = start + 0x0000000f|0) < len) {
      start = start + ((array[offset] < sValue) << 4) | 0;
    }
    if ((offset = start + 0x00000007|0) < len) {
      start = start + ((array[offset] < sValue) << 3) | 0;
    }
  }

  offset = start + 0x00000003|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 2) & nCB) | 0;

  offset = start + 0x00000001|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 1) & nCB) | 0;

  offset = start;
  nCB = -(offset < len|0) | 0;
  start = start + ((array[offset & nCB] < sValue) & nCB) | 0;

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }

  return start |0;
}```
</div>
</div>
</p>
<p>But wait... asunder whispers the eve of even greater performance. Likely, you are calling the binary search in a tight loop. In such a case, we can precompute the first value that will actually get processed and skip right to it with a high performance integer index switch statement. HOWEVER, while using this, you must make certain that you never reuse the generated fast function after the length of the array has been modified because then only part of the array will be searched.</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const clz32 = Math.clz32 || (function(log, LN2){
  return function(x) {
    return 31 - log(x >>> 0) / LN2 | 0; // the "| 0" acts like math.floor
  };
})(Math.log, Math.LN2);
const ArrayProtoSlice = Array.prototype.slice;

const sArr = [0,4,5,6,9,13,14,21,27,44];
const compFunc = fastestBS(sArr);
for (var i=0,str="",len=sArr.length|0; i < len; i=i+1|0)
  str += sArr[i]+" is at "+compFunc(sArr[i])+"<br/>";
document.body.innerHTML = str; // show the result

function fastestBS(array, ARG_start, ARG_len){
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var init_start = ARG_start | 0;
  var len = ARG_len === void 0 ? array.length|0 : init_start+(ARG_len|0)|0;
  const compGoto = clz32(len) & 31;

  var arrPadded = array;
  var relLen = len - init_start | 0;
  if (relLen & (relLen - 1)) { // if its not a power of 2
    var sizeUp = relLen;
    sizeUp |= sizeUp >>> 16;
    sizeUp |= sizeUp >>> 8;
    sizeUp |= sizeUp >>> 4;
    sizeUp |= sizeUp >>> 2;
    sizeUp |= sizeUp >>> 1;
    sizeUp = sizeUp + 1 - relLen | 0;

    arrPadded = ArrayProtoSlice.call(array);

    var accCur = [array[len - 1 | 0]];
    while (1 < sizeUp && accCur.length < 65536) {
      if (sizeUp & 1) arrPadded.push.apply(arrPadded, accCur);
      sizeUp >>>= 1;
      accCur.push.apply(accCur, accCur);
    }
    for (var i=0; i < sizeUp; i=i+1|0) {
      arrPadded.push.apply(arrPadded, accCur);
    }
  }

  return function(sValue) {
    var start = init_start | 0, offset = 0;
    switch (compGoto) {
      case 1:
        start = start + ((arrPadded[start + 0x3fffffff|0] < sValue) << 30) | 0;
      case 2:
        start = start + ((arrPadded[start + 0x1fffffff|0] < sValue) << 29) | 0;
      case 3:
        start = start + ((arrPadded[start + 0x0fffffff|0] < sValue) << 28) | 0;
      case 4:
        start = start + ((arrPadded[start + 0x07ffffff|0] < sValue) << 27) | 0;
      case 5:
        start = start + ((arrPadded[start + 0x03ffffff|0] < sValue) << 26) | 0;
      case 6:
        start = start + ((arrPadded[start + 0x01ffffff|0] < sValue) << 25) | 0;
      case 7:
        start = start + ((arrPadded[start + 0x00ffffff|0] < sValue) << 24) | 0;
      case 8:
        start = start + ((arrPadded[start + 0x007fffff|0] < sValue) << 23) | 0;
      case 9:
        start = start + ((arrPadded[start + 0x003fffff|0] < sValue) << 22) | 0;
      case 10:
        start = start + ((arrPadded[start + 0x001fffff|0] < sValue) << 21) | 0;
      case 11:
        start = start + ((arrPadded[start + 0x000fffff|0] < sValue) << 20) | 0;
      case 12:
        start = start + ((arrPadded[start + 0x0007ffff|0] < sValue) << 19) | 0;
      case 13:
        start = start + ((arrPadded[start + 0x0003ffff|0] < sValue) << 18) | 0;
      case 14:
        start = start + ((arrPadded[start + 0x0001ffff|0] < sValue) << 17) | 0;
      case 15:
        start = start + ((arrPadded[start + 0x0000ffff|0] < sValue) << 16) | 0;
      case 16:
        start = start + ((arrPadded[start + 0x00007fff|0] < sValue) << 15) | 0;
      case 17:
        start = start + ((arrPadded[start + 0x00003fff|0] < sValue) << 14) | 0;
      case 18:
        start = start + ((arrPadded[start + 0x00001fff|0] < sValue) << 13) | 0;
      case 19:
        start = start + ((arrPadded[start + 0x00000fff|0] < sValue) << 12) | 0;
      case 20:
        start = start + ((arrPadded[start + 0x000007ff|0] < sValue) << 11) | 0;
      case 21:
        start = start + ((arrPadded[start + 0x000003ff|0] < sValue) << 10) | 0;
      case 22:
        start = start + ((arrPadded[start + 0x000001ff|0] < sValue) << 9) | 0;
      case 23:
        start = start + ((arrPadded[start + 0x000000ff|0] < sValue) << 8) | 0;
      case 24:
        start = start + ((arrPadded[start + 0x0000007f|0] < sValue) << 7) | 0;
      case 25:
        start = start + ((arrPadded[start + 0x0000003f|0] < sValue) << 6) | 0;
      case 26:
        start = start + ((arrPadded[start + 0x0000001f|0] < sValue) << 5) | 0;
      case 27:
        start = start + ((arrPadded[start + 0x0000000f|0] < sValue) << 4) | 0;
      case 28:
        start = start + ((arrPadded[start + 0x00000007|0] < sValue) << 3) | 0;
      case 29:
        start = start + ((arrPadded[start + 0x00000003|0] < sValue) << 2) | 0;
      case 30:
        start = start + ((arrPadded[start + 0x00000001|0] < sValue) << 1) | 0;
      case 31:
        start = start + ((arrPadded[start] < sValue) << 0) | 0;
    }
    if (arrPadded[start|0] !== sValue) {
      if (len <= start) start = len - 1 | 0; // because we padd the array up to the next power of 2
      // remove this if-statement to return the next closest
      // element going downwards from the searched-for value
      // OR 0 if the value is less than all values in the
      // array. https://stackoverflow.com/a/44981570/5601591
      return -1 - start |0;
    }
    return start;
  };
}</code>```

Demo:

(function(document){"use strict";
var textarea = document.getElementById('inputbox'),
    searchinput = document.getElementById('search'),
    searchStart = document.getElementById('start'),
    searchedLength = document.getElementById('length'),
    resultbox = document.getElementById('result'),
    timeoutID = -1;
function doUpdate(){
   try {
      var txt = textarea.value.replace(/\s*\[|\]\s*/g, '').split(',');
      var arr = JSON.parse(textarea.value);
      var searchval = JSON.parse(searchinput.value);
      var textmtchs = textarea.value.match(/\s*\[|\]\s*/g);
      var start = searchStart.value || void 0;
      var sub = searchedLength.value || void 0;

      txt = refSort(txt, arr);
      textarea.value = textmtchs[0] +
                        txt.join(',') +
                       textmtchs[textmtchs.length-1];
      arr = JSON.parse(textarea.value);
      resultbox.value = fastBinarySearch(arr, searchval, start, sub);
   } catch(e) {
      resultbox.value = 'Error';
   }
}
textarea.oninput = searchinput.oninput =
    searchStart.oninput = searchedLength.oninput =
    textarea.onkeyup = searchinput.onkeyup =
    searchStart.onkeyup = searchedLength.onkeyup =
    textarea.onchange = searchinput.onchange =
    searchStart.onchange = searchedLength.onchange = function(e){
  clearTimeout( timeoutID );
  timeoutID = setTimeout(doUpdate, e.target === textarea ? 384 : 125);
}

function refSort(targetData, refData) {
  var indices = Object.keys(refData);
  indices.sort(function(indexA, indexB) {
    if (refData[indexA] < refData[indexB]) return -1;
    if (refData[indexA] > refData[indexB]) return 1;
    return 0;
  });
  return indices.map(function(i){ return targetData[i] })
}
function fastBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0, nCB = 0;

  if ((start + 0x00007fff|0) < len) {
    if ((start + 0x007fffff|0) < len) {
      if ((start + 0x07ffffff|0) < len) {
        if ((start + 0x1fffffff|0) < len) {
          if ((offset = start + 0x3fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 30) | 0;
          }
          if ((offset = start + 0x1fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 29) | 0;
          }
        }
        if ((offset = start + 0x0fffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 28) | 0;
        }
        if ((offset = start + 0x07ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 27) | 0;
        }
      }
      if ((start + 0x01ffffff|0) < len) {
        if ((offset = start + 0x03ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 26) | 0;
        }
        if ((offset = start + 0x01ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 25) | 0;
        }
      }
      if ((offset = start + 0x00ffffff|0) < len) {
        start = start + ((array[offset] < sValue) << 24) | 0;
      }
      if ((offset = start + 0x007fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 23) | 0;
      }
    }
    if ((start + 0x0007ffff|0) < len) {
      if ((start + 0x001fffff|0) < len) {
        if ((offset = start + 0x003fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 22) | 0;
        }
        if ((offset = start + 0x001fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 21) | 0;
        }
      }
      if ((offset = start + 0x000fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 20) | 0;
      }
      if ((offset = start + 0x0007ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 19) | 0;
      }
    }
    if ((start + 0x0001ffff|0) < len) {
      if ((offset = start + 0x0003ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 18) | 0;
      }
      if ((offset = start + 0x0001ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 17) | 0;
      }
    }
    if ((offset = start + 0x0000ffff|0) < len) {
      start = start + ((array[offset] < sValue) << 16) | 0;
    }
    if ((offset = start + 0x00007fff|0) < len) {
      start = start + ((array[offset] < sValue) << 15) | 0;
    }
  }
  if ((start + 0x0000007f|0) < len) {
    if ((start + 0x000007ff|0) < len) {
      if ((start + 0x00001fff|0) < len) {
        if ((offset = start + 0x00003fff|0) < len) {
          start = start + ((array[offset] < sValue) << 14) | 0;
        }
        if ((offset = start + 0x00001fff|0) < len) {
          start = start + ((array[offset] < sValue) << 13) | 0;
        }
      }
      if ((offset = start + 0x00000fff|0) < len) {
        start = start + ((array[offset] < sValue) << 12) | 0;
      }
      if ((offset = start + 0x000007ff|0) < len) {
        start = start + ((array[offset] < sValue) << 11) | 0;
      }
    }
    if ((start + 0x000001ff|0) < len) {
      if ((offset = start + 0x000003ff|0) < len) {
        start = start + ((array[offset] < sValue) << 10) | 0;
      }
      if ((offset = start + 0x000001ff|0) < len) {
        start = start + ((array[offset] < sValue) << 9) | 0;
      }
    }
    if ((offset = start + 0x000000ff|0) < len) {
      start = start + ((array[offset] < sValue) << 8) | 0;
    }
    if ((offset = start + 0x0000007f|0) < len) {
      start = start + ((array[offset] < sValue) << 7) | 0;
    }
  }
  if ((start + 0x00000007|0) < len) {
    if ((start + 0x0000001f|0) < len) {
      if ((offset = start + 0x0000003f|0) < len) {
        start = start + ((array[offset] < sValue) << 6) | 0;
      }
      if ((offset = start + 0x0000001f|0) < len) {
        start = start + ((array[offset] < sValue) << 5) | 0;
      }
    }
    if ((offset = start + 0x0000000f|0) < len) {
      start = start + ((array[offset] < sValue) << 4) | 0;
    }
    if ((offset = start + 0x00000007|0) < len) {
      start = start + ((array[offset] < sValue) << 3) | 0;
    }
  }

  offset = start + 0x00000003|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 2) & nCB) | 0;

  offset = start + 0x00000001|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 1) & nCB) | 0;

  offset = start;
  nCB = -(offset < len|0) | 0;
  start = start + ((array[offset & nCB] < sValue) & nCB) | 0;

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }

  return start |0;
}
})(document);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><h3 style="margin:.125em;width:100%;text-align:center">The Array (Must Be A Valid JSON Array)</h3>
<textarea placeholder="[-24, -12, 0, 0, 9, 16, 18, 64, 80]" type="text" rows=6 style="width:calc(100% - .5em);display:block" id="inputbox">[-24, -12, 0, 0, 9, 16, 18, 64, 80]</textarea>

<table style="table-layout:fixed;font-size:1.2em" width="100%"><tbody>
  <tr>
    <td colspan="3">Search Value: <input type="text" id="search" value="-12" style="width:8em;text-align:center;float:right" /></td>
    <td></td>
    <td colspan="3">Resulting Index: <input type="text" id="result" value="1" style="width:8em;text-align:center;float:right" readonly="" />
  </tr>
  <tr>
    <td colspan="3">Start Index: <input type="text" id="start" value="" placeholder="(0)" style="width:8em;text-align:center;float:right" /></td>
    <td></td>
    <td colspan="3">Searched Length: <input type="text" id="length" value="" placeholder="(array length)" style="width:8em;text-align:center;float:right" />
  </tr>
</tbody></table></code>```

You can also use an array of strings (surrounded by quotation marks) in the demo, and it should work just fine. To search for a string, you must put quotes around the search value.

ContentLicense: CC BY-SA 4.0

Title: Binary Search in Javascript

Body:
I'm trying to implement a binary search algorithm in JavaScript.  Things seem okay, but my return statements appear to be returning undefined. Can anybody tell me what's wrong here?

Fiddle: http://jsfiddle.net/2mBdL/

var a = [
    1,
    2,
    4,
    6,
    1,
    100,
    0,
    10000,
    3
];

a.sort(function (a, b) {
    return a - b;
});

console.log('a,', a);

function binarySearch(arr, i) {
    var mid = Math.floor(arr.length / 2);
    console.log(arr[mid], i);

    if (arr[mid] === i) {
        console.log('match', arr[mid], i);
        return arr[mid];
    } else if (arr[mid]  1) {
        console.log('mid lower', arr[mid], i);
        binarySearch(arr.splice(mid, Number.MAX_VALUE), i);
    } else if (arr[mid] > i && arr.length > 1) {
        console.log('mid higher', arr[mid], i);
        binarySearch(arr.splice(0, mid), i);
    } else {
        console.log('not here', i);
        return -1;
    }

}
var result = binarySearch(a, 100);
console.log(result);

Body:
  ?  .

Binary searches implemented right (without modifying the array, making shallow copies of the array, or other absurdities) have an average complexity around O(k*log2(n)) (where k is constant representing needless overhead). Say you have an array of 1024 elements, and the constant k is 1 in this case. With a linear search, the average complexity would be O(k*n/2)=O(1*1024/2)=O(512). With a binary search, you would have a complexity of O(k*log2(n))=O(1*log2(1024))=O(1*10)=O(10). Now, say that you make both the linear search algorithm 25% faster and the binary search algorithm 25% faster. Now, k is 0.75 for both algorithms. The complexity of the linear search decreases to O(384) (a gain of 128 performance points), whereas the binary search decreases to O(7.5) (a gain of only 2.5 performance points). This minimal gain from optimizing the binary search method is because the binary search method is already so fast. Therefore, any sane person should be more inclined to optimize the rest of their program before they try to optimize their binary search algorithm. Despite this clear line of reasoning, I eventually gave into temptations and optimized the binary search function to the absolute limits of JavaScript engineering.

To start off the performance maxima, let us first investigate the initial function I started with. This function may be much slower than the ones shown further down the page (it's still much faster than any other answer posted here), but it should be much less confusing.

const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at "+compactBS(sArr, s);

function compactBS(array, searchedValue, ARG_start, ARG_len){
  // `void 0` is shorthand for `undefined`
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? array.length|0 : start+(ARG_len|0)|0;
  var offset = 0;

  for (var i=30; i >= 0; i=i-1|0) {
    offset = start + ((1<<i) - 1|0)|0;
    if (offset < len) {
      start = start + ((array[offset] < searchedValue) << i) | 0;
    }
  }

  if (array[start|0] !== searchedValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }
  return start |0;
}

The return value of the above function is as follows.

If the value was found, then it returns the index of the value.

If the value was not found, then it returns -1 - nearestIndex where the nearestIndex is the index found which is the closest number <= index and capped at 0.

If the array is not sorted within the specified range, then it will return some meaningless number.

And now, then, unroll it, precompute it, make it fast, nice and good, just like that:

const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at index "+goodBinarySearch(sArr, s);

function goodBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0;

  if ((offset = start + 0x3fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 30) | 0;
  }
  if ((offset = start + 0x1fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 29) | 0;
  }
  if ((offset = start + 0x0fffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 28) | 0;
  }
  if ((offset = start + 0x07ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 27) | 0;
  }
  if ((offset = start + 0x03ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 26) | 0;
  }
  if ((offset = start + 0x01ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 25) | 0;
  }
  if ((offset = start + 0x00ffffff|0) < len) {
    start = start + ((array[offset] < sValue) << 24) | 0;
  }
  if ((offset = start + 0x007fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 23) | 0;
  }
  if ((offset = start + 0x003fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 22) | 0;
  }
  if ((offset = start + 0x001fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 21) | 0;
  }
  if ((offset = start + 0x000fffff|0) < len) {
    start = start + ((array[offset] < sValue) << 20) | 0;
  }
  if ((offset = start + 0x0007ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 19) | 0;
  }
  if ((offset = start + 0x0003ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 18) | 0;
  }
  if ((offset = start + 0x0001ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 17) | 0;
  }
  if ((offset = start + 0x0000ffff|0) < len) {
    start = start + ((array[offset] < sValue) << 16) | 0;
  }
  if ((offset = start + 0x00007fff|0) < len) {
    start = start + ((array[offset] < sValue) << 15) | 0;
  }
  if ((offset = start + 0x00003fff|0) < len) {
    start = start + ((array[offset] < sValue) << 14) | 0;
  }
  if ((offset = start + 0x00001fff|0) < len) {
    start = start + ((array[offset] < sValue) << 13) | 0;
  }
  if ((offset = start + 0x00000fff|0) < len) {
    start = start + ((array[offset] < sValue) << 12) | 0;
  }
  if ((offset = start + 0x000007ff|0) < len) {
    start = start + ((array[offset] < sValue) << 11) | 0;
  }
  if ((offset = start + 0x000003ff|0) < len) {
    start = start + ((array[offset] < sValue) << 10) | 0;
  }
  if ((offset = start + 0x000001ff|0) < len) {
    start = start + ((array[offset] < sValue) << 9) | 0;
  }
  if ((offset = start + 0x000000ff|0) < len) {
    start = start + ((array[offset] < sValue) << 8) | 0;
  }
  if ((offset = start + 0x0000007f|0) < len) {
    start = start + ((array[offset] < sValue) << 7) | 0;
  }
  if ((offset = start + 0x0000003f|0) < len) {
    start = start + ((array[offset] < sValue) << 6) | 0;
  }
  if ((offset = start + 0x0000001f|0) < len) {
    start = start + ((array[offset] < sValue) << 5) | 0;
  }
  if ((offset = start + 0x0000000f|0) < len) {
    start = start + ((array[offset] < sValue) << 4) | 0;
  }
  if ((offset = start + 0x00000007|0) < len) {
    start = start + ((array[offset] < sValue) << 3) | 0;
  }
  if ((offset = start + 0x00000003|0) < len) {
    start = start + ((array[offset] < sValue) << 2) | 0;
  }
  if ((offset = start + 0x00000001|0) < len) {
    start = start + ((array[offset] < sValue) << 1) | 0;
  }
  if (start < len) {
    start = start + ((array[start] < sValue) << 0) | 0;
  }

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }
  return start |0;
}

To further optimize performance, we can interleave the if-statements and use bitwise manipulations to make the last three checks branchless like so:

const sArr = [0,4,5,6,9,13,14,21,27,44];
const s = sArr[Math.random() * sArr.length | 0];
document.body.innerHTML = s+" is at index "+fastBinarySearch(sArr, s);

function fastBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0, nCB = 0;

  if ((start + 0x00007fff|0) < len) {
    if ((start + 0x007fffff|0) < len) {
      if ((start + 0x07ffffff|0) < len) {
        if ((start + 0x1fffffff|0) < len) {
          if ((offset = start + 0x3fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 30) | 0;
          }
          if ((offset = start + 0x1fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 29) | 0;
          }
        }
        if ((offset = start + 0x0fffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 28) | 0;
        }
        if ((offset = start + 0x07ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 27) | 0;
        }
      }
      if ((start + 0x01ffffff|0) < len) {
        if ((offset = start + 0x03ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 26) | 0;
        }
        if ((offset = start + 0x01ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 25) | 0;
        }
      }
      if ((offset = start + 0x00ffffff|0) < len) {
        start = start + ((array[offset] < sValue) << 24) | 0;
      }
      if ((offset = start + 0x007fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 23) | 0;
      }
    }
    if ((start + 0x0007ffff|0) < len) {
      if ((start + 0x001fffff|0) < len) {
        if ((offset = start + 0x003fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 22) | 0;
        }
        if ((offset = start + 0x001fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 21) | 0;
        }
      }
      if ((offset = start + 0x000fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 20) | 0;
      }
      if ((offset = start + 0x0007ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 19) | 0;
      }
    }
    if ((start + 0x0001ffff|0) < len) {
      if ((offset = start + 0x0003ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 18) | 0;
      }
      if ((offset = start + 0x0001ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 17) | 0;
      }
    }
    if ((offset = start + 0x0000ffff|0) < len) {
      start = start + ((array[offset] < sValue) << 16) | 0;
    }
    if ((offset = start + 0x00007fff|0) < len) {
      start = start + ((array[offset] < sValue) << 15) | 0;
    }
  }
  if ((start + 0x0000007f|0) < len) {
    if ((start + 0x000007ff|0) < len) {
      if ((start + 0x00001fff|0) < len) {
        if ((offset = start + 0x00003fff|0) < len) {
          start = start + ((array[offset] < sValue) << 14) | 0;
        }
        if ((offset = start + 0x00001fff|0) < len) {
          start = start + ((array[offset] < sValue) << 13) | 0;
        }
      }
      if ((offset = start + 0x00000fff|0) < len) {
        start = start + ((array[offset] < sValue) << 12) | 0;
      }
      if ((offset = start + 0x000007ff|0) < len) {
        start = start + ((array[offset] < sValue) << 11) | 0;
      }
    }
    if ((start + 0x000001ff|0) < len) {
      if ((offset = start + 0x000003ff|0) < len) {
        start = start + ((array[offset] < sValue) << 10) | 0;
      }
      if ((offset = start + 0x000001ff|0) < len) {
        start = start + ((array[offset] < sValue) << 9) | 0;
      }
    }
    if ((offset = start + 0x000000ff|0) < len) {
      start = start + ((array[offset] < sValue) << 8) | 0;
    }
    if ((offset = start + 0x0000007f|0) < len) {
      start = start + ((array[offset] < sValue) << 7) | 0;
    }
  }
  if ((start + 0x00000007|0) < len) {
    if ((start + 0x0000001f|0) < len) {
      if ((offset = start + 0x0000003f|0) < len) {
        start = start + ((array[offset] < sValue) << 6) | 0;
      }
      if ((offset = start + 0x0000001f|0) < len) {
        start = start + ((array[offset] < sValue) << 5) | 0;
      }
    }
    if ((offset = start + 0x0000000f|0) < len) {
      start = start + ((array[offset] < sValue) << 4) | 0;
    }
    if ((offset = start + 0x00000007|0) < len) {
      start = start + ((array[offset] < sValue) << 3) | 0;
    }
  }

  offset = start + 0x00000003|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 2) & nCB) | 0;

  offset = start + 0x00000001|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 1) & nCB) | 0;

  offset = start;
  nCB = -(offset < len|0) | 0;
  start = start + ((array[offset & nCB] < sValue) & nCB) | 0;

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }

  return start |0;
}

But wait... asunder whispers the eve of even greater performance. Likely, you are calling the binary search in a tight loop. In such a case, we can precompute the first value that will actually get processed and skip right to it with a high performance integer index switch statement. HOWEVER, while using this, you must make certain that you never reuse the generated fast function after the length of the array has been modified because then only part of the array will be searched.

const clz32 = Math.clz32 || (function(log, LN2){
  return function(x) {
    return 31 - log(x >>> 0) / LN2 | 0; // the "| 0" acts like math.floor
  };
})(Math.log, Math.LN2);
const ArrayProtoSlice = Array.prototype.slice;

const sArr = [0,4,5,6,9,13,14,21,27,44];
const compFunc = fastestBS(sArr);
for (var i=0,str="",len=sArr.length|0; i < len; i=i+1|0)
  str += sArr[i]+" is at "+compFunc(sArr[i])+"<br/>";
document.body.innerHTML = str; // show the result

function fastestBS(array, ARG_start, ARG_len){
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var init_start = ARG_start | 0;
  var len = ARG_len === void 0 ? array.length|0 : init_start+(ARG_len|0)|0;
  const compGoto = clz32(len) & 31;

  var arrPadded = array;
  var relLen = len - init_start | 0;
  if (relLen & (relLen - 1)) { // if its not a power of 2
    var sizeUp = relLen;
    sizeUp |= sizeUp >>> 16;
    sizeUp |= sizeUp >>> 8;
    sizeUp |= sizeUp >>> 4;
    sizeUp |= sizeUp >>> 2;
    sizeUp |= sizeUp >>> 1;
    sizeUp = sizeUp + 1 - relLen | 0;

    arrPadded = ArrayProtoSlice.call(array);

    var accCur = [array[len - 1 | 0]];
    while (1 < sizeUp && accCur.length < 65536) {
      if (sizeUp & 1) arrPadded.push.apply(arrPadded, accCur);
      sizeUp >>>= 1;
      accCur.push.apply(accCur, accCur);
    }
    for (var i=0; i < sizeUp; i=i+1|0) {
      arrPadded.push.apply(arrPadded, accCur);
    }
  }

  return function(sValue) {
    var start = init_start | 0, offset = 0;
    switch (compGoto) {
      case 1:
        start = start + ((arrPadded[start + 0x3fffffff|0] < sValue) << 30) | 0;
      case 2:
        start = start + ((arrPadded[start + 0x1fffffff|0] < sValue) << 29) | 0;
      case 3:
        start = start + ((arrPadded[start + 0x0fffffff|0] < sValue) << 28) | 0;
      case 4:
        start = start + ((arrPadded[start + 0x07ffffff|0] < sValue) << 27) | 0;
      case 5:
        start = start + ((arrPadded[start + 0x03ffffff|0] < sValue) << 26) | 0;
      case 6:
        start = start + ((arrPadded[start + 0x01ffffff|0] < sValue) << 25) | 0;
      case 7:
        start = start + ((arrPadded[start + 0x00ffffff|0] < sValue) << 24) | 0;
      case 8:
        start = start + ((arrPadded[start + 0x007fffff|0] < sValue) << 23) | 0;
      case 9:
        start = start + ((arrPadded[start + 0x003fffff|0] < sValue) << 22) | 0;
      case 10:
        start = start + ((arrPadded[start + 0x001fffff|0] < sValue) << 21) | 0;
      case 11:
        start = start + ((arrPadded[start + 0x000fffff|0] < sValue) << 20) | 0;
      case 12:
        start = start + ((arrPadded[start + 0x0007ffff|0] < sValue) << 19) | 0;
      case 13:
        start = start + ((arrPadded[start + 0x0003ffff|0] < sValue) << 18) | 0;
      case 14:
        start = start + ((arrPadded[start + 0x0001ffff|0] < sValue) << 17) | 0;
      case 15:
        start = start + ((arrPadded[start + 0x0000ffff|0] < sValue) << 16) | 0;
      case 16:
        start = start + ((arrPadded[start + 0x00007fff|0] < sValue) << 15) | 0;
      case 17:
        start = start + ((arrPadded[start + 0x00003fff|0] < sValue) << 14) | 0;
      case 18:
        start = start + ((arrPadded[start + 0x00001fff|0] < sValue) << 13) | 0;
      case 19:
        start = start + ((arrPadded[start + 0x00000fff|0] < sValue) << 12) | 0;
      case 20:
        start = start + ((arrPadded[start + 0x000007ff|0] < sValue) << 11) | 0;
      case 21:
        start = start + ((arrPadded[start + 0x000003ff|0] < sValue) << 10) | 0;
      case 22:
        start = start + ((arrPadded[start + 0x000001ff|0] < sValue) << 9) | 0;
      case 23:
        start = start + ((arrPadded[start + 0x000000ff|0] < sValue) << 8) | 0;
      case 24:
        start = start + ((arrPadded[start + 0x0000007f|0] < sValue) << 7) | 0;
      case 25:
        start = start + ((arrPadded[start + 0x0000003f|0] < sValue) << 6) | 0;
      case 26:
        start = start + ((arrPadded[start + 0x0000001f|0] < sValue) << 5) | 0;
      case 27:
        start = start + ((arrPadded[start + 0x0000000f|0] < sValue) << 4) | 0;
      case 28:
        start = start + ((arrPadded[start + 0x00000007|0] < sValue) << 3) | 0;
      case 29:
        start = start + ((arrPadded[start + 0x00000003|0] < sValue) << 2) | 0;
      case 30:
        start = start + ((arrPadded[start + 0x00000001|0] < sValue) << 1) | 0;
      case 31:
        start = start + ((arrPadded[start] < sValue) << 0) | 0;
    }
    if (arrPadded[start|0] !== sValue) {
      if (len <= start) start = len - 1 | 0; // because we padd the array up to the next power of 2
      // remove this if-statement to return the next closest
      // element going downwards from the searched-for value
      // OR 0 if the value is less than all values in the
      // array. https://stackoverflow.com/a/44981570/5601591
      return -1 - start |0;
    }
    return start;
  };
}

Demo:

(function(document){"use strict";
var textarea = document.getElementById('inputbox'),
    searchinput = document.getElementById('search'),
    searchStart = document.getElementById('start'),
    searchedLength = document.getElementById('length'),
    resultbox = document.getElementById('result'),
    timeoutID = -1;
function doUpdate(){
   try {
      var txt = textarea.value.replace(/\s*\[|\]\s*/g, '').split(',');
      var arr = JSON.parse(textarea.value);
      var searchval = JSON.parse(searchinput.value);
      var textmtchs = textarea.value.match(/\s*\[|\]\s*/g);
      var start = searchStart.value || void 0;
      var sub = searchedLength.value || void 0;

      txt = refSort(txt, arr);
      textarea.value = textmtchs[0] +
                        txt.join(',') +
                       textmtchs[textmtchs.length-1];
      arr = JSON.parse(textarea.value);
      resultbox.value = fastBinarySearch(arr, searchval, start, sub);
   } catch(e) {
      resultbox.value = 'Error';
   }
}
textarea.oninput = searchinput.oninput =
    searchStart.oninput = searchedLength.oninput =
    textarea.onkeyup = searchinput.onkeyup =
    searchStart.onkeyup = searchedLength.onkeyup =
    textarea.onchange = searchinput.onchange =
    searchStart.onchange = searchedLength.onchange = function(e){
  clearTimeout( timeoutID );
  timeoutID = setTimeout(doUpdate, e.target === textarea ? 384 : 125);
}

function refSort(targetData, refData) {
  var indices = Object.keys(refData);
  indices.sort(function(indexA, indexB) {
    if (refData[indexA] < refData[indexB]) return -1;
    if (refData[indexA] > refData[indexB]) return 1;
    return 0;
  });
  return indices.map(function(i){ return targetData[i] })
}
function fastBinarySearch(array, sValue, ARG_start, ARG_len) {
  // Range of [start, start+len): only start is inclusive. It works
  // similarly to "...".substr(start, len).indexOf(sValue)
  // `void 0` is shorthand for `undefined`
  var start = ARG_start | 0;
  var len = ARG_len === void 0 ? (array.length|0) - start |0 : ARG_len|0;
  var offset = 0, nCB = 0;

  if ((start + 0x00007fff|0) < len) {
    if ((start + 0x007fffff|0) < len) {
      if ((start + 0x07ffffff|0) < len) {
        if ((start + 0x1fffffff|0) < len) {
          if ((offset = start + 0x3fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 30) | 0;
          }
          if ((offset = start + 0x1fffffff|0) < len) {
            start = start + ((array[offset] < sValue) << 29) | 0;
          }
        }
        if ((offset = start + 0x0fffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 28) | 0;
        }
        if ((offset = start + 0x07ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 27) | 0;
        }
      }
      if ((start + 0x01ffffff|0) < len) {
        if ((offset = start + 0x03ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 26) | 0;
        }
        if ((offset = start + 0x01ffffff|0) < len) {
          start = start + ((array[offset] < sValue) << 25) | 0;
        }
      }
      if ((offset = start + 0x00ffffff|0) < len) {
        start = start + ((array[offset] < sValue) << 24) | 0;
      }
      if ((offset = start + 0x007fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 23) | 0;
      }
    }
    if ((start + 0x0007ffff|0) < len) {
      if ((start + 0x001fffff|0) < len) {
        if ((offset = start + 0x003fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 22) | 0;
        }
        if ((offset = start + 0x001fffff|0) < len) {
          start = start + ((array[offset] < sValue) << 21) | 0;
        }
      }
      if ((offset = start + 0x000fffff|0) < len) {
        start = start + ((array[offset] < sValue) << 20) | 0;
      }
      if ((offset = start + 0x0007ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 19) | 0;
      }
    }
    if ((start + 0x0001ffff|0) < len) {
      if ((offset = start + 0x0003ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 18) | 0;
      }
      if ((offset = start + 0x0001ffff|0) < len) {
        start = start + ((array[offset] < sValue) << 17) | 0;
      }
    }
    if ((offset = start + 0x0000ffff|0) < len) {
      start = start + ((array[offset] < sValue) << 16) | 0;
    }
    if ((offset = start + 0x00007fff|0) < len) {
      start = start + ((array[offset] < sValue) << 15) | 0;
    }
  }
  if ((start + 0x0000007f|0) < len) {
    if ((start + 0x000007ff|0) < len) {
      if ((start + 0x00001fff|0) < len) {
        if ((offset = start + 0x00003fff|0) < len) {
          start = start + ((array[offset] < sValue) << 14) | 0;
        }
        if ((offset = start + 0x00001fff|0) < len) {
          start = start + ((array[offset] < sValue) << 13) | 0;
        }
      }
      if ((offset = start + 0x00000fff|0) < len) {
        start = start + ((array[offset] < sValue) << 12) | 0;
      }
      if ((offset = start + 0x000007ff|0) < len) {
        start = start + ((array[offset] < sValue) << 11) | 0;
      }
    }
    if ((start + 0x000001ff|0) < len) {
      if ((offset = start + 0x000003ff|0) < len) {
        start = start + ((array[offset] < sValue) << 10) | 0;
      }
      if ((offset = start + 0x000001ff|0) < len) {
        start = start + ((array[offset] < sValue) << 9) | 0;
      }
    }
    if ((offset = start + 0x000000ff|0) < len) {
      start = start + ((array[offset] < sValue) << 8) | 0;
    }
    if ((offset = start + 0x0000007f|0) < len) {
      start = start + ((array[offset] < sValue) << 7) | 0;
    }
  }
  if ((start + 0x00000007|0) < len) {
    if ((start + 0x0000001f|0) < len) {
      if ((offset = start + 0x0000003f|0) < len) {
        start = start + ((array[offset] < sValue) << 6) | 0;
      }
      if ((offset = start + 0x0000001f|0) < len) {
        start = start + ((array[offset] < sValue) << 5) | 0;
      }
    }
    if ((offset = start + 0x0000000f|0) < len) {
      start = start + ((array[offset] < sValue) << 4) | 0;
    }
    if ((offset = start + 0x00000007|0) < len) {
      start = start + ((array[offset] < sValue) << 3) | 0;
    }
  }

  offset = start + 0x00000003|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 2) & nCB) | 0;

  offset = start + 0x00000001|0;
  nCB = -(offset < len|0) | 0;
  start = start + (((array[offset & nCB] < sValue) << 1) & nCB) | 0;

  offset = start;
  nCB = -(offset < len|0) | 0;
  start = start + ((array[offset & nCB] < sValue) & nCB) | 0;

  if (array[start|0] !== sValue) {
    // remove this if-statement to return the next closest
    // element going downwards from the searched-for value
    // OR 0 if the value is less than all values in the
    // array. https://stackoverflow.com/a/44981570/5601591
    return -1 - start |0;
  }

  return start |0;
}
})(document);

<h3 style="margin:.125em;width:100%;text-align:center">The Array (Must Be A Valid JSON Array)</h3>
<textarea placeholder="[-24, -12, 0, 0, 9, 16, 18, 64, 80]" type="text" rows=6 style="width:calc(100% - .5em);display:block" id="inputbox">[-24, -12, 0, 0, 9, 16, 18, 64, 80]</textarea>

<table style="table-layout:fixed;font-size:1.2em" width="100%"><tbody>
  <tr>
    <td colspan="3">Search Value: <input type="text" id="search" value="-12" style="width:8em;text-align:center;float:right" /></td>
    <td></td>
    <td colspan="3">Resulting Index: <input type="text" id="result" value="1" style="width:8em;text-align:center;float:right" readonly="" />
  </tr>
  <tr>
    <td colspan="3">Start Index: <input type="text" id="start" value="" placeholder="(0)" style="width:8em;text-align:center;float:right" /></td>
    <td></td>
    <td colspan="3">Searched Length: <input type="text" id="length" value="" placeholder="(array length)" style="width:8em;text-align:center;float:right" />
  </tr>
</tbody></table>

You can also use an array of strings (surrounded by quotation marks) in the demo, and it should work just fine. To search for a string, you must put quotes around the search value.


问:
Sum of List must be 16
I am stuck in this problem for 2 hours now! My problem in prolog is I am thinking in a declarative way!

So my issue is to make prolog generate a list equal to N!  The size of list is 5.

```<code>somme([],0) :- !.
somme([X|L],S) :- somme(L,S1), S is S1+X.

generateList(L,RES) :- C1 is random(4)+1,
              C2 is random(5)+1,
              C3 is random(6)+1,
              append(L,[C1,C2,C3],RES).

go(L) :- generateList([2,3],L), somme(L,S), S \==16, go(L).
go(L) :- generateList([2,3],L), somme(L,S), S == 16,write(L).
</code>```

We suppose that the 2 first element are 2 and 3.

Title: Sum of List must be 16

Body:
I am stuck in this problem for 2 hours now! My problem in prolog is I am thinking in a declarative way!

So my issue is to make prolog generate a list equal to N!  The size of list is 5.

somme([],0) :- !.
somme([X|L],S) :- somme(L,S1), S is S1+X.

generateList(L,RES) :- C1 is random(4)+1,
              C2 is random(5)+1,
              C3 is random(6)+1,
              append(L,[C1,C2,C3],RES).

go(L) :- generateList([2,3],L), somme(L,S), S \==16, go(L).
go(L) :- generateList([2,3],L), somme(L,S), S == 16,write(L).

We suppose that the 2 first element are 2 and 3.

Body:
You could also use CLP(FD) to describe such lists:

:- use_module(library(clpfd)).

numbers(L) :-
   L=[2,3,_A,_B,_C],   % list has 5 elements and begins with 2,3
   L ins 0..16,        % the list elements are between 0 and 16
   sum(L, #=, 16).     % the sum of the list elements is 16

If you query this predicate you get residual goals as an answer because there is no unique solution to the predicate:

   ?- numbers(L).
L = [2,3,_A,_B,_C],
_A in 0..11,
_A+_B+_C#=11,
_B in 0..11,
_C in 0..11

Add label/1 to the query and you get all 78 solutions:

   ?- numbers(L), label(L).
L = [2,3,0,0,11] ? ;
L = [2,3,0,1,10] ? ;
L = [2,3,0,2,9] ? ;
...

You can collect all solutions by using bagof/3 like so:

   ?- bagof(L,(numbers(L), label(L)),Xs).
Xs = [[2,3,0,0,11],[2,3,0,1,10],[2,3,0,2,9],[2,3,0,3,8],[2,3,0,4,7],[2,3,0,5,6],[2,3,0,6,5],[2,3,0,7,4],[2,3,0,8,3],[2,3,0,9,2],[2,3,0,10,1],[2,3,0,11,0],[2,3,1,0,10],[2,3,1,1,9],[2,3,1,2,8],[2,3,1,3,7],[2,3,1,4,6],[2,3,1,5,5],[2,3,1,6,4],[2,3,1,7,3],[2,3,1,8,2],[2,3,1,9,1],[2,3,1,10,0],[2,3,2,0,9],[2,3,2,1,8],[2,3,2,2,7],[2,3,2,3,6],[2,3,2,4,5],[2,3,2,5,4],[2,3,2,6,3],[2,3,2,7,2],[2,3,2,8,1],[2,3,2,9,0],[2,3,3,0,8],[2,3,3,1,7],[2,3,3,2,6],[2,3,3,3,5],[2,3,3,4,4],[2,3,3,5,3],[2,3,3,6,2],[2,3,3,7,1],[2,3,3,8,0],[2,3,4,0,7],[2,3,4,1,6],[2,3,4,2,5],[2,3,4,3,4],[2,3,4,4,3],[2,3,4,5,2],[2,3,4,6,1],[2,3,4,7,0],[2,3,5,0,6],[2,3,5,1,5],[2,3,5,2,4],[2,3,5,3,3],[2,3,5,4,2],[2,3,5,5,1],[2,3,5,6,0],[2,3,6,0,5],[2,3,6,1,4],[2,3,6,2,3],[2,3,6,3,2],[2,3,6,4,1],[2,3,6,5,0],[2,3,7,0,4],[2,3,7,1,3],[2,3,7,2,2],[2,3,7,3,1],[2,3,7,4,0],[2,3,8,0,3],[2,3,8,1,2],[2,3,8,2,1],[2,3,8,3,0],[2,3,9,0,2],[2,3,9,1,1],[2,3,9,2,0],[2,3,10,0,1],[2,3,10,1,0],[2,3,11,0,0]]

With an additional goal length/2 you can count the number of the collected solutions:

   ?- bagof(L,(numbers(L), label(L)),Xs), length(Xs,Len).
Len = 78,
Xs = [[2,3,0,0,11],[2,3,0,1,10],[2,3,0,2,9],[2,3,0,3,8],[2,3,0,4,7],[2,3,0,5,6],[2,3,0,6,5],[2,3,0,7,4],[2,3,0,8,3],[2,3,0,9,2],[2,3,0,10,1],[2,3,0,11,0],[2,3,1,0,10],[2,3,1,1,9],[2,3,1,2,8],[2,3,1,3,7],[2,3,1,4,6],[2,3,1,5,5],[2,3,1,6,4],[2,3,1,7,3],[2,3,1,8,2],[2,3,1,9,1],[2,3,1,10,0],[2,3,2,0,9],[2,3,2,1,8],[2,3,2,2,7],[2,3,2,3,6],[2,3,2,4,5],[2,3,2,5,4],[2,3,2,6,3],[2,3,2,7,2],[2,3,2,8,1],[2,3,2,9,0],[2,3,3,0,8],[2,3,3,1,7],[2,3,3,2,6],[2,3,3,3,5],[2,3,3,4,4],[2,3,3,5,3],[2,3,3,6,2],[2,3,3,7,1],[2,3,3,8,0],[2,3,4,0,7],[2,3,4,1,6],[2,3,4,2,5],[2,3,4,3,4],[2,3,4,4,3],[2,3,4,5,2],[2,3,4,6,1],[2,3,4,7,0],[2,3,5,0,6],[2,3,5,1,5],[2,3,5,2,4],[2,3,5,3,3],[2,3,5,4,2],[2,3,5,5,1],[2,3,5,6,0],[2,3,6,0,5],[2,3,6,1,4],[2,3,6,2,3],[2,3,6,3,2],[2,3,6,4,1],[2,3,6,5,0],[2,3,7,0,4],[2,3,7,1,3],[2,3,7,2,2],[2,3,7,3,1],[2,3,7,4,0],[2,3,8,0,3],[2,3,8,1,2],[2,3,8,2,1],[2,3,8,3,0],[2,3,9,0,2],[2,3,9,1,1],[2,3,9,2,0],[2,3,10,0,1],[2,3,10,1,0],[2,3,11,0,0]]


问:
Log4Net works on VisualStudio Debug/Release, but not after deployment
In order to make more complex logs, I've decided to use the Log4Net for my WPF desktop app. It works perfectly, creating both 'Debug' messages at the 'Output' and writes to a file all the logs...

BUT if I deploy it/install it (using visual studio's wizard to create a .MSI setup) it stops working. I can't find any file on the folder or anywhere on the computer related to it.

I'm using Caliburn.Micro to organize my code. And in order to have the logs, I 'centralized' it by using a public static class by the name of "Logging.cs".

The code inside "Initialize()" was put right now as a way to try out, but it doesn't seem to be doing anything.

```<code>public static class Logging
{

    //Declaration of the logger
    /// <summary>
    /// Logger for the Logging manager.
    /// </summary>
    private static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    public static void Initialize()
    {
        log4net.Config.XmlConfigurator.Configure();
    }
    /// <summary>
    /// Creates a log in Fatal level accompanied by an expection
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Fatal(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Fatal(message, error);
    }
    /// <summary>
    /// Creates a log in Fatal level
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Fatal(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Fatal(message);
    }

    /// <summary>
    /// Creates a log in Error level accompanied by an expection
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Error(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        MessageBox.Show(error.ToString());
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Error(message, error);
    }
    /// <summary>
    /// Creates a log in Error level
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Error(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Error(message);
    }

    /// <summary>
    /// Creates a log in Warn level accompanied by an expection
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Warn(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Warn(message, error);
    }
    /// <summary>
    /// Creates a log in Warn level
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Warn(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Warn(message);

    }

    /// <summary>
    /// Creates a log in Info level accompanied by an expection
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Info(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Info(message, error);
    }
    /// <summary>
    /// Creates a log in Info level
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Info(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Info(message);
    }
    /// <summary>
    /// Creates a log in Debug level accompanied by an expection
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Debug(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message, error);
    }
    /// <summary>
    /// Creates a log in Debug level
    /// </summary>
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Debug(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message);
    }
    /// <summary>
    /// Log created in Debug level containing not only a log message but also an object to be serialized and logged.
    /// </summary>
    /// <param name="message">The message to be logged (should be description of object)</param>
    /// <param name="obj">Object to be displayed</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void ShowObject(string message, object obj, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message + "\n<object>" + JsonConvert.SerializeObject(obj) + "</object>\n");
    }
}
</code>```

Also, here is my log4net config file:

```<code>    <log4net>
    <root>
      <level value="ALL" />
      <appender-ref ref="console" />
      <appender-ref ref="file" />
    </root>
    <appender name="console" type="log4net.Appender.ColoredConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level %logger - [%message] // %exception%newline" />
      </layout>
    </appender>
    <appender name="file" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="DesktopApp.log" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - [%message] // %exception%newline" />
      </layout>
    </appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="log-file.txt" />
    <appendToFile value="true" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
</appender>
  </log4net>
</code>```

And at the AssemblyInfo.cs, I've merely inserted this at the end:

```<code>[assembly: log4net.Config.XmlConfigurator(Watch = true,ConfigFile ="log4net.config")]
</code>```

Thank you for your time, please comment if I can add any more details.

P.S.: The software is installed inside the AppData, so no file permission issues should arise, since I am using another framework to automatically update the app.

P.S.2: I used DebugView and in the middle of mostly info that seemed random I've found an error:

```<code>[5480] log4net:ERROR Failed to find configuration section 'log4net' in the application's .config file. Check your .config file for the <log4net> and <configSections> elements. The configuration section should look like: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</code>```

Still haven't tried fixing it, just keeping this question up to date. (Thanks Varun!)

答:
I found the issue. I was looking at the wrong place all this time. When I checked the instalation folder, I noticed there was no log4net.config! ... This is why it worked well during debug (because the config was there) but not after deployment!

Sorry for the bother and thank you for all the help.

Body:
In order to make more complex logs, I've decided to use the Log4Net for my WPF desktop app. It works perfectly, creating both 'Debug' messages at the 'Output' and writes to a file all the logs...

BUT if I deploy it/install it (using visual studio's wizard to create a .MSI setup) it stops working. I can't find any file on the folder or anywhere on the computer related to it.

I'm using Caliburn.Micro to organize my code. And in order to have the logs, I 'centralized' it by using a public static class by the name of "Logging.cs".

The code inside "Initialize()" was put right now as a way to try out, but it doesn't seem to be doing anything.

public static class Logging
{

    //Declaration of the logger
    ///
    /// Logger for the Logging manager.
    ///
    private static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    public static void Initialize()
    {
        log4net.Config.XmlConfigurator.Configure();
    }
    ///
    /// Creates a log in Fatal level accompanied by an expection
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Fatal(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Fatal(message, error);
    }
    ///
    /// Creates a log in Fatal level
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Fatal(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Fatal(message);
    }

    ///
    /// Creates a log in Error level accompanied by an expection
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Error(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        MessageBox.Show(error.ToString());
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Error(message, error);
    }
    ///
    /// Creates a log in Error level
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Error(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Error(message);
    }

    ///
    /// Creates a log in Warn level accompanied by an expection
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Warn(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Warn(message, error);
    }
    ///
    /// Creates a log in Warn level
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Warn(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Warn(message);

    }

    ///
    /// Creates a log in Info level accompanied by an expection
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Info(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Info(message, error);
    }
    ///
    /// Creates a log in Info level
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Info(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Info(message);
    }
    ///
    /// Creates a log in Debug level accompanied by an expection
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="error">Exception thrown along with the log</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Debug(string message, Exception error, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message, error);
    }
    ///
    /// Creates a log in Debug level
    ///
    /// <param name="message">The message to be logged</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void Debug(string message, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message);
    }
    ///
    /// Log created in Debug level containing not only a log message but also an object to be serialized and logged.
    ///
    /// <param name="message">The message to be logged (should be description of object)</param>
    /// <param name="obj">Object to be displayed</param>
    /// <param name="senderType">From where the log comes from</param>
    public static void ShowObject(string message, object obj, Type senderType)
    {
        //Defines 'type' in the log.
        Logger = log4net.LogManager.GetLogger(senderType);
        Logger.Debug(message + "\n<object>" + JsonConvert.SerializeObject(obj) + "</object>\n");
    }
}

Also, here is my log4net config file:

    <log4net>
    <root>
      <level value="ALL" />
      <appender-ref ref="console" />
      <appender-ref ref="file" />
    </root>
    <appender name="console" type="log4net.Appender.ColoredConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level %logger - [%message] // %exception%newline" />
      </layout>
    </appender>
    <appender name="file" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="DesktopApp.log" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - [%message] // %exception%newline" />
      </layout>
    </appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="log-file.txt" />
    <appendToFile value="true" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
</appender>
  </log4net>

And at the AssemblyInfo.cs, I've merely inserted this at the end:

[assembly: log4net.Config.XmlConfigurator(Watch = true,ConfigFile ="log4net.config")]

Thank you for your time, please comment if I can add any more details.

P.S.: The software is installed inside the AppData, so no file permission issues should arise, since I am using another framework to automatically update the app.

P.S.2: I used DebugView and in the middle of mostly info that seemed random I've found an error:

[5480] log4net:ERROR Failed to find configuration section 'log4net' in the application's .config file. Check your .config file for the <log4net> and <configSections> elements. The configuration section should look like:

Still haven't tried fixing it, just keeping this question up to date. (Thanks Varun!)


问:
Fastest way to find 2 missing numbers in an array
This question exist only because of pure curiosity. Not a homework.

Find the fastest way to find two missing number in an array 1..n

So, In a related post: Quickest way to find missing number in an array of numbers
I found out that you can do this pretty quickly by summing up and substracting total.

but what about 2 numbers?

So, our options are:

Sequential search

Summing up items, substracting from total for all items from 1..n, then searching all possible cases.

Anything else?
Possible to have O(n) solution?
I found this in ruby section of one of the websites, but any language is considered (unless there are some specific things for a language)

答:
```<code>If the array is sorted from 0 to N then you can compare the difference with index. The recursion function for this is O(logN)
Pseudo code for it is:
// OffsetA will keep track of the index offset of our first missing Number
// OffsetB will keep track of our second missing number
// Both Offset are set to Zero on the first recursion call.

Missing( Array A , Array B , OffsetA,  OffsetB ){
Add Array's A and B together. Will call it array C.// At the beginning Array B would be empty.

BaseCase:  If array C.length is 2 return C

    M= C.length/2

// for the middle value.

    If (C[M] == M + OffsetA){ // This means that both the values that are missing are to the right side of the array.
       return Missing((Arrays.copyOfRange(C,M,C.length)),ArrayB,M + Of

    fsetA,OffsetB);
    }

    If (C[M] == M + OffsetA +2){// This means both our values are to the left side of the missing array

     return Missing((Arrays.copyOfRange(C,0,M)),ArrayB,OffsetA,OffsetB);
    }

//This is the more complicated one.

`If(C[M] == M + OffsetA + 1){` This means that their are values on both the left and right side of the array. So we have to check the the middle of the first half and the middle of the second half of the array and we send the two quarter parts into our Missing Function. The checks are pretty much the same as the if statements up top but you should be able to figure out them your self. It seems like a homework or interview question.

EDIT: There might me a small issue with the offset switching and I dont have time to change it now but you should be able to figure out the basic concept.

}
</code>```


问:
Project Explorer not showing projects in eclipse rcp application
With help from many members of stackoverflow, I sort of finally completed my first RCP application.

I'm facing some issues with my Project Explorer

Project Explorer seems not be active when I open my RCP application (Sort of wakes up when I right click on my empty project explorer window)

Even when it ON, it doesnt show me the project explore options. I mean it just shows me the name of the project and nothing else (No files inside it are shown)

Pic:

My Perspective.java file looks as shown below

```<code> package kr;

import org.eclipse.ui.IFolderLayout;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {

    public void createInitialLayout(IPageLayout layout) {
        String editorArea = layout.getEditorArea();

         // Top left: Project Explorer view and Bookmarks view placeholder
         IFolderLayout topLeft = layout.createFolder("topLeft", IPageLayout.LEFT, 0.25f,
            editorArea);
         topLeft.addView(IPageLayout.ID_PROJECT_EXPLORER);
         topLeft.addPlaceholder(IPageLayout.ID_BOOKMARKS);

         // Bottom left: Outline view and Property Sheet view
         IFolderLayout bottomLeft = layout.createFolder("bottomLeft", IPageLayout.BOTTOM, 0.50f,
                   "topLeft");
         bottomLeft.addView(IPageLayout.ID_OUTLINE);
         bottomLeft.addView(IPageLayout.ID_PROP_SHEET);

         // Bottom right: Task List view
        // layout.addView(IPageLayout.ID_TASK_LIST, IPageLayout.BOTTOM, 0.66f, editorArea);
    }
}
</code>```

I have added o.e.ui.navigator and o.e.ui.navigator.resources to the dependency list

答:
For the initial empty view, you need to override the getDefaultPageInput in the WorkbenchAdvisor class of your RCP defining plugin, like this:

```<code>@Override
public IAdaptable getDefaultPageInput() {
    return ResourcesPlugin.getWorkspace().getRoot();
}
</code>```

Body:
With help from many members of stackoverflow, I sort of finally completed my first RCP application.

I'm facing some issues with my Project Explorer

Project Explorer seems not be active when I open my RCP application (Sort of wakes up when I right click on my empty project explorer window)

Even when it ON, it doesnt show me the project explore options. I mean it just shows me the name of the project and nothing else (No files inside it are shown)

Pic:

My Perspective.java file looks as shown below

 package kr;

import org.eclipse.ui.IFolderLayout;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {

    public void createInitialLayout(IPageLayout layout) {
        String editorArea = layout.getEditorArea();

         // Top left: Project Explorer view and Bookmarks view placeholder
         IFolderLayout topLeft = layout.createFolder("topLeft", IPageLayout.LEFT, 0.25f,
            editorArea);
         topLeft.addView(IPageLayout.ID_PROJECT_EXPLORER);
         topLeft.addPlaceholder(IPageLayout.ID_BOOKMARKS);

         // Bottom left: Outline view and Property Sheet view
         IFolderLayout bottomLeft = layout.createFolder("bottomLeft", IPageLayout.BOTTOM, 0.50f,
                   "topLeft");
         bottomLeft.addView(IPageLayout.ID_OUTLINE);
         bottomLeft.addView(IPageLayout.ID_PROP_SHEET);

         // Bottom right: Task List view
        // layout.addView(IPageLayout.ID_TASK_LIST, IPageLayout.BOTTOM, 0.66f, editorArea);
    }
}

I have added o.e.ui.navigator and o.e.ui.navigator.resources to the dependency list

Body:
For the initial empty view, you need to override the getDefaultPageInput in the WorkbenchAdvisor class of your RCP defining plugin, like this:

@Override
public IAdaptable getDefaultPageInput() {
    return ResourcesPlugin.getWorkspace().getRoot();
}


问:
Android Studio: can no longer see dependencies javadoc
Android Studio v3.0 Canary 4,
but happens for me on Android Studio v2.3.3 too

I'm not sure since when this started to happen, what version or configuration I've made (if any), but I can no longer see libraries/dependencies javadoc:

for instance, RxJava:

Even though, Android SDK does show the javadocs correctly:

This is true for all libs I have, I looked everywhere on the net for this issue, and it seems like I'm the only one.

答: What you can do as a workaround is to inspect a class in the dependency, and it'll give you the decompiled byte code with an option to "Download...". Click that, source is downloaded, and now you have javadocs. You have to do this for each dependency, but it persists through cleans and resyncs.</p>


问:
how to do authentication on different type of users using devise
first of all, I avoid using the term "role" here. because there is a similar post answered by ---"looking into cancan".

The problem I need to sovle is that I need to do authentication on two different type of users, and the attributes of the two users are so different that  each of them has their own model and corresdonding table.

If we treat devise's work as access control to the model, my question can be rephrased as does devise support multiple models authentication?I'm quite suspious of that, because look at the file name, under app/views/devise/ , none of
them contails "model" info in it. But anyway, need a confirmative answer from you guys.

答:
All is explain on this todo : https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role

The model in devise library is an include so can be include on several Model of your application.

ContentLicense: CC BY-SA 2.5


问:
How to pass entire directory into python via command line and sys.argv
So in the past when I've used a unix server to do my python development if I wanted to pass in an entire folder or directory, I would just put an asterisk() on the end of it. An example would be something like users/wilkenia/shakespeare/ to pass in a set of files containing each of shakespeare's plays. Is there a way to do this in windows? I've tried putting in C:\Users\Alexander\Desktop\coding-data-exam\wx_data* and the same with the disk name removed. Nothing has worked so far, in fact, it takes in the directory as an argument itself.

Edit: implemented glob, getting a permissions error, even though I'm running as administrator. Here's my code if anyone wants to have a look.

答:
For the sake of showing how you can use pathlib to achieve this result. You can do something like this:

some_script.py:

```<code>from pathlib import Path

path = Path(sys.argv[1])

glob_path = path.glob('*')

for file_path in glob_path:
    print(file_path)
</code>```

Demo:

```<code>python some_script.py C:/some/path/
</code>```

Output:

```<code>C:/some/path/depth_1.txt
C:/some/path/dude.docx
C:/some/path/dude.py
C:/some/path/dude_bock.txt
</code>```

The nice thing about pathlib, is that it takes an object oriented approach to help work with the filesystem easier.

Note: pathlib is available out-of-the-box from Python 3.4 and above. If you are using an older version of Python, you will need to use the backported package that you can get from pypi: here

Simply: pip install pathlib2

Body:
For the sake of showing how you can use pathlib to achieve this result. You can do something like this:

some_script.py:

from pathlib import Path

path = Path(sys.argv[1])

glob_path = path.glob('*')

for file_path in glob_path:
    print(file_path)

Demo:

python some_script.py C:/some/path/

Output:

C:/some/path/depth_1.txt
C:/some/path/dude.docx
C:/some/path/dude.py
C:/some/path/dude_bock.txt

The nice thing about pathlib, is that it takes an object oriented approach to help work with the filesystem easier.

Note: pathlib is available out-of-the-box from Python 3.4 and above. If you are using an older version of Python, you will need to use the backported package that you can get from pypi: here

Simply: pip install pathlib2


问:
How to install an R package to R-3.3.0 from GitHub, which is built on R-3.4.0?
We have R-3.3.0 in our university's computing system. For some reason, the IT staffs do not want to update R version to R-3.4.0 soon. However, I need to install an R package from the GitHub, which is built on R-3.4.0. Is there any way to install that R package from the GitHub's to R-3.3.0? </p>

答:
@patrick's answer may work just fine. The benefit (if it works) is that you have all recent changes and functionality of the package. However, you may never know if one of the changes requiring 3.4 is about accuracy or correctness, meaning you may still get a return value but you don't necessarily know that it is correct.

For this answer, I'm going to assume that there is a valid reason to not use the current version and trick R into installing it anyway.

Grab from a specific commit

Go to the repo, https://github.com/mshasan/OPWeight in this case.

Open the DESCRIPTION file and click on the "Blame" button on the right. This brings up the commit message-header and timeframe for each group of lines with their most recent commit. In this case, it shows "Update DESCRIPTION":

Click on the description, and you're taken to the specific commit. Seeing that this is a single-line change, it is likely that an earlier commit may have been what actually changed code to use R (>= 3.4.0) a hard requirement. Take note of the commit hash (5c0a43c in this case).

Go back to the repo main page and click on "Commits". If you now search for that 7-char hash-substring, you'll see it happened on June 20, 2017. Unfortunately, the commit descriptions and timeline do not give a great expectation of where the version-depending change happened.

If you can find "the commit" that did it, then take that hash-substring and use that as your ref="..." argument to install_github. If not, however, you are either stuck (1) trying them iteratively or randomly, or (2) asking the author at which commit they started using 3.4-specific code.

Once you know a ref to use (or want to try), then run

```<code>devtools::install_github("mshasen/OPWeight", ref="5c0a43c")
</code>```

(This is obviously the wrong ref to use, since that's the first commit at which we are certain the dependency exists.)

Using tests to know which to use

Since the repo contains a tests/ subdir, one can hope/assume that the tests will accurately catch if things are not working correctly in your R-3.3. This alternative method involves you testing each commit on your specific version of R (before the DESCRIPTION file was changed) until the tests no longer fail.

Using git (command-line or GUI), clone the repo to your local computer.

```<code>$ git glone https://github.com/mshasan/OPWeight
</code>```

Now, iterate through the references (found using the above method or perhaps with git log) with something like:

```<code>$ git checkout --detach <hash_substring>
</code>```

... and in R, run

```<code>devtools::test("path/to/your/copy/of/OPWeight")
</code>```

If the tests have been set up correctly and you chose a worthy version, then stick with it.

Body:
@patrick's answer may work just fine. The benefit (if it works) is that you have all recent changes and functionality of the package. However, you may never know if one of the changes requiring 3.4 is about accuracy or correctness, meaning you may still get a return value but you don't necessarily know that it is correct.

For this answer, I'm going to assume that there is a valid reason to not use the current version and trick R into installing it anyway.

Grab from a specific commit

Go to the repo, https://github.com/mshasan/OPWeight in this case.

Open the DESCRIPTION file and click on the "Blame" button on the right. This brings up the commit message-header and timeframe for each group of lines with their most recent commit. In this case, it shows "Update DESCRIPTION":

Click on the description, and you're taken to the specific commit. Seeing that this is a single-line change, it is likely that an earlier commit may have been what actually changed code to use R (>= 3.4.0) a hard requirement. Take note of the commit hash (5c0a43c in this case).

Go back to the repo main page and click on "Commits". If you now search for that 7-char hash-substring, you'll see it happened on June 20, 2017. Unfortunately, the commit descriptions and timeline do not give a great expectation of where the version-depending change happened.

If you can find "the commit" that did it, then take that hash-substring and use that as your ref="..." argument to install_github. If not, however, you are either stuck (1) trying them iteratively or randomly, or (2) asking the author at which commit they started using 3.4-specific code.

Once you know a ref to use (or want to try), then run

devtools::install_github("mshasen/OPWeight", ref="5c0a43c")

(This is obviously the wrong ref to use, since that's the first commit at which we are certain the dependency exists.)

Using tests to know which to use

Since the repo contains a tests/ subdir, one can hope/assume that the tests will accurately catch if things are not working correctly in your R-3.3. This alternative method involves you testing each commit on your specific version of R (before the DESCRIPTION file was changed) until the tests no longer fail.

Using git (command-line or GUI), clone the repo to your local computer.

$ git glone https://github.com/mshasan/OPWeight

Now, iterate through the references (found using the above method or perhaps with git log) with something like:

$ git checkout --detach <hash_substring>

... and in R, run

devtools::test("path/to/your/copy/of/OPWeight")

If the tests have been set up correctly and you chose a worthy version, then stick with it.


问:
Add Outlook Search Folder on shared folder
I'm trying to create a new "Search Folder" in an Outlook shared folder using VBA in Excel.

It is failing on the last line, which is the save function.

"Object could not be found".

Sub createfolder()

    Dim oApp As Outlook.Application
    Dim oSearch As Outlook.Search
    Dim oInbox  As Outlook.mapifolder
    Dim sFolderPath As String
    Dim oScope As String
    Dim sFilter As String

    Set oApp = New Outlook.Application
    Set oInbox = oApp.GetNamespace("MAPI").Folders("Fin Reporting").Folders("July")

    sFolderPath = oInbox.FolderPath
    sScope = "'" & oInbox.FolderPath & "'"
    Set oSearch = oApp.AdvancedSearch(sScope)

    oSearch.Save ("TestSearch")

End Sub
```

答:
you did not say where your "fin reporting" folder is located

for this example code, i put it in the top folder, so it is on same level as "inbox"

```<code>top ---
       |
       fin reporting
       |   |
       |   july
       |
       inbox
       |
       sent items
       |
       etc.
</code>```

try these two. see which one works, or does not work.

single-step through the code by pressing F8 key repeatedly

try this one in outlook

```<code>Sub createfolder_outlook()

    Dim oInbox  As MAPIFolder
    Dim oSearch As Search

    Set oInbox = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders("Fin Reporting").Folders("July")
    Set oSearch = Application.AdvancedSearch("'" & oInbox.FolderPath & "'")

    oSearch.Save ("TestSearch")

End Sub
</code>```

then do same in excel

```<code>Sub createfolder_excel()

    Dim oInbox  As Outlook.MAPIFolder
    Dim oSearch As Outlook.Search

    Set oInbox = Outlook.Application.GetNamespace("MAPI").GetDefaultFolder(Outlook.olFolderInbox).Parent.Folders("Fin Reporting").Folders("July")
    Set oSearch = Outlook.Application.AdvancedSearch("'" & oInbox.FolderPath & "'")

    oSearch.Save ("TestSearch")

End Sub
</code>```

Body:
you did not say where your "fin reporting" folder is located

for this example code, i put it in the top folder, so it is on same level as "inbox"

top ---
       |
       fin reporting
       |   |
       |   july
       |
       inbox
       |
       sent items
       |
       etc.

try these two. see which one works, or does not work.

single-step through the code by pressing F8 key repeatedly

try this one in outlook

Sub createfolder_outlook()

    Dim oInbox  As MAPIFolder
    Dim oSearch As Search

    Set oInbox = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders("Fin Reporting").Folders("July")
    Set oSearch = Application.AdvancedSearch("'" & oInbox.FolderPath & "'")

    oSearch.Save ("TestSearch")

End Sub

then do same in excel

Sub createfolder_excel()

    Dim oInbox  As Outlook.MAPIFolder
    Dim oSearch As Outlook.Search

    Set oInbox = Outlook.Application.GetNamespace("MAPI").GetDefaultFolder(Outlook.olFolderInbox).Parent.Folders("Fin Reporting").Folders("July")
    Set oSearch = Outlook.Application.AdvancedSearch("'" & oInbox.FolderPath & "'")

    oSearch.Save ("TestSearch")

End Sub