问:
Routing "paths" through a rectangular array
I'm trying to create my own implementation of a puzzle game.

To create my game board, I need to traverse each square in my array once and only once.

The traversal needs to be linked to an adjacent neighbor (horizontal, vertical or diagonal).

I'm using an array structure of the form:

```<code>board[n,m] = byte
Each bit of the byte represents a direction 0..7 and exactly 2 bits are always set
Directions are numbered clockwise
0 1 2
7 . 3
6 5 4
Board[0,0] must have some combination of bits 3,4,5 set
</code>```

My current approach for constructing a random path is:

```<code> Start at a random position
 While (Squares remain)
    if no directions from this square are valid, step backwards
    Pick random direction from those remaining in bitfield for this square
    Erase the direction to this square from those not picked
    Move to the next square
</code>```

This algorithm takes far too long on some medium sized grids, because earlier choices remove areas from consideration.

What I'd like to have is a function that takes an index into every possible path, and returns with the array filled in for that path.   This would let me provide a 'seed' value to return to this particular board.

Other suggestions are welcome..

答:
Bizarrely enough, I spent an undergrad summer in my Math degree studying this problem as well as coming up with algorithms to address it. First I will comment on the other answers.

Martin B: Correctly identified this as a Hamiltonian path problem. However, if the graph is a regular grid (as you two discussed in the comments) then a Hamiltonian path can trivially be found (snaking row-major order for example.)

agnorest: Correctly talked about the Hamiltonian path problem being in a class of hard problems. agnorest also alluded to possibly exploiting the graph structure, which funny enough, is trivial in the case of a regular grid.

I will now continue the discussion by elaborating on what I think you are trying to achieve. As you mentioned in the comments, it is trivial to find certain classes of "space-filling" non intersecting "walks" on a regular lattice/grid. However, it seems you are not satisfied only with these and would like to find an algorithm that finds "interesting" walks that cover your grid at random. But before I explore that possibility, I'd like to point out that the "non-intersecting" property of these walks is extremely important and what causes the difficulties of enumerating them.

In fact, the thing that I studied in my summer internship is called the Self Avoiding Walk. Surprisingly, the study of SAWs (self avoiding walks) is very important to a few sub-domains of modeling in physics (and was a key ingredient to the Manhattan project!) The algorithm you gave in your question is actually a variant on an algorithm known as the "growth" algorithm or Rosenbluth's algorithm (named after non other than Marshal Rosenbluth). More details on both the general version of this algorithm (used to estimate statistics on SAWs) as well as their relation to physics can be readily found in literature like this thesis.

SAWs in 2 dimensions are notoriously hard to study. Very few theoretical results are known about SAWs in 2 dimensions. Oddly enough, in higher than 3 dimensions you can say that most properties of SAWs are known theoretically, such as their growth constant. Suffice it to say, SAWs in 2 dimensions are very interesting things!

Reigning in this discussion to talk about your problem at hand, you are probably finding that your implementation of the growth algorithm gets "cut off" quite frequently and can not expand to fill the whole of your lattice. In this case, it is more appropriate to view your problem as a Hamiltonian Path problem. My approach to finding interesting Hamiltonian paths would be to formulate the problem as an Integer Linear Program, and add fix random edges to be used in the ILP. The fixing of random edges would give randomness to the generation process, and the ILP portion would efficiently compute whether certain configurations are feasible and if they are would return a solution.

The Code

The following code implements the Hamiltonian path or cycle problem for arbitrary initial conditions. It implements it on a regular 2D lattice with 4-connectivity. The formulation follows the standard sub-tour elimination ILP Lagrangian. The sub-tours are eliminated lazily, meaning there can be potentially many iterations required.

You could augment this to satisfy random or otherwise initial conditions that you deem "interesting" for your problem. If the initial conditions are infeasible it terminates early and prints this.

This code depends on NetworkX and PuLP.

```<code>"""
Hamiltonian path formulated as ILP, solved using PuLP, adapted from

https://projects.coin-or.org/PuLP/browser/trunk/examples/Sudoku1.py

Authors: ldog
"""

# Import PuLP modeler functions
from pulp import *

# Solve for Hamiltonian path or cycle
solve_type = 'cycle'

# Define grid size
N = 10

# If solving for path a start and end must be specified
if solve_type == 'path':
    start_vertex = (0,0)
    end_vertex = (5,5)

# Assuming 4-connectivity (up, down, left, right)
Edges = ["up", "down", "left", "right"]
Sequence = [ i for i in range(N) ]

# The Rows and Cols sequences follow this form, Vals will be which edge is used
Vals = Edges
Rows = Sequence
Cols = Sequence

# The prob variable is created to contain the problem data
prob = LpProblem("Hamiltonian Path Problem",LpMinimize)

# The problem variables are created
choices = LpVariable.dicts("Choice",(Vals,Rows,Cols),0,1,LpInteger)

# The arbitrary objective function is added
prob += 0, "Arbitrary Objective Function"

# A constraint ensuring that exactly two edges per node are used
# (a requirement for the solution to be a walk or path.)
for r in Rows:
    for c in Cols:
        if solve_type == 'cycle':
            prob += lpSum([choices[v][r][c] for v in Vals ]) == 2, ""
        elif solve_type == 'path':
            if (r,c) == end_vertex or (r,c) == start_vertex:
                prob += lpSum([choices[v][r][c] for v in Vals]) == 1, ""
            else:
                prob += lpSum([choices[v][r][c] for v in Vals]) == 2, ""

# A constraint ensuring that edges between adjacent nodes agree
for r in Rows:
    for c in Cols:
        #The up direction
        if r > 0:
            prob += choices["up"][r][c] == choices["down"][r-1][c],""
        #The down direction
        if r < N-1:
            prob += choices["down"][r][c] == choices["up"][r+1][c],""
        #The left direction
        if c > 0:
            prob += choices["left"][r][c] == choices["right"][r][c-1],""
        #The right direction
        if c < N-1:
            prob += choices["right"][r][c] == choices["left"][r][c+1],""

# Ensure boundaries are not used
for c in Cols:
    prob += choices["up"][0][c] == 0,""
    prob += choices["down"][N-1][c] == 0,""
for r in Rows:
    prob += choices["left"][r][0] == 0,""
    prob += choices["right"][r][N-1] == 0,""

# Random conditions can be specified to give "interesting" paths or cycles
# that have this condition.
# In the simplest case, just specify one node with fixed edges used.
prob += choices["down"][2][2] == 1,""
prob += choices["up"][2][2] == 1,""

# Keep solving while the smallest cycle is not the whole thing
while True:
    # The problem is solved using PuLP's choice of Solver
    prob.solve()

    # The status of the solution is printed to the screen
    status = LpStatus[prob.status]
    print "Status:", status
    if status == 'Infeasible':
        print 'The set of conditions imposed are impossible to solve for. Change the conditions.'
        break

    import networkx as nx
    g = nx.Graph()
    g.add_nodes_from([i for i in range(N*N)])

    for r in Rows:
        for c in Cols:
            if value(choices['up'][r][c])  == 1:
                nr = r - 1
                nc = c
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['down'][r][c])  == 1:
                nr = r + 1
                nc = c
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['left'][r][c])  == 1:
                nr = r
                nc = c - 1
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['right'][r][c])  == 1:
                nr = r
                nc = c + 1
                g.add_edge(r*N+c,nr*N+nc)

    # Get connected components sorted by length
    cc = sorted(nx.connected_components(g), key = len)

    # For the shortest, add the remove cycle condition
    def ngb(idx,v):
        r = idx/N
        c = idx%N
        if v == 'up':
            nr = r - 1
            nc = c
        if v == 'down':
            nr = r + 1
            nc = c
        if v == 'left':
            nr = r
            nc = c - 1
        if v == 'right':
            nr = r
            nc = c + 1
        return nr*N+c

    prob += lpSum([choices[v][idx/N][idx%N] for v in Vals for idx in cc[0] if ngb(idx,v) in cc[0] ]) \
            <= 2*(len(cc[0]))-1,  ""

    # Pretty print the solution
    if len(cc[0]) == N*N:
        print ''
        print '***************************'
        print ' This is the final solution'
        print '***************************'
    for r in Rows:
        s = ""
        for c in Cols:
            if value(choices['up'][r][c])  == 1:
                s += " | "
            else:
                s += "   "
        print s
        s = ""
        for c in Cols:
            if value(choices['left'][r][c])  == 1:
                s += "-"
            else:
                s += " "
            s += "X"
            if value(choices['right'][r][c])  == 1:
                s += "-"
            else:
                s += " "
        print s
        s = ""
        for c in Cols:
            if value(choices['down'][r][c])  == 1:
                s += " | "
            else:
                s += "   "
        print s

    if len(cc[0]) != N*N:
        print 'Press key to continue to next iteration (which eliminates a suboptimal subtour) ...'
    elif len(cc[0]) == N*N:
        print 'Press key to terminate'
    raw_input()

    if len(cc[0]) == N*N:
        break
</code>```

OwnerDisplayName: Aspirant

Body:
I'm trying to create my own implementation of a puzzle game.

To create my game board, I need to traverse each square in my array once and only once.

The traversal needs to be linked to an adjacent neighbor (horizontal, vertical or diagonal).

I'm using an array structure of the form:

board[n,m] = byte
Each bit of the byte represents a direction 0..7 and exactly 2 bits are always set
Directions are numbered clockwise
0 1 2
7 . 3
6 5 4
Board[0,0] must have some combination of bits 3,4,5 set

My current approach for constructing a random path is:

 Start at a random position
 While (Squares remain)
    if no directions from this square are valid, step backwards
    Pick random direction from those remaining in bitfield for this square
    Erase the direction to this square from those not picked
    Move to the next square

This algorithm takes far too long on some medium sized grids, because earlier choices remove areas from consideration.

What I'd like to have is a function that takes an index into every possible path, and returns with the array filled in for that path.   This would let me provide a 'seed' value to return to this particular board.

Other suggestions are welcome..

Body:
Bizarrely enough, I spent an undergrad summer in my Math degree studying this problem as well as coming up with algorithms to address it. First I will comment on the other answers.

Martin B: Correctly identified this as a Hamiltonian path problem. However, if the graph is a regular grid (as you two discussed in the comments) then a Hamiltonian path can trivially be found (snaking row-major order for example.)

agnorest: Correctly talked about the Hamiltonian path problem being in a class of hard problems. agnorest also alluded to possibly exploiting the graph structure, which funny enough, is trivial in the case of a regular grid.

I will now continue the discussion by elaborating on what I think you are trying to achieve. As you mentioned in the comments, it is trivial to find certain classes of "space-filling" non intersecting "walks" on a regular lattice/grid. However, it seems you are not satisfied only with these and would like to find an algorithm that finds "interesting" walks that cover your grid at random. But before I explore that possibility, I'd like to point out that the "non-intersecting" property of these walks is extremely important and what causes the difficulties of enumerating them.

In fact, the thing that I studied in my summer internship is called the Self Avoiding Walk. Surprisingly, the study of SAWs (self avoiding walks) is very important to a few sub-domains of modeling in physics (and was a key ingredient to the Manhattan project!) The algorithm you gave in your question is actually a variant on an algorithm known as the "growth" algorithm or Rosenbluth's algorithm (named after non other than Marshal Rosenbluth). More details on both the general version of this algorithm (used to estimate statistics on SAWs) as well as their relation to physics can be readily found in literature like this thesis.

SAWs in 2 dimensions are notoriously hard to study. Very few theoretical results are known about SAWs in 2 dimensions. Oddly enough, in higher than 3 dimensions you can say that most properties of SAWs are known theoretically, such as their growth constant. Suffice it to say, SAWs in 2 dimensions are very interesting things!

Reigning in this discussion to talk about your problem at hand, you are probably finding that your implementation of the growth algorithm gets "cut off" quite frequently and can not expand to fill the whole of your lattice. In this case, it is more appropriate to view your problem as a Hamiltonian Path problem. My approach to finding interesting Hamiltonian paths would be to formulate the problem as an Integer Linear Program, and add fix random edges to be used in the ILP. The fixing of random edges would give randomness to the generation process, and the ILP portion would efficiently compute whether certain configurations are feasible and if they are would return a solution.

The Code

The following code implements the Hamiltonian path or cycle problem for arbitrary initial conditions. It implements it on a regular 2D lattice with 4-connectivity. The formulation follows the standard sub-tour elimination ILP Lagrangian. The sub-tours are eliminated lazily, meaning there can be potentially many iterations required.

You could augment this to satisfy random or otherwise initial conditions that you deem "interesting" for your problem. If the initial conditions are infeasible it terminates early and prints this.

This code depends on NetworkX and PuLP.

"""
Hamiltonian path formulated as ILP, solved using PuLP, adapted from

https://projects.coin-or.org/PuLP/browser/trunk/examples/Sudoku1.py

Authors: ldog
"""

# Import PuLP modeler functions
from pulp import *

# Solve for Hamiltonian path or cycle
solve_type = 'cycle'

# Define grid size
N = 10

# If solving for path a start and end must be specified
if solve_type == 'path':
    start_vertex = (0,0)
    end_vertex = (5,5)

# Assuming 4-connectivity (up, down, left, right)
Edges = ["up", "down", "left", "right"]
Sequence = [ i for i in range(N) ]

# The Rows and Cols sequences follow this form, Vals will be which edge is used
Vals = Edges
Rows = Sequence
Cols = Sequence

# The prob variable is created to contain the problem data
prob = LpProblem("Hamiltonian Path Problem",LpMinimize)

# The problem variables are created
choices = LpVariable.dicts("Choice",(Vals,Rows,Cols),0,1,LpInteger)

# The arbitrary objective function is added
prob += 0, "Arbitrary Objective Function"

# A constraint ensuring that exactly two edges per node are used
# (a requirement for the solution to be a walk or path.)
for r in Rows:
    for c in Cols:
        if solve_type == 'cycle':
            prob += lpSum([choices[v][r][c] for v in Vals ]) == 2, ""
        elif solve_type == 'path':
            if (r,c) == end_vertex or (r,c) == start_vertex:
                prob += lpSum([choices[v][r][c] for v in Vals]) == 1, ""
            else:
                prob += lpSum([choices[v][r][c] for v in Vals]) == 2, ""

# A constraint ensuring that edges between adjacent nodes agree
for r in Rows:
    for c in Cols:
        #The up direction
        if r > 0:
            prob += choices["up"][r][c] == choices["down"][r-1][c],""
        #The down direction
        if r < N-1:
            prob += choices["down"][r][c] == choices["up"][r+1][c],""
        #The left direction
        if c > 0:
            prob += choices["left"][r][c] == choices["right"][r][c-1],""
        #The right direction
        if c < N-1:
            prob += choices["right"][r][c] == choices["left"][r][c+1],""

# Ensure boundaries are not used
for c in Cols:
    prob += choices["up"][0][c] == 0,""
    prob += choices["down"][N-1][c] == 0,""
for r in Rows:
    prob += choices["left"][r][0] == 0,""
    prob += choices["right"][r][N-1] == 0,""

# Random conditions can be specified to give "interesting" paths or cycles
# that have this condition.
# In the simplest case, just specify one node with fixed edges used.
prob += choices["down"][2][2] == 1,""
prob += choices["up"][2][2] == 1,""

# Keep solving while the smallest cycle is not the whole thing
while True:
    # The problem is solved using PuLP's choice of Solver
    prob.solve()

    # The status of the solution is printed to the screen
    status = LpStatus[prob.status]
    print "Status:", status
    if status == 'Infeasible':
        print 'The set of conditions imposed are impossible to solve for. Change the conditions.'
        break

    import networkx as nx
    g = nx.Graph()
    g.add_nodes_from([i for i in range(N*N)])

    for r in Rows:
        for c in Cols:
            if value(choices['up'][r][c])  == 1:
                nr = r - 1
                nc = c
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['down'][r][c])  == 1:
                nr = r + 1
                nc = c
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['left'][r][c])  == 1:
                nr = r
                nc = c - 1
                g.add_edge(r*N+c,nr*N+nc)
            if value(choices['right'][r][c])  == 1:
                nr = r
                nc = c + 1
                g.add_edge(r*N+c,nr*N+nc)

    # Get connected components sorted by length
    cc = sorted(nx.connected_components(g), key = len)

    # For the shortest, add the remove cycle condition
    def ngb(idx,v):
        r = idx/N
        c = idx%N
        if v == 'up':
            nr = r - 1
            nc = c
        if v == 'down':
            nr = r + 1
            nc = c
        if v == 'left':
            nr = r
            nc = c - 1
        if v == 'right':
            nr = r
            nc = c + 1
        return nr*N+c

    prob += lpSum([choices[v][idx/N][idx%N] for v in Vals for idx in cc[0] if ngb(idx,v) in cc[0] ]) \
            <= 2*(len(cc[0]))-1,  ""

    # Pretty print the solution
    if len(cc[0]) == N*N:
        print ''
        print '***************************'
        print ' This is the final solution'
        print '***************************'
    for r in Rows:
        s = ""
        for c in Cols:
            if value(choices['up'][r][c])  == 1:
                s += " | "
            else:
                s += "   "
        print s
        s = ""
        for c in Cols:
            if value(choices['left'][r][c])  == 1:
                s += "-"
            else:
                s += " "
            s += "X"
            if value(choices['right'][r][c])  == 1:
                s += "-"
            else:
                s += " "
        print s
        s = ""
        for c in Cols:
            if value(choices['down'][r][c])  == 1:
                s += " | "
            else:
                s += "   "
        print s

    if len(cc[0]) != N*N:
        print 'Press key to continue to next iteration (which eliminates a suboptimal subtour) ...'
    elif len(cc[0]) == N*N:
        print 'Press key to terminate'
    raw_input()

    if len(cc[0]) == N*N:
        break


来源: stackexchange

问:
Scheduling data extraction from AWS Redshift to S3
I am trying to build out a job for extracting data from Redshift and write the same data to S3 buckets.
Till now I have explored AWS Glue, but Glue is not capable to run custom sql's on redshift. I know we can run unload commands and can be stored to S3 directly. I am looking for a solution which can be parameterised and scheduled in AWS.   </p>

答:
Consider using AWS Data Pipeline for this.

AWS Data Pipeline is AWS service that allows you to define and schedule regular jobs. These jobs are referred to as pipelines. Pipeline contains a business logic of the work required, for example, extracting data from Redshift to S3. You can schedule a pipeline to run however often you require e.g. daily.

Pipeline is defined by you, you can even version control it. You can prepare a pipeline definition in a browser using Data Pipeline Architect or compose it using JSON file locally on your computer. Pipeline definition is composed of components, such as, Redshift database, S3 node , SQL activity, as well as parameters, for example to specifying S3 path to use for extracted data.

AWS Data Pipeline service handles scheduling, dependency between components in your pipeline, monitoring and error handling.

For your specific use case, I would consider the following options:

Option 1

Define pipeline with the following components: SQLDataNode and S3DataNode. SQLDataNode would reference your Redshift database and SELECT query to use to extract your data. S3DataNode would point to S3 path to be used to store your data. You add a CopyActivity activity to copy data from SQLDataNode to S3DataNode. When such pipeline runs, it will retrieve data from Redshift using SQLDataNode and copy that data to S3DataNode using CopyActivity. S3 path in S3DataNode can be parameterised so it is different every time you run a pipeline.

Option 2

Firstly, define SQL query with UNLOAD statement to be used to unload your data to S3. Optionally, you can save it in a file and upload to S3. Use SQLActivity component to specify SQL query to execute in Redshift database. SQL query in SQLActivity can be a reference to S3 path where you stored your query (optionally), or just a query itself. Whenever a pipeline runs, it will connect to Redshift and execute SQL query which stores the data in S3.
Constraints of option 2: in UNLOAD statement, S3 path is static. If you plan to store every data extract in a separate S3 path, you will have to modify UNLOAD statement to use another S3 path every time you run it which is not out-of-the-box function.

Where do these pipelines run?

On EC2 instance with a TaskRunner, a tool provided by AWS to run data pipelines. You can start that instance automatically at the time when pipeline runs, or you can reference already running instance with a TaskRunner installed on it. You have to make sure that EC2 instance is allowed to connect to your Redshift database.

Relevant documentation:

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/what-is-datapipeline.html

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-object-redshiftdatabase.html

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-object-sqldatanode.html

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-object-sqlactivity.html

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-using-task-runner.html

ContentLicense: CC BY-SA 3.0


问:
How to get only first property from JSON file?
I am trying to get only the selected item from this JSON file:

```<code>{
  "faqs": [
    {
      "id": 1,
      "question": "What is Salmon about?",
      "answer": "Building great sites for our amazing clients. Simple."
    },
    {
      "id": 3,
      "question": "What is the location of Salmon Watford?",
      "answer": "Just 2 minutes walk from Watford Junction Train Station"
    },
    {
      "id": 5,
      "question": "Is this the last question?",
      "answer": "Yes. You have done well!"
    }
  ]
}
</code>```

For example i need first question and answer to be shown in first
, second question and answer in second
 and the third q & a in the third
.

I am using AJAX to access the file:

```<code>$.ajax({
    url: 'faqs.json',
    dataType: 'json',
    type: 'GET',
    cache: true,
    success: function(data) {
      $(data.faqs).each(function(index, value) {
        $('#firstQuestion').text("Q: " + value.question);
        $('#firstAnswer').text(value.answer);
        $('#secondQuestion').text("Q: " + value.question);
        $('#secondAnswer').text(value.answer);
        $('#thirdQuestion').text("Q: " + value.question);
        $('#thirdAnswer').text(value.answer);
      });
    }
  });
</code>```

And now I got some result that loops through all the items and gives me the last one but as I already said earlier I need the first question and answer at the first
 and so on.

Can you provide me with some ideas or a solution? I am trying to solve this for about 4 hours now and I have nothing. Any help is greatly appreciated.

答:
Let's say that we have a function called zip, which takes in two arrays and returns a single array of doubles:

```<code>const zip = (array1, array2) => [[array1[0], array2[0]], ...]
</code>```

ramda, lodash, and I believe underscore and jquery have this function. If not, here is a basic zip function:

```<code>const zip = (a, b) => {
  const result = []
  const maxLength = Math.max(a.length, b.length)
  for(let i = 0; i < maxLength; i++) {
    result.push(
      [a[i], b[i]]
    )
  }

  return result
}
</code>```

Now we take in your list of ordered divs and our list of faqs, creating a single list of [[div, faqObj]]

Then we iterate over that and do our work:

```<code>const fullList = zip(divs, faqs)

fullList.forEach((div, obj) => {
  // do your imperative work here,
  // given a div and an object
})
</code>```

Body:
I am trying to get only the selected item from this JSON file:

{
  "faqs": [
    {
      "id": 1,
      "question": "What is Salmon about?",
      "answer": "Building great sites for our amazing clients. Simple."
    },
    {
      "id": 3,
      "question": "What is the location of Salmon Watford?",
      "answer": "Just 2 minutes walk from Watford Junction Train Station"
    },
    {
      "id": 5,
      "question": "Is this the last question?",
      "answer": "Yes. You have done well!"
    }
  ]
}

For example i need first question and answer to be shown in first
, second question and answer in second
 and the third q & a in the third
.

I am using AJAX to access the file:

$.ajax({
    url: 'faqs.json',
    dataType: 'json',
    type: 'GET',
    cache: true,
    success: function(data) {
      $(data.faqs).each(function(index, value) {
        $('#firstQuestion').text("Q: " + value.question);
        $('#firstAnswer').text(value.answer);
        $('#secondQuestion').text("Q: " + value.question);
        $('#secondAnswer').text(value.answer);
        $('#thirdQuestion').text("Q: " + value.question);
        $('#thirdAnswer').text(value.answer);
      });
    }
  });

And now I got some result that loops through all the items and gives me the last one but as I already said earlier I need the first question and answer at the first
 and so on.

Can you provide me with some ideas or a solution? I am trying to solve this for about 4 hours now and I have nothing. Any help is greatly appreciated.

Body:
Let's say that we have a function called zip, which takes in two arrays and returns a single array of doubles:

const zip = (array1, array2) => [[array1[0], array2[0]], ...]

ramda, lodash, and I believe underscore and jquery have this function. If not, here is a basic zip function:

const zip = (a, b) => {
  const result = []
  const maxLength = Math.max(a.length, b.length)
  for(let i = 0; i < maxLength; i++) {
    result.push(
      [a[i], b[i]]
    )
  }

  return result
}

Now we take in your list of ordered divs and our list of faqs, creating a single list of [[div, faqObj]]

Then we iterate over that and do our work:

const fullList = zip(divs, faqs)

fullList.forEach((div, obj) => {
  // do your imperative work here,
  // given a div and an object
})


问:
"git pull" runs out of memory
I tired to git pull, it suddenly comes out .. </p>

<p>Please let me know what I have to do </p>

```<code>git pull
remote: Counting objects: 196, done.
remote: warning: suboptimal pack - out of memory
remote: fatal: Out of memory, malloc failed (tried to allocate 220610561 bytes)
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption on the remote side.
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed
</code>```

答:
If you have access to the remote server, try to open an ssh session on it and type:

```<code>git config pack.windowMemory 10m
git config pack.packSizeLimit 20m
</code>```

But if you don't , you will have to do some shallow fetch, in order to not fetch the all history at once.

```<code>git clone /url/of/remote/repo --depth=1
git fetch --depth=10
git fetch --depth=20
...
git fetch --depth=100
git fetch --unshallow    //Downloads all history allowing to push from repo
</code>```

Title: "git pull" runs out of memory

Body:
I tired to git pull, it suddenly comes out ..

Please let me know what I have to do

git pull
remote: Counting objects: 196, done.
remote: warning: suboptimal pack - out of memory
remote: fatal: Out of memory, malloc failed (tried to allocate 220610561 bytes)
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption on the remote side.
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed

Body:
If you have access to the remote server, try to open an ssh session on it and type:

git config pack.windowMemory 10m
git config pack.packSizeLimit 20m

But if you don't , you will have to do some shallow fetch, in order to not fetch the all history at once.

git clone /url/of/remote/repo --depth=1
git fetch --depth=10
git fetch --depth=20
...
git fetch --depth=100
git fetch --unshallow    //Downloads all history allowing to push from repo


问:
Variant Api android in Gradle 4.1
In previous version of gradle I have such code as below for generating outputFileName for my release apk.

```<code>applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(outputPathName)
        }
    }
</code>```

But after last gradle update this code is not working. I have read on official migrating docs that I should change my code to:

```<code>android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}
</code>```

And this is not working. This code just creates path in /home/pugman/AndroidStudioProjects/clickerapp/app/build/outputs/apk/release directory.
Also I have read this text:

"However, more complicated tasks that involve accessing outputFile objects no longer work. That's because variant-specific tasks are no longer created during the configuration stage. This results in the plugin not knowing all of its outputs up front, but it also means faster configuration times."

Does this means that method above will not work?

答:
As you said, the official migration docs states that there have been breaking changes introduced in 3.0.0. With that said, it also says clearly:

It still works for simple tasks, such as changing the APK name during
  build time

And indeed it does :)
But I suspect that you're probably doing something wrong in your build.gradle. Anyways, notice that they prefix applicationVariants with android in the example:

```<code>android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}
</code>```

But, the prefix is not needed unless you're outside the android closure, e.g.:

```<code>android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    // More stuff here...
}

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}
</code>```

If this doesn't solve the issue then most likely you issue is somewhere else in your build.gradle.

Title: Variant Api android in Gradle 4.1

Body:
In previous version of gradle I have such code as below for generating outputFileName for my release apk.

applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(outputPathName)
        }
    }

But after last gradle update this code is not working. I have read on official migrating docs that I should change my code to:

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}

And this is not working. This code just creates path in /home/pugman/AndroidStudioProjects/clickerapp/app/build/outputs/apk/release directory.
Also I have read this text:

"However, more complicated tasks that involve accessing outputFile objects no longer work. That's because variant-specific tasks are no longer created during the configuration stage. This results in the plugin not knowing all of its outputs up front, but it also means faster configuration times."

Does this means that method above will not work?

Body:
As you said, the official migration docs states that there have been breaking changes introduced in 3.0.0. With that said, it also says clearly:

It still works for simple tasks, such as changing the APK name during
  build time

And indeed it does :)
But I suspect that you're probably doing something wrong in your build.gradle. Anyways, notice that they prefix applicationVariants with android in the example:

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}

But, the prefix is not needed unless you're outside the android closure, e.g.:

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    // More stuff here...
}

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}

If this doesn't solve the issue then most likely you issue is somewhere else in your build.gradle.


问:
Use a function builded for UICollectionView inside the function UITableView heightForRowAt (Swift)
I'm a beginner and i would like to know how can i add this function that was created for a UICollectionView

```<code>func heightForAnnotationAtIndexPath(indexPath: IndexPath, withWidth width: CGFloat) -> CGFloat {

        let place = places[indexPath.row]
        let annotationPadding = CGFloat(5)

        let font = UIFont.systemFont(ofSize: 15)
        let commentHeight = place.heightForComment(font, width: width)

        let height = annotationPadding + commentHeight + annotationPadding

        return height
    }
</code>```

inside

```<code> func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 130
}
</code>```

since unlike the collectionView in the tableView i only need of the height value because there aren't columns

答:
I don't have access to my Mac right now, but why not just return your heightForAnnotationAtIndexPath() function inside your tableView() function? I'm thinking as follows:

```<code>func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    //you'll have to set your indexPath and withWidth parameters
    return heightForAnnotationAtIndexPath(indexPath, withWidth)

}
</code>```

They both return CGFloats for you, so that should work for you.

Body:
I'm a beginner and i would like to know how can i add this function that was created for a UICollectionView

func heightForAnnotationAtIndexPath(indexPath: IndexPath, withWidth width: CGFloat) -> CGFloat {

        let place = places[indexPath.row]
        let annotationPadding = CGFloat(5)

        let font = UIFont.systemFont(ofSize: 15)
        let commentHeight = place.heightForComment(font, width: width)

        let height = annotationPadding + commentHeight + annotationPadding

        return height
    }

inside

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 130
}

since unlike the collectionView in the tableView i only need of the height value because there aren't columns

Body:
I don't have access to my Mac right now, but why not just return your heightForAnnotationAtIndexPath() function inside your tableView() function? I'm thinking as follows:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    //you'll have to set your indexPath and withWidth parameters
    return heightForAnnotationAtIndexPath(indexPath, withWidth)

}

They both return CGFloats for you, so that should work for you.


问:
New to CSS, issues with nav bar
I am new to CSS and can't work out a kink. I am having several issues with my nav css. The hover state is not inline with the normal state, and the last item is pushed onto a new line rather than equally spacing across a single bar.

JSFiddle

```<code>ul {
    left: 20%;
    top: 10%;
    list-style-type: none;
    margin: 0;
    padding: 0;
    text-align: center;
    overflow: hidden;
    background: radial-gradient(circle, #505050, #3E3E3E);
    width: 50%;
}

li {
    display: inline-block;
    float: left;
    width: 24%;
    margin: 0;
    padding: 0;
    border-right: 1px solid #232323;
}

/* Remove border from last tab */
li:last-child {
    border: none;
}

li:first-child {
    border: none;
}

/* Setting up the text on the menu */
li a {
    text-align: center;
    font: Verdana;
    font-size: 16px;
    display: inline-block;
    color: #EAE0D2;
    margin: 0;
    padding: 20px 20px;
    text-decoration: none;
    width: 25%;
}

/* Change the link color on hover */
li a:hover {

    background: linear-gradient(#2B2B2B, #232323);
    border:none;
    width: 83%;
}

/* Color the active tab */
.active {
    background: linear-gradient(#3E3E3E, #2B2B2B);
    color: #white;
}
</code>```

答:
excuse me for my bad english.

first to get your last button inline you must change the box model on your list items, and set back your 4 buttons to 25%

```<code>li {
   box-sizing: border-box;
   width:25%; ...
</code>```

now your 1px borders don't break your alignment anymore

then same issue with your anchors in the list items, change the box model and correct the width

```<code>li a {
      box-sizing: border-box;
      width: 100%; //the whole width of the parent li
</code>```

now that's your padding which  are no longer a problem

you can now delete the width in li a:hover

width: 83%

everything should be fine

jsfiddle

Title: New to CSS, issues with nav bar

Body:
I am new to CSS and can't work out a kink. I am having several issues with my nav css. The hover state is not inline with the normal state, and the last item is pushed onto a new line rather than equally spacing across a single bar.

JSFiddle

ul {
    left: 20%;
    top: 10%;
    list-style-type: none;
    margin: 0;
    padding: 0;
    text-align: center;
    overflow: hidden;
    background: radial-gradient(circle, #505050, #3E3E3E);
    width: 50%;
}

li {
    display: inline-block;
    float: left;
    width: 24%;
    margin: 0;
    padding: 0;
    border-right: 1px solid #232323;
}

/* Remove border from last tab */
li:last-child {
    border: none;
}

li:first-child {
    border: none;
}

/* Setting up the text on the menu */
li a {
    text-align: center;
    font: Verdana;
    font-size: 16px;
    display: inline-block;
    color: #EAE0D2;
    margin: 0;
    padding: 20px 20px;
    text-decoration: none;
    width: 25%;
}

/* Change the link color on hover */
li a:hover {

    background: linear-gradient(#2B2B2B, #232323);
    border:none;
    width: 83%;
}

/* Color the active tab */
.active {
    background: linear-gradient(#3E3E3E, #2B2B2B);
    color: #white;
}

Body:
excuse me for my bad english.

first to get your last button inline you must change the box model on your list items, and set back your 4 buttons to 25%

li {
   box-sizing: border-box;
   width:25%; ...

now your 1px borders don't break your alignment anymore

then same issue with your anchors in the list items, change the box model and correct the width

li a {
      box-sizing: border-box;
      width: 100%; //the whole width of the parent li

now that's your padding which  are no longer a problem

you can now delete the width in li a:hover

width: 83%

everything should be fine

jsfiddle


问:
String to bytes to Big Int conversion VICE VERSA error
im trying to convert a hash to a big integer so i can do some calculations with it. Im successful in that but on the other side i need to be able to convert the big integer back to the hash to do verification. But i cant do the conversion back succesfully, below is my code and the output. Please do advise and assist..

This is the code

```<code>//convert hash to bytes then to big int to mod pow
BigInteger hashy = new
BigInteger(hash.getBytes(StandardCharsets.ISO_8859_1));
System.out.println("hashy: " +hashy);
//test if convert back to big int works
String convertedBackHash = (hashy.toByteArray()).toString();
System.out.println("hash to hashy to hash: " + convertedBackHash);
</code>```

This is the output

```<code>hash: d1bb961ac85f6d9ae66b469b5cabe83f9f88e4ee
hashy: 835979497806227327262557895525398820611883198135120938003873334575862278693562754177889725605221
hash to hashy to hash: [B@60e53b93
</code>```

Anyone knows what went wrong?

答:
For cryptographic functions you generally need to convert the byte array (the hash) to a positive integer and back. This can be done by thinking of the byte array as a constant sized, unsigned, big endian integer.

PKCS#1 specifies this for RSA calculations, for instance, where OS2IP (octet string to integer primitive) converts from a byte array to an integer and I2OSP (integer to octet string primitive) converts back from the integer to an octet string. An octet string is nothing more than a byte array. Neither is particularly tricky to implement, but the fact that Java hasn't got the function build in (hint!) and that Java cannot resize arrays makes I2OSP more tricky than you might expect. Fortunately I already supplied the answer here - it took me some time to find it again.

Now your input hash seems to be hex encoded. This is not what you would want to turn into an integer. You want to turn the bytes represented by the byte array into an integer. So you first need to hex decode the bytes. There are plenty of libraries that implement hex encoding and there are answers here on Stackoverflow as well. Conversely, after I2OSP you want to encode the bytes back to hexadecimals if you want to view them. This way you only have to deal with an integer of half the size as well.

So BigInteger i = os2ip(Hex.decode(hashString)), then do stuff with i and when you've got it back again, String hashString = Hex.encodeToString(i2osp(i)).

Body:
im trying to convert a hash to a big integer so i can do some calculations with it. Im successful in that but on the other side i need to be able to convert the big integer back to the hash to do verification. But i cant do the conversion back succesfully, below is my code and the output. Please do advise and assist..

This is the code

//convert hash to bytes then to big int to mod pow
BigInteger hashy = new
BigInteger(hash.getBytes(StandardCharsets.ISO_8859_1));
System.out.println("hashy: " +hashy);
//test if convert back to big int works
String convertedBackHash = (hashy.toByteArray()).toString();
System.out.println("hash to hashy to hash: " + convertedBackHash);

This is the output

hash: d1bb961ac85f6d9ae66b469b5cabe83f9f88e4ee
hashy: 835979497806227327262557895525398820611883198135120938003873334575862278693562754177889725605221
hash to hashy to hash: [B@60e53b93

Anyone knows what went wrong?


问:
JFree Chart with itext problem with font
I want to use Jfree chart with itext to make a pdf. I have used custom font for JFree chart title and its other components using java.awt.Font class. It works ok in windows but on linux centOS, the title is overlapping with upper line and so do other things. Need help. </p>

<p>Thanks  </p>

答: Found the answer. It's because the two platforms are using different version of java. On Windows its java (SE) 1.6 and on linux I was using openjdk. By making both java SE, problem's solved.</p>

ContentLicense: CC BY-SA 2.5

Body:
I want to use Jfree chart with itext to make a pdf. I have used custom font for JFree chart title and its other components using java.awt.Font class. It works ok in windows but on linux centOS, the title is overlapping with upper line and so do other things. Need help.

Thanks


问:
No value when document isn't found in VBA excel
right now I have code that works to get information from different workbooks into one master excel. However, when the document is not found it gives a #NAME error which is affecting a table that I need to present that data. I was trying to write if statements to fix this but have not been successful, I also tried to not make it by cell name but just the cell itself but got a #VALUE error. Is there a way to make that value blank if the document is not found?
Thanks for the help.
This is the code I have: </p>

```<code>Sub ROI()

 Dim JobNumber As String
 Dim srcCell As String

 Dim id As Integer

   For id = 4 To 156
       srcCell = "C" & id

       JobNumber = Range(srcCell).Value

       Range("D" & id).Value = "='Y:\Public\QA Other\Scorecards\Scorecard " & JobNumber & ".xlsm'!Total"
   Next

End Sub
</code>```

答:
Do this:</p>

```<code>Range("D" & id).Value = "=IFERROR('Y:\Public\QA Other\Scorecards\Scorecard " & JobNumber & ".xlsm'!Total, '')"
</code>```

Body:
right now I have code that works to get information from different workbooks into one master excel. However, when the document is not found it gives a #NAME error which is affecting a table that I need to present that data. I was trying to write if statements to fix this but have not been successful, I also tried to not make it by cell name but just the cell itself but got a #VALUE error. Is there a way to make that value blank if the document is not found?
Thanks for the help.
This is the code I have:

Sub ROI()

 Dim JobNumber As String
 Dim srcCell As String

 Dim id As Integer

   For id = 4 To 156
       srcCell = "C" & id

       JobNumber = Range(srcCell).Value

       Range("D" & id).Value = "='Y:\Public\QA Other\Scorecards\Scorecard " & JobNumber & ".xlsm'!Total"
   Next

End Sub

Body:
Do this:

Range("D" & id).Value = "=IFERROR('Y:\Public\QA Other\Scorecards\Scorecard " & JobNumber & ".xlsm'!Total, '')"


问:
I can't understand the JWT Authentication well
Nowadays many developers use the JWT Authentication to authorize the api call.
By the way, if a hacker can capture the api call request of the authenticated user then he can have the authenticated JWT token.
Then the hacker can access this api with the authorized JWT token, without his authenticating.
Is this alright?
I am wondering that the JWT Authentication is actually safe.
Can you explain that?</p>

答:
JWT is just a secure msg transporter between fsb server and client so that fsb server can determine whether the client is logged in or not; if logged in, the fsb server will fetch personal unique user based data.

google oauth

G sends back user gid to my server only if user has a google account and successfully inputs gmail and password correctly.

user id is saved in jwt’s payload.

jwt

if google validates the user and google returns gid

create jwt content and internal maintenance: exp date, encryption

jwt is sent and stored in local store of user’s browser;

each user’s req sends jwt back to my server

my server decodes the jwt using secretOrKey, which only my server has, and gets the content(uid) from the jwt.

if uid is in my db, user had already registered and right now is logged in.

send the requested data from my db to the user because he is logged in

if use fails google validation due to wrong password or G email, jwt isn't created.

Process of JWT

user’s google popup logs in

google server returns information to my server. If the gid isn’t in my db, I’ll save it in my db so that the user can be registered.

create jwt and add uid as content. Exp date.

jwt is sent and stored in local storage of users browser

user requests a page though http, it includes the jwt. my server checks whether this user is logged in or not by Login determination test: if user’s jwt uid is in my DB, user is logged in. the user requested data will be given to the user. If user doesn’t have jwt or uid doesn’t match then the user isn't logged in, send the user to login page.

JWT descriptions

https://medium.com/@rahulgolwalkar/pros-and-cons-in-using-jwt-json-web-tokens-196ac6d41fb4

https://scotch.io/tutorials/the-ins-and-outs-of-token-based-authentication

https://scotch.io/tutorials/the-anatomy-of-a-json-web-token

https://auth0.com/blog/cookies-vs-tokens-definitive-guide/


问:
Compare two hashmaps by keys and return keys which do not have same frequencies
I would like to sort two HashMaps by keys and compare their values and print out all the keys which do not have same value. Could you help me how to do this. Here is my code as below. I am new to Java and learning data structures one by one. Thanks for the help.

Code :-

```<code>import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int val;

        int n = scan.nextInt();
        HashMap<Integer,Integer> h1 = new HashMap<Integer,Integer>();

        for( int i=0;i<n;i++ ) {
             val = scan.nextInt();
             if(!h1.containsKey(val)) {
                 h1.put(val,1);
             }
            else {
                h1.put(val,h1.get(val)+1);
            }
         }

        int m = scan.nextInt();

        HashMap<Integer,Integer> h2 = new HashMap<Integer,Integer>();

         for( int i=0;i<m;i++ ) {
             val = scan.nextInt();
             if(!h2.containsKey(val)) {
                 h2.put(val,1);
             }
            else {
                h2.put(val,h2.get(val)+1);
            }
         }

        System.out.println(h1.keySet());
        System.out.println(h1.values());
        System.out.println(h2.keySet());
        System.out.println(h2.values());

        }
}
</code>```

答:
One way would be to merge h1 and h2 entries by subtracting their values into a new TreeMap, which sorts entries by key. Then, we could remove the entries with values equal to zero:

```<code>Map<Integer, Integer> merged = new TreeMap<>(h1); // Copy h1 into merged

h2.forEach((k2, v2) -> merged.merge(k2, v2, (oldVal, newVal) -> oldVal - newVal));

merged.values().removeIf(v -> v.equals(0));
</code>```

To print the keys, you could simply print the map's keyset:

```<code>System.out.println(merged.keySet());
</code>```

Or iterate its keys and print them one by one:

```<code>merged.keySet().forEach(System.out::println);
</code>```

Body:
I would like to sort two HashMaps by keys and compare their values and print out all the keys which do not have same value. Could you help me how to do this. Here is my code as below. I am new to Java and learning data structures one by one. Thanks for the help.

Code :-

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int val;

        int n = scan.nextInt();
        HashMap<Integer,Integer> h1 = new HashMap<Integer,Integer>();

        for( int i=0;i<n;i++ ) {
             val = scan.nextInt();
             if(!h1.containsKey(val)) {
                 h1.put(val,1);
             }
            else {
                h1.put(val,h1.get(val)+1);
            }
         }

        int m = scan.nextInt();

        HashMap<Integer,Integer> h2 = new HashMap<Integer,Integer>();

         for( int i=0;i<m;i++ ) {
             val = scan.nextInt();
             if(!h2.containsKey(val)) {
                 h2.put(val,1);
             }
            else {
                h2.put(val,h2.get(val)+1);
            }
         }

        System.out.println(h1.keySet());
        System.out.println(h1.values());
        System.out.println(h2.keySet());
        System.out.println(h2.values());

        }
}

Body:
One way would be to merge h1 and h2 entries by subtracting their values into a new TreeMap, which sorts entries by key. Then, we could remove the entries with values equal to zero:

Map<Integer, Integer> merged = new TreeMap<>(h1); // Copy h1 into merged

h2.forEach((k2, v2) -> merged.merge(k2, v2, (oldVal, newVal) -> oldVal - newVal));

merged.values().removeIf(v -> v.equals(0));

To print the keys, you could simply print the map's keyset:

System.out.println(merged.keySet());

Or iterate its keys and print them one by one:

merged.keySet().forEach(System.out::println);


问:
Possible to programatically change IIS's SMTP server "Smart Host"
I recently discovered a way to audit SMTP emails prior to them actually leaving the SMTP server.  This is accomplished by changing the "Smart Host" value to something that is

Named a host that doesn't exist

Less than 15 characters

Has no periods in the name

This allows me to view the messages with Outlook Express, check the file attachments, and other programatically generated content through System.Net.Mail

I release the messages by changing this to a valid value and restarting the SMTP service.

Question

How can I programatically change this value so I can allow for the controlled queueing, audit, and release of these email messages?

答:
Ouch!  One method might be to just create a program that directly edits the Metabase, and then restarts SMTPSVC.  I'm sure there's a way with WMI, but I don't know offhand.

By the way, you might be able to go in the "other" direction by editing your app.config/web.config to drop the files in a folder of your choice:

http://msdn.microsoft.com/en-us/library/ms164241.aspx

After you inspect the emails, you can move them to IIS's queue.


问:
How does GetValueOrDefault work?
I'm responsible for a LINQ provider which performs some runtime evaluation of C# code. As an example:

```<code>int? thing = null;
accessor.Product.Where(p => p.anInt == thing.GetValueOrDefault(-1))
</code>```

Currently the above code doesn't work with my LINQ provider due to thing being null.

While I've been working with C# for a long time, I don't know how GetValueOrDefault is implemented and therefore how I should resolve this.

So my question is: how does GetValueOrDefault work in the case that the instance on which it is called is null? Why isn't a NullReferenceException thrown?

A follow on question: how should I go about replicating a call to GetValueOrDefault using reflection, given that I need to handle null values.

答:
I think you provider was not working correctly. I've made a simple test and it worked correctly.

```<code>using System;
using System.Linq;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var products = new Product[] {
                new Product(){ Name = "Product 1", Quantity = 1 },
                new Product(){ Name = "Product 2", Quantity = 2 },
                new Product(){ Name = "Product -1", Quantity = -1 },
                new Product(){ Name = "Product 3", Quantity = 3 },
                new Product(){ Name = "Product 4", Quantity = 4 }
            };

            int? myInt = null;

            foreach (var prod in products.Where(p => p.Quantity == myInt.GetValueOrDefault(-1)))
            {
                Console.WriteLine($"{prod.Name} - {prod.Quantity}");
            }

            Console.ReadKey();
        }
    }

    public class Product
    {
        public string Name { get; set; }
        public int Quantity { get; set; }
    }
}
</code>```

It produces as output: Product -1 - -1

Title: How does GetValueOrDefault work?

Body:
I'm responsible for a LINQ provider which performs some runtime evaluation of C# code. As an example:

int? thing = null;
accessor.Product.Where(p => p.anInt == thing.GetValueOrDefault(-1))

Currently the above code doesn't work with my LINQ provider due to thing being null.

While I've been working with C# for a long time, I don't know how GetValueOrDefault is implemented and therefore how I should resolve this.

So my question is: how does GetValueOrDefault work in the case that the instance on which it is called is null? Why isn't a NullReferenceException thrown?

A follow on question: how should I go about replicating a call to GetValueOrDefault using reflection, given that I need to handle null values.

Body:
I think you provider was not working correctly. I've made a simple test and it worked correctly.

using System;
using System.Linq;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var products = new Product[] {
                new Product(){ Name = "Product 1", Quantity = 1 },
                new Product(){ Name = "Product 2", Quantity = 2 },
                new Product(){ Name = "Product -1", Quantity = -1 },
                new Product(){ Name = "Product 3", Quantity = 3 },
                new Product(){ Name = "Product 4", Quantity = 4 }
            };

            int? myInt = null;

            foreach (var prod in products.Where(p => p.Quantity == myInt.GetValueOrDefault(-1)))
            {
                Console.WriteLine($"{prod.Name} - {prod.Quantity}");
            }

            Console.ReadKey();
        }
    }

    public class Product
    {
        public string Name { get; set; }
        public int Quantity { get; set; }
    }
}

It produces as output: Product -1 - -1


问:
Talend open studio - How to rename existing project
I have this already existing Talend Open Studio project that I simply wish to rename from "testProject1" for example, to "Project1".

Can someone provide simple step by step please as for some forums talk about IMPORTING AN EXISTING PROJECT AND SIMPLY PROVIDE A NEW NAME and then CLICK ON THE BROWSE BUTTON BUT POINT to the already existing project name (testProject1).

Does anyone know if this will work ? Do we need to then copy/paste some folders here and there or no need ? Anyone knows another way to rename an already existing project name?

答:
I would suggest that create a new project with whatever name you have and import all the jobs from the previous project. Previous project's folder will be in workspace folder or whatever path you have set for the workspace.

Alternate solution is given in the following link :
https://www.talendforge.org/forum/viewtopic.php?id=41577

Google well before posting a question.


问:
MATLAB is rounding my values to 1
```<code>n = 215;
N = 215.01:0.1:250;
p = 0.52;
q = 0.48;
Gamblers = (1 - (q/p)^n)./(1 - (q/p).^N);
plot(Gamblers)
</code>```

Matlab takes the numerators and denominators as simply 1, filling the array with nothing but that value. How can I correct this?

答:
Your denominator and numerator are very close to 1 but not exactly 1. The plot(Gamblers) confirms this.

By default MATLAB will display numbers with four digits after the decimal place. Your numerator is 0.999999966414861, which with four digits rounds to 1. MATLAB uses double precision numbers so your calculation here is still accurate.

Try double clicking on the Gamblers variable to open the variables window and then double clicking on one of the results. You'll see it change from the default display precision to a much more accurate depiction of your variable.

Title: MATLAB is rounding my values to 1

Body:
n = 215;
N = 215.01:0.1:250;
p = 0.52;
q = 0.48;
Gamblers = (1 - (q/p)^n)./(1 - (q/p).^N);
plot(Gamblers)

Matlab takes the numerators and denominators as simply 1, filling the array with nothing but that value. How can I correct this?


问:
Setting up context java:comp/env in Jetty running inside GWT 2.7
Contents of jetty-web.xml  in /WEB-INF:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Array id="plusConfig" type="java.lang.String">
    <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
    <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
    <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
  </Array>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.initial</Arg>
    <Arg><Property name="java.naming.factory.initial" default="org.eclipse.jetty.jndi.InitialContextFactory"/></Arg>
  </Call>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.url.pkgs</Arg>
    <Arg><Property name="java.naming.factory.url.pkgs" default="org.eclipse.jetty.jndi"/></Arg>
  </Call>
</Configure>
```

<p>Contents of jetty-plus.xml  in /WEB-INF:</p>

<pre class="lang-xml prettyprint-override"><code><Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add plus Configuring classes to all webapps for this Server -->
<!-- =========================================================== -->
  <Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
    <Arg><Ref refid="Server" /></Arg>
    <Call name="addAfter">
      <Arg name="afterClass">org.eclipse.jetty.webapp.FragmentConfiguration</Arg>
      <Arg>
        <Array type="String">
        <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
        <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
      </Array>
    </Arg>
  </Call>
</Call>
</Configure>
</code>```

This is my calling code in Servlet's init() method:

Context _initCtx = new InitialContext();
Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");
```

<p>Error it throws:</p>

<pre class="lang-none prettyprint-override"><code>javax.naming.NameNotFoundException; remaining name 'env'
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:449)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:551)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:117)
at javax.naming.InitialContext.lookup(Unknown Source)
</code>```

I'm running vanilla GWT 2.7 and I'm trying to use JNDI lookup in my server code.
I have also attached jetty-all-8.1.9.v20130131.jar and jetty-plus-8.1.9.v20130131.jar to the project since some of Context and JNDI classes are missing in GWT jars.  I tried to verify the version of jetty in GWT, and I got this:

Server server = new Server(7070);
System.out.println(server.getVersion());

8.y.z-SNAPSHOT
```

<p>I saw solution where you can configure JNDI other ways, however since I'm running in GWT, I can only work with the jetty-web.xml and jetty-plus.xml files.</p>

<p>When debugging the servlet, I'm getting context for: </p>

<pre class="lang-java prettyprint-override"><code>Context _envCtx  = (Context) _initCtx.lookup("java:comp");
</code>```

But not for:

Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");
```

<p>Stacktrace is above.</p>

<p>I'm really stuck here.  Any jetty gurus out there?</p>

<hr>

<h2>Edit 1:</h2>

<p>Added jetty-env.xml :</p>

<pre class="lang-xml prettyprint-override"><code><?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id='portal' class="org.eclipse.jetty.webapp.WebAppContext">
  <New id="DStest" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg></Arg>
  <Arg>jdbc/DSTest</Arg>
  <Arg>
    <New class="org.hsqldb.jdbcDriver">
      <Set name="Url">jdbc:hsqldb:hsql://localhost</Set>
      <Set name="User">sa</Set>
      <Set name="Password"></Set>
    </New>
  </Arg>
</New>
</Configure>
</code>```

And this to my web.xml:

<resource-ref>
  <description>Primary database</description>
  <res-ref-name>jdbc/DSTest</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>
```

<p>Still _envCtx is null with the exception below.  _initCtx.lookup("java:comp") does return org.eclipse.jetty.jndi.NamingContext instance.</p>

<pre class="lang-java prettyprint-override"><code>Context           _initCtx          = new InitialContext();
Context           _envCtx           = (Context) _initCtx.lookup("java:comp/env");
</code>```

results in

javax.naming.NameNotFoundException; remaining name 'env'
```

<hr>

<h2>Edit 2:</h2>

<p>I must be missing something else (basic)....??!?
I changed that 1 line in jetty-env.xml to:</p>

```<Arg><Ref refid="portal"/>jdbc/DSTest</Arg>
```

<p>And the doctype:</p>

```<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
```

I could not find more appropriate .dtd  for v8.X
Still same problem.

答:
Thanks for the question and the answer by Thomas.  I had a very similar situation.   It was very hard to get the right combination of configuration, but I finally got it to work.  I guess I may as well document my findings here.

I was doing this to set up GWT 2.6, which uses Jetty 8.1.12v20130726.  My
goal was to set up JNDI for a DBCP2 connection pool.  I am running
GWT in Eclipse in DevMode

WEB-INF/jetty-web.xml

I am using the JVM scope but set the values inside a WebAppContext

Note also that the name that is used is java:comp/env/jdbc/datalakeDbcp2 (that is, with the prefix java:comp/env/)

```<code><?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext">

    <New id="datalakeDsDbcp2" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>                                 <!-- scope -->
        <Arg>java:comp/env/jdbc/datalakeDbcp2</Arg> <!-- name  -->
        <Arg>                                       <!-- value -->
            <New class="org.apache.commons.dbcp2.BasicDataSource">
                <Set name="driverClassName">org.apache.hive.jdbc.HiveDriver</Set>
                <Set name="url">jdbc:hive2://someServer:somePort/someDb</Set>
                <Set name="username"></Set>
                <Set name="password"></Set>
            </New>
        </Arg>
    </New>

</Configure>
</code>```

JettyLauncher.java

Copied a JettyLauncher.java from here to your own working
directory (under the path of src/com/google/gwt/dev/shell/jetty/ naturally)

There is only one local modification needed.

bootStrapOnlyClassLoader

```<code>/*
 * Change suggested by:
 * https://groups.google.com/forum/#!topic/google-web-toolkit/SBFltI27ssk
 */
private final ClassLoader bootStrapOnlyClassLoader
    = Thread.currentThread().getContextClassLoader();
//    private final ClassLoader bootStrapOnlyClassLoader = new ClassLoader(null) {
//    };
</code>```

No need to change WebAppClassLoaderExtension -- just use it
as the original code:

```<code>private class WebAppClassLoaderExtension extends WebAppClassLoader {

  private static final String META_INF_SERVICES = "META-INF/services/";

  public WebAppClassLoaderExtension() throws IOException {
    super(bootStrapOnlyClassLoader, WebAppContextWithReload.this);
  }
</code>```

pom.xml

```<code><dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-jndi</artifactId>
    <version>8.1.12.v20130726</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-plus</artifactId>
    <version>8.1.12.v20130726</version>
    <scope>provided</scope>
</dependency>
</code>```

VM arguments (in Eclipse)

```<code>-Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory
</code>```

WEB-INF/web.xml

Perhaps because I am using the VM scope in my jetty-web.xml, I did
not need to change my web.xml

Program code to obtain a JNDI named connection

```<code>try {
   InitialContext ic = new InitialContext();
   DataSource ds
       = (DataSource) ic.lookup("java:/comp/env/jdbc/datalakeDbcp2");
   conn = ds.getConnection();
} catch (NamingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw new RuntimeException(e);
};
</code>```

References

The code use Jetty v8.1.12.v20130726 but I could not find the matching
documentation, so I have been using the doc for 'Jetty 9.3.x'.  It
seems still applicable:

Chapter 12

Chapter 4

Chapter 3

GWT Issue 8507 here

Body:
Contents of jetty-web.xml  in /WEB-INF:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Array id="plusConfig" type="java.lang.String">
    <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
    <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
    <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
  </Array>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.initial</Arg>
    <Arg><Property name="java.naming.factory.initial" default="org.eclipse.jetty.jndi.InitialContextFactory"/></Arg>
  </Call>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.url.pkgs</Arg>
    <Arg><Property name="java.naming.factory.url.pkgs" default="org.eclipse.jetty.jndi"/></Arg>
  </Call>
</Configure>

Contents of jetty-plus.xml  in /WEB-INF:

<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
    <Arg><Ref refid="Server" /></Arg>
    <Call name="addAfter">
      <Arg name="afterClass">org.eclipse.jetty.webapp.FragmentConfiguration</Arg>
      <Arg>
        <Array type="String">
        <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
        <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
      </Array>
    </Arg>
  </Call>
</Call>
</Configure>

This is my calling code in Servlet's init() method:

Context _initCtx = new InitialContext();
Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");

Error it throws:

javax.naming.NameNotFoundException; remaining name 'env'
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:449)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:551)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:117)
at javax.naming.InitialContext.lookup(Unknown Source)

I'm running vanilla GWT 2.7 and I'm trying to use JNDI lookup in my server code.
I have also attached jetty-all-8.1.9.v20130131.jar and jetty-plus-8.1.9.v20130131.jar to the project since some of Context and JNDI classes are missing in GWT jars.  I tried to verify the version of jetty in GWT, and I got this:

Server server = new Server(7070);
System.out.println(server.getVersion());

8.y.z-SNAPSHOT

I saw solution where you can configure JNDI other ways, however since I'm running in GWT, I can only work with the jetty-web.xml and jetty-plus.xml files.

When debugging the servlet, I'm getting context for:

Context _envCtx  = (Context) _initCtx.lookup("java:comp");

But not for:

Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");

Stacktrace is above.

I'm really stuck here.  Any jetty gurus out there?

Edit 1:

Added jetty-env.xml :

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id='portal' class="org.eclipse.jetty.webapp.WebAppContext">
  <New id="DStest" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg></Arg>
  <Arg>jdbc/DSTest</Arg>
  <Arg>
    <New class="org.hsqldb.jdbcDriver">
      <Set name="Url">jdbc:hsqldb:hsql://localhost</Set>
      <Set name="User">sa</Set>
      <Set name="Password"></Set>
    </New>
  </Arg>
</New>
</Configure>

And this to my web.xml:

<resource-ref>
  <description>Primary database</description>
  <res-ref-name>jdbc/DSTest</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

Still _envCtx is null with the exception below.  _initCtx.lookup("java:comp") does return org.eclipse.jetty.jndi.NamingContext instance.

Context           _initCtx          = new InitialContext();
Context           _envCtx           = (Context) _initCtx.lookup("java:comp/env");

results in

javax.naming.NameNotFoundException; remaining name 'env'

Edit 2:

I must be missing something else (basic)....??!?
I changed that 1 line in jetty-env.xml to:

<Arg><Ref refid="portal"/>jdbc/DSTest</Arg>

And the doctype:

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

I could not find more appropriate .dtd  for v8.X
Still same problem.

Body:
Thanks for the question and the answer by Thomas.  I had a very similar situation.   It was very hard to get the right combination of configuration, but I finally got it to work.  I guess I may as well document my findings here.

I was doing this to set up GWT 2.6, which uses Jetty 8.1.12v20130726.  My
goal was to set up JNDI for a DBCP2 connection pool.  I am running
GWT in Eclipse in DevMode

WEB-INF/jetty-web.xml

I am using the JVM scope but set the values inside a WebAppContext

Note also that the name that is used is java:comp/env/jdbc/datalakeDbcp2 (that is, with the prefix java:comp/env/)

<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext">

    <New id="datalakeDsDbcp2" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>                                 <!-- scope -->
        <Arg>java:comp/env/jdbc/datalakeDbcp2</Arg> <!-- name  -->
        <Arg>                                       <!-- value -->
            <New class="org.apache.commons.dbcp2.BasicDataSource">
                <Set name="driverClassName">org.apache.hive.jdbc.HiveDriver</Set>
                <Set name="url">jdbc:hive2://someServer:somePort/someDb</Set>
                <Set name="username"></Set>
                <Set name="password"></Set>
            </New>
        </Arg>
    </New>

</Configure>

JettyLauncher.java

Copied a JettyLauncher.java from here to your own working
directory (under the path of src/com/google/gwt/dev/shell/jetty/ naturally)

There is only one local modification needed.

bootStrapOnlyClassLoader

/*
 * Change suggested by:
 * https://groups.google.com/forum/#!topic/google-web-toolkit/SBFltI27ssk
 */
private final ClassLoader bootStrapOnlyClassLoader
    = Thread.currentThread().getContextClassLoader();
//    private final ClassLoader bootStrapOnlyClassLoader = new ClassLoader(null) {
//    };

No need to change WebAppClassLoaderExtension -- just use it
as the original code:

private class WebAppClassLoaderExtension extends WebAppClassLoader {

  private static final String META_INF_SERVICES = "META-INF/services/";

  public WebAppClassLoaderExtension() throws IOException {
    super(bootStrapOnlyClassLoader, WebAppContextWithReload.this);
  }

pom.xml

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-jndi</artifactId>
    <version>8.1.12.v20130726</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-plus</artifactId>
    <version>8.1.12.v20130726</version>
    <scope>provided</scope>
</dependency>

VM arguments (in Eclipse)

-Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory

WEB-INF/web.xml

Perhaps because I am using the VM scope in my jetty-web.xml, I did
not need to change my web.xml

Program code to obtain a JNDI named connection

try {
   InitialContext ic = new InitialContext();
   DataSource ds
       = (DataSource) ic.lookup("java:/comp/env/jdbc/datalakeDbcp2");
   conn = ds.getConnection();
} catch (NamingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw new RuntimeException(e);
};

References

The code use Jetty v8.1.12.v20130726 but I could not find the matching
documentation, so I have been using the doc for 'Jetty 9.3.x'.  It
seems still applicable:

Chapter 12

Chapter 4

Chapter 3

GWT Issue 8507 here


问:
Can I grant access to objects owned by another account in AWS S3 using bucket policies?
I want to control access to an object, which is created by another AWS account. Can I do that by bucket policies?
In other words, does bucket policies apply to objects that are owned by another account?

I do not have 2 AWS accounts so I can not test this case in action.

答:
No.

The ability to grant access to objects can only be done from the Account that owns the bucket/object.

If you think about it, this makes sense -- you would not want me granting access to your objects. Only the account that owns the bucket/object can do this.


问:
perror with exit value macro
In my last application I have a lot of error checking lines like:

```<code>if (something != 0) {
    perror("something error");
    exit(-1);
}
</code>```

My question is, how to create a macro to make it one-liner like:

```<code>if (something != 0)
    PR("something error", -1);
</code>```

答:
I think there are better ways to deal with it.

A) perror() and exit()

The first thing to keep in mind is that perror() uses the errno variable to print a message. So, in your simple case, if errno is not set, perror() will add a : Success\n at the end of your string, and that may be confusing, depending on what your message is. One way to solve that is:

```<code>#include <errno.h>
#define PR(s, e) {errno=(e); perror((s)); exit((e)); }
</code>```

then

```<code>if(something != 0)
  PR("some error msg", 1);
</code>```

Note: a positive 1 instead a -1 as error code. More about that bellow.

B) error()

A better way is to use the error() message. It has all you want, no macros needed:

```<code>#include <error.h>
</code>```

and

```<code>if(something != 0)
  error(1, YOURERRORCODE, "some error msg");
</code>```

Definition of the error(arg1, arg2, arg3, ...) function:

arg1: if 0, the program will not exit. Any other value causes an exit with that value (up to 255).

arg2: the error code. See bellow.

arg3: a string with your custom message. It can be formatted like a printf() message, and then it uses arg4, ...

Caution:

exit code range: The error code to exit(e) should be in the range [0, 255] only. Usually, 0 for success, and 1 to 255 to indicate an error code. But mind you, the shell will module the number if it is above 255, meaning that if you try exit(256) or exit(512) you will get the code 0 (for success), or for example exit(257) gives you error code 1, and so on.

error messages: take a look at all the error messages and do not use magic numbers, instead use the correct error code to set errno.

Error code messages bellow. The values are not POSIX defined. It is recommended to use only the MACROS.

```<code>#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of function */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Invalid system call number */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */

#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */

#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED 125 /* Operation Canceled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */
#define EOWNERDEAD 130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */
#define ERFKILL 132 /* Operation not possible due to RF-kill */
#define EHWPOISON 133 /* Memory page has hardware error */

#define EWOULDBLOCK EAGAIN /* 11/41 Try again / Operation would block */
#define EDEADLOCK EDEADLK /* 35/58 Resource/File deadlock error */
#define ENOTSUP EOPNOTSUPP /* 95 Operation not supported on transport endpoint */

"Unknown errors": 41, 58, 134-255
</code>```

In some older systems, instead of an alias, those error codes would be:

```<code>#define EWOULDBLOCK 41 /* Operation would block */
#define EDEADLOCK 58 /* File locking deadlock error */
</code>```

But ENOTSUP is just an alias.

A draft for the above list can be generated by your own machine with the bash command:

```<code>$ find /usr/include/ -name "errno*.h" -exec grep -HIe "define\s*E" {} \; | cut -d"#" -f2 | tr "\t" " " | tr -s " " | sed 's/^ //' | sed 's/^/#/' | sort -nk3 > errorcodes.txt
</code>```

Files (Debian Stretch 9):

```<code>$ find /usr/include/ -name "errno*.h"
/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h
/usr/include/errno.h
/usr/include/linux/errno.h
/usr/include/x86_64-linux-gnu/bits/errno.h
/usr/include/x86_64-linux-gnu/sys/errno.h
/usr/include/x86_64-linux-gnu/asm/errno.h
/usr/include/sys/errno.h
</code>```

References:

https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html

https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html#index-ENOBUFS-117

http://www.virtsync.com/c-error-codes-include-errno

Default value of errno variable

PS. The answer above is OK, but I would prefer to use error instead. Always try to use what is already done in standard libraries. Avoid reinvent the wheel.

Title: perror with exit value macro

Body:
In my last application I have a lot of error checking lines like:

if (something != 0) {
    perror("something error");
    exit(-1);
}

My question is, how to create a macro to make it one-liner like:

if (something != 0)
    PR("something error", -1);

Body:
I think there are better ways to deal with it.

A) perror() and exit()

The first thing to keep in mind is that perror() uses the errno variable to print a message. So, in your simple case, if errno is not set, perror() will add a : Success\n at the end of your string, and that may be confusing, depending on what your message is. One way to solve that is:

#include <errno.h>
#define PR(s, e) {errno=(e); perror((s)); exit((e)); }

then

if(something != 0)
  PR("some error msg", 1);

Note: a positive 1 instead a -1 as error code. More about that bellow.

B) error()

A better way is to use the error() message. It has all you want, no macros needed:

#include <error.h>

and

if(something != 0)
  error(1, YOURERRORCODE, "some error msg");

Definition of the error(arg1, arg2, arg3, ...) function:

arg1: if 0, the program will not exit. Any other value causes an exit with that value (up to 255).

arg2: the error code. See bellow.

arg3: a string with your custom message. It can be formatted like a printf() message, and then it uses arg4, ...

Caution:

exit code range: The error code to exit(e) should be in the range [0, 255] only. Usually, 0 for success, and 1 to 255 to indicate an error code. But mind you, the shell will module the number if it is above 255, meaning that if you try exit(256) or exit(512) you will get the code 0 (for success), or for example exit(257) gives you error code 1, and so on.

error messages: take a look at all the error messages and do not use magic numbers, instead use the correct error code to set errno.

Error code messages bellow. The values are not POSIX defined. It is recommended to use only the MACROS.

#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of function */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Invalid system call number */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */

#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */

#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED 125 /* Operation Canceled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */
#define EOWNERDEAD 130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */
#define ERFKILL 132 /* Operation not possible due to RF-kill */
#define EHWPOISON 133 /* Memory page has hardware error */

#define EWOULDBLOCK EAGAIN /* 11/41 Try again / Operation would block */
#define EDEADLOCK EDEADLK /* 35/58 Resource/File deadlock error */
#define ENOTSUP EOPNOTSUPP /* 95 Operation not supported on transport endpoint */

"Unknown errors": 41, 58, 134-255

In some older systems, instead of an alias, those error codes would be:

#define EWOULDBLOCK 41 /* Operation would block */
#define EDEADLOCK 58 /* File locking deadlock error */

But ENOTSUP is just an alias.

A draft for the above list can be generated by your own machine with the bash command:

$ find /usr/include/ -name "errno*.h" -exec grep -HIe "define\s*E" {} \; | cut -d"#" -f2 | tr "\t" " " | tr -s " " | sed 's/^ //' | sed 's/^/#/' | sort -nk3 > errorcodes.txt

Files (Debian Stretch 9):

$ find /usr/include/ -name "errno*.h"
/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h
/usr/include/errno.h
/usr/include/linux/errno.h
/usr/include/x86_64-linux-gnu/bits/errno.h
/usr/include/x86_64-linux-gnu/sys/errno.h
/usr/include/x86_64-linux-gnu/asm/errno.h
/usr/include/sys/errno.h

References:

https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html

https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html#index-ENOBUFS-117

http://www.virtsync.com/c-error-codes-include-errno

Default value of errno variable

PS. The answer above is OK, but I would prefer to use error instead. Always try to use what is already done in standard libraries. Avoid reinvent the wheel.