Tips on finding the volume of water in a 3d chess board

Question: So I have an assignment where I have to recreate a 3d chessboard that is a RxC grid of squares each being a different height. If the chessboard is water tight, and someone pours water all over it until it can hold no more water, it will hold a fixed amount of water. If the board is already holding its maximum volume of water, any excess water poured onto the board will drain off the edges, there is no tall container surrounding the board. You can assume the squares on the chess board are one inch square, and the heights are given in inches.
int CalcContainedWater( const int *p_data, int num_columns, int num_rows )

Where p_data is a pointer to the first element of a contiguous two-dimensional, row-major array of signed integers. Your function will be tested against a reference implementation for boards of varying shapes and contents to determine its correctness.
Keep in mind the value inside of p_data can hold both positive and negative values for the heights.
For example:
A)  The following board yields a containment of 3.
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,

B) The following board yields a containment of 0.
1, 0, 1,
1, 0, 1,
1, 1, 1,

C) The following board yields a containment of 1.
0, 1, 0,
1, 0, 1,
0, 1, 0,

This is what I have so far :
    #include "stdafx.h"
    #include <queue>
    #include <vector>
    using namespace std;

enum GridPosition
{
    TOP_LEFT_CORNER,
    TOP_RIGHT_CORNER,
    BOTTOM_LEFT_CORNER,
    BOTTOM_RIGHT_CORNER,
    TOP_ROW,
    BOTTOM_ROW,
    LEFT_COLUMN,
    RIGHT_COLUMN,
    FREE,
};

struct Square
{
    int nHeight;
    int nPos;
    GridPosition gPos;
    bool bIsVisited;
    bool bIsFenced;
    bool bIsFlooding;

    Square(){ nHeight = 0; nPos = 0; gPos = FREE; bIsVisited = false; bIsFenced = false; bIsFlooding = false;};
    ~Square(){};
    Square( int Height, int Pos, GridPosition GridPos, bool Visited, bool Fenced, bool Flooding)
    {
        nHeight = Height;
        nPos = Pos;
        gPos = GridPos;
        bIsVisited = Visited;
        bIsFenced = Fenced;
        bIsFlooding = Flooding;
    }
};

template< typename FirstType, typename SecondType >
struct PairComparator
{
  bool operator()( const pair<FirstType, SecondType>& p1,
    const pair<FirstType, SecondType>& p2 ) const
    {
        return p1.second > p2.second;
    }
};

int CalcContainedWater( const int *p_data, int num_columns, int num_rows );

int CalcContainedWater( const int *p_data, int num_columns, int num_rows )
{
    priority_queue<pair<int,int>, vector<pair<int,int>>, PairComparator<int,int>> qPerimeter;
    queue<pair<int,int>> qFlooding;
    vector<Square> vSquareVec(num_columns * num_rows);

    int nTotalContained = 0;

    int nCurrentSqHeight = 0;
    int nCurrWaterLvl = 0;
    int nDepth = 1;

    for( int nRow = 0; nRow < num_rows; ++nRow)
    {
        for( int nColumn = 0; nColumn < num_columns; ++ nColumn)
        {
            int nCurrArrayPoint = nRow * num_columns + nColumn;
            nCurrentSqHeight = p_data[nCurrArrayPoint];

            Square sSquare(nCurrentSqHeight, nCurrArrayPoint, FREE, false,false,false);

            if(nRow == 0  && nColumn == 0)
                sSquare.gPos = TOP_LEFT_CORNER;
            else if(nRow == 0  && nColumn == num_columns - 1)
                sSquare.gPos = TOP_RIGHT_CORNER;
            else if(nRow == num_rows - 1  && nColumn == 0)
                sSquare.gPos = BOTTOM_LEFT_CORNER;
            else if(nRow == num_rows - 1  && nColumn == num_columns - 1)
                sSquare.gPos = BOTTOM_RIGHT_CORNER;
            else if( nRow == 0)
                sSquare.gPos = TOP_ROW;
            else if( nRow == num_rows -1 )
                sSquare.gPos = BOTTOM_ROW;
            else if( nColumn == 0)
                sSquare.gPos = LEFT_COLUMN;
            else if( nColumn == num_columns - 1)
                sSquare.gPos = RIGHT_COLUMN;

            vSquareVec[nCurrArrayPoint] = sSquare;

            if( nRow == 0  || nColumn == 0 ||
                nColumn == num_columns - 1 || nRow == num_rows -1 )
            {
                sSquare.bIsFenced = true;

                vSquareVec[nCurrArrayPoint] = sSquare;

                pair<int,int> p1(nCurrArrayPoint, nCurrentSqHeight);

                qPerimeter.push(p1);
            }
        }
    }

    nCurrWaterLvl = qPerimeter.top().second;

    while( !qPerimeter.empty() )
    {
        pair<int,int> PerimPos = qPerimeter.top();
        qPerimeter.pop();

        if( !vSquareVec[PerimPos.first].bIsVisited )
        {
            if( vSquareVec[PerimPos.first].nHeight > nCurrWaterLvl )
                nCurrWaterLvl = vSquareVec[PerimPos.first].nHeight;

            vSquareVec[PerimPos.first].bIsFlooding = true;
            qFlooding.push(PerimPos);

            while( !qFlooding.empty() )
            {
                pair<int,int> FloodPos = qFlooding.front();
                qFlooding.pop();
                nDepth = nCurrWaterLvl - vSquareVec[FloodPos.first].nHeight;

                if( nDepth >= 0)
                {
                    vSquareVec[FloodPos.first].bIsVisited = true;
                    pair<int,int> newFloodPos;
                    switch(vSquareVec[FloodPos.first].gPos)
                    {
                    case TOP_LEFT_CORNER:
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case TOP_RIGHT_CORNER:
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case BOTTOM_LEFT_CORNER:
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case BOTTOM_RIGHT_CORNER:
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case TOP_ROW:
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case BOTTOM_ROW:
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case LEFT_COLUMN:
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case RIGHT_COLUMN:
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1 ].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        break;
                    case FREE:
                        if( !vSquareVec[FloodPos.first + 1].bIsVisited &&
                            !vSquareVec[FloodPos.first + 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - 1].bIsVisited &&
                            !vSquareVec[FloodPos.first - 1].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - 1].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - 1].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - 1].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first + num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first + num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first + num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first + num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first + num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }
                        if( !vSquareVec[FloodPos.first - num_rows].bIsVisited &&
                            !vSquareVec[FloodPos.first - num_rows].bIsFlooding)
                        {
                            vSquareVec[FloodPos.first - num_rows].bIsFlooding = true;
                            newFloodPos.first = vSquareVec[FloodPos.first - num_rows].nPos;
                            newFloodPos.second = vSquareVec[FloodPos.first - num_rows].nHeight;
                            qFlooding.push(newFloodPos);
                        }

                        nTotalContained += nDepth;

                        break;
                    }

                }
                else
                {
                    vSquareVec[FloodPos.first].bIsFlooding = false;
                    if( !vSquareVec[FloodPos.first].bIsFenced )
                    {
                        vSquareVec[FloodPos.first].bIsFenced = true;
                        qPerimeter.push(FloodPos);
                    }
                }

            }
        }

    }
    return nTotalContained;
    }

All I'm finding is the top,bottom, left and right square heights.
Currently I'm stuck trying to figure out out how to get the total volume knowing that water will spill over to squares if they are smaller in height. The more that I look at this the more I think that it should be done recursively but can't find a way to implement it.
Any help would be much appreciated. Not looking for the answer just for a push into the right direction into what I need to do.
Comment: Interesting, despite all appearances, I'd call this a path-finding problem.
Comment: From each square, find the path from that square to an edge, where you minimize the height of the highest square you cross. Each square holds water equal to the height of the highest square it's path crossed minus it's starting height. Then sum those for an answer. Of course, that's all theory, There's far easier/faster/better designs for doing this in a practical manner.
Comment: Yea my whole thought process behind it is very similar to what you are talking about.
Comment: Actually had this as an interview question a bit back.  Not an easy problem to try and white board :)
Answer: Fun question, with many varied solutions.  I've been thinking about it this afternoon and I would go for something like flood-fill with a priority queue (min-heap, perhaps).  Let's call it the fence.
You'll also want to keep track of which items have been visited.  Mark all items as unvisited, initially.
Start off by adding all points around the perimeter of your grid to the fence.
Now you loop like so:
Pop the front item from the fence.  You have selected one of the lowest points on the perimeter.

If the item has been visited, discard it and loop again.
If it's unvisited, its height becomes your new water level only if it is greater than the current water level.

You now do a flood-fill from that point.  You can do this recursively (depth-first), but I will discuss this using an unordered queue (breadth-first).  Let's call this queue the flood.  You start by pushing the item onto flood.
Flooding then goes like this:  Loop until there are no items remaining in flood...

Pop an item from flood
If it is already visited, ignore it and loop again.
If the item height is less than or equal to the current water level, compute the height difference and add that to your total volume.  Mark the item as visited, then add all unvisited neighbours to flood.
If the item height is greater than the current water level, just add it to fence.  You'll want to have a way to tell whether the item is already in fence - you don't want to add it again.  Maybe you can extend your 'visited' flags to cope with this.

And that's it.  Admittedly it was just a thought experiment while I lay around feeling hungover and seedy, but I reckon it's good.

As you requested...  Some pseudocode.
Initial setup:
## Clear flags.  Note I've added a 'flooding' flag
for each item in map
    item.visited <- false     # true means item has had its water depth added
    item.fenced <- false      # true means item is in the fence queue
    item.flooding <- false    # true means item is in the flooding queue
end

## Set up perimeter
for each item on edge of map (top, left, right, bottom)
    push item onto fence
end

waterlevel <- 0
total <- 0

Now the main chunk of the algorithm
while fence has items
    item <- pop item from fence
    if item.visited = true then loop again

    ## Update water level
    if item.height > waterlevel then waterlevel = item.height

    ## Flood-fill item using current water level
    push item onto flood
    item.flooding <- true

    while flood has items
        item <- pop item from flood
        depth <- waterlevel - item.height

        if depth >= 0 then
            # Item is at or below water level.  Add its depth to total.
            total <- total + depth
            item.visited <- true

            # Consider all immediate neighbours of item.
            for each neighbour of item
                if neighbour.visited = false then
                    if neighbour.flooding = false then
                        push neighbour onto flood
                        neighbour.flooding <- true
                    end
                end
            end
        else
            # Item is above water
            item.flooding <- false
            if item.fenced = false then
                push item onto fence
                item.fenced <- true
            end
        end

    end
end

Comment: So if I'm following this correctly after the first item is popped off fence every other square will go through the flooding process?
Comment: I don't quite get your question, but I guess the answer is 'yes' -- eventually.  It works by flooding each level in succession from the edge (which is zero).  If there is a way for water to escape higher levels, the flood-filling will find it.  I implemented this yesterday and it worked for a reasonably complicated case.  Because you always push newly encountered items onto the fence, you guarantee that all grid positions will be examined.
Comment: Note that my answer is a little wrong - you only mark the item as visited in the first case (where you are checking its neighbours) -- I will edit to correct that.
Comment: Oh yeah, and you also have to check the 'visited' status while flooding, because one node might be in there several times as a different neighbour.
Comment: Hey @TCoder how did you get on with this method?  I chucked some ASTER terrain data at it last night for fun - being a Kiwi, I selected the Southern Alps and glaciers around Mount Cook in New Zealand.  My unoptimized solution using ordinary C++ containers took just over 3 seconds to process a 3601x3601 image.  I'm doing more calculation than I need to, because I'm stamping events in order to animate the filling process.  When I have something cool to show I'll post a video =)
Comment: I'm still a little confused with how you are doing the looping here. Did you loop through all the items in fence first and then continue with the flood loop or do you loop through the items in fence while you are looping through the items in flood? If you have some psuedo code to show what you mean it will help out tons.
Comment: I added pseudocode so you can see better what I mean.  It should make a lot more sense.  Hope I got it right.  You'll notice I added an extra flag, which I've found helpful.  I implemented this in C++ with just `priority_queue` and `queue`, but it might be loads faster if you use a fixed-size circular buffer instead of `queue` (and maybe your own min-heap).  However, you should get it going with basic tools to begin with.
Comment: K i updated with my code trying to follow your puesdo code. Ignore the huge switch statement and what not because i just want to get it done before i go to optimize it. With the board '{2,2,2},
       {2,-1,1},
       {2,2,2}' it gives a result of 4 when it needs to be 2.
Comment: Ok @paddy not sure what is wrong with the code but if i had to guess it with 'nCurrWaterLvl' and 'nDepth'. Dont think its taking into account any water that touches an edge, if that edge is lower all the water that is contained in that space will spill over the edge to become even.
Comment: There are a couple of things wrong.  First, you're not using a priority queue for the perimeter.  This is an absolute requirement.  Any time you pop an item it must be the one with minimum height.  Second, you should not store copies of `Square` in your queues.  You should reference into your `vSquareVec`, either with pointers or array indices.
Answer: This is going to take more than simply calculating volume.
According to the examples you posted, you have test for containment first, then worry about the volume of the container.
I suggest determining whether or not there is a closed polygon in the board.
If the polygon is closed, determine its area.
The height used for volume calculation will be the minimum height of all the bounding walls.
Finally, the volume will be the minimal height multiplied by the area of the polygon.
Research on the web for algorithms on determining a closed polygon based on a vector of vertices or line segments.
Comment: (1) you overlooked the height of the contained squares, I beleive there are other possible heights besides 0 and 1. (2) You don't mention multiple enclosed polygons (3) I think there's simpler solutions that are more accurate
Comment: The values inside of p_data hold both positive and negative values.
Comment: @TCoder please edit the question to say that to avoid further confusion.
Answer: This is a bit brute-force-ish but would probably work.
You might try to conceptually break the board into layers for instance:
-------------------------
0 | 1 | 1 | 0 | 1 | 1 | 0
1 | 0 |-1 | 1 | 0 | 0 | 1
1 | 1 | 1 | 1 | 1 | 1 | 1
-------------------------

Looking at just the lowest layer. Assuming -1 is the bottom, the board would look like this:
-------------------------
0 | 0 | 0 | 0 | 0 | 0 | 0
0 | 0 |-1 | 0 | 0 | 0 | 0
0 | 0 | 0 | 0 | 0 | 0 | 0
-------------------------

For each square, determine if there exists a square to the left, right, top and bottom that all have a greater value. In this case we count 1.
Then move to the next layer, filling in the "holes" in the last layer.
-------------------------
0 | 1 | 1 | 0 | 1 | 1 | 0
1 | 0 | 0 | 1 | 0 | 0 | 1
1 | 1 | 1 | 1 | 1 | 1 | 1
-------------------------

Rinse, repeat. In this layer we count 4 giving us a total of 5.
-------------------------
1 | 1 | 1 | 1 | 1 | 1 | 1
1 | 1 | 1 | 1 | 1 | 1 | 1
1 | 1 | 1 | 1 | 1 | 1 | 1
-------------------------

Top layer obviously has none and we're done.
In pseudo code:
for each layer l in layers
   for each square in l
      if there exists a square left, right, top and bottom with higher value
          count the square.

Edit
Of course since there is something seriously wrong with me, when I woke up this morning the first thing I thought of was this problem and immediately broke my solution.
Let's make one change to the example:
-------------------------
0 | 1 | 1 | 0 | 1 | 1 | 0
1 | 0 |-1 | 1 | 0 | 0 | 1
1 | 1 | 1 | 1 | 1 | 0 | 1
-------------------------
                    ^

Open a hole to the outside. With the current algorithm we would get a solution of 4 which is obviously wrong.
To fix this we need to implement a back tracking algorithm.
Instead of looking anywhere to the left, right, top and bottom for a higher value, we check just the immediately adjacent squares. If any are at the same height we need to visit that square as well and perform the check again. If we find our way to the outside then the original square (and subsequently all the visited squares) fail. If we hit a dead end, then all the visited squares can be counted.
With this modification we would get the correct result of 3.
Comment: In feel like this can be time consuming if large 2d arrays with big heights are put into the function. Essentially its just looping through the entire array for every number between the lowest and highest height.
Answer: Here is a piece of working code: the basic idea is slicing the board horizontally into levels, and determining the volume each level can hold (complexity O(x * y * z)):
#include <stdio.h>
#include <memory.h>

// The Cell structure for each level
struct Cell
{
    unsigned char height; // either 0 or 1
    bool visited; // we only visit the cells that have height of 0
};

// The recursive function that visits a cell, accumulate the water volume (or if leaked due to being at the border, reset the values); it also
// looks to its 4 adjacent cells (if valid) recursively.
// Note that the top level function actually attempts to visit *all* the "connected" cells (and mark them as visited, so they will not be visited again)
// From the top level, the cells are thus visited in "chunks" (as long as they are connected)
void VisitCell(Cell* one_level_cells, unsigned short a_w, unsigned short a_h, unsigned short w, unsigned short h, unsigned __int64* sum, bool* leaked)
{
    Cell& cell = one_level_cells[h * a_w + w];
    if (cell.height == 0 && !cell.visited)
    {
        cell.visited = true;
        if (w == 0 || w + 1 == a_w || h == 0 || h + 1 == a_h)
        {
            // I am at the border while I am not guarding the water, the water for this "chunk" is then leaked!
            *leaked = true;
            *sum = 0;
        }

        if (!*leaked)
        {
            // potentially increment the volume, until it's detected leaked at some point
            ++*sum;
        }

        if (w < a_w - 1)    VisitCell(one_level_cells, a_w, a_h, w+1, h, sum, leaked);
        if (w > 0)          VisitCell(one_level_cells, a_w, a_h, w-1, h, sum, leaked);
        if (h < a_h - 1)    VisitCell(one_level_cells, a_w, a_h, w, h+1, sum, leaked);
        if (h > 0)          VisitCell(one_level_cells, a_w, a_h, w, h-1, sum, leaked);
    }
}

//@param int const * const unsigned short *a_board - argument representing the NxM board.
//@param unsigned short a_w - argument representing the width of the board
//@param unsigned short a_h - argument representing the height of the board
//@return - unsigned __int64 - the volume of water the board retains

// complexity: O(a_w * a_h * max_height)
unsigned __int64 CalculateVolume(const unsigned short *a_board, unsigned short a_w, unsigned short a_h)
{
    if (!a_board || a_w < 3 || a_h < 3)
    {
        return 0;
    }
    // Basic algorithm: slice the board horizontally into as many levels as the maximum height of the board
    // for each sliced level, determine the water volume cubed so far, and the total volume is the sum of the volume of the individual level
    unsigned __int32 n = a_w * a_h;
    unsigned short max_height = 0;
    for (unsigned __int32 i = 0; i < n; ++i)
    {
        if (max_height < a_board[i])
        {
            max_height = a_board[i];
        }
    }
    unsigned short *board = new unsigned short[n];
    memcpy(board, a_board, n * sizeof(unsigned short));
    Cell* one_level_cells = new Cell[n];
    unsigned __int64 total_volume = 0;
    for (unsigned short i = 0; i < max_height; ++i)
    {
        // form a new current level of cells (and update the copy of the board accordingly)
        unsigned __int64 volume_this_level = 0;
        for (unsigned __int32 j = 0; j < n; ++j)
        {
            if (board[j] > 0)
            {
                --board[j];
                one_level_cells[j].height = 1;
            }
            else
            {
                one_level_cells[j].height = 0;
            }
            one_level_cells[j].visited = false;
        }

        // visit all the cells within the current level
        // we mark the cells after being visited, and the cells are visited in "chunks" when they are "connected" together
        // so effectively, most of the top level cell visiting would return immediately, rather than trying to revisit the cells again and again
        for (unsigned short h = 0; h < a_h; ++h)
        {
            for (unsigned short w = 0; w < a_w; ++w)
            {
                unsigned __int64 sum = 0;
                bool leaked = false;
                // NB: the top level function here will attempt to cover *all* the connected cells at the current level (in the recursion)
                // so even though we are still iterating through all the cells at the top level, most of them should find that the cell has been visited
                // so the sum here is actually a "chunked" sum in the perception of the top level cells
                VisitCell(one_level_cells, a_w, a_h, w, h, &sum, &leaked);
                volume_this_level += sum;
            }
        }

        total_volume += volume_this_level;
    }

    delete[] one_level_cells;
    delete[] board;

    return total_volume;
}

int main()
{
    // feel free to play with this board
    unsigned short board[] = {
        2, 2, 2, 2, 2, 2, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 2,
        2, 1, 2, 3, 3, 2, 1, 2,
        2, 1, 3, 1, 1, 3, 1, 2,
        2, 1, 3, 1, 1, 3, 1, 2,
        2, 1, 2, 3, 3, 2, 1, 2,
        2, 1, 1, 1, 1, 1, 1, 2,
        2, 2, 2, 2, 2, 2, 2, 2,
    };
    printf("Volume: %lld\n", CalculateVolume(board, 8, 8));
    return 0;
}

Answer: This is python(2.7) version of the pseudocode by @paddy .Hope this will help someone .
import heapq
block =[
1, 2, 3,
4 ,2,6,
7, 0,5,
11,15, 13,
14,15,16,
1,0,1,
1,1,1]
cmax =3;
rmax =7;
items =[]
fence = []
flood = []
waterlevel = 0
total = 0
class Item(object):
    visited = False
    fenced = False
    flooding = False
    height= 0
    index = 0
i=0
## initializing blocks
for val in block:
    item =  Item();
    item.height = val
    item.index = i
    i+=1
    items.append((item.height,item))
## find out the edges
for i in range (cmax):
    heapq.heappush(fence, items[i])
    heapq.heappush(fence, items[i+(rmax-1)*cmax])
    print items[i][1].height,items[i+(rmax-1)*cmax][1].height

for i in range(1,rmax-1):
    heapq.heappush(fence, items[cmax*i])
    heapq.heappush(fence, items[cmax*i+(cmax-1)])
    print items[cmax*i][1].height,items[cmax*i+(cmax-1)][1].height

## get neighbour
def get_neighbour(i):
    c= i%cmax
    r= i//cmax
    neighbour = []
    if (c != 0):
        neighbour.append(items[r*cmax+c-1])
    if (c != (cmax -1)):
        neighbour.append(items[r*cmax+c+1])
    if (r != 0):
        neighbour.append(items[(r-1)*cmax+c])
    if (r != (rmax -1)):
        neighbour.append(items[(r+1)*cmax+c])
    return neighbour

while (len(fence)>0):
    item = heapq.heappop(fence)
    if(item[1].visited):
        continue
    if (item[1].height > waterlevel):
        waterlevel = item[1].height
    heapq.heappush(flood,item)
    item[1].flooding = True
    while(len(flood)>0):
        fitem = heapq.heappop(flood)
        depth = waterlevel - fitem[1].height
        if (depth >= 0):
            total += depth
            fitem[1].visited = True
            neighbour = get_neighbour(fitem[1].index)
            for nitem in neighbour:
                if nitem[1].visited == False :
                    if nitem[1].flooding == False :
                        heapq.heappush(flood,nitem)
                        nitem[1].flooding = True
        else:
            fitem[1].flooding = False
            if fitem[1].fenced == False:
                heapq.heappush(fence,fitem)
                fitem[1].fenced = True
print total


Is a time trend a substitute for first differencing?

Question: I am doing a macroeconomic analysis involving BOP, investment ratio, GDP growth rates, and CPI inflation as dependent variables. My independent variables are other macro variables.
When I test for unit root, many of the variables display unit root.
But, by first differencing some of the IVs (for example the growth of exports) the interpretation of the affects on the DV become "growth of growth rates" and seems not right.
I know by adding a linear time trend variable as an IV into the regression, it removes the spurious regression with time. But, is this a replacement for first differencing? If not, what are the alternatives to first differencing my variables the interpretation is more coherent?
Answer: First differencing also affects the error term, so they are slightly different.
To see this, suppose you have some underlying time-series $\{ \varepsilon_t | t \in \mathbb{Z} \}$ and you are going to form a new time-series on top of this.  Suppose we compare a series $\{ X_t | t \in \mathbb{Z} \}$ from a model that includes a drift term with a series $\{ Y_t | t \in \mathbb{Z} \}$ from a model that does not include a drift term but is defined on its first differences.  Specifically, we have the two alternative models:
$$\begin{aligned}
X_t &= \mu + \lambda t + \varepsilon_t, \\[6pt]
\Delta Y_t &= \lambda + \varepsilon_t.\\[6pt]
\end{aligned}$$
Now, taking the first difference of the first series gives:
$$\ \Delta X_t = \lambda + \varepsilon_t - \varepsilon_{t-1},$$
so the models are similar, but the error terms for the two models look different.  In particular, looking at the first difference of the first model, we see that there will now be some correlation in the error terms.
Comment: Actually, I would argue that the error terms are substantially different - $\Delta X_t$ now has zero long-run variance, i.e., is overdifferenced.
Answer: Differencing is applicable for stochastic non-stationary time series while time trends are applicable for deterministic non-stationary series.  See the discussion here stochastic vs. deterministic trend in time series and ADF test fail to reject while kpss and box say white noise and stationary as to possible ways to identify which is more appropriate for any individual time series.
Decompose a time series data into deterministic trend and stochastic trend might also be of help to you .
Answer: Standard analysis of macroeconomic series is usually done via VAR (vector autoregression models), rather than fitting univariate models for individual series. Macroeconomic variables are simultaneously determined. Classification into "dependent" and "independent" are likely artificial with no economic justification.
(Structural VAR's is a slightly different story.)
VAR of integrated variables can be estimated in the same way as VAR of stationary variables, after adding more lags to accommodate the degree of integration.
This circumvents the need for differencing and allows one to deal directly with levels of variables.
Determining the degree of integration can be done via univariate unit root tests, as you have already carried out.
In short, if the task is standard macroeconomic analysis (e.g. forecast/impulse response/Granger causality/etc.), use VAR's. Avoid first difference unless you're specifically interested in growth rates, and avoid univariate models.


How do I change this code to use request_uri()?

Question: I'm trying to write a patch to make a module follow the Drupal coding standards.
I get this complain and I don't know how to fix it.

Line 148: the use of REQUEST_URI is prone to XSS exploits and does not work on IIS; use request_uri() instead [security_12] return "http" . (isset($_SERVER['HTTPS']) ? "s" : "") . "://" . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

The function using that code is the following one.
function module_get_url() {
   return "http" . (isset($_SERVER['HTTPS']) ? "s" : "") . "://" . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
}

Should I change the code to the following one?
function module_request_uri() {
  return "http" . (isset($_SERVER['HTTPS']) ? "s" : "") . "://" . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
}

Answer: It means replace $_SERVER['REQUEST_URI'] with request_uri().
So module_get_url() needs to change slightly.
function module_get_url() {
  $uri = request_uri();
  return "http" . (isset($_SERVER['HTTPS']) ? "s" : "") . "://" . "{$_SERVER['HTTP_HOST']}{$uri}";
}

Comment: Thank you @clive it work. But now I have another issue because I do not know how to used this in a variable. I open another question http://drupal.stackexchange.com/questions/133969/request-uri-to-url because this is similar but different question.
Answer: Simply swap out $_SERVER['REQUEST_URI'] with request_uri().
The reasoning is that $_SERVER['REQUEST_URI'] is Apache specific.
From the function documentation page:

Returns the equivalent of Apache's $_SERVER['REQUEST_URI'] variable.
Because $_SERVER['REQUEST_URI'] is only available on Apache, we generate an equivalent using other environment variables.
Answer: Try:
function module_get_url() {
  return url(current_path(), array('absolute' => true));
}


Choice between different robust regressions in R

Question: I'm writing a program for evaluating real estates and I don't really understand the differences between some robust regression models, that's why I don't know which one to choose.
I tried lmrob, ltsReg and rlm. for the same data set, all three methods gave me different values for the coefficients.
I thought that it is best to use ltsReg because, summary(ltsReg()) provides information about R-squared and p-values and this will help me to decide if upon accepting or dismissing the model.
Do you think that ltsReg is a good choice?
EDIT:
I've just read on Goodness-of-Fit Statistics that the adjusted R-squared is generally the best indicator of quality fit
Comment: Both p-values and $R^2$ can be misleading so choosing a package based on the fact that it outputs them is not really a good criteria for such choice...
Comment: Also consider ordinal regression because it may be more robust and interpretable, and more powerful.
Comment: Someone wants to close this question! I dont think that is right, even if on surface it is about choosing R functions, it is really about how and why's of choosing robust regression methods, that is, ontopic.
Comment: then how can I decide if the model is a valid one without plotting it?
Comment: @user603: I confirm it. for the evaluation of a real estate, I create several models, which contain different number of characteristics (eg: 1. price ~ livingArea + floorNumber + age + ...).
Comment: I don't think this question is opinion based. The answer I propose is unbiased towards any of the two fits and so it is not opinion based. Since it admits an answer that is not opinion based, I think the question isn't either.
Comment: @kjetilbhalvorsen: I asked this question because I'm not sure which robust regression I should choose, because I don't understand the differences between them.
Comment: And the methods you mention, are really made for solving **very** different problems ...
Comment: "in R" is incidental to the question and would be better excised from the title.
Answer: In the notation I will use, $p$ will be the number of design variables (including the constant term), $n$ the number of observations with $n\geq2p+1$ (if this last condition was not met, the package would not have returned a fit but an error, so I assume it is met). I will denote by $\hat{\boldsymbol\beta}_{FLTS}$ the vector of coefficients estimated by FLTS (ltsReg) and $\hat{\boldsymbol\beta}_{MM}$ the coefficients estimated by MM (lmrob). I will also write:
$$r^2_i(\hat{\boldsymbol\beta})=(y_i-\boldsymbol x_i^\top\hat{\boldsymbol\beta})^2$$
(these are the squared residuals, not the standardized ones!)
The rlm function fits an 'M' estimate of regression and, like @Frank Harrell's proposal made in the comments to your question, it is not robust to outliers on the design space. Ordinal regression has a breakdown point (the proportion of your data that needs to be replaced by outliers to pull the fitted coefficients to arbitrary values) of essentially $1/n$ meaning that a single outlier (regardless of $n$!) suffice to render the fit meaningless. For regression M estimates (e.g. Huber M regression) the breakdown point is essentially $1/(p+1)$.  This is somewhat higher but in practice still uncomfortably close to 0 (because often $p$ will be large). The only conclusion that can be drawn from rlm finding a different fit than the other two methods is that it has been swayed by design outliers and that there must be more than $p+1$ of these in your data set.
In contrast, the other two algorithms are much more robust: their breakdown point is just below $1/2$ and more importantly, doesn't shrink as $p$ gets large. When fitting a linear model using a robust method, you assume that at least $h=\lfloor(n+p+1)/2\rfloor+1$ observations in your data are uncontaminated. The task of these two algorithms is to find  those observations and fit them as well as possible. More precisely, if we denote:
\begin{align}
H_{FLTS} &= \{i:r^2_i(\hat{\boldsymbol\beta}_{FLTS})\leq q_{h/n}(r^2_i(\hat{\boldsymbol\beta}_{FLTS}))\}  \\
H_{MM}   &= \{i:r^2_i(\hat{\boldsymbol\beta}_{MM})\leq q_{h/n}(r^2_i(\hat{\boldsymbol\beta}_{MM}))\}
\end{align}
(where $q_{h/n}(r^2_i(\hat{\boldsymbol\beta}_{MM}))$ is the $h/n$ quantile of the
vector $r^2_i(\hat{\boldsymbol\beta}_{MM})$)
then $\hat{\boldsymbol\beta}_{MM}$ ($\hat{\boldsymbol\beta}_{FLTS}$) tries to fit the observations with indices in $H_{MM}$ ($H_{FLTS}$).
The fact that there are large differences between $\hat{\boldsymbol\beta}_{FLTS}$ and $\hat{\boldsymbol\beta}_{MM}$ indicates that the two algorithms do not identify the same set of observations as outliers. This means that at least one of them is swayed by the outliers. In this case, using the (adjusted) $R^2$ or any one statistics from either of the two fits to decide which to use, though intuitive, is a terrible idea: contaminated fits typically have smaller residuals than clean ones (but since knowledge of this is the reason one uses robust statistics
 in the first place, I assume that the OP is well aware of this fact and that I don't need to expand on this).
The two robust fits give conflicting results and the question is which is correct? One way to solve this is to consider the set:
$$H^+=H_{MM}\cap H_{FLTS}$$
because $h\geq[n/2]$, $\#\{H^+\}\geq p$. Furthermore, if either of $H_{MM}$ or $H_{FLTS}$ is free of outliers, so is $H^+$. The solution I propose exploits this fact. Compute:
$$D(H^+,\hat{\boldsymbol\beta}_{FLTS},\hat{\boldsymbol\beta}_{MM})=\sum_{i\in H^+}\left(r^2_i(\hat{\boldsymbol\beta}_{FLTS})-r^2_i(\hat{\boldsymbol\beta}_{MM})\right)$$
For example, if $D(H^+,\hat{\boldsymbol\beta}_{FLTS},\hat{\boldsymbol\beta}_{MM})<0$, then,
$\hat{\boldsymbol\beta}_{FLTS}$ fits the good observations better than $\hat{\boldsymbol\beta}_{MM}$ and so I would trust $\hat{\boldsymbol\beta}_{FLTS}$ more. And vice versa.
Comment: +1. I guess you are using $[\ \  ]$ to mean round down to integer or floor function $\lfloor\ \ \rfloor$. I find the latter notation more explicit. It's easy to assume for readers new to that notation for integer rounding to assume that square brackets are just brackets.


Quick-one: Better Environment for Exchange 2010: Server 2008 R2 or SBS 2011 Standard?

Question: This is a quick question: I want/need to set up a Exchange 2010 Server on my home server (mainly for testing but will be needed).
I understand the downsides of hosting my mail on my dedicated hardware, but I need it anyway.
Already have a Server 2008 R2 setup, but I'm considering Small Business Server 2011. My Server is not that advanced (quad-core, 4 GB Ram, Dual NIC), but, It'll be serving(Exhange, there's more AD users) 5 to 10 users tops (average around 4 or 5).
I want to know: Which Os will be better, considering my hardware? Please note that I will need AD on that same server and maybe even SharePoint but with 2 or 3 users (for development). Any advice is welcome.
Comment: You should check the hardware requirements, if i'm not mistaken you barely meet the minimums for SBS.
Comment: What downsides to hosting your own email are you referring to?
Answer: I'd go Small Business Server - that is designed to have things on the same box that ordinarily should be kept at arms distance.
Installing "Normal" Exchange on the same server as Active Directory can give you some unexpected results, and may not be supported by Microsoft (don't quote me on that though). I'm no SharePoint expert by any stretch of the imagination, but I imagine that is a similar situation with regards to supportability.
With a bit more of a powerful box, you might be able to install something like ESXi or Hyper-V on it and install a Domain Controller, Exchange and SharePoint in separate VMs, but since your box is quite memory constrained (Exchange and SQL Server do like lots of RAM) I wouldn't really recommend it - you'd just about run the Operating System with nothing else installed on it.
Comment: I'm aware of my hardware constrains. But right now I'm running with 2GB of Ram and 2 out of 4 cores a VM with SQL Server 2008 R2, Sharepoint Foundation 2010 and Team Foundation Server, getting aceptable performance, I was considering keeping things as they are. But you're right, I should not share the AD server with other stuffs
Comment: Having AD on the same box as Exchange *does work* - I have a single testing VM with this setup, but it does do some weird things sometimes and it's most likely because Exchange and AD are together. You sound like you might get away with utilising the unused capacity, but it depends on whether you are prepared to reload the whole thing from scratch if it doesn't quite go to plan.
Answer: You're kind of comparing apples to oranges. Windows Server 2008 R2 is a network operating system (as all Windows operating systems are) that can host many roles, from AD\DNS to web services and everything in between. Windows Small Business server is a "business IT infrastructure" in a box. Many of the individual roles that you would install seperately on Server 2008 are included in SBS such as AD\DNS, Exchange Server, Sharepoint, File, Print, and Fax services and much more. It sounds to me like you'd be better served with SBS.
Answer: Minimum system requirements for SBS2011 and Exchange 2010 are not going to be met by your hardware. You'll need much more memory. So I'm going to say neither. Upgrade your memory.
Exchange 2010 Memory Requirements:
http://technet.microsoft.com/en-us/library/dd346700.aspx
SBS2011 System Requirements:
http://technet.microsoft.com/en-us/library/gg491249.aspx
Assuming you upgrade your memory, you'll generally find the licensing for SBS 2011 to be much more affordable. Plus the setup is much simpler as Exchange and Sharepoint are already installed for you.
Comment: Exchange 2010 runs perfectly with only 4GB of RAM (if you don't have a lot of users)...


How can I access comand line like cmd.exe on my dedicated linux server?

Question: I have installed the ffmpeg by composer in my local server(windows7) and everything is working good now the site is live on internet (server CENTOS 6.7 x86_64 kvm) and I need to install it to the server.
I dont know how to do this. I installed it on my local server by command line with composer. But I don't have any idea how to do this on my server.
I have this in in my composer.json file:
{
"require": {
"php-ffmpeg/php-ffmpeg": "dev-master"
}
}

and then to install it locally I wrote this in my command line composer install.
I have no idea, how to do these on server I have the same composer.json file on server too but how can i access cmd line on my linux dedicated Server.
My local server is windows7 wamp.
Now I am on CENTOS 6.7 x86_64 kvm.
Comment: I'm voting to close this question as off-topic because it's more properly addressed to Bluehost support.  They should give you the SSH information you need, if a shell is part of your plan.
Comment: What flavor of Linux?
Comment: Also some major rewording is probably important for this. You refer to a server as "local server" and "the server" and I have no idea if these are two different servers or what's going on. It's kinda a slight mess and you may get better answers if you polish it. Sorry if english is a secondary language, simply trying to help.
Comment: sorry sir, i have updated the question my server is CENTOS 6.7 x86_64 kvm please help me ... its very imp for me
Comment: And regarding that, even if they have an issue with SSH I explained that.
Answer: To access the server I'm assuming you have

Valid credentials
SSH up

To access the machine on the Internet (assuming you don't have local access to it) you can download PuTTY in windows and enter the IP and hit Open and then your credentials. Or log in with a private key if this is how your hosting is set up. It kind of depends on how your hosting provider spun up the server but they almost always spin it up with SSH. How you log in with SSH depends on how they do it (example: AWS requires a private key)
If this isn't with a hosting provider and it's just in your basement or something, boot up locally and hit CTRL+ALT+F2 to drop to a shell.
I'll try to be more specific if you specify your hosting provider.
Comment: my hosting provider is bluehost.com and i am having a dedicated server with CENTOS 6.7 x86_64
Comment: i have all the rights and privliudges but i dont know how to access them as i am new to these please help me by providing some thing in details..
Comment: Please try to SSH in with Putty as linked and see what happens. If you don't have an account, it should be under Server > Access Management > Primary User. For help getting Sudo access/root, bluehost has this: https://my.bluehost.com/cgi/help/2358


Prove that $(A\vec{x})\cdot (A\vec{y})=\vec{x}\cdot \vec{y}$ if $\|A\vec{x}\|=\|\vec{x}\| \ \forall\vec{x}$

Question: How should I prove that$$(A\vec{x})\cdot (A\vec{y})=\vec{x}\cdot \vec{y}$$
if $$\|A\vec{x}\|=\|\vec{x}\|,\ \forall \vec{x}$$
could you help me to solve this step-by-step? Thank you!
Comment: Expand $\| Ax - Ay\|^2=\|x-y\|^2$
Comment: Its true if $A$ is  an orthogonal matrix meaning $A^T = A^{-1}$
Comment: Does this answer your question? [Show that $(A\vec{x})\cdot (A\vec{y})=\vec{x}\cdot \vec{y}\implies \|A\vec{x}\|=\|\vec{x}\|$](https://math.stackexchange.com/questions/1006774/show-that-a-vecx-cdot-a-vecy-vecx-cdot-vecy-implies-a-vecx)
Answer: I can't see how this is true. If we have
$$A = \begin{bmatrix}1&1\\0&0\end{bmatrix}$$
$$x = \begin{bmatrix}1\\0\end{bmatrix}, y = \begin{bmatrix}0\\1\end{bmatrix}$$
then $||A \overrightarrow x|| = 1 = ||\overrightarrow x||$ but $(A \overrightarrow x) \cdot (A \overrightarrow y) = 1 \neq 0 = \overrightarrow x \cdot \overrightarrow y$.
Perhaps you meant $||A \overrightarrow x|| = ||\overrightarrow x||$ for all $\overrightarrow x$. In this case, your statement is indeed true, so perhaps you should clarify exactly what each of your terms mean. It's a little bit ambiguous currently.
Comment: Am I missing something here?
Comment: Thank you for your help. Is there an exception for A? I like rain too btw:)
Comment: Its not true in this interpretation, but if you take the second line to mean $A$ is distance preserving then its true
Comment: @CalvinKhor but is my $A$ here not distance preserving?
Comment: No, with your $x,y$, $A(x-y)=0$ right?
Comment: Oh, so you mean $||A \overrightarrow x|| = || \overrightarrow x|| \forall \overrightarrow x \implies$ it is true?
Comment: Yeah. Im not OP, but that makes it true
Comment: Got it. I'm guessing that's what OP meant too then.
Comment: Its true if $A$ is unimodular.


Continuous embedding of fractional Sobolev spaces

Question: Consider the spaces $H^{1/2}(\mathbb{R}^3), H^{-1/2}(\mathbb{R}^3)$ and $L^{2}(\mathbb{R}^3)$. Are the continuous embeddings true
$$H^{1/2}(\mathbb{R}^3)\hookrightarrow L^2(\mathbb{R}^3)\hookrightarrow H^{-1/2}(\mathbb{R}^3)?$$
If the continuous embeddings are true, are they also dense?
Could anyone help, please? Thank you in advance!
Comment: Yes, of course the embedding are true, just use the definition of the norms in Fourier.
Answer: As intimated in the comments, use the definition $$H^s(\mathbb{R}^n)=\{u\in\mathcal{S}': \langle\xi\rangle^s\hat{u}\in L^2\}.$$ From here, it's immediately clear that $H^s\subset H^t$ for $s>t,$ owing to the fact that $\langle\xi\rangle^s\geq\langle\xi\rangle^t$ for $s>t.$  In particular, you get your sequence of inclusions.
Comment: Sure. It's pretty easy to see-think of a dense space that's contained in all of them.
Comment: Smooth, compactly supported functions are contained and dense in both, for example.
Comment: Thank you for the answer @cmk.
They are also dense in each other?
Comment: could you explain me why they are dense in each other. It is not clear for me.


Organic Groups (7.23) and D7 | drush or cmdline integration?

Question: Just wondering how to manage OG in D7 from command line oder drush. OG seems frequently used so I'm surprised not to see any method to manage OG from shell, e.g. like create, modify Ogroups... As far as I know there were some former OG-DRUSH integrations in D6 but not in D7. Someone pointed out that the 'feature' module might be a solution (as part of the installation?). Anybody there who's willing to share his knowledge or give some information?
Comment: There is lots of discussion about Drush in the Organic Groups issue queue. Do you have a specific question or problem?
Comment: Thanks for answer. There are no OG problems in general. I just would like to do a drush drupal installation and create OG and its (already drush created) users on the fly. Before starting to use OG, I just created 'roles' as a replacement for missing (ACL) groups within drupal. Then I divided users into different 'groups' = roles but in the long run this turns out to become too complicated.
Answer: I started, but never had time to finish Drush commands for og-6.x-1.x.  Please see https://drupal.org/node/1090438 for the preliminary implementation.  I don't know why no one else has picked this up; I agree it would be useful.
For og-7.x-2.x, I do some programmatic operations in my sandbox project https://drupal.org/sandbox/greg1anderson/2049677.  These are not broken out into direct og operations, but it might serve as a starting point for someone who wanted to pick up the task of adding Drush commands to organic groups.
Finally, for anyone who wants to quickly make a Drush command from a template, see https://drupal.org/project/drushify.
Comment: Thanks for answers. Your feature was just that one what I saw in D6 as I realized that there was no further development in D7. I have to agree, that I don't understand why no one continue this excellent (drush related) work, too. Unfortunately, I'm not a drupal developer just more a drupal user who struggles with drupal's multiple ACL related modules.
Comment: Your sandbox project of course sounds very interesting to bigger sites or communities. From users' perspective it might make user/group management more flexible. From admin's point of view I'd prefer drush integration after all. I still wonder whether drush/og module owners cooperate for a seamless integration or not.
Comment: I just posted a D7 patch which implements a couple of Drush commands.  See the above issue in the queue for details.  And I started with Drushify! :)


SVN Authentication using Active Directory

Question: Is it possible to use Active Directory (Server 2008 R2) to manage users for a subversion repo that's hosted on Debian (Wheezy)?
I've tried linking the SVN hosted on Apache on a Debian server to the Active Directory on the windows server. I'm able to check out the repository however when I go to commit my changes I get a commit failed authorization failed (using tortoisesvn on a windows client, it never even asks for credentials when committing)
I'm using apache2 | 2.2.22-13+deb7u1
dav_svn.conf below:
<Location /svn>
DAV svn
SVNParentPath /srv/repos/svn
SVNListParentPath on
AuthName "helloworld"
AuthType basic
AuthzLDAPAuthoritative off
AuthBasicProvider ldap
AuthLDAPURL ldap://192.168.1.10/dc=example,dc=com?sAMAccountName" NONE
AuthLDAPBindDN "CN=subversion,OU=Users,DC=example,DC=com"
AuthLDAPBindPassword "secret"
Require ldap-group CN=svn,OU=groups,dc=example,dc=com
</Location>

Answer: Your config is just terrible bad (I can see a few correct string). Use config from here as good starting point (it miss only Require valid-user from my POV)
Answer: I needed to specify the global catalog port in the AuthLDAPURL.  I got it to work using the config below:
<Location /svn>
    DAV svn
    AuthType basic
    SVNParentPath /srv/repos/svn
    AuthName "helloworld"
    AuthBasicProvider ldap
    AuthLDAPURL "ldap://192.168.1.10:3268/dc=example,dc=com?sAMAccountName" NONE
    AuthLDAPBindDN "CN=subversion,CN=users,DC=example,DC=com"
    AuthLDAPBindPassword "secret"
    Require ldap-group CN=svn,OU=groups,DC=example,DC=com
</Location>


How to add external javascript on popup?

Question: I have a splashify popup with links on the front page I want to set a cookie when the link is clicked but the external javascript I have written to set cookie is not working on popup.
How to add external javascript on popup?
Answer: Please read Managing JavaScript in Drupal 7 there are various methods to add your own js. I assume you are using Drupal 7, this is important because in Drupal 8 adding js is different.
Also your js code needs to be like this
<code>(function ($) {
  $( document ).ready(function() {
            // custom code goes here
  });
}(jQuery));
</code>


Hide taxonomy term from a view filter where the filter results are empty

Question: I have several nodes and several taxonomies, but only some nodes have taxonomy relationships.

My problem is that the taxonomy filter shows those terms too which don't have any node relationships at all, example:

So even if I don't have any nodes in "Category 1", the term will show up in the filter.
Is there a way to remove those taxonomy terms from the filter which have no content associated to them?
Comment: One way is to use a Contextual filter with Summary option instead of the Exposed filter. It looks a bit different but acts the same. It gives you links of existing taxonomy terms (there's an option to include only the ones existing in the results) that you click through to see the results. Search for it to see examples and how to set it up.
Answer: Managed to solve this with the combination of the Search API and Facets modules. Actually, it's not that complicated when you know what to do.

Created a search index with the content of the categories.
Created a new view with a Filter criteria with Content datasource (Content
type).
Finally, added a new facet where the source is the view display page I have created, and the field is the category.
Answer: In Views, there is an option to specify a relationship and to require that relationship. You can find it in your View's config page, under Advanced. Just add a relationship to your taxonomy vocabulary and check the option to require the relationship.
The screen shot below is from the Content view that ships with Drupal 8, which is a great example of how to define a required relationship.
Comment: This will not work. This will hide nodes without a category, but it will not change the available categories in an exposed filter.


Changing a field title in a panel

Question: I've got a field in a panel. I want the field title to be replaced by something that is dependent on another node. In a view this is really straightforward:
View -> Configure Field -> Rewrite Results -> Rewrite the output of this field: ([field_A] is the name of this thing)
The Panel, however, doesn't recognize the [bracket] functionality in Node -> Settings -> Override title.
Apologies if this is obvious, but I can't find the solution anywhere. Any help would be hugely appreciated.
Comment: Are you using a view of type *content pane* with the *Use panel path* option set to *Yes*?
Comment: If I understand correctly, in the Panel tab Content, I've got the title type set to "Manually set", not to "From pane".
Answer: You can use keywords from contexts when you override a title of a pane in Panels. Go to Contexts in the Page Manager UI. The summary of contexts displays the available keywords.
In your situation you may want to add a new context, the node that you want your pane title to be pre-populated from. You can select the node ID, and the same node will always be loaded.
If it's not always the same node that you want to use, but e.g. a reference field in your already loaded node defines it, you can use a relationship to create the appropriate node context.
Comment: Thanks. I'm actually trying to override the field title, not the panel title. I need the field title in the Panel to have the same functionality of the field title in a View. In a View, I can click "rewrite the output of this field" to change the title to something like: "[field_A] is great." That View, then, will output "John is great." when field_A = John. Hopefully, that makes sense.
Comment: Apologies, I misread your first line. Am trying your suggestion now.
Comment: Unfortunately, I don't think keywords are going to get me the custom field title I need that mimics the View "rewrite output" functionality. Thanks anyway.
Comment: Can you please explain why? Context keywords are designed for such a use case you are trying to solve. But maybe I misunderstood what you want to achieve.

Have you succeeded with adding the other node as a context (either manually or through a relationship)? Or do you even need another node? What was the problematic part?
Comment: Sorry, I should have explained. I have an integer field. Let's call it "Number of Days". In Views, I can check the "rewrite output" and put "[field_number_of_days] days" so that the output is "3 days", "10 days", etc. instead of the default output of title and value: "Number of days: 3".  In panels, I can't do that. Keywords can create an association with another node, but that's not what I need. I need the title to output based on the value in the field. So, it's not that I need two nodes to have a relationship, it's that I need one node to change its output based on the value of that node.

Changing a field title in a panel


Subtração com data - Google Apps Script

Question: Caros,
Preciso realizar o calculo de quantos dias restam para atingir a data prevista.
Estou obtendo os seguintes valores
var dataPrev = row[4]; //26/01/2018
var dataNaoFormat = new Date(); //22/01/2018

Estou realizando o seguinte calculo:
var sub = dataPrev - dataNaoFormat;

E o resultado é :
2.65807814E8
Tirando o formato cientifico, 26.580.781.400.000.000,00
Preciso que me retorne um número inteiro, nesse caso seria 4.
Answer:     var row = data[i];
    var dataCarimbo = Utilities.formatDate(new Date(row[0]), "GMT", "dd/MM/yyyy");
    var dataForm = new Date(row[1]);
    var email = row[2];
    var dataPrev = row[4];
    var opcao = row[3];

    var timeDiff = Math.abs(dataPrev.getTime() - dataForm.getTime());
    var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));

Visto no tópico: Calcular diferença entre duas datas para validar campos da data
Answer: Você não pode utilizar nenhuma biblioteca js para tratar essas datas? Existe uma chamada momentJs https://ifpb.github.io/jaguaribetech/2016/09/01/moment-js/
Com ela voce consegue tratar isso de forma muito fácil.
Segue um exemplo em php também caso ajude:
$date = new DateTime("NOW");
echo $date->format('Y-m-d')."
";

//subtrai mês da data atual
$date = $date->sub(DateInterval::createfromdatestring('+ 1 month'));
echo 'Subtraindo 1 mês: '.($date->format('Y-m-d')).'
';

//Adiciona 1 mês a data
$date = $date->add(DateInterval::createfromdatestring('+ 1 month'));

//Recarrega mês atual
echo 'Adicionando 1 mês'.($date->format('Y-m-d')).'';

Subtração com data - Google Apps Script


Windows Server virtual disk cache settings

Question: In Windows under Azure or Hyper-V, the Disk Policy write cache settings for a virtual disk will always appear to be enabled from the server configuration, regardless of the actual status of write cache settings on the underlying disk system. However, there is a second setting related to the first, for which its effect is unclear in this case of virtual disks, where the first is checked/enabled in the setting, but actually disabled in the virtual disk hardware. The disk settings appear like this:
<code>[x] Enable Write Caching on the device
    [ ] Turn off Windows write-cache buffer flushing on the device
</code>
Intuitively, I would assume there is no reason to enable this, since write caching is actually NOT on for the device, and if it were a physical disk, this setting would be disabled. But this article suggests that enabling it will free the OS and hardware from doing meaningless work, improving performance while maintaining the same data integrity, for this case where write caching is enabled in the setting but is actually disabled in hardware:

...since a virtual hard disk isn't really a disk at all, that setting
  has no meaning as far as virtual disks are concerned. But the second
  setting is different and does have meaning as it controls the cache
  flush on/off settings for the disk. When you select the second
  setting, cache flushes will essentially pretend to succeed--at least
  at the level of the software stack. ... when you select this setting
  in the guest OS for a virtual hard disk in a virtual machine, you
  might see some performance improvement for applications running in the
  virtual machine. But always remember that it's the host's disk cache
  settings that are the important ones as far as data integrity are
  concerned.

Can anyone confirm whether or not this claim is true and a safe thing to do WRT data integrity?
Answer: I think those settings do not really have any sense if your data disks were initially configured with Read/None cache. This article states it is more a matter of host caching that can be modified through Service Management APIs or Powershell commands.
Comment: Intuitively, I agree, it makes no sense. But the author of the article I linked in my question is suggesting that checking the disable buffer flushing box does have a positive effect on performance with no risk to data integrity when the virtual disk is configured to Read/None cache. I'm trying to determine if that is true.
Comment: There is still a risk. System crash and you may lose the data in RAM. As they say, no risk, no reward :)
Answer: I would suggest going with VM with enabled option "Turn off Windows write-cache buffer flushing on the device" only in the case if you have redundancy on power/UPS or storage system levels. You should consider the data loss in case of power outage or hardware failure if you would enable the option. I can suggest going with S2D, StarWind or HPE VSA as software defined storage that can provide you with redundancy on node level so you could use the write-caching feature on-premise VMs.
For the case, the option "Turn off Windows write-cache buffer flushing on the device" will boost the overall VM system performance: RAM is used as the source for hot data and data flushing to the device is performed only when RAM is full.
I would suggest disabling Write-Caching, in case you are running Hyper-V standalone host with a PSU connection to a single line.
These assumptions are only reliable to on-premise virtualized hosts. The cloud vendors have own functionality to provide redundancy for their instances, therefore, I use the write-caching feature only for my Amazon VMs.
EDIT: the point of the feature is decreasing of latency on performed I/O operations.

Once WB cache is disabled the I/O requests go directly to underlying storage thus cause max latency.
In case "Enable Write Caching on the device" enabled, the I/O go to RAM first, once data becomes "cold", Windows OS flush them onto storage. For the case, it decreases the latency.
And when both WB options are marked, you can face the minimal latency due to hot and cold data is located on RAM. The data flushes onto storage only when RAM got full.
Comment: The virtual disk will actually have write caching disabled (it will be hosting a database). The question is regarding specifically what happens when buffer flushing is disabled and so is write caching. What is the meaning of disabling buffer flushing if there's no write caching? This is specifically for a Premium Storage disk in an Azure VM,
Comment: The answer was edited.
Comment: Please reread my question. I am asking what happens when write caching is *disabled* AND buffer flushing is *disabled*. This would not normally appear possible via the dialog, except in the case of a virtual disk that displays WB enabled when it is actually disabled.


Can an evaded cadence end the antecedent of a period?

Question: I would especially like an answer in the context of the theory of formal functions, although input from other perspectives is also welcomed.
The question arised when I was analyzing the main theme (or main themes?) of the first movement of the Piano Sonata nº 7 in C, k. by Mozart. In measures 7-8 we have a root position dominant moving to a root position tonic in a way that sounds to me as a cadential evasion, due to sudden change in dynamics, register and texture.

What follows is a restatement of the 4 opening measures which, after a greatly extended continuation, lead to a perfect authentic cadence in m. 21. As an evaded cadence is weaker than a perfect cadence and the basic idea is clearly brought back, I'm inclined to hear this as a (compound) period. Nowhere, as far as I could find, does Caplin mention that a antecedent may end in an evaded cadence. To be sure, he does not forbid it. Hence, the question: Can an evaded cadence end the antecedent of a period?
If that is not the case, then I believe m. 8 would bring a PAC and the beginning of a new main theme (as a transition clearly starts at m. 21, after a PAC) which would leave us with two main themes with identical basic ideas and a weak/strong cadential pattern. As single main themes are the more normative option and as I am not used to considering two themes with such similar openings and with such a cadential pattern to not be a compound period, that option feels rather uncomfortable.
Answer:
In measures 7-8 we have a root position dominant moving to a root position tonic in a way that sounds to me as a cadential evasion, due to sudden change in dynamics, register and texture.

Dynamics, register, texture don't determine cadences. Bass and melody determine cadences. It's a perfect cadence at m. 8. That makes sense as it emphatically establishes the tonic.
Mm. 17 to 18 there is an actual evaded cadence, or at least an evasive progression.
Generally I think an antecedent could end with any inconclusive cadence, any ending that isn't the tonic. That's how Caplin puts it, in relative terms of weak/strong, rather that specific chords like V and I, in his book Classical Form.
I don't think the opening of this movement involves periods. Caplin mentions the "nonelision of antecedent with consequent" There isn't a weak phrase ending - without eliding overlap - then a strong phrase ending. The movement starts with a series of sentences.
Comment: _"Passages of cadential content do not always function as syntactical cadences."_ Right. And Caplin is the one who set me straight on that, but it's a different issue. My understanding, my simplified way to put the idea is this: we need the end of a phrase to mark a cadence and then classify it by it's harmony. Mm. 7 to 8 do mark the end and start of a phrase, the harmony is `V` to `I`, so its a perfect cadence, the phrases are elided so it isn't a period.
Comment: I tend to think of forms other than sonata allegro form, those like minuet/trio, rondo, theme and variations, etc. to more commonly involve periods.
Comment: I dissagree that harmonic content alone determining cadences, and so does Caplin. As he puts in The Classical Cadence: Conceptions and Misconceptions and elsewhere: "Passages of cadential content do not always function as syntactical cadences." I am referring here to cadences as formal endings, maybe I should have made that clear in the question. If we accept that a cadence is solely determined by harmonic content, then there is no doubt that m. 8 brings a cadence.
Comment: As the V resolve to a IV (or VI, depending on how you analyze) in m. 18, I consider that to be a deceptive cadence. But yes, there is a cadential deviation there.
Comment: But I tend to agree that, more generally, an antecedent could end with any inconclusive cadence. It seems to me that the 'weak/strong' principle is more defining than the specific types of cadences involded.
Comment: As far as I understand, the conditions you put (ending and starting a phrase, movement from V to I and elision) can also be satisfied by evaded cadences in the sense that "A cadential evasion can occur even if the cadential dominant moves to a root-position tonic, as long as there is sufficient disruption of melody, texture, dynamics, register, and so on to counter our perceiving a structural end when the I chord appears" (Analyzing Classical Form, p. 370), so they do not automatically make the situation a perfect cadence.
Comment: But I do perceive a thematic ending at m. 8, so I agree that, indeed, it is a perfect cadence at m. 8 (as far as the theory of formal functions is concerned).
Comment: I also agree with the nonelision requirement. I keep forgetting that one. Thanks!


Erro ORA-01460 no Oracle

Question: Tenho a procedure abaixo:
PROCEDURE GRAVA_(P_IMEI_DISPOSITIVO IN NVARCHAR2,
                              P          LONG,
                              P_DET      LONG,
                              RETORNO_OPERACAO   OUT VARCHAR2)

Nos parâmetros P e P_DET recebo strings com dados em XML, e dentro da procedure converto para XML. Conforme abaixo:
PL_MZ_CAB_XML           SYS.XMLTYPE;
PL_MZ_CAB_XML := SYS.XMLTYPE.CREATEXML(P);

Quando recebo arquivo maiores que 32.000 Bytes o Oracle está me retornando a mensagem abaixo:

Ora-01460: conversão não-implementada ou não resolvível solicitada.

O que posso fazer para resolver isso?
Tenho que mudar o tipo do meu parâmetro será?
Answer: Você não falou a respeito da versão do seu Oracle, mas provavelmente ela é inferior a 10.1.0.5. Esse erro ocorre em versões mais antigas do oracle. Outro possivel problema é o driver do JDBC desatualizado.
uma outra solução é usar o tipo de dado como CLOB.

Erro ORA-01460 no Oracle


How to add a custom language?

Question: In Drupal 7 there is a section to add a custom language

But in Drupal 8 that section does not exist,

How can I add my custom language in Drupal 8?
Answer: There is,just open Language name select list and  choose  last item Custom language ... .

How to add a custom language?


subsequential limits of $\sin(n\pi x)$ when $x$ rational and $x$ irrational

Question: Let $x \in \mathbb{R}$ be fixed. Prove the sequence $a_n= \sin(n\pi x)$, $n = 1,2,3,\ldots$ has finitely many subsequential limits (accumulation points) iff $x \in \mathbb{Q}$, and every number in $[-1,1]$ is an accumulation point, if $x$ is irrational.
I need hints on this problem. Not sure where to start. Please, don't solve it for me, just some hints to help me figure out on my own. Thanks :)
(I have only covered the first 3 chapters of baby rudin in my class)
Answer: For your first problem, (the case where $x \in \mathbb Q$ ) take $x= \frac 3 7$ and calculate $a_1, a_2, a_3, \cdots$. You will see a pattern. For example $\sin \left( \frac{21 \pi}{7} \right) = 0$. Try to generalize for any rational $x$.
On the other hand, when $x \in \mathbb Q^c$, observe that $y:= \pi x$ is also irrational, and now you will have to show that $\{ \sin (ny) : n \in \mathbb N \}$ is dense in $[-1,1]$. This denseness somehow implies that every number in $[-1,1]$ is an accumulation point.
Answer: Let $[y]$ be the largest integer not exceeding the real number $y$. (This is an older,pre-computer, notation for "floor (y)". ) For rational $x=a/b$ with integer $a$ and positive integer $b$ , how many different values can $[n x]$ have for integer $n$ ? For irrational $x$ , prove that $\{[n x] : n\in Z\}$ is dense in $[0,1]$.Remark:The newer notation for $[x]$ takes 14 keystrokes in LaTeX including one mandatory space.The old one takes 3.And I'm an awful typist.


ASP.NET - TTL on Session Key-Value-Pairs (InProc)

Question: Is there a sanctioned method for adding TTL to ASP.NET InProc Session State entries?
Example:
Session("First", 60) = "John"
Session("Adams", 500) = "Adams"

Answer: Out of the box, no there isn't. Individual Session State Key-Value-Pairs do not have any built-in method for adding a TTL or TTE.
Regarding the "global" InProc session state-timeout, it is controlled by a session state wide value configured in your web.config file (the timeout value in the /system.web/sessionState settings).
Additionally, whilst it may look like an attractive proposition to create your own session state provider, you couldn't use the Session property exposed by the page or controller code as this returns a HttpSessionState object. None of the methods, properties or indexers support having an extra parameter to specify individual session value timeouts.
You may consider doing the following:

Maintain an active session for each user:
Session("PersistMe") = true
Grab SessionID, and use it to store values in the ASP.NET Cache where you may utilize a TTL value.
Comment: Thanks, I will just make sure the Session stays live (by storing SOMETHING in the session), and then using the SessionID in the ASP.NET Cache where TTL works.


What does this groupby function mean I have done?

Question: I have 3 columns: topic, year and country.
I am trying to find the maximum number of topics per country over the years and want it to group by the maximum project count for each country.
I've used this groupby function below:
df.groupby(['topic', 'year', 'country']).count()

However I can't really tell what it is showing me as it has just grouped each topic with each year and the country. I don't have another column for count also as I would like to see how many per topic so I have numbers to plot later also. How do I do this?
topic              year       country
Mechanics         2014.0         FI
                                 IT
                  2015.0         NL
                                 UK
                  2016.0         FR
                                 UK

biochemistry       2014.0        DE
                   2015.0        AT
                                 BE
                                 DE
                                 DK
                                 ES
                                 FI
                    2016.0       AT

Comment: could you show what the output is?
Comment: Please add a sample of what your `df` looks like to the question.
Comment: That's a portion of my output and what it looks like
Answer: that groupby should give you the count of each unique tuple of ('topic', 'year', 'country')
Comment: But how do I get only the unique tuple for just topics. and only the topic count and as another column?
Comment: @s.23 that's odd - could you post a snippet of your data as well?


Truncate lognormal distribution with excel

Question: I have a dataset where I extract the mean and the standard deviation, I want to generate a new synthetic dataset which is lognormal distributed based on the original dataset paramaters. Like a montecarlo simulation.
My problem is that I need that synthetic dataset is truncated, with the maximum and minimum value of the orignal set, in other words I don't want any synthetic value greater than the maximum value and minimum value of the original datset.
Thanks @whuber, following your guidelines it works perfectly with the positive side of my original dataset, long right tail distribution within the max and min limits.
Comment: How do you want to handle data outside min and max? Are you satisfied with capping, meaning there will be mass points atthe min and max, or do you want a lognormal conditional on being within the min and max? The former is easily handled by min/max or median calls in Excel. The latter is harder.
Comment: Hi @Avraham. I don't want any value outside the max and min in the synthetic dataseries generated. I would like to get n random lognormal synthetic dataseries from the original, but i don't want any value outside min and max of the original.
Comment: Yes, but there are two ways to handle it. One is to deal with a regular distribution which has probability outside the limits, but cap the observations. So if you would generate a 6.4, it would be forced to be a 5.59 and similarly for the min. Which means that less than 100% exists between max and min, and there are mass points at the end. The other way is to create a conditional distribution that only exists between max and min, and 100% lives between max and min, and P(x < min) = P (> max) = 0.
Comment: Look at the excellent answer of @whuber.
Comment: Yes @Avraham, awasome answer. I edited after read his great answer, but hard to me to understand it, i'll do my best with your help and my new detail.
Comment: Peering closely at the graphic in your post, I see some negative values in your "original data." The lognormal is defined on the non-negative numbers; are you certain you want to fit a lognormal?
Comment: Yes, @Avraham, i know a lognormal don't have negative numbers, sometimes my original data have  very long tails to the positive side. i deal always with two sort of original data, pseudonomal and anothers with long positive tails. I realized that with one of your solutions it's very easy to do what i want, i am editing my post again modifying the formula with your solution but i don't know if it will be accurate enough.
Comment: I will not question your objectives, which are obscure, but will merely remark that your step (4) does not generate truncated lognormal variates: it appears to generate a *mixture* of something complicated (which I don't care to analyze further; it's enough to know that it is incorrect). Since you wish to understand how to generate truncated lognormals step by step, I will humbly refer you back to my answer which describes this process in three ways, including step-by-step Excel formulas that you can follow.
Comment: Thank you @whuber, i'll try to work and understand your answer deeply. I have a little mess, and my approach as you said is not  correct.
Answer: Solution
Generate these numbers using the probability integral transform.
When $F$ is any cumulative distribution function and it is truncated at values $t_0 \lt t_1$, then random values can be obtained as
$$X = F^{-1}(U)$$
where $U$ is uniformly distributed in the interval $[a,b]=[F(t_0), F(t_1)]$.  In this case $F^{-1}$ can be computed explicitly (even by Excel).

Implementation Details
Due to the notorious and long-standing deficiencies in Excel's documentation and computations, I never use its lognormal functions: as a policy, I use only the most basic function that will get the job done.  This minimizes the amount of testing that needs to be performed in order to establish reliable results and maximizes the chance that I correctly understand what the software is doing.
In this case, everything can be handled with the CDF $\Phi$ and inverse CDF $\Phi^{-1}$ of the standard normal distribution.  (Excel's names for these are NORMSDIST and NORMSINV, respectively.)  For a lognormal distribution of mean $m$ and standard deviation $s$, compute
$$\sigma = \log\left(1 + \left(\frac{s}{m}\right)^2\right)$$
and then
$$\mu = \log(m) - \sigma^2/2.$$
These are the standard deviation and mean, respectively, of the distribution of the logarithms of the values.  In these terms
$$F(x) = \Phi\left(\frac{\log(x) - \mu}{\sigma}\right)$$
and
$$F^{-1}(q) = \exp\left(\mu + \sigma \Phi^{-1}(q)\right).$$
In Excel--as well as in many other software platforms--a uniform random value $U$ in an interval $[a,b]$ is generated by obtaining a random variate $V$ from the interval $[0,1]$--which is produced by Excel's RAND function--and rescaling it:
$$U = a + (b-a)V.$$

Excel Implementation
In addition to the usual arithmetic operations (addition, multiplication, etc) this calculation relies on only four functions: RAND, NORMSDIST, NORMSINV, and LN.  The first three have well-known problems (but there's no workaround for them short of recoding them in VBA).  Nevertheless, for the small simulations that Excel can handle RAND will be fine--especially when using more recent versions of Excel--and the errors in NORMSDIST and NORMSINV (which occur way out in the tails) are unlikely to be encountered.
The screen shot displays a portion of spreadsheet in which 256 random variates X (in column C) are generated according to the specifications at its right: Mean, SD, Min, and Max.  These are the only inputs to the calculation.  The bars in the chart tally one realization of these variates while the solid line is the graph of the truncated probability density function (rescaled to show the expected counts in each bin).  The deviations between the bar heights and the graph are due to random variation only.  (Notice how level the graph is: in this particular example the truncated lognormal distribution could be closely approximated by a simple uniform distribution.)

All values in the Value column are referenced by names derived from the Parameter column.  The formulas are:

LogMean represents $\mu$: =LN(Mean) - LogSD^2/2
LogSD: represents $\sigma$: =LN(1 + SD^2/Mean^2).
LogMin is the logarithm of the left endpoint of the truncation interval: =LN(Min)
LogMax is the logarithm of the right endpoint of the truncation interval: =LN(Max)
qMin is $a$, the lower limit of the quantile $U$: =NORMSDIST((LogMin - LogMean)/LogSD)
qMax is $b$, the upper limit of $U$: =NORMSDIST((LogMax-LogMean)/LogSD)
DeltaQ is $b-a$ for the calculation of $U$: =qMax-qMin.

The entries in columns A:C are each obtained by a formula entered at the first row and copied down:

Uniform RN represents $U$, computed as =qMin + DeltaQ*RAND().
Y are the logarithms of the random values, computed as =LogMean + LogSD * NORMSINV(A2) et seq.
X is obtained by exponentiating Y: =EXP(B2), et seq.
Comment: Nice answer. I was trying to pin down the OP, but your answer will serve much better. As an aside, Excel 2010 is much better, but I've still written my own VBA code for gammaln and other needed functions, and, of course, use R as often as I can.
Comment: Based on your edits, it is now clear you have already taken the first step of analyzing the logarithms of your data. Therefore you do not need to begin with `Mean`, `SD`, `Min`, and `Max`. Instead, just directly input the values of `LogMean`, `LogSD`, `LogMin`, and `LogMax`. This leaves very few formulas to enter: only `qMin`, `qMax`, and `DeltaQ` are needed to set up the random number generation performed in columns `A:C`. For Monte-Carlo simulation those columns can be combined into a single formula `Exp(LogMean + LogSD * NORMSINV(qMin + DeltaQ*RAND()))`.
Comment: Thank you so much @whuber. I can hardly understand the mathematical notation, but I want to fully understand the process. I understand the limitations of excel, but it is easier for me to develop the process in my excel UNTIL i understand the logic and steps well. Then move on to another software. i edited my question detailing what i have until now.
Comment: Thanks @whuber, i am going to edit my post following your guidelines, i need some time.
Comment: works great @whuber with the positive side, just extracting positive numbers of my original dataset and then computing parameters from them. But how can i deal with negatives values?.
Comment: You cannot deal with negative values using a lognormal distribution, Vince, because it can only describe positive distributions of numbers. I cannot advise you further because I have no information about why you are doing this or what you are trying to achieve.  Consider asking a new question in which you describe your data and what you need to accomplish with your analysis.
Comment: Yes @whuber, i was think about that just right now, i am mixing things, i'll try to ask a new question and define what are my aims. I learned here how to truncate a lognormal distribution without using LOGNORM.INV, thanks again.
Comment: More sophisticated methods to generate data from truncated distributions are explained at http://stats.stackexchange.com/questions/19736/what-does-truncated-distribution-mean. (I elected not to go into such details due to the need to suggest methods that could easily be implemented in Excel.) Some of these methods would have to used in special cases, such as truncation of all but the extreme tail of a distribution, because then the inaccuracies (or even just the imprecision) of the quantile functions like `NORMSINV` can create large errors.


Azure Security Center VM security configurations: how to suppress / exempt?

Question: Azure Security Center has recommendations for the configuration of my Windows virtual machines (VMs).

Azure Security Center → Secure Score → Recommendations → Remediate security configurations › Vulnerabilities in security configuration on your machines should be remediated → Remediate security configurations

These recommendations are sensible and I intend to simply comply with most of them. However, some conflict with another company policy. For those rules, I would like to suppress / exempt them, i.e. mark them as "won't fix, because of (reasons)".
For Security Center recommendations that result from an Azure Policy, I have a clear Exempt button. Not here though. For these security configurations, the "State: Open" column implies that they can have other states as well. Hopefully this includes something like "Exempted"? For the life of me, I can't find a way to turn some of these rules off (or all of them, for that matter).
Is this possible? If so, how?
Answer: I asked MS support. They showed me that these recommendations are part of the Policy Assignment called "ASC Default".
Within the parameters of this Initiative Assignment, there is an option to disable the VM security config recommendations. This disables the entire scan, for all VMs in the subscription. This means that the control simply no longer shows up at all on the Secure Score page.
There is also an option to add an exemption here. This can be done at the sub / rg / VM level. You can exempt only the VM security configs, and leave the rest of the ASC Default untouched.
There is no option to exempt or disable only certain rules.


Get timestamp from time string with today/tomorrow's date

Question: Need some help with converting a time string to a timestamp. Say my time is 07:00:00, how do I make this into a timestamp but also after the current date time?
Currently I have datetime.strptime('07:00:00', '%H:%M:%S') but that returns 1900-01-01 07:00:00.
Comment: Please accept the best answer: https://stackoverflow.com/help/someone-answers.
Answer: Well, something like this should work:
from datetime import datetime as dt

today = dt.today()
time = dt.strptime('07:00:00', '%H:%M:%S')

time = time.replace(day=today.day, month=today.month, year=today.year)

print(time) # datetime.datetime(2019, 7, 20, 7, 0)

Answer: You might want to check this page.
from datetime import datetime
# current date and time
now = datetime.now()
timestamp = datetime.timestamp(now)
print("timestamp =", timestamp)

Answer: You could try replacing todays parts:
from datetime import datetime
today = datetime.today()
mytime = '07:00:00'

then = today.replace(**dict(zip(['hour', 'minute','second'], map(int, mytime.split(':')))))
print(then)

output:
2019-07-20 07:00:00.108203

Answer: Try this
import datetime as dt_lib
from dateutil import parser as date_parser

def get_upcoming_7_o_clock_timestamp():
    today = dt_lib.datetime.now()
    upcoming_7_o_clock = date_parser.parse(today.date().isoformat() + ' ' + '07:00:00')

    if today > upcoming_7_o_clock:
        upcoming_7_o_clock = date_parser.parse((today + dt_lib.timedelta(days=1)).date().isoformat() + ' ' + '07:00:00')
    return upcoming_7_o_clock

Answer: You can try
from datetime import datetime, date
#first get current date
current_date = datetime.now().strftime('%Y-%m-%d');
timestamp = int(datetime.timestamp(datetime.strptime(current_date + ' 07:00:00', '%Y-%m-%d %H:%M:%S')))

Output-

1563586200
Answer: You can add today's date to your time and then apply strptime.
from datetime import date, datetime

my_datetime = f"07:00:00 {date.today()}"
print(datetime.strptime(my_datetime, "%H:%M:%S %Y-%m-%d"))
# 2019-07-20 07:00:00

Answer: This seems to be the easiest way that avoids stupid double conversion of the date to the string and back:
import datetime

date = datetime.datetime.now()
time = datetime.datetime.strptime( '07:00:00', '%H:%M:%S').time()

datetime.datetime.combine( date, time )

gives:
datetime.datetime(2019, 7, 20, 7, 0)

(probably using date and time as variable names was not the best idea, but for the sake of clarity... =)
Comment: Please don't encourage poor code quality using (very) bad variable names.