问:
Communicate "out" from Chromium via DevTools protocol
I have a page running in a headless Chromium instance, and I'm manipulating it via the DevTools protocol, using the Puppeteer NPM package in Node.

I'm injecting a script into the page. At some point, I want the script to call me back and send me some information (via some event exposed by the DevTools protocol or some other means).

What is the best way to do this? It'd be great if it can be done using Puppeteer, but I'm not against getting my hands dirty and listening for protocol messages by hand.

I know I can sort-of do this by manipulating the DOM and listening to DOM changes, but that doesn't sound like a good idea.

答:
If the script sends all its data back in one call, the simplest approach would be to use page.evaluate and return a Promise from it:

```<code>const dataBack = page.evaluate(`new Promise((resolve, reject) => {
  setTimeout(() => resolve('some data'), 1000)
})`)
dataBack.then(value => { console.log('got data back', value) })
</code>```

This could be generalized to sending data back twice, etc. For sending back an arbitrary stream of events, perhaps console.log would be slightly less of a hack than DOM events? At least it's super-easy to do with Puppeteer:

```<code>page.on('console', message => {
  if (message.text.startsWith('dataFromMyScript')) {
    message.args[1].jsonValue().then(value => console.log('got data back', value))
  }
})
page.evaluate(`setInterval(() => console.log('dataFromMyScript', {ts: Date.now()}), 1000)`)
</code>```

(The example uses a magic prefix to distinguish these log messages from all others.)

Body:
If the script sends all its data back in one call, the simplest approach would be to use page.evaluate and return a Promise from it:

const dataBack = page.evaluate(`new Promise((resolve, reject) => {
  setTimeout(() => resolve('some data'), 1000)
})`)
dataBack.then(value => { console.log('got data back', value) })

This could be generalized to sending data back twice, etc. For sending back an arbitrary stream of events, perhaps console.log would be slightly less of a hack than DOM events? At least it's super-easy to do with Puppeteer:

page.on('console', message => {
  if (message.text.startsWith('dataFromMyScript')) {
    message.args[1].jsonValue().then(value => console.log('got data back', value))
  }
})
page.evaluate(`setInterval(() => console.log('dataFromMyScript', {ts: Date.now()}), 1000)`)

(The example uses a magic prefix to distinguish these log messages from all others.)


来源: stackexchange

问:
Strange mixing of system + homebrew Python with LLDB
When I attempt to run the Python interpretter within lldb, I'm seeing:

```<code>$ lldb
(lldb) script
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
    import weakref
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in <module>
    from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
</code>```

When I inspect what version of Python was launched, Python reports that it should be the Homebrew Python (which is symlinked into this location):

```<code>>>> sys.executable
'/usr/local/opt/python/bin/python2.7'
</code>```

However, asking the Python version returns the version associated with the default system Python installation, e.g.

```<code>>>> sys.version_info
sys.version_info(major=2, minor=7, micro=10, releaselevel='final', serial=0)
</code>```

And, just to confirm, the Python version at the binary path above is indeed different (note the difference in the micro version):

```<code>$ /usr/local/opt/python/bin/python2.7 --version
Python 2.7.14

$ /usr/bin/python --version
Python 2.7.10
</code>```

To make things more confusing, the name _remove_dead_weakref does exist in the _weakref module for my Homebrew Python installation, but not the default system installation:

```<code>$ /usr/bin/python -c "import _weakref; print _weakref._remove_dead_weakref"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute '_remove_dead_weakref'

$ /usr/local/opt/python/bin/python2.7 -c "import _weakref; print _weakref._remove_dead_weakref"
<built-in function _remove_dead_weakref>
</code>```

Any idea what could be causing this apparent cross-talk between my Python installations with LLDB? How can I prevent this?

答:
One workaround to this issue is to explicitly launch LLDB with only the system Python installation on the PATH, e.g.

```<code>PATH=/usr/bin /usr/bin/lldb
</code>```

It appears as though LLDB queries the PATH for the 'active' Python installation; if you have a Homebrew installation of Python available on the PATH then you can run into this sort of cross-talk when LLDB attempts to launch Python.

ContentLicense: CC BY-SA 3.0

Body:
When I attempt to run the Python interpretter within lldb, I'm seeing:

$ lldb
(lldb) script
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
    import weakref
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in <module>
    from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.

When I inspect what version of Python was launched, Python reports that it should be the Homebrew Python (which is symlinked into this location):

>>> sys.executable
'/usr/local/opt/python/bin/python2.7'

However, asking the Python version returns the version associated with the default system Python installation, e.g.

>>> sys.version_info
sys.version_info(major=2, minor=7, micro=10, releaselevel='final', serial=0)

And, just to confirm, the Python version at the binary path above is indeed different (note the difference in the micro version):

$ /usr/local/opt/python/bin/python2.7 --version
Python 2.7.14

$ /usr/bin/python --version
Python 2.7.10

To make things more confusing, the name _remove_dead_weakref does exist in the _weakref module for my Homebrew Python installation, but not the default system installation:

$ /usr/bin/python -c "import _weakref; print _weakref._remove_dead_weakref"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute '_remove_dead_weakref'

$ /usr/local/opt/python/bin/python2.7 -c "import _weakref; print _weakref._remove_dead_weakref"
<built-in function _remove_dead_weakref>

Any idea what could be causing this apparent cross-talk between my Python installations with LLDB? How can I prevent this?

Body:
One workaround to this issue is to explicitly launch LLDB with only the system Python installation on the PATH, e.g.

PATH=/usr/bin /usr/bin/lldb

It appears as though LLDB queries the PATH for the 'active' Python installation; if you have a Homebrew installation of Python available on the PATH then you can run into this sort of cross-talk when LLDB attempts to launch Python.


问:
Return AuthenticateResult.Fail result during AddOAuth OnCreatingTicket
I want to cause oAuth to fail during the OnCreatingTicket event.  I can call .Fail but it doesn't seem to do anything.  Is it too late in the workflow?  Am I missing some additional code to actually process the failure?</p>

```<code>services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie().AddOAuth("schemename", SetOAuthOptions);

private void SetOAuthOptions(OAuthOptions options)
{
    options.ClientId = ...;
    options.ClientSecret = ...;
    options.CallbackPath = ...;
    options.AuthorizationEndpoint = ...;
    options.TokenEndpoint = ...;
    options.Events = new OAuthEvents
    {
        OnCreatingTicket = async context => await AddIdentityClaimsAsync(context),
        OnTicketReceived = ...
    };
}

private async Task AddIdentityClaimsAsync(OAuthCreatingTicketContext context)
{
    ...
    if(noAccess)
        context.Fail("Sorry, you don't have access to the product.");
}
</code>```

答:
This is what I ended up with:

In startup, after AddOAuth:

.AddScheme<OAuthOptions, BearerAuthHandler>(BearerAuthHandler.DefaultSchemeName, ...);

This goes in your controller:

[Authorize(AuthenticationSchemes = BearerAuthHandler.DefaultSchemeName)]

This is the scheme class: https://dotnetfiddle.net/hujDtz

Body:
I want to cause oAuth to fail during the OnCreatingTicket event.  I can call .Fail but it doesn't seem to do anything.  Is it too late in the workflow?  Am I missing some additional code to actually process the failure?

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie().AddOAuth("schemename", SetOAuthOptions);

private void SetOAuthOptions(OAuthOptions options)
{
    options.ClientId = ...;
    options.ClientSecret = ...;
    options.CallbackPath = ...;
    options.AuthorizationEndpoint = ...;
    options.TokenEndpoint = ...;
    options.Events = new OAuthEvents
    {
        OnCreatingTicket = async context => await AddIdentityClaimsAsync(context),
        OnTicketReceived = ...
    };
}

private async Task AddIdentityClaimsAsync(OAuthCreatingTicketContext context)
{
    ...
    if(noAccess)
        context.Fail("Sorry, you don't have access to the product.");
}


问:
datatables not rendering the results
I am using the datatables plugin to render some results, the complexity here is that I have to loop through some lists in Sharepoint, then make a query, and then append each result into a final result, and then show that final result.

When I debug the foreach(result), I can see that the results are appended, and I get 13 result items so far.

However when the debugger reaches the datatable.add method, then the array is empty, and nothing is rendered.

```<code>function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
                    var enhanceFunctions = [
                        function(searchResultRow) {
                            return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
                        },
                        function(searchResultRow) {
                            return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
                        },
                        function(searchResultRow) {
                            return spService.AddImageMapping(searchResultRow, config.ImageFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatNumberFields(searchResultRow, config.NumberFields);
                        }
                    ];

                    var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
                    var extendedSelectProperties = selectProperties.slice(); // copy array
                    var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
                    extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);

                    spService.GetAllListsFromWeb()
                        .then(function(lists){
                            var listEnumerator = lists.getEnumerator();
                            var result =[];
                            while (listEnumerator.moveNext()) {
                                var oList = listEnumerator.get_current();
                                var title = oList.get_title();
                                var id = oList.get_id();
                                if(title.indexOf("Bill Cycles") !== -1){
                                    // Get data from SP
                                    GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
                                    .then(function (data) {
                                        var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
                                        // Add data to dataTable

                                        trimmedData.forEach(function(item){ // loop over source array
                                            result.push(item); //append to result array
                                        });
                                    })
                                    .catch (function (message) {
                                        vm.Name = "Error";
                                        vm.ValidDataLoaded = true;
                                    });
                                }
                                //Do something with oList.
                            }

                            var dataTable = $(tableSelector).DataTable();
                            dataTable.clear().rows.add(result).columns.adjust().draw(); // Resize columns based on new data sizes
                            vm.ValidDataLoaded = true;

                        })

                }

    function getAllListsFromWeb(){
                        var deferred = $q.defer();
                        var context = SP.ClientContext.get_current();
                        var web = context.get_web();
                        var lists = web.get_lists();
                        context.load(lists);
                        context.executeQueryAsync(
                           function() {
                                $log.info("Successfully retrieved list item result");
                                deferred.resolve(lists);
                           },
                           function(error, errorInfo) {
                                $log.warn("Retrieving list item result failed");

                                deferred.reject(errorInfo);
                           }
                        );
                        return deferred.promise;
                    }
</code>```

Update 1

Also tried this but didnt work

```<code>function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
                    var enhanceFunctions = [
                        function(searchResultRow) {
                            return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
                        },
                        function(searchResultRow) {
                            return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
                        },
                        function(searchResultRow) {
                            return spService.AddImageMapping(searchResultRow, config.ImageFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatNumberFields(searchResultRow, config.NumberFields);
                        }
                    ];

                    var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
                    var extendedSelectProperties = selectProperties.slice(); // copy array
                    var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
                    extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);

                    var result =[];

                    var data = spService.GetAllListsFromWeb()
                        .then(function(lists){
                            var listEnumerator = lists.getEnumerator();
                            while (listEnumerator.moveNext()) {
                                var oList = listEnumerator.get_current();
                                var title = oList.get_title();
                                var id = oList.get_id();
                                if(title.indexOf("Bill Cycles") !== -1){
                                    // Get data from SP
                                    GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
                                    .then(function (data) {
                                        var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
                                        // Add data to dataTable

                                        trimmedData.forEach(function(item){ // loop over source array
                                            result.push(item); //append to result array
                                        });
                                    })
                                    .catch (function (message) {
                                        vm.Name = "Error";
                                        vm.ValidDataLoaded = true;
                                    });
                                }
                            }

                            return result;
                        })

                        var resultadata = data;
                        var dataTable = $(tableSelector).DataTable();
                        dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
                        vm.ValidDataLoaded = true;

                }
</code>```

答:
Since data seems to be a promise you could try this:

```<code>//not saving it to data
spService.GetAllListsFromWeb()
.then(function (lists) {
  var listEnumerator = lists.getEnumerator();
  return Promise.all(
    (function(){
      var promises = [];
      while (listEnumerator.moveNext()) {
        var oList = listEnumerator.get_current();
        var title = oList.get_title();
        var id = oList.get_id();
        if (title.indexOf("Bill Cycles") !== -1) {
          // Get data from SP !!! this is also async and returns a promise
          //   add the promise to promises array and wait for all to finish
          //   look above in Promise.all
          promises.push(
            GetRelatedBillCyclesFromList(
              id,
              extendedSelectProperties,
              billCycleId,
              clientCode,
              jobCodes,
              engagementCode,
              enhanceFunctions
            )
            .then(function (data) {
              return spService
              .SpSearchQuery
              .TrimSearchResultsToSelectProperties(
                data,
                selectProperties
              );
            })
          );
        }
      }
      return promises
    })() //IIFE returning an array of promises
  );
})
.then(
  function(data){
    console.log("got data:",JSON.stringify(data,undefined,2));
    var resultadata = data;
    var dataTable = $(tableSelector).DataTable();
    dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
    vm.ValidDataLoaded = true;
  }
);
</code>```

You should really check out what a promise is and how it's used in JavaScript.

Since functions you write are always synchronous (only one thread running your code) your functions need to return a value immediately (non blocking).

When a function needs to make a network request, file IO or long running process you immediately return a promise. A promise is an object that has a function called then that takes 2 handler functions

Resolve handler: This is called when the promise resolves (network request finished and value is returned). The handler is passed one argument which is the resolve value (for network request this would be the response).

Reject handler: This is called when the promise rejects. For example the url for a request is invalid or server is down. The parameter to this function is the error.

So when you try to do stuff like:

```<code>var result = [];
var later = x => new Promise(r=>setTimeout(r(x),100));
[1,2,3,4,5]
.map(
  x =>
    later(x)
    .then(
      x => {
        console.log("resolved with:",x);
        result.push(x);
        return x;
      }
    )
);
console.log("first output",result);

//the output will be:
// first output []
// resolved with: 1
// resolved with: 2
// resolved with: 3
// resolved with: 4
// resolved with: 5
</code>```

You will see that by the time you try to do something with result none of the promises are resolved so it's empty. In the answer I put here I use Promise.all to resolve all promises and then use the resolve values for the dataTable.

Title: datatables not rendering the results

Body:
I am using the datatables plugin to render some results, the complexity here is that I have to loop through some lists in Sharepoint, then make a query, and then append each result into a final result, and then show that final result.

When I debug the foreach(result), I can see that the results are appended, and I get 13 result items so far.

However when the debugger reaches the datatable.add method, then the array is empty, and nothing is rendered.

function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
                    var enhanceFunctions = [
                        function(searchResultRow) {
                            return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
                        },
                        function(searchResultRow) {
                            return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
                        },
                        function(searchResultRow) {
                            return spService.AddImageMapping(searchResultRow, config.ImageFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatNumberFields(searchResultRow, config.NumberFields);
                        }
                    ];

                    var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
                    var extendedSelectProperties = selectProperties.slice(); // copy array
                    var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
                    extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);

                    spService.GetAllListsFromWeb()
                        .then(function(lists){
                            var listEnumerator = lists.getEnumerator();
                            var result =[];
                            while (listEnumerator.moveNext()) {
                                var oList = listEnumerator.get_current();
                                var title = oList.get_title();
                                var id = oList.get_id();
                                if(title.indexOf("Bill Cycles") !== -1){
                                    // Get data from SP
                                    GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
                                    .then(function (data) {
                                        var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
                                        // Add data to dataTable

                                        trimmedData.forEach(function(item){ // loop over source array
                                            result.push(item); //append to result array
                                        });
                                    })
                                    .catch (function (message) {
                                        vm.Name = "Error";
                                        vm.ValidDataLoaded = true;
                                    });
                                }
                                //Do something with oList.
                            }

                            var dataTable = $(tableSelector).DataTable();
                            dataTable.clear().rows.add(result).columns.adjust().draw(); // Resize columns based on new data sizes
                            vm.ValidDataLoaded = true;

                        })

                }

    function getAllListsFromWeb(){
                        var deferred = $q.defer();
                        var context = SP.ClientContext.get_current();
                        var web = context.get_web();
                        var lists = web.get_lists();
                        context.load(lists);
                        context.executeQueryAsync(
                           function() {
                                $log.info("Successfully retrieved list item result");
                                deferred.resolve(lists);
                           },
                           function(error, errorInfo) {
                                $log.warn("Retrieving list item result failed");

                                deferred.reject(errorInfo);
                           }
                        );
                        return deferred.promise;
                    }

Update 1

Also tried this but didnt work

function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
                    var enhanceFunctions = [
                        function(searchResultRow) {
                            return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
                        },
                        function(searchResultRow) {
                            return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
                        },
                        function(searchResultRow) {
                            return spService.AddImageMapping(searchResultRow, config.ImageFields);
                        },
                        function(searchResultRow) {
                            return spService.FormatNumberFields(searchResultRow, config.NumberFields);
                        }
                    ];

                    var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
                    var extendedSelectProperties = selectProperties.slice(); // copy array
                    var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
                    extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);

                    var result =[];

                    var data = spService.GetAllListsFromWeb()
                        .then(function(lists){
                            var listEnumerator = lists.getEnumerator();
                            while (listEnumerator.moveNext()) {
                                var oList = listEnumerator.get_current();
                                var title = oList.get_title();
                                var id = oList.get_id();
                                if(title.indexOf("Bill Cycles") !== -1){
                                    // Get data from SP
                                    GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
                                    .then(function (data) {
                                        var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
                                        // Add data to dataTable

                                        trimmedData.forEach(function(item){ // loop over source array
                                            result.push(item); //append to result array
                                        });
                                    })
                                    .catch (function (message) {
                                        vm.Name = "Error";
                                        vm.ValidDataLoaded = true;
                                    });
                                }
                            }

                            return result;
                        })

                        var resultadata = data;
                        var dataTable = $(tableSelector).DataTable();
                        dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
                        vm.ValidDataLoaded = true;

                }

Body:
Since data seems to be a promise you could try this:

//not saving it to data
spService.GetAllListsFromWeb()
.then(function (lists) {
  var listEnumerator = lists.getEnumerator();
  return Promise.all(
    (function(){
      var promises = [];
      while (listEnumerator.moveNext()) {
        var oList = listEnumerator.get_current();
        var title = oList.get_title();
        var id = oList.get_id();
        if (title.indexOf("Bill Cycles") !== -1) {
          // Get data from SP !!! this is also async and returns a promise
          //   add the promise to promises array and wait for all to finish
          //   look above in Promise.all
          promises.push(
            GetRelatedBillCyclesFromList(
              id,
              extendedSelectProperties,
              billCycleId,
              clientCode,
              jobCodes,
              engagementCode,
              enhanceFunctions
            )
            .then(function (data) {
              return spService
              .SpSearchQuery
              .TrimSearchResultsToSelectProperties(
                data,
                selectProperties
              );
            })
          );
        }
      }
      return promises
    })() //IIFE returning an array of promises
  );
})
.then(
  function(data){
    console.log("got data:",JSON.stringify(data,undefined,2));
    var resultadata = data;
    var dataTable = $(tableSelector).DataTable();
    dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
    vm.ValidDataLoaded = true;
  }
);

You should really check out what a promise is and how it's used in JavaScript.

Since functions you write are always synchronous (only one thread running your code) your functions need to return a value immediately (non blocking).

When a function needs to make a network request, file IO or long running process you immediately return a promise. A promise is an object that has a function called then that takes 2 handler functions

Resolve handler: This is called when the promise resolves (network request finished and value is returned). The handler is passed one argument which is the resolve value (for network request this would be the response).

Reject handler: This is called when the promise rejects. For example the url for a request is invalid or server is down. The parameter to this function is the error.

So when you try to do stuff like:

var result = [];
var later = x => new Promise(r=>setTimeout(r(x),100));
[1,2,3,4,5]
.map(
  x =>
    later(x)
    .then(
      x => {
        console.log("resolved with:",x);
        result.push(x);
        return x;
      }
    )
);
console.log("first output",result);

//the output will be:
// first output []
// resolved with: 1
// resolved with: 2
// resolved with: 3
// resolved with: 4
// resolved with: 5

You will see that by the time you try to do something with result none of the promises are resolved so it's empty. In the answer I put here I use Promise.all to resolve all promises and then use the resolve values for the dataTable.


问:
Replacing numbers in a list using dictionary
I am trying to use a dictionary to replace the last digits in a string. I extract the elements into a list, replace, and then join the list back into a string. The code runs but it only replaces using the second element in the dictionary.

```<code>text = "foo 123 doo 342 ghh 568 loo 243"
s = re.split(r'(\d+)', text)
textDict = {"2$":"fg" , "3$":"gh", "8$":"hj"}
for key in textDict:
    t = [re.sub(key , textDict[key], x) for x in s]
u = ["".join(t)]
u = str(u)
print u
</code>```

I am expecting the following input

```<code>foo 12gh doo 34fg ghh 56hj loo 24gh
</code>```

But am currently getting

```<code>foo 12gh doo 342 ghh 568 loo 24gh
</code>```

Extending the question a little:

If I want to change two last digits, then I can not get neither of the solutions to work. Both of them return the original string:

```<code>import re

text = "foo 123 doo 342 ghh 568 loo 243"
textDict = {"23":"fg" , "43":"gh", "68":"hj"}
</code>```

Using solution #1:

```<code>s = re.split(r'(\d+)', text)
for i in range(len(s) - 2):
  s[i] = s[i][:-2] + textDict[s[i][-2]] if s[i][-2] in textDict else s[i]

u = "".join(s)
print u
</code>```

Using solution #2:

```<code>result_str = ''
for txt in text.split(' '):
    if txt.isdigit() is True:
        txt = txt[:-2] + textDict.get(txt[-2], txt[-2])
    result_str += (txt + ' ')

result_str.strip()
</code>```

答:
One way of doing it is to reverse your for loop. Instead of iterating through your keys, you can iterate through your text segments. I don't think you need to use regular expressions since you have a very specific case.

```<code>import re

text = "foo 123 doo 342 ghh 568 loo 243"
s = re.split(r'(\d+)', text)

textDict = {"2":"fg" , "3":"gh", "8":"hj"}
for i in range(len(s) - 1):
  s[i] = s[i][:-1] + textDict[s[i][-1]] if str(s[i][-1]) in textDict else s[i]

u = "".join(s)
u = str(u)
print u
</code>```

This gives the following output :

```<code>> foo 12gh doo 34fg ghh 56hj loo 24gh
</code>```

I believe this is also more efficient since instead of having two nested loops (which gives us a complexity in the order of O(n*m)), you iterate through one list, which gives us O(n).

Body:
I am trying to use a dictionary to replace the last digits in a string. I extract the elements into a list, replace, and then join the list back into a string. The code runs but it only replaces using the second element in the dictionary.

text = "foo 123 doo 342 ghh 568 loo 243"
s = re.split(r'(\d+)', text)
textDict = {"2$":"fg" , "3$":"gh", "8$":"hj"}
for key in textDict:
    t = [re.sub(key , textDict[key], x) for x in s]
u = ["".join(t)]
u = str(u)
print u

I am expecting the following input

foo 12gh doo 34fg ghh 56hj loo 24gh

But am currently getting

foo 12gh doo 342 ghh 568 loo 24gh

Extending the question a little:

If I want to change two last digits, then I can not get neither of the solutions to work. Both of them return the original string:

import re

text = "foo 123 doo 342 ghh 568 loo 243"
textDict = {"23":"fg" , "43":"gh", "68":"hj"}

Using solution #1:

s = re.split(r'(\d+)', text)
for i in range(len(s) - 2):
  s[i] = s[i][:-2] + textDict[s[i][-2]] if s[i][-2] in textDict else s[i]

u = "".join(s)
print u

Using solution #2:

result_str = ''
for txt in text.split(' '):
    if txt.isdigit() is True:
        txt = txt[:-2] + textDict.get(txt[-2], txt[-2])
    result_str += (txt + ' ')

result_str.strip()

Body:
One way of doing it is to reverse your for loop. Instead of iterating through your keys, you can iterate through your text segments. I don't think you need to use regular expressions since you have a very specific case.

import re

text = "foo 123 doo 342 ghh 568 loo 243"
s = re.split(r'(\d+)', text)

textDict = {"2":"fg" , "3":"gh", "8":"hj"}
for i in range(len(s) - 1):
  s[i] = s[i][:-1] + textDict[s[i][-1]] if str(s[i][-1]) in textDict else s[i]

u = "".join(s)
u = str(u)
print u

This gives the following output :

> foo 12gh doo 34fg ghh 56hj loo 24gh

I believe this is also more efficient since instead of having two nested loops (which gives us a complexity in the order of O(n*m)), you iterate through one list, which gives us O(n).


问:
why do not Redis provide a batch set expire time operation on multiple keys?
I want to set multiple keys with an expire time, but it seems I have to expire every keys one by one.Why do not Redis provide an operation just like "mset"?</p>

答:
You can use one script as it.</p>

```<code>EVAL 'for i, name in ipairs(redis.call("KEYS", "0*")) do redis.call("EXPIRE", name, 10); end' 0
</code>```

Body:
You can use one script as it.

EVAL 'for i, name in ipairs(redis.call("KEYS", "0*")) do redis.call("EXPIRE", name, 10); end' 0


问:
Why aren't variables being recognized even when i properly set them
I am relatively new to Xcode and Swift and i was following this guide: https://codewithchris.com/iphone-app-connect-to-mysql-database/#app but three of the variables aren't being recognized even though they were properly recognized earlier:

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

        // Retrieve cell
        let cellIdentifier: String = "BasicCell"
        let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        // Get the location to be shown
        let item: InputModel = feedItems[indexPath.row] as! InputModel
        // Get references to labels of cell
        myCell.textLabel!.text = item.Street

        return myCell
    }

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // Set selected location to var
    selectedLocation = feedItems[indexPath.row] as! InputModel
    // Manually call segue to detail view controller
    self.performSegue(withIdentifier: "detailSegue", sender: self)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    // Get reference to the destination view controller
    let detailVC  = segue.destination as! DetailViewController
    // Set the property to the selected location so when the view for
    // detail view controller loads, it can access that property to get the feeditem obj
    detailVC.selectedLocation = selectedLocation
}
</code>```

the result i got back was "use of unresolved identifier selectedLocation" twice and "use of unresolved identifier feedItems". i should also say that i changed the title of locationModel() to InputModel, and address to street. i can explain more and add source files if need be.

Edit: sorry, the variables were set earlier, here:

```<code>  class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, HomeModelProtocol  {

        //Properties
        var feedItems: NSArray = NSArray()
        var selectedLocation : InputModel = InputModel()
        @IBOutlet weak var listTableView: UITableView!

        override func viewDidLoad() {
            super.viewDidLoad()

            //set delegates and initialize homeModel

            self.listTableView.delegate = self
            self.listTableView.dataSource = self

            let homeModel = HomeModel()
            homeModel.delegate = self
            homeModel.downloadItems()

        }

        func itemsDownloaded(items: NSArray) {

            feedItems = items
            self.listTableView.reloadData()
        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // Return the number of feed items
            return feedItems.count

        }
</code>```

答:
Basically you're missing the declaration of two variables "selectedLocation" and "feedItems"

That, from the code you posted are in this lines

```<code>func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Missing the declaration of both variables here
    selectedLocation = feedItems[indexPath.row] as! InputModel
    // The rest of the code
}
</code>```

And missing only one variable here

```<code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // previous code ...
        // Missing variable declaration in the next line
        let item: InputModel = feedItems[indexPath.row] as! InputModel
        // rest of the code
    }
}
</code>```

Not knowing where and how they were declared it's hard to know where the error is.

First of all, are these variables inside the same class that these functions?

If not that's the problem, you'll need to get the instance of the class where they're set for example

```<code>otherclass.selectedLocation = otherclass.feedItems[indexPath.row] as! InputModel
</code>```

If they are, try to access them using the self declaration (it shouldn't be necessary but it might work) for example

```<code>self.selectedLocation = self.feedItems[indexPath.row] as! InputModel
</code>```

Would be easier if you could provide the code where these variables are set though

Body:
I am relatively new to Xcode and Swift and i was following this guide: https://codewithchris.com/iphone-app-connect-to-mysql-database/#app but three of the variables aren't being recognized even though they were properly recognized earlier:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // Retrieve cell
        let cellIdentifier: String = "BasicCell"
        let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        // Get the location to be shown
        let item: InputModel = feedItems[indexPath.row] as! InputModel
        // Get references to labels of cell
        myCell.textLabel!.text = item.Street

        return myCell
    }

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // Set selected location to var
    selectedLocation = feedItems[indexPath.row] as! InputModel
    // Manually call segue to detail view controller
    self.performSegue(withIdentifier: "detailSegue", sender: self)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    // Get reference to the destination view controller
    let detailVC  = segue.destination as! DetailViewController
    // Set the property to the selected location so when the view for
    // detail view controller loads, it can access that property to get the feeditem obj
    detailVC.selectedLocation = selectedLocation
}

the result i got back was "use of unresolved identifier selectedLocation" twice and "use of unresolved identifier feedItems". i should also say that i changed the title of locationModel() to InputModel, and address to street. i can explain more and add source files if need be.

Edit: sorry, the variables were set earlier, here:

  class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, HomeModelProtocol  {

        //Properties
        var feedItems: NSArray = NSArray()
        var selectedLocation : InputModel = InputModel()
        @IBOutlet weak var listTableView: UITableView!

        override func viewDidLoad() {
            super.viewDidLoad()

            //set delegates and initialize homeModel

            self.listTableView.delegate = self
            self.listTableView.dataSource = self

            let homeModel = HomeModel()
            homeModel.delegate = self
            homeModel.downloadItems()

        }

        func itemsDownloaded(items: NSArray) {

            feedItems = items
            self.listTableView.reloadData()
        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // Return the number of feed items
            return feedItems.count

        }

Body:
Basically you're missing the declaration of two variables "selectedLocation" and "feedItems"

That, from the code you posted are in this lines

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Missing the declaration of both variables here
    selectedLocation = feedItems[indexPath.row] as! InputModel
    // The rest of the code
}

And missing only one variable here

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // previous code ...
        // Missing variable declaration in the next line
        let item: InputModel = feedItems[indexPath.row] as! InputModel
        // rest of the code
    }
}

Not knowing where and how they were declared it's hard to know where the error is.

First of all, are these variables inside the same class that these functions?

If not that's the problem, you'll need to get the instance of the class where they're set for example

otherclass.selectedLocation = otherclass.feedItems[indexPath.row] as! InputModel

If they are, try to access them using the self declaration (it shouldn't be necessary but it might work) for example

self.selectedLocation = self.feedItems[indexPath.row] as! InputModel

Would be easier if you could provide the code where these variables are set though


答:
This solution works without using re. I modified your textDict

```<code>In [19]: text = "foo 123 doo 342 ghh 568 loo 243"

In [20]: textDict = {"2":"fg" , "3":"gh", "8":"hj"} # modified textDict

In [21]: result_str = ''

In [22]: c_len = 1 # just modify this according to length of dict key

In [23]: for txt in text.split(' '):
    ...:     if txt.isdigit() is True:
    ...:         txt = txt[:-c_len] + textDict.get(txt[-c_len:], txt[-c_len:])
    ...:     result_str += (txt + ' ')
    ...:

In [24]: result_str.strip()    # to remove last space
Out[24]: 'foo 12gh doo 34fg ghh 56hj loo 24gh '
</code>```

To answer you seond question, just modify c_len according to dict key length.

Title: Replacing numbers in a list using dictionary

Body:
This solution works without using re. I modified your textDict

In [19]: text = "foo 123 doo 342 ghh 568 loo 243"

In [20]: textDict = {"2":"fg" , "3":"gh", "8":"hj"} # modified textDict

In [21]: result_str = ''

In [22]: c_len = 1 # just modify this according to length of dict key

In [23]: for txt in text.split(' '):
    ...:     if txt.isdigit() is True:
    ...:         txt = txt[:-c_len] + textDict.get(txt[-c_len:], txt[-c_len:])
    ...:     result_str += (txt + ' ')
    ...:

In [24]: result_str.strip()    # to remove last space
Out[24]: 'foo 12gh doo 34fg ghh 56hj loo 24gh '

To answer you seond question, just modify c_len according to dict key length.


问:
Clang ambiguity with custom conversion operator
I've been developing a kind of adapter class, when I encountered a problem under clang. When both conversion operators for lvalue-reference and rvalue reference are defined you get an ambiguity compilation error trying to move from your class (when such code should be fine, as

```<code>operator const T& () const&
</code>```

is allowed only for lvalues AFAIK). I've reproduced error with simple example:

```<code>#include <string>

class StringDecorator
{
public:
  StringDecorator()
  : m_string( "String data here" )
  {}

  operator const std::string& () const& // lvalue only
  {
    return m_string;
  }

  operator std::string&& () && // rvalue only
  {
    return std::move( m_string );
  }

private:
    std::string m_string;
};

void func( const std::string& ) {}
void func( std::string&& ) {}

int main(int argc, char** argv)
{
  StringDecorator my_string;

  func( my_string ); // fine, operator std::string&& not allowed
  func( std::move( my_string ) ); // error "ambiguous function call"
}
</code>```

Compiles fine on gcc 4.9+, fails on any clang version.
So the question: is there any workaround? Is my understanding of const& function modifier right?

P.S.: To clarify - the question is about fixing StringDecorator class itself (or finding the workaround for such class as if were a library code). Please refrain providing answers that call operator T&&() directly or specify conversion type explicitly.

答:
The problem comes from the selection of the best viable function. In the case of the second func call, it implies the comparison of 2 user-defined conversion sequence. Unfortunately, 2 user-defined conversion sequence are undistinguishable if they do not use the same user-defined conversion function or constructor C++ standard [over.ics.rank/3]:

Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
  the following rules applies:

[...]

User-defined conversion sequence
  U1
  is a better conversion sequence than another user-defined conversion
  sequence
  U2
  if they contain the same user-defined conversion function or constructor [...]

Because a rvalue can always bind to a const lvalue reference, you will in any case fall on this ambiguous call if a function is overloaded for const std::string& and std::string&&.

As you mentioned it, my first answer consisting in redeclaring all functions is not a solution as you are implementing a library. Indeed it is not possible to define proxy-functions for all functions taking a string as argument!!

So that let you with a trade off between 2 imperfect solutions:

You remove operator std::string&&() &&, and you will loose some optimization, or;

You publicly inherit from std::string, and remove the 2 conversion functions, in which case you expose your library to misuses:

```<code>#include <string>

class StringDecorator
  : public std::string
{
public:
  StringDecorator()
  : std::string("String data here" )
  {}
};

void func( const std::string& ) {}
void func( std::string&& ) {}

int main(int argc, char** argv)
{
  StringDecorator my_string;

  func( my_string ); // fine, operator std::string&& not allowed
  func( std::move( my_string  )); // No more bug:
    //ranking of standard conversion sequence is fine-grained.
}
</code>```

An other solution is not to use Clang because it is a bug of Clang.

But if you have to use Clang, the Tony Frolov answer is the solution.

Body:
I've been developing a kind of adapter class, when I encountered a problem under clang. When both conversion operators for lvalue-reference and rvalue reference are defined you get an ambiguity compilation error trying to move from your class (when such code should be fine, as

operator const T& () const&

is allowed only for lvalues AFAIK). I've reproduced error with simple example:

#include <string>

class StringDecorator
{
public:
  StringDecorator()
  : m_string( "String data here" )
  {}

  operator const std::string& () const& // lvalue only
  {
    return m_string;
  }

  operator std::string&& () && // rvalue only
  {
    return std::move( m_string );
  }

private:
    std::string m_string;
};

void func( const std::string& ) {}
void func( std::string&& ) {}

int main(int argc, char** argv)
{
  StringDecorator my_string;

  func( my_string ); // fine, operator std::string&& not allowed
  func( std::move( my_string ) ); // error "ambiguous function call"
}

Compiles fine on gcc 4.9+, fails on any clang version.
So the question: is there any workaround? Is my understanding of const& function modifier right?

P.S.: To clarify - the question is about fixing StringDecorator class itself (or finding the workaround for such class as if were a library code). Please refrain providing answers that call operator T&&() directly or specify conversion type explicitly.

Body:
The problem comes from the selection of the best viable function. In the case of the second func call, it implies the comparison of 2 user-defined conversion sequence. Unfortunately, 2 user-defined conversion sequence are undistinguishable if they do not use the same user-defined conversion function or constructor C++ standard [over.ics.rank/3]:

Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
  the following rules applies:

[...]

User-defined conversion sequence
  U1
  is a better conversion sequence than another user-defined conversion
  sequence
  U2
  if they contain the same user-defined conversion function or constructor [...]

Because a rvalue can always bind to a const lvalue reference, you will in any case fall on this ambiguous call if a function is overloaded for const std::string& and std::string&&.

As you mentioned it, my first answer consisting in redeclaring all functions is not a solution as you are implementing a library. Indeed it is not possible to define proxy-functions for all functions taking a string as argument!!

So that let you with a trade off between 2 imperfect solutions:

You remove operator std::string&&() &&, and you will loose some optimization, or;

You publicly inherit from std::string, and remove the 2 conversion functions, in which case you expose your library to misuses:

#include <string>

class StringDecorator
  : public std::string
{
public:
  StringDecorator()
  : std::string("String data here" )
  {}
};

void func( const std::string& ) {}
void func( std::string&& ) {}

int main(int argc, char** argv)
{
  StringDecorator my_string;

  func( my_string ); // fine, operator std::string&& not allowed
  func( std::move( my_string  )); // No more bug:
    //ranking of standard conversion sequence is fine-grained.
}

An other solution is not to use Clang because it is a bug of Clang.

But if you have to use Clang, the Tony Frolov answer is the solution.


问:
How to give data from laravel to vue.js?
When i start write application i used to laravel blade. But now i have to transfer all to vue js and i don't known how to give data from controllers to vue.js. Also i don't know how to transfer this code</p>

```<code>@if(Session::has('error_text'))
        <div class="col-md-6 col-md-offset-3 formMessage">
            <div class="iw">
                <div class="text-error">{{Session::get('error_text')}}</div>
                @if(Session::has('with_link'))
                    <div class="help-text"><a href="{{Session::get('with_link')}}">{{Session::get('link_text')}}</a></div>
                @endif

                @if(Session::has('unknown_symbols'))
                    <div class="help-text"><a href="#">Report a bug</a></div>
                @endif
            </div>
        </div>
    @endif
</code>```

答:
The best way to do this is by creating a component and assign the data with properties</p>

```<code><custom-component data="{{ $bladeVariable }}"></custom-component>
</code>```

ContentLicense: CC BY-SA 4.0

Body:
When i start write application i used to laravel blade. But now i have to transfer all to vue js and i don't known how to give data from controllers to vue.js. Also i don't know how to transfer this code

@if(Session::has('error_text'))

{{Session::get('error_text')}}

                @if(Session::has('with_link'))

{{Session::get('link_text')}}

                @endif

                @if(Session::has('unknown_symbols'))

Report a bug

                @endif

    @endif

Body:
The best way to do this is by creating a component and assign the data with properties

<custom-component data="{{ $bladeVariable }}"></custom-component>


问:
extract a protion of html file
I have used dompdf to create pdf file, I have used a portion of the html file ie between  to generate pdf . (cut & pasted manual way)

since I have a valid pdf out put now, I want to further automate the process,

I want to copy all contents between  tables

```<code><table> </table>
</code>```

to a file, would like to know  what would be possible options in php.
any suggestion is highly appreciated

答:
Don't use regex, instead use DomDocument.

The following class will extract out the content between any element. So load your html from your file, or just pass it the contents of ob_get_contents()

```<code><?php

class DOMExtract extends DOMDocument
{
    private $source;
    private $dom;

    public function __construct()
    {
        libxml_use_internal_errors(true);
        $this->preserveWhiteSpace = false;
        $this->strictErrorChecking = false;
        $this->formatOutput = true;
    }

    public function setSource($source)
    {
        $this->source = $source;
        return $this;
    }

    public function getInnerHTML($tag, $id=null, $nodeValue = false)
    {
        if (empty($this->source)) {
            throw new Exception('Error: Missing $this->source, use setSource() first');
        }

        $this->loadHTML($this->source);
        $tmp = $this->getElementsByTagName($tag);
        $ret = null;
        foreach ($tmp as $v) {
            if ($id !== null) {
                $attr = explode('=', $id);
                if ($v->getAttribute($attr[0]) == $attr[1]) {
                    if ($nodeValue == true) {
                        $ret .= trim($v->nodeValue);
                    } else {
                        $ret .= $this->innerHTML($v);
                    }
                }
            } else {
                if ($nodeValue == true) {
                    $ret .= trim($v->nodeValue);
                } else{
                    $ret .= $this->innerHTML($v);
                }
            }
        }
        return $ret;
    }

    protected function innerHTML($dom)
    {
        $ret = "";
        foreach ($dom->childNodes as $v) {
            $tmp = new DOMDocument();
            $tmp->appendChild($tmp->importNode($v, true));
            $ret .= trim($tmp->saveHTML());
        }
        return $ret;
    }

}

$html = '
<h3>HTML Table Example</h3>
<div>
<table id="customers">
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>
</div>';

$dom = new DOMExtract();
$dom->setSource($html);

echo '
<table cellspacing="0" cellpadding="3" border="0" width="100%">',
    //match and return only tables inner content with id=customers
    $dom->getInnerHTML('table', 'id=customers'),
    //match all tables inner content
    //$dom->getInnerHTML('table'),
'</table>';
</code>```

https://3v4l.org/OkbQW

```<code><table cellspacing="0" cellpadding="3" border="0" width="100%"><tr><th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr><tr><td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr><tr><td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr><tr><td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr><tr><td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr><tr><td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr><tr><td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr></table>
</code>```

Title: extract a protion of html file

Body:
I have used dompdf to create pdf file, I have used a portion of the html file ie between  to generate pdf . (cut & pasted manual way)

since I have a valid pdf out put now, I want to further automate the process,

I want to copy all contents between  tables

to a file, would like to know  what would be possible options in php.
any suggestion is highly appreciated

Body:
Don't use regex, instead use DomDocument.

The following class will extract out the content between any element. So load your html from your file, or just pass it the contents of ob_get_contents()

<?php

class DOMExtract extends DOMDocument
{
    private $source;
    private $dom;

    public function __construct()
    {
        libxml_use_internal_errors(true);
        $this->preserveWhiteSpace = false;
        $this->strictErrorChecking = false;
        $this->formatOutput = true;
    }

    public function setSource($source)
    {
        $this->source = $source;
        return $this;
    }

    public function getInnerHTML($tag, $id=null, $nodeValue = false)
    {
        if (empty($this->source)) {
            throw new Exception('Error: Missing $this->source, use setSource() first');
        }

        $this->loadHTML($this->source);
        $tmp = $this->getElementsByTagName($tag);
        $ret = null;
        foreach ($tmp as $v) {
            if ($id !== null) {
                $attr = explode('=', $id);
                if ($v->getAttribute($attr[0]) == $attr[1]) {
                    if ($nodeValue == true) {
                        $ret .= trim($v->nodeValue);
                    } else {
                        $ret .= $this->innerHTML($v);
                    }
                }
            } else {
                if ($nodeValue == true) {
                    $ret .= trim($v->nodeValue);
                } else{
                    $ret .= $this->innerHTML($v);
                }
            }
        }
        return $ret;
    }

    protected function innerHTML($dom)
    {
        $ret = "";
        foreach ($dom->childNodes as $v) {
            $tmp = new DOMDocument();
            $tmp->appendChild($tmp->importNode($v, true));
            $ret .= trim($tmp->saveHTML());
        }
        return $ret;
    }

}

$html = '
<h3>HTML Table Example</h3>
<div>
<table id="customers">
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>
</div>';

$dom = new DOMExtract();
$dom->setSource($html);

echo '
<table cellspacing="0" cellpadding="3" border="0" width="100%">',
    //match and return only tables inner content with id=customers
    $dom->getInnerHTML('table', 'id=customers'),
    //match all tables inner content
    //$dom->getInnerHTML('table'),
'</table>';

https://3v4l.org/OkbQW

<table cellspacing="0" cellpadding="3" border="0" width="100%"><tr><th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr><tr><td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr><tr><td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr><tr><td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr><tr><td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr><tr><td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr><tr><td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr></table>


问:
C - Caesar Cipher [Moving Code to Function]
I am totally new to C programming language, so don't be too critical about my code. I found some tutorials to make Caesar Cipher encryption and decryption program, I just would like to run it from the CLI.

I have code, but it uses global variables and doesn't use functions, i need both of them, i need to somehow move my code to function called "encryption" and another function called "decryption", this all goes to problem number 2

I created encryption code, but i can't make decryption, i understand the main idea, but because i don't have function (Which i need) i can't make the decryption part of the code.

Please help me. Here is my code:

```<code>#include<stdio.h>

int main()
{
    char message[100], symbol;
    int i, key;

    printf("Message to encrypt: ");
    gets(message); //fgets is better
    printf("Enter key: ");
    scanf("%d", &key);

    for(i = 0; message[i] != '\0'; ++i){
        symbol = message[i];

        if(symbol >= 'a' && symbol <= 'z'){
            symbol = symbol + key;

            if(symbol > 'z'){
                symbol = symbol - 'z' + 'a' - 1;
            }

            message[i] = symbol;
        }
        else if(symbol >= 'A' && symbol <= 'Z'){
            symbol = symbol + key;

            if(symbol > 'Z'){
                symbol = symbol - 'Z' + 'A' - 1;
            }

            message[i] = symbol;
        }
        else if(symbol >= '0' && symbol <= '9'){
            symbol = symbol + key;

            if(symbol > '9'){
                symbol = symbol - '9' + '1' - 1;
            }

            message[i] = symbol;
        }
    }

    printf("Encrypted message: %s", message);

    return 0;
}
</code>```

As i said, i need to make 2 function, one for encryption and another one for decryption, can i get some help ?

Thank you.

答:
The function you need will be something like

```<code>void encryption(char message[100], char encrypted[100], int key)
</code>```

You can copy paste your code inside that like:

```<code>void encryption(char message[100], char encrypted[100], int key){
   // declare variables here
   for(i = 0; message[i] != '\0'; ++i){
    symbol = message[i];

    if(symbol >= 'a' && symbol <= 'z'){
        symbol = symbol + key;

        if(symbol > 'z'){
            symbol = symbol - 'z' + 'a' - 1;
        }

        encrypted[i] = symbol;
    }
    else if(symbol >= 'A' && symbol <= 'Z'){
        symbol = symbol + key;

        if(symbol > 'Z'){
            symbol = symbol - 'Z' + 'A' - 1;
        }

        encrypted[i] = symbol;
    }
    else if(symbol >= '0' && symbol <= '9'){
        symbol = symbol + key;

        if(symbol > '9'){
            symbol = symbol - '9' + '1' - 1;
        }

        encrypted[i] = symbol;
    }
  }
}
</code>```

You don't HAVE to make an array called encrypted[] but since you might need your original message[] later (eg. for checking if your decoding is correct) I would advise against overwriting it.

Body:
I am totally new to C programming language, so don't be too critical about my code. I found some tutorials to make Caesar Cipher encryption and decryption program, I just would like to run it from the CLI.

I have code, but it uses global variables and doesn't use functions, i need both of them, i need to somehow move my code to function called "encryption" and another function called "decryption", this all goes to problem number 2

I created encryption code, but i can't make decryption, i understand the main idea, but because i don't have function (Which i need) i can't make the decryption part of the code.

Please help me. Here is my code:

#include<stdio.h>

int main()
{
    char message[100], symbol;
    int i, key;

    printf("Message to encrypt: ");
    gets(message); //fgets is better
    printf("Enter key: ");
    scanf("%d", &key);

    for(i = 0; message[i] != '\0'; ++i){
        symbol = message[i];

        if(symbol >= 'a' && symbol <= 'z'){
            symbol = symbol + key;

            if(symbol > 'z'){
                symbol = symbol - 'z' + 'a' - 1;
            }

            message[i] = symbol;
        }
        else if(symbol >= 'A' && symbol <= 'Z'){
            symbol = symbol + key;

            if(symbol > 'Z'){
                symbol = symbol - 'Z' + 'A' - 1;
            }

            message[i] = symbol;
        }
        else if(symbol >= '0' && symbol <= '9'){
            symbol = symbol + key;

            if(symbol > '9'){
                symbol = symbol - '9' + '1' - 1;
            }

            message[i] = symbol;
        }
    }

    printf("Encrypted message: %s", message);

    return 0;
}

As i said, i need to make 2 function, one for encryption and another one for decryption, can i get some help ?

Thank you.

Body:
The function you need will be something like

void encryption(char message[100], char encrypted[100], int key)

You can copy paste your code inside that like:

void encryption(char message[100], char encrypted[100], int key){
   // declare variables here
   for(i = 0; message[i] != '\0'; ++i){
    symbol = message[i];

    if(symbol >= 'a' && symbol <= 'z'){
        symbol = symbol + key;

        if(symbol > 'z'){
            symbol = symbol - 'z' + 'a' - 1;
        }

        encrypted[i] = symbol;
    }
    else if(symbol >= 'A' && symbol <= 'Z'){
        symbol = symbol + key;

        if(symbol > 'Z'){
            symbol = symbol - 'Z' + 'A' - 1;
        }

        encrypted[i] = symbol;
    }
    else if(symbol >= '0' && symbol <= '9'){
        symbol = symbol + key;

        if(symbol > '9'){
            symbol = symbol - '9' + '1' - 1;
        }

        encrypted[i] = symbol;
    }
  }
}

You don't HAVE to make an array called encrypted[] but since you might need your original message[] later (eg. for checking if your decoding is correct) I would advise against overwriting it.


问:
Add properties to a datatable generated in JSON format in ashx file
This is a part of my html:

```<code>        ...
        <section id="mainSection">
          <div id="MyDataTable"></div>
        </section>
        ...
</code>```

The following javascript code generates my datatable:

```<code>function getData() {
    $('#MyDataTable').html('<table id="MyDataTable" class="display" cellspacing="0" width="100%"></table>');
    $.ajax({
        "url": "myurl\getData.ashx"
        "success": function (json) {
             $('#MyDataTable').dataTable(json);
        },
        "dataType": "json"
    });
}
</code>```

The getData.ashx file generates columns and content of the datatable:

```<code>        ...
        String Data = JsonConvert.SerializeObject(List<Object>);
        String Columns = JsonConvert.SerializeObject(List<Object>);
        context.Response.Write("{\"data\":" + Data + ",\"columns\":" + Columns + "}")
</code>```

What I'm trying to figure out is, how do I ADD PROPERTIES to my datatable. The property I want to add is "defaultContent": "Not set"  Everywhere I look on the internet, datatables are generated differently, e.g. -

```<code>$('#example').dataTable({
    "columns": [
        null,
        null,
        null {
            "data": "first_name",
            //THIS IS THE PROPERTY I AM TRYING TO ADD
            "defaultContent": "<i>Not set</i>"
        }
    ]
});
</code>```

I can't add a property the way it was done in this example because the generation of my table is different. How do I do it then? Is it at all possible?

答:
Why not just append the feature in the success handler?

```<code>"success": function(json) {
   json.columnDefs = [{
     targets: '_all',
     defaultContent: '<i>Not set</i>'
   }];
   $('#MyDataTable').dataTable(json);
}
</code>```

You could do that with other features / properties as well.

Body:
This is a part of my html:

        ...

        ...

The following javascript code generates my datatable:

function getData() {
    $('#MyDataTable').html('

');
    $.ajax({
        "url": "myurl\getData.ashx"
        "success": function (json) {
             $('#MyDataTable').dataTable(json);
        },
        "dataType": "json"
    });
}

The getData.ashx file generates columns and content of the datatable:

        ...
        String Data = JsonConvert.SerializeObject(List<Object>);
        String Columns = JsonConvert.SerializeObject(List<Object>);
        context.Response.Write("{\"data\":" + Data + ",\"columns\":" + Columns + "}")

What I'm trying to figure out is, how do I ADD PROPERTIES to my datatable. The property I want to add is "defaultContent": "Not set"  Everywhere I look on the internet, datatables are generated differently, e.g. -

$('#example').dataTable({
    "columns": [
        null,
        null,
        null {
            "data": "first_name",
            //THIS IS THE PROPERTY I AM TRYING TO ADD
            "defaultContent": "Not set"
        }
    ]
});

I can't add a property the way it was done in this example because the generation of my table is different. How do I do it then? Is it at all possible?

Body:
Why not just append the feature in the success handler?

"success": function(json) {
   json.columnDefs = [{
     targets: '_all',
     defaultContent: '<i>Not set</i>'
   }];
   $('#MyDataTable').dataTable(json);
}

You could do that with other features / properties as well.


问:
How can I speed up nearest neighbor search with python?
I have a code, which calculates the nearest voxel (which is unassigned) to a voxel ( which is assigned). That is i have an array of voxels, few voxels already have a scalar (1,2,3,4....etc) values assigned, and few voxels are empty (lets say a value of '0'). This code below finds the nearest assigned voxel to an unassigned voxel and assigns that voxel the same scalar. So, a voxel with a scalar '0' will be assigned a value (1 or 2 or 3,...) based on the nearest voxel. This code below works, but it takes too much time.
Is there an alternative to this ? or if you have any feedback on how to improve it further?

""" #self.voxels is a 3D numpy array"""

```<code>def fill_empty_voxel1(self,argx, argy, argz):
""" where # argx, argy, argz are the voxel location where the voxel is zero"""
    argx1, argy1, argz1 = np.where(self.voxels!=0)   # find the non zero voxels
    a = np.column_stack((argx1, argy1, argz1))
    b = np.column_stack((argx, argy, argz))
    tree = cKDTree(a, leafsize=a.shape[0]+1)
    distances, ndx = tree.query(b, k=1, distance_upper_bound= self.mean) # self.mean is a mean radius search value
    argx2, argy2, argz2 = a[ndx][:][:,0],a[ndx][:][:,1],a[ndx][:][:,2]
    self.voxels[argx,argy,argz] = self.voxels[argx2,argy2,argz2] # update the voxel array
</code>```

Example

""" Here is a small example with small dataset:"""

```<code>import numpy as np
from scipy.spatial import cKDTree
import timeit

voxels = np.zeros((10,10,5), dtype=np.uint8)
voxels[1:2,:,:] = 5.
voxels[5:6,:,:] = 2.
voxels[:,3:4,:] = 1.
voxels[:,8:9,:] = 4.
argx, argy, argz = np.where(voxels==0)

tic=timeit.default_timer()
argx1, argy1, argz1 = np.where(voxels!=0)   # non zero voxels
a = np.column_stack((argx1, argy1, argz1))
b = np.column_stack((argx, argy, argz))
tree = cKDTree(a, leafsize=a.shape[0]+1)
distances, ndx = tree.query(b, k=1, distance_upper_bound= 5.)
argx2, argy2, argz2 = a[ndx][:][:,0],a[ndx][:][:,1],a[ndx][:][:,2]
voxels[argx,argy,argz] = voxels[argx2,argy2,argz2]
toc=timeit.default_timer()
timetaken = toc - tic #elapsed time in seconds
print '\nTime to fill empty voxels', timetaken
</code>```

for visualization:

```<code>from mayavi import mlab
data = voxels.astype('float')
scalar_field = mlab.pipeline.scalar_field(data)
iso_surf = mlab.pipeline.iso_surface(scalar_field)
surf = mlab.pipeline.surface(scalar_field)
vol = mlab.pipeline.volume(scalar_field,vmin=0,vmax=data.max())
mlab.outline()
mlab.show()
</code>```

Now, if I have the dimension of the voxels array as something like (500,500,500), then the time it takes to compute the nearest search is no longer efficient. How can I overcome this? Could parallel computation reduce the time (I have no idea whether I can parallelize the code, if you do, please let me know)?

A potential fix:

I could substantially improve the computation time by adding the n_jobs = -1 parameter in the cKDTree query.

```<code>distances, ndx = tree.query(b, k=1, distance_upper_bound= 5., n_jobs=-1)
</code>```

I was able to compute the distances in less than a hour for an array of (400,100,100) on a 13 core CPU. I tried with 1 processor and it takes around 18 hours to complete the same array.
Thanks to @gsamaras for the answer!

答: You can switch to approximate nearest neighbors (ANN) algorithms which usually take advantage of sophisticated hashing or proximity graph techniques to index your data quickly and perform faster queries. One example is Spotify's Annoy. Annoy's README includes a plot which shows precision-performance tradeoff comparison of various ANN algorithms published in recent years. The top-performing algorithm (at the time this comment was posted), hnsw, has a Python implementation under Non-Metric Space Library (NMSLIB).</p>

Body:
I have a code, which calculates the nearest voxel (which is unassigned) to a voxel ( which is assigned). That is i have an array of voxels, few voxels already have a scalar (1,2,3,4....etc) values assigned, and few voxels are empty (lets say a value of '0'). This code below finds the nearest assigned voxel to an unassigned voxel and assigns that voxel the same scalar. So, a voxel with a scalar '0' will be assigned a value (1 or 2 or 3,...) based on the nearest voxel. This code below works, but it takes too much time.
Is there an alternative to this ? or if you have any feedback on how to improve it further?

""" #self.voxels is a 3D numpy array"""

def fill_empty_voxel1(self,argx, argy, argz):
""" where # argx, argy, argz are the voxel location where the voxel is zero"""
    argx1, argy1, argz1 = np.where(self.voxels!=0)   # find the non zero voxels
    a = np.column_stack((argx1, argy1, argz1))
    b = np.column_stack((argx, argy, argz))
    tree = cKDTree(a, leafsize=a.shape[0]+1)
    distances, ndx = tree.query(b, k=1, distance_upper_bound= self.mean) # self.mean is a mean radius search value
    argx2, argy2, argz2 = a[ndx][:][:,0],a[ndx][:][:,1],a[ndx][:][:,2]
    self.voxels[argx,argy,argz] = self.voxels[argx2,argy2,argz2] # update the voxel array

Example

""" Here is a small example with small dataset:"""

import numpy as np
from scipy.spatial import cKDTree
import timeit

voxels = np.zeros((10,10,5), dtype=np.uint8)
voxels[1:2,:,:] = 5.
voxels[5:6,:,:] = 2.
voxels[:,3:4,:] = 1.
voxels[:,8:9,:] = 4.
argx, argy, argz = np.where(voxels==0)

tic=timeit.default_timer()
argx1, argy1, argz1 = np.where(voxels!=0)   # non zero voxels
a = np.column_stack((argx1, argy1, argz1))
b = np.column_stack((argx, argy, argz))
tree = cKDTree(a, leafsize=a.shape[0]+1)
distances, ndx = tree.query(b, k=1, distance_upper_bound= 5.)
argx2, argy2, argz2 = a[ndx][:][:,0],a[ndx][:][:,1],a[ndx][:][:,2]
voxels[argx,argy,argz] = voxels[argx2,argy2,argz2]
toc=timeit.default_timer()
timetaken = toc - tic #elapsed time in seconds
print '\nTime to fill empty voxels', timetaken

for visualization:

from mayavi import mlab
data = voxels.astype('float')
scalar_field = mlab.pipeline.scalar_field(data)
iso_surf = mlab.pipeline.iso_surface(scalar_field)
surf = mlab.pipeline.surface(scalar_field)
vol = mlab.pipeline.volume(scalar_field,vmin=0,vmax=data.max())
mlab.outline()
mlab.show()

Now, if I have the dimension of the voxels array as something like (500,500,500), then the time it takes to compute the nearest search is no longer efficient. How can I overcome this? Could parallel computation reduce the time (I have no idea whether I can parallelize the code, if you do, please let me know)?

A potential fix:

I could substantially improve the computation time by adding the n_jobs = -1 parameter in the cKDTree query.

distances, ndx = tree.query(b, k=1, distance_upper_bound= 5., n_jobs=-1)

I was able to compute the distances in less than a hour for an array of (400,100,100) on a 13 core CPU. I tried with 1 processor and it takes around 18 hours to complete the same array.
Thanks to @gsamaras for the answer!


问:
reading a subset of files within a folder using R
I'm quite new to R and am looking to build an R script that takes a csv file containing 3 elements:

```<code>Id
Type
Filename
</code>```

The contents of the DataFrame look something like:

```<code>14261336    5   Test1.xml
16767594    8   Test2.xml
13601470    7   Test3.xml
12963658    5   Test4.xml
17771952    6   Test5.xml
</code>```

I've tried to use the following code to get the filenames, and then use these to be able to parse the XML, but I seem to be hitting a bit of a wall (down to my inexperience with R):

```<code>headerNames <- c('Id','Type','Filename')
GetNames <- read.csv(file= 'c:/temp/XML/myXMLFiles.csv', header = FALSE, col.names = headerNames) #

list(c(GetNames[3])) %>%
  map(read_xml)
</code>```

The outcome is that I get the message:
Error in UseMethod("read_xml") :
  no applicable method for 'read_xml' applied to an object of class "list"

Can one of you experts point me in the right direction please?

Many Thanks

答:
You can normally only read data from a string. Furthermore, to read xml, you will need the xmlParse() from xml-library:

```<code>library(XML)  # install it with install.packages("XML") if needed
files_inp <- as.character(GetNames[,3]) # you will need the filenames as character

for (f in files_inp) {
  assign(paste0("file",f), xmlParse(file = f))  # I never read XML files, but that should work! :-)
}
</code>```

Your output data should be variables named file1, file2, ...

Hope that helps!

Body:
I'm quite new to R and am looking to build an R script that takes a csv file containing 3 elements:

Id
Type
Filename

The contents of the DataFrame look something like:

14261336    5   Test1.xml
16767594    8   Test2.xml
13601470    7   Test3.xml
12963658    5   Test4.xml
17771952    6   Test5.xml

I've tried to use the following code to get the filenames, and then use these to be able to parse the XML, but I seem to be hitting a bit of a wall (down to my inexperience with R):

headerNames <- c('Id','Type','Filename')
GetNames <- read.csv(file= 'c:/temp/XML/myXMLFiles.csv', header = FALSE, col.names = headerNames) #

list(c(GetNames[3])) %>%
  map(read_xml)

The outcome is that I get the message:
Error in UseMethod("read_xml") :
  no applicable method for 'read_xml' applied to an object of class "list"

Can one of you experts point me in the right direction please?

Many Thanks

Body:
You can normally only read data from a string. Furthermore, to read xml, you will need the xmlParse() from xml-library:

library(XML)  # install it with install.packages("XML") if needed
files_inp <- as.character(GetNames[,3]) # you will need the filenames as character

for (f in files_inp) {
  assign(paste0("file",f), xmlParse(file = f))  # I never read XML files, but that should work! :-)
}

Your output data should be variables named file1, file2, ...

Hope that helps!


问:
Creating a UInt16 from 2 UInt8s
In order to illustrate a concept to use later for larger data types like UInt128, and UInt256, I'm trying to do the following function:

My function takes 2 UInt8s, shifts the first (theoretically the more significant bits), to the left 8 and then adds int2, (theoretically the lower bits)

```<code>func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
   let x: UInt16 = (int1 << 8) + int2
   return x
}
</code>```

Is there something that I need to do to avoid the error: (int1 << 8) + int2 isn't equal to the specified type UInt16?

答:
You must explicitly convert the smaller to the larger type:

```<code>func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    let x: UInt16 = (UInt16(int1) << 8) + UInt16(int2)
    return x
}
</code>```

This also makes the explicit type annotation unnecessary:

```<code>func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    let x = (UInt16(int1) << 8) + UInt16(int2)
    return x
}
</code>```

and it can be shortened to:

```<code>func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    return UInt16(int1) << 8 + UInt16(int2)
}
</code>```

The conversion to the larger type must be done before shifting/adding,
which might overflow otherwise.

Title: Creating a UInt16 from 2 UInt8s

Body:
In order to illustrate a concept to use later for larger data types like UInt128, and UInt256, I'm trying to do the following function:

My function takes 2 UInt8s, shifts the first (theoretically the more significant bits), to the left 8 and then adds int2, (theoretically the lower bits)

func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
   let x: UInt16 = (int1 << 8) + int2
   return x
}

Is there something that I need to do to avoid the error: (int1 << 8) + int2 isn't equal to the specified type UInt16?

Body:
You must explicitly convert the smaller to the larger type:

func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    let x: UInt16 = (UInt16(int1) << 8) + UInt16(int2)
    return x
}

This also makes the explicit type annotation unnecessary:

func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    let x = (UInt16(int1) << 8) + UInt16(int2)
    return x
}

and it can be shortened to:

func combineBits(int1: UInt8, int2: UInt8) -> UInt16 {
    return UInt16(int1) << 8 + UInt16(int2)
}

The conversion to the larger type must be done before shifting/adding,
which might overflow otherwise.


问:
How to show sas data set using group by in report
I'm working in SAS EGRC 6.1 module and I've a data set as below in work library

```<code>SAGIA_Detail
 BranchCode BranchName RegionCode SagiaLicNo IssuingDate ExpiryDate
   20         Abc      Central        1          1/1/2000     1/1/2001
   20         Abc      Central        2          1/1/2000     1/1/2001
   10         def      East           3          1/1/2000     1/1/2001

 BranchManager IsIssuance IssuanceFees IsRenewal RenewalFees Total
    name          Yes        100         No         0         100
    name          Yes        100         Yes        100       200
    name          Yes        200         Yes        100       300
</code>```

I want to print this data set in my SASStoredProcess report with group by of BranchName or by BranchName.
I wrote this code but but its only printing the data lines of my data set without any total or grandtotal row of html table.

In short it's not executing any code after the end statement of do loop. Please help me to figure out that where I did wrong in my coding.

```<code>data _null_;
 file _webout;
 put '<html><body><table>';
 do until(last.region);
 set SAGIA_Detail nobs=nobs end=eof;
 by BranchCode RegionCode BranchName;
 if first.BranchCode then put
            '<tr><th colspan="9"><span><b><u>BranchCode</u></b>: ' BranchCode '</span><span><b><u>BranchName</u></b>: '  BranchName '</span><span><b><u>RegionCode</u></b>: ' RegionCode '</sapn></th></tr>
            <tr class=Head>
                        <th>Sagia LicenseNo</th>
                        <th>Issue Date</th>
                        <th>Expiry Date</th>
                        <th>Manager Name</th>
                        <th>Is Issuance</th>
                        <th>Issuance Fees</th>
                        <th>Is Renewal</th>
                        <th>Renewal Fees</th>
                        <th>Total</th>
                    </tr>';
            put '<tr>
                    <td>';put SagiaLicNo; put '</td>
                    <td>';put IssuingDate date10.; put '</td>
                    <td>';put ExpiryDate  date10.; put '</td>
                    <td>';put BranchManager; put '</td>
                    <td>';put IsIssuance; put '</td>
                    <td>';put IssuanceFees comma12.2; put '</td>
                    <td>';put IsRenewal; put '</td>
                    <td>';put RenewalFees comma12.2; put '</td>
                    <td>';put Total comma12.2; put '</td>
                </tr>';

                Total_IssuanceFees = sum(Total_IssuanceFees,IssuanceFees);
                Total_RenewalFees = sum(Total_RenewalFees,RenewalFees);
                Total_TotalFees = sum(Total_TotalFees,Total);
  end;

  put           '<tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>';

put             '<tr class=Grand>
                    <td>Grand</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>' Total_IssuanceFees  '</td>
                    <td></td>
                    <td>' Total_RenewalFees  '</td>
                    <td>' Total_TotalFees '</td>
                </tr>';

                Issuancegrand+Total_IssuanceFees;
                Renewalgrand+Total_RenewalFees;
                Totalgrand+Total_TotalFees;

 if eof then put
  '<tr class=Grand>
      <td colspan="6">GrandTotal</td>'
      '<td>' Issuancegrand '</td>'
      '<td>' Renewalgrand '</td>'
      '<td>' Totalgrand '</td></tr>'
  '</table>
 </body>
</html>';

run;
</code>```

答:
First, you are using a BY clause, make sure your data is sorted.

```<code>proc sort data=SAGIA_Detail;
 by BranchCode RegionCode BranchName;
run;
</code>```

Second, your sample data has the variable BranchRegion but your code uses RegionCode. Are these the same? Make sure your code is using a variable that actually exists.

Further, your data step references last.region.  There is no region variable.

Fixing those should get you closer to what you are looking for.

Body:
I'm working in SAS EGRC 6.1 module and I've a data set as below in work library

SAGIA_Detail
 BranchCode BranchName RegionCode SagiaLicNo IssuingDate ExpiryDate
   20         Abc      Central        1          1/1/2000     1/1/2001
   20         Abc      Central        2          1/1/2000     1/1/2001
   10         def      East           3          1/1/2000     1/1/2001

 BranchManager IsIssuance IssuanceFees IsRenewal RenewalFees Total
    name          Yes        100         No         0         100
    name          Yes        100         Yes        100       200
    name          Yes        200         Yes        100       300

I want to print this data set in my SASStoredProcess report with group by of BranchName or by BranchName.
I wrote this code but but its only printing the data lines of my data set without any total or grandtotal row of html table.

In short it's not executing any code after the end statement of do loop. Please help me to figure out that where I did wrong in my coding.

data _null_;
 file _webout;
 put '
';
 do until(last.region);
 set SAGIA_Detail nobs=nobs end=eof;
 by BranchCode RegionCode BranchName;
 if first.BranchCode then put
            '
BranchCode: ' BranchCode 'BranchName: '  BranchName 'RegionCode: ' RegionCode '</sapn>

                        Sagia LicenseNo
                        Issue Date
                        Expiry Date
                        Manager Name
                        Is Issuance
                        Issuance Fees
                        Is Renewal
                        Renewal Fees
                        Total

';
            put '

                    ';put SagiaLicNo; put '
                    ';put IssuingDate date10.; put '
                    ';put ExpiryDate  date10.; put '
                    ';put BranchManager; put '
                    ';put IsIssuance; put '
                    ';put IssuanceFees comma12.2; put '
                    ';put IsRenewal; put '
                    ';put RenewalFees comma12.2; put '
                    ';put Total comma12.2; put '

';

                Total_IssuanceFees = sum(Total_IssuanceFees,IssuanceFees);
                Total_RenewalFees = sum(Total_RenewalFees,RenewalFees);
                Total_TotalFees = sum(Total_TotalFees,Total);
  end;

  put           '

';

put             '

                    Grand

                    ' Total_IssuanceFees  '

                    ' Total_RenewalFees  '
                    ' Total_TotalFees '

';

                Issuancegrand+Total_IssuanceFees;
                Renewalgrand+Total_RenewalFees;
                Totalgrand+Total_TotalFees;

 if eof then put
  '

      GrandTotal	'
      '' Issuancegrand '	'
      '' Renewalgrand '	'
      '' Totalgrand '
'
  '

';

run;

Body:
First, you are using a BY clause, make sure your data is sorted.

proc sort data=SAGIA_Detail;
 by BranchCode RegionCode BranchName;
run;

Second, your sample data has the variable BranchRegion but your code uses RegionCode. Are these the same? Make sure your code is using a variable that actually exists.

Further, your data step references last.region.  There is no region variable.

Fixing those should get you closer to what you are looking for.


问:
How to deploy an edited node module package(local) to heroku without losing the changes?
So, I have a situation where I needed to edit a node module package I'm using in my node app. Now, on deploying the app to heroku the changes are getting lost because it is getting that package from npm. </p>

<p>Please suggest a way other than publishing my own version of that package to npm. </p>

答:
I don't think you can :/

I have a bot deployed there and every time I wanna deploy some new changes everything gets lost. Probably you should check some external packages installed by Heroku.

Body:
So, I have a situation where I needed to edit a node module package I'm using in my node app. Now, on deploying the app to heroku the changes are getting lost because it is getting that package from npm.

Please suggest a way other than publishing my own version of that package to npm.


问:
How to find the second minimum number without using arrays or loops
I tried to write a program that receive from the user 5 integers and print the second minimum number.

Here is a sample of what I've tried:

```<code>#include <iostream>
using namespace std;
int main () {
int a,b,c,d,e;
cin>>a>>b>>c>>d>>e;
if (a>b && a<c && a<d && a<e)
    cout<<a<<endl;
if (b>a && b<c && b<d && b<e)
    cout<<b<<endl;
if (c>a && c<b && c<d && c<e)
    cout<<c<<endl;
if (d>a && d<b && d<c && d<e)
    cout <<d<<endl;
if (e>a && e<b && e<c && e<d)
cout <<e<<endl;
return 0;

}
</code>```

When I enter 1 2 3 4 5 it prints the second minimum, but when I enter

5 4 3 2 1 Nothing will print on the screen. What am I doing wrong with this? Is there any other way to write my program?

答:
One approach is to first find the minimum number, min and then find the smallest value that isn't min. To do this first find the minimum value:

```<code>int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));
</code>```

Now we need to do the same again, but ignoring min. We can do this using a function called triMin which takes 3 values and discards any value that is the minimum:

```<code>int triMin(int currentMin, int left, int right)
{
    if(currentMin == left) return right;
    if(currentMin == right) return left;

    return std::min(left, right);
}
</code>```

You can now combine them to get the answer:

```<code>int a = 5, b = 4, c = 3, d = 2, e = 1;

int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));
int min2 = triMin(min, a, triMin(min, b, triMin(min, c, triMin(min, d, e))));

std::cout << "Second min = " << min2 << std::endl;
</code>```

This prints 2

Body:
I tried to write a program that receive from the user 5 integers and print the second minimum number.

Here is a sample of what I've tried:

#include <iostream>
using namespace std;
int main () {
int a,b,c,d,e;
cin>>a>>b>>c>>d>>e;
if (a>b && a<c && a<d && a<e)
    cout<<a<<endl;
if (b>a && b<c && b<d && b<e)
    cout<<b<<endl;
if (c>a && c<b && c<d && c<e)
    cout<<c<<endl;
if (d>a && d<b && d<c && d<e)
    cout <<d<<endl;
if (e>a && e<b && e<c && e<d)
cout <<e<<endl;
return 0;

}

When I enter 1 2 3 4 5 it prints the second minimum, but when I enter

5 4 3 2 1 Nothing will print on the screen. What am I doing wrong with this? Is there any other way to write my program?

Body:
One approach is to first find the minimum number, min and then find the smallest value that isn't min. To do this first find the minimum value:

int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));

Now we need to do the same again, but ignoring min. We can do this using a function called triMin which takes 3 values and discards any value that is the minimum:

int triMin(int currentMin, int left, int right)
{
    if(currentMin == left) return right;
    if(currentMin == right) return left;

    return std::min(left, right);
}

You can now combine them to get the answer:

int a = 5, b = 4, c = 3, d = 2, e = 1;

int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));
int min2 = triMin(min, a, triMin(min, b, triMin(min, c, triMin(min, d, e))));

std::cout << "Second min = " << min2 << std::endl;

This prints 2