问:
How to create a new string list from a list of strings excluding one variable?
I have a list of strings and I'm trying to iterate through it and create each iteration a new list without one of the strings.
I tried the following:

```<code>tx_list = ['9540a4ff214d6368cc557803e357f8acebf105faad677eb06ab10d1711d3db46', 'dd92415446692593a4768e3604ab1350c0d81135be42fd9581e2e712f11d82ed',....]
for txid in tx_list:
    tx_list_copy = tx_list
    tx_list_without_txid = tx_list_copy.remove(txid)
</code>```

But each iteration the new list is empty.

答:
You may try this:</p>

```<code>for i in range(len(tx_list)) :
    tx_list_without_txid = tx_list[:i] + tx_list[i+1:]
    # do something with the new list...
</code>```

Body:
I have a list of strings and I'm trying to iterate through it and create each iteration a new list without one of the strings.
I tried the following:

tx_list = ['9540a4ff214d6368cc557803e357f8acebf105faad677eb06ab10d1711d3db46', 'dd92415446692593a4768e3604ab1350c0d81135be42fd9581e2e712f11d82ed',....]
for txid in tx_list:
    tx_list_copy = tx_list
    tx_list_without_txid = tx_list_copy.remove(txid)

But each iteration the new list is empty.

Body:
You may try this:

for i in range(len(tx_list)) :
    tx_list_without_txid = tx_list[:i] + tx_list[i+1:]
    # do something with the new list...


来源: stackexchange

问:
Waking up a thread waiting on a condition in infinite loop
I have a pretty basic producer / consumer implementation. The producer is the "main" thread, and the consumer is executed on a separate thread. However the consumer needs to be explicitly started, using a Start() function. This sets the "processing" flag to true (used in the infinite while loop).

Once in the while loop, the consumer then uses a condition variable to see if there is data in the queue to process. If yes, it does its work, goes back to the top of the infinite loop, then the condition variable, and so on.

The problem I am having is the consumer is waiting for data in the queue, and I want to stop processing. How can I wake up the consumer? I have provided some example code below, removing some major components, just showing the high level design (everything is not actually public).

```<code>// Consumer object
class Consumer {
public:
  std::mutex mtx_;
  bool processing_ = false;
  std::thread processing_thread_;
  std::queue<int> data_;
  std::condition_variable cv_;
  ~Consumer() {
    // Make sure the processing thread is stopped
    {
      std::lock_guard<std::mutex> lock(mtx_);
      processing_ = false;
    }

    if (processing_thread_.joinable()) {

      processing_thread_.join();
    }
  }
  void Start() {
    std::lock_guard<std::mutex> lock(mtx_);

    processing_ = true;
    processing_thread_ = std::thread(
      &Consumer::Run,
       this);
  }
  void Stop() {
    std::lock_guard<std::mutex> lock(mtx_);

    processing_ = false;
  }
  void AddData(int d) {
    std::lock_guard<std::mutex> lock(mtx_);
    data_.push(d);
    cv_.notify_one();
  }
  bool IsDataAvailable() const {
    return (!data.empty());
  }
  void Run() {

    // The infinite loop
    while (processing_) {
      // This is where I get stuck waiting even tho processing has been
      // changed to false by the main thread
      std::unique_lock<std::mutex> lock(mtx_);
      cv_.wait(lock, std::bind(
        &Consumer::IsDataAvailable, this));
      // do some processing
    }
  }

}; // end of consumer

// Somewhere in main trying to stop the processing thread cause I am
// done processing OR my_consumer goes out of scope and tries to join
// ...
  my_consumer.Stop();
}
// my_consumer goes out of scope here calling destructor.
</code>```

答:
A couple of changes is required for the consumer to wait for change in processing_:

```<code>~Consumer() {
  if (processing_thread_.joinable()) {
    Stop();
    processing_thread_.join();
  }
}
// ...
void Stop() {
  std::lock_guard<std::mutex> lock(mtx_);
  processing_ = false;
  cv_.notify_one();
}
// ...

void Run() {
  for(;;) {
    std::unique_lock<std::mutex> lock(mtx_);
    // Wait till something is put into the queue or stop requested.
    cv_.wait(lock, [this]() { return !processing_ || !data_.empty(); });
    if(!data_.empty())
      // Process queue elements.
    else if(!processing_)
      return; // Only exit when the queue is empty.
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a pretty basic producer / consumer implementation. The producer is the "main" thread, and the consumer is executed on a separate thread. However the consumer needs to be explicitly started, using a Start() function. This sets the "processing" flag to true (used in the infinite while loop).

Once in the while loop, the consumer then uses a condition variable to see if there is data in the queue to process. If yes, it does its work, goes back to the top of the infinite loop, then the condition variable, and so on.

The problem I am having is the consumer is waiting for data in the queue, and I want to stop processing. How can I wake up the consumer? I have provided some example code below, removing some major components, just showing the high level design (everything is not actually public).

// Consumer object
class Consumer {
public:
  std::mutex mtx_;
  bool processing_ = false;
  std::thread processing_thread_;
  std::queue<int> data_;
  std::condition_variable cv_;
  ~Consumer() {
    // Make sure the processing thread is stopped
    {
      std::lock_guard<std::mutex> lock(mtx_);
      processing_ = false;
    }

    if (processing_thread_.joinable()) {

      processing_thread_.join();
    }
  }
  void Start() {
    std::lock_guard<std::mutex> lock(mtx_);

    processing_ = true;
    processing_thread_ = std::thread(
      &Consumer::Run,
       this);
  }
  void Stop() {
    std::lock_guard<std::mutex> lock(mtx_);

    processing_ = false;
  }
  void AddData(int d) {
    std::lock_guard<std::mutex> lock(mtx_);
    data_.push(d);
    cv_.notify_one();
  }
  bool IsDataAvailable() const {
    return (!data.empty());
  }
  void Run() {

    // The infinite loop
    while (processing_) {
      // This is where I get stuck waiting even tho processing has been
      // changed to false by the main thread
      std::unique_lock<std::mutex> lock(mtx_);
      cv_.wait(lock, std::bind(
        &Consumer::IsDataAvailable, this));
      // do some processing
    }
  }

}; // end of consumer

// Somewhere in main trying to stop the processing thread cause I am
// done processing OR my_consumer goes out of scope and tries to join
// ...
  my_consumer.Stop();
}
// my_consumer goes out of scope here calling destructor.

Body:
A couple of changes is required for the consumer to wait for change in processing_:

~Consumer() {
  if (processing_thread_.joinable()) {
    Stop();
    processing_thread_.join();
  }
}
// ...
void Stop() {
  std::lock_guard<std::mutex> lock(mtx_);
  processing_ = false;
  cv_.notify_one();
}
// ...

void Run() {
  for(;;) {
    std::unique_lock<std::mutex> lock(mtx_);
    // Wait till something is put into the queue or stop requested.
    cv_.wait(lock, [this]() { return !processing_ || !data_.empty(); });
    if(!data_.empty())
      // Process queue elements.
    else if(!processing_)
      return; // Only exit when the queue is empty.
  }
}


问:
Add column to table with Liquibase
I'm new to back-end development and currently trying to add a column to my app_user table. like below.

```<code>- changeSet:
      id: 300520202335
      author: Malindu De Alwis
      changes:
        - addColumn:
            tableName: app_user
              columns:
              -column:
                name: address
                type: VARCHAR(255)
</code>```

It gives this error

```<code>Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here
</code>```

in 'reader', line 23, column 22:
                  columns:
                         ^

I use Spring boot and postgre sql. Please try to figureout the issue

答:
If you look at an example yaml test changelog like the one included here : https://github.com/liquibase/liquibase/blob/master/liquibase-core/src/test/resources/liquibase/parser/core/yaml/testCasesChangeLog.yaml -- you will be able to replicate an addColumn change type in yaml format that works. For example:

```<code>    - changeSet:
        id: using after column attribute
        author: cmouttet
        changes:
            - addColumn:
                columns:
                    - column:
                        afterColumn: firstname
                        name: middlename
                        type: varchar(50)
                tableName: person
</code>```

I believe @tobhai is correct though -- there is missing whitespace in - column.

Title: Add column to table with Liquibase

Body:
I'm new to back-end development and currently trying to add a column to my app_user table. like below.

- changeSet:
      id: 300520202335
      author: Malindu De Alwis
      changes:
        - addColumn:
            tableName: app_user
              columns:
              -column:
                name: address
                type: VARCHAR(255)

It gives this error

Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here

in 'reader', line 23, column 22:
                  columns:
                         ^

I use Spring boot and postgre sql. Please try to figureout the issue

Body:
If you look at an example yaml test changelog like the one included here : https://github.com/liquibase/liquibase/blob/master/liquibase-core/src/test/resources/liquibase/parser/core/yaml/testCasesChangeLog.yaml -- you will be able to replicate an addColumn change type in yaml format that works. For example:

    - changeSet:
        id: using after column attribute
        author: cmouttet
        changes:
            - addColumn:
                columns:
                    - column:
                        afterColumn: firstname
                        name: middlename
                        type: varchar(50)
                tableName: person

I believe @tobhai is correct though -- there is missing whitespace in - column.


问:
How to randomly assign to treatment groups for online web study?
I am conducting a web study where participants will be proportionately and randomly assigned to treatment groups in the form of different web pages.  I have a study landing page where I plan to assign participants to different treatment groups by directing them to different pages based on a random integer within the range of the sample size.  For example, for a n=100 study, this code might look like:

```<code>/// Function for randomly shuffling array
function shuffle(array) {
  array.sort(() => Math.random() - 0.5);
}

const STUDY_LEN = 100;  /// Study n
const arr_0 = new Array(STUDY_LEN/2).fill(0);  /// Create array for treatment 1
const arr_1 = new Array(STUDY_LEN/2).fill(1);  /// Create array for treatment 2

const arr_assign = arr_0.concat(arr_1);  /// Concatenate treatment arrays for entire study assignment
arr_shuffle = shuffle(arr_assign);  /// Randomize order of array

for (i = 0; i < STUDY_LEN-1; i++){
  if (arr_shuffle[i] == 0){
    //// Change hyperlink to web page for treatment 1
}
  else{
    //// Change hyperlink to web page for treatment 2
  }
}
</code>```

How can I store these variables (mainly the shuffled assignment array) across multiple visits to the web page so that I assign participants to each treatment equally (50 participants in treatment 1, 50 participants in treatment 2)?  My solution doesn't seem like a very robust way to randomly assign users to different treatments, so I'm open to any/all suggestions.

答:
You'll have to get the test type from a server if you want to randomly but equally distribute the tests

```<code>function getTestType () {
  if (Math.random() < 0.5) {
    // This will ensure that the maximum number of occurences for the test A will be 50.
    if (getNumberOfOccurencesOfTestA() < 50) {
      return true; // Test A
    }
  }

  // This will ensure that the maximum number of occurences for the test B will be 50.
  if (getNumberOfOccurencesOfTestB() < 50) {
    return false; // Test B
  }

  // Just return 'undefined' if both of the test already have 50 occurences each.
  return;
}
</code>```

The "getNumberOfOccurencesOfTestA" and "getNumberOfOccurencesOfTestB" are functions that look in a variable that keeps the state of the number occurences of test A and test B occuring respectivelly, it can be a global variable, a database, a file etc.

Body:
I am conducting a web study where participants will be proportionately and randomly assigned to treatment groups in the form of different web pages.  I have a study landing page where I plan to assign participants to different treatment groups by directing them to different pages based on a random integer within the range of the sample size.  For example, for a n=100 study, this code might look like:

/// Function for randomly shuffling array
function shuffle(array) {
  array.sort(() => Math.random() - 0.5);
}

const STUDY_LEN = 100;  /// Study n
const arr_0 = new Array(STUDY_LEN/2).fill(0);  /// Create array for treatment 1
const arr_1 = new Array(STUDY_LEN/2).fill(1);  /// Create array for treatment 2

const arr_assign = arr_0.concat(arr_1);  /// Concatenate treatment arrays for entire study assignment
arr_shuffle = shuffle(arr_assign);  /// Randomize order of array

for (i = 0; i < STUDY_LEN-1; i++){
  if (arr_shuffle[i] == 0){
    //// Change hyperlink to web page for treatment 1
}
  else{
    //// Change hyperlink to web page for treatment 2
  }
}

How can I store these variables (mainly the shuffled assignment array) across multiple visits to the web page so that I assign participants to each treatment equally (50 participants in treatment 1, 50 participants in treatment 2)?  My solution doesn't seem like a very robust way to randomly assign users to different treatments, so I'm open to any/all suggestions.

Body:
You'll have to get the test type from a server if you want to randomly but equally distribute the tests

function getTestType () {
  if (Math.random() < 0.5) {
    // This will ensure that the maximum number of occurences for the test A will be 50.
    if (getNumberOfOccurencesOfTestA() < 50) {
      return true; // Test A
    }
  }

  // This will ensure that the maximum number of occurences for the test B will be 50.
  if (getNumberOfOccurencesOfTestB() < 50) {
    return false; // Test B
  }

  // Just return 'undefined' if both of the test already have 50 occurences each.
  return;
}

The "getNumberOfOccurencesOfTestA" and "getNumberOfOccurencesOfTestB" are functions that look in a variable that keeps the state of the number occurences of test A and test B occuring respectivelly, it can be a global variable, a database, a file etc.


问:
How to generate a unique id in a recursive function in PHP?
In my recursive function I can't generate a unique id (via an incremented variable) for my multidimensional array, here is what I tried.

I need to assign a unique ID for each directory name I find: $data[] = ['id'=>$i,'text'=>$dir];

```<code>    function scandir_rec($root, $i)
    {
        $data = [];

        if (!is_dir($root)) {
            return;
        }

        $dirs = scandir($root);

        foreach ($dirs as $dir) {

            $i++;

            if ($dir == '.' || $dir == '..') {
                continue;
            }

            $path = $root . '/' . $dir;

            if (is_file($path)) {
                continue;
            }

            if (is_dir($path)) {

                $nodes = scandir_rec($path, $i); // <--- unique ID

                if (!empty($nodes)) $chunk['children'] = $nodes;
            }

            $data[] = [ 'id' =>  $i, 'text' =>  $dir ]; // <--- unique ID
        }

        return $data;
    }

    $rootDir = '/var/www/html';
    $i = 0;
    $json_data = json_encode(scandir_rec($rootDir, $i), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); // <--- unique ID
    file_put_contents('tree.json', $json_data);
</code>```

Desired result

```<code>    [
    {
       "id":1,
       "text":"Root folder",
       "children":[
          {
             "id":2,
             "text":"Child folder 1"
          },
          {
             "id":3,
             "text":"Child folder 2"
          }
       ]
    },
    {
        "id":4,
        "text":"Root folder"
     },
    {
       "id":5,
       "text":"Root folder",
       "children":[
          {
             "id":6,
             "text":"Child folder 1"
          },
          {
             "id":7,
             "text":"Child folder 2"
          }
       ]
    }
 ]
</code>```

答:
Personally I hate returning from recursive functions, it tends to get weird unless you are returning a status for the caller to do something with. Instead, it is often easier to use byref parameters.

I've commented the code below, hopefully it makes sense. We're passing two parameters byref, one is "the current array to add stuff to" and the other is "the global index". We're also keeping track of depth because you are treating the root differently than children.

function scandir_rec(string $root, array &$current_parent, int &$global_index, int $depth = 0): void
{
    // Bail early if we don't have a directory
    if (!is_dir($root)) {
        return;
    }

    // Get the children
    $dirs = scandir($root);

    // This is the local child index and resets for successive calls
    $local_index = 1;
    foreach ($dirs as $dir) {

        // Once again, bail early if we can
        if ($dir === '.' || $dir === '..') {
            continue;
        }

        // The next path to scan
        $next_path = $root . '/' . $dir;

        // Make sure it isn't a file
        if (is_file($next_path)) {
            continue;
        }

        // Everyone gets this
        $current_node = [
            // Set the ID and increment so that the next gets a bigger one
            'id' => $global_index++,
            // Root node is treated differently thant children
            'text' => 0 === $depth ? 'Root node' : "Child node ${local_index}",
        ];

        // If the next node is a directory
        if (is_dir($next_path)) {
            // Create a temporary holder for the contents
            $children = [];

            // Scan again, incrementing the depth by one
            scandir_rec($next_path, $children, $global_index, ++$depth);

            // If the above did something to our array, append to our local (the master)
            if ($children) {
                $current_node['children'] = $children;
            }
        }

        // Append the current node
        $current_parent[] = $current_node;

    }
}
```

<p>To call this, remember that it doesn't return so we need to run it by itself, We also want to pass the global index in by ref so we need to create a variable to hold it.</p>

<pre class="lang-php prettyprint-override"><code>$current_parent = [];
$global_index = 1;
scandir_rec('/var/www', $current_parent, $global_index);
$json_data = json_encode($current_parent, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
</code>```

This code is written against PHP 7.4 do you might need to tweak a couple of things if you are on an older version.

edit

In hindsight, I was taking your text too literally, I think. You can probably get rid of the $depth parameter completely and just set your text to:

            'text' => $root,
```

<p>I'm running this from Windows and I just ran a quick test folder which produced:</p>

```[
    {
        "id": 1,
        "text": "/Dell",
        "children": [
            {
                "id": 2,
                "text": "/Dell/25tgw",
                "children": [
                    {
                        "id": 3,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 4,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 5,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 6,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    }
                ]
            }
        ]
    },
    {
        "id": 7,
        "text": "/Dell",
        "children": [
            {
                "id": 8,
                "text": "/Dell/UpdatePackage"
            }
        ]
    },
    {
        "id": 9,
        "text": "/Dell"
    }
]
```

Body:
In my recursive function I can't generate a unique id (via an incremented variable) for my multidimensional array, here is what I tried.

I need to assign a unique ID for each directory name I find: $data[] = ['id'=>$i,'text'=>$dir];

    function scandir_rec($root, $i)
    {
        $data = [];

        if (!is_dir($root)) {
            return;
        }

        $dirs = scandir($root);

        foreach ($dirs as $dir) {

            $i++;

            if ($dir == '.' || $dir == '..') {
                continue;
            }

            $path = $root . '/' . $dir;

            if (is_file($path)) {
                continue;
            }

            if (is_dir($path)) {

                $nodes = scandir_rec($path, $i); // <--- unique ID

                if (!empty($nodes)) $chunk['children'] = $nodes;
            }

            $data[] = [ 'id' =>  $i, 'text' =>  $dir ]; // <--- unique ID
        }

        return $data;
    }

    $rootDir = '/var/www/html';
    $i = 0;
    $json_data = json_encode(scandir_rec($rootDir, $i), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); // <--- unique ID
    file_put_contents('tree.json', $json_data);

Desired result

    [
    {
       "id":1,
       "text":"Root folder",
       "children":[
          {
             "id":2,
             "text":"Child folder 1"
          },
          {
             "id":3,
             "text":"Child folder 2"
          }
       ]
    },
    {
        "id":4,
        "text":"Root folder"
     },
    {
       "id":5,
       "text":"Root folder",
       "children":[
          {
             "id":6,
             "text":"Child folder 1"
          },
          {
             "id":7,
             "text":"Child folder 2"
          }
       ]
    }
 ]

Body:
Personally I hate returning from recursive functions, it tends to get weird unless you are returning a status for the caller to do something with. Instead, it is often easier to use byref parameters.

I've commented the code below, hopefully it makes sense. We're passing two parameters byref, one is "the current array to add stuff to" and the other is "the global index". We're also keeping track of depth because you are treating the root differently than children.

function scandir_rec(string $root, array &$current_parent, int &$global_index, int $depth = 0): void
{
    // Bail early if we don't have a directory
    if (!is_dir($root)) {
        return;
    }

    // Get the children
    $dirs = scandir($root);

    // This is the local child index and resets for successive calls
    $local_index = 1;
    foreach ($dirs as $dir) {

        // Once again, bail early if we can
        if ($dir === '.' || $dir === '..') {
            continue;
        }

        // The next path to scan
        $next_path = $root . '/' . $dir;

        // Make sure it isn't a file
        if (is_file($next_path)) {
            continue;
        }

        // Everyone gets this
        $current_node = [
            // Set the ID and increment so that the next gets a bigger one
            'id' => $global_index++,
            // Root node is treated differently thant children
            'text' => 0 === $depth ? 'Root node' : "Child node ${local_index}",
        ];

        // If the next node is a directory
        if (is_dir($next_path)) {
            // Create a temporary holder for the contents
            $children = [];

            // Scan again, incrementing the depth by one
            scandir_rec($next_path, $children, $global_index, ++$depth);

            // If the above did something to our array, append to our local (the master)
            if ($children) {
                $current_node['children'] = $children;
            }
        }

        // Append the current node
        $current_parent[] = $current_node;

    }
}

To call this, remember that it doesn't return so we need to run it by itself, We also want to pass the global index in by ref so we need to create a variable to hold it.

$current_parent = [];
$global_index = 1;
scandir_rec('/var/www', $current_parent, $global_index);
$json_data = json_encode($current_parent, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);

This code is written against PHP 7.4 do you might need to tweak a couple of things if you are on an older version.

edit

In hindsight, I was taking your text too literally, I think. You can probably get rid of the $depth parameter completely and just set your text to:

            'text' => $root,

I'm running this from Windows and I just ran a quick test folder which produced:

[
    {
        "id": 1,
        "text": "/Dell",
        "children": [
            {
                "id": 2,
                "text": "/Dell/25tgw",
                "children": [
                    {
                        "id": 3,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 4,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 5,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    },
                    {
                        "id": 6,
                        "text": "/Dell/25tgw/RealtekHDAudio"
                    }
                ]
            }
        ]
    },
    {
        "id": 7,
        "text": "/Dell",
        "children": [
            {
                "id": 8,
                "text": "/Dell/UpdatePackage"
            }
        ]
    },
    {
        "id": 9,
        "text": "/Dell"
    }
]


问:
How to measure usability to get hard data?
There are a few posts on usability but none of them was useful to me.

I need a quantitative measure of usability of some part of an application.
I need to estimate it in hard numbers to be able to compare it with future versions (for e.g. reporting purposes). The simplest way is to count clicks and keystrokes, but this seems too simple (for example is the cost of filling a text field a simple sum of typing all the letters ? - I guess it is more complicated).
I need some mathematical model for that so I can estimate the numbers.

Does anyone know anything about this?

P.S. I don't need links to resources about designing user interfaces. I already have them. What I need is a mathematical apparatus to measure existing applications interface usability in hard numbers.

Thanks in advance.

答:
First you want to define goals: for example increasing the percentage of users who can complete a certain set of tasks, and reducing the time they need for it.

Then, get two cameras, a few users (5-10) give them a list of tasks to complete and ask them to think out loud. Half of the users should use the "old" system, the rest should use the new one.

Review the tapes, measure the time it took, measure success rates, discuss endlessly about interpretations.

Alternatively, you can develop a system for bucket-testing -- it works the same way, though it makes it far more difficult to find out something new. On the other hand, it's much cheaper, so you can do many more iterations. Of course that's limited to sites you can open to public testing.

That obviously implies you're trying to get comparative data between two designs. I can't think of a way of expressing usability as a value.

OwnerDisplayName: lbownik

ContentLicense: CC BY-SA 2.5

LastEditorDisplayName: bdukes

OwnerDisplayName: Pies


问:
Cannot save a url as a value in a PropertiesConfiguration object
This one has me stumped.

I have something like:

```<code>PropertiesConfiguration pc = new PropertiesConfiguration();
pc.setProperty("url", "jdbc:postgres://localhost:5432/somedb");
pc.setBasePath(".");
pc.setFileName("my.properties");
</code>```

I have this code in a jar that was built on Linux.  When it gets run on a Windows box, then the file that gets saved comes out like:

```<code>url = jdbc:postgres:\/\/localhost:5432/somedb.
</code>```

This file is going to get consumed by some python code, and it's not at all happy with that URL.

I've searched and searched, but for the life of me, I don't understand why PC would be escaping a forward slash.

Any clues?

答: I faced a similar issue i was able to resolve it by using backward slash. Try to use '\' instead of '/' for windows system. </p>

ContentLicense: CC BY-SA 3.0

Body:
This one has me stumped.

I have something like:

PropertiesConfiguration pc = new PropertiesConfiguration();
pc.setProperty("url", "jdbc:postgres://localhost:5432/somedb");
pc.setBasePath(".");
pc.setFileName("my.properties");

I have this code in a jar that was built on Linux.  When it gets run on a Windows box, then the file that gets saved comes out like:

url = jdbc:postgres:\/\/localhost:5432/somedb.

This file is going to get consumed by some python code, and it's not at all happy with that URL.

I've searched and searched, but for the life of me, I don't understand why PC would be escaping a forward slash.

Any clues?


问:
Refund payment by order line item ID
Can I refund an Order/Payment by specifying the the uid of the OrderLineItem instead of specifying a Money?

答:
Not via the API, but you could via the Dashboard or POS application. The API currently does not support itemized refunds.

https://developer.squareup.com/reference/square/refunds-api/refund-payment

Title: Refund payment by order line item ID


问:
Can I continue the for loop from callback inside the loop?
I am using selenium concurrently element checking using timer in c#. If element found the call back will call then I need to continue the for loop.

This is my code, it is not working. Any Suggestions?

for (i = 0; i < list.length(); i++) {
    //statement
    mycallback((s) => { if(s) continue; }); // continue here
    //statement
}
```

答:
in C# you can use labels to go where you want.
they transfer the program control directly to a labeled statement

look at the snippet below:

```<code>for (i = 0; i < list.length(); i++) {
    //statement

    mycallback((s) => { if(s) goto myLabel; });

    // continue here
    myLabel: // parts of your code

    //statement
}
</code>```

it is not recommended though that could be useful in some cases.

more info about this syntax:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto

more discussion about using labels: Does anyone still use [goto] in C# and if so why?

Body:
in C# you can use labels to go where you want.
they transfer the program control directly to a labeled statement

look at the snippet below:

for (i = 0; i < list.length(); i++) {
    //statement

    mycallback((s) => { if(s) goto myLabel; });

    // continue here
    myLabel: // parts of your code

    //statement
}

it is not recommended though that could be useful in some cases.

more info about this syntax:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto

more discussion about using labels: Does anyone still use [goto] in C# and if so why?


问:
how to plot a scatter plot if there are hundreds of rows in a column using matplotlib or seaborn
x axis is cluttered on the chart with 100 rows.How to deal with this kind of columns?

```<code>  plt.scatter(data=ipl,x='budget',y='player')
</code>```

答:
You can try showing every nth tick-label on the x-axis</p>

```<code>fig, ax = plt.subplots()

ax.scatter(data=ipl,x='budget',y='player')

n = 4

for idx, label in enumerate(ax.xaxis.get_ticklabels()):
    if idx % n != 0:
        label.set_visible(False)
</code>```

Body:
x axis is cluttered on the chart with 100 rows.How to deal with this kind of columns?

  plt.scatter(data=ipl,x='budget',y='player')

Body:
You can try showing every nth tick-label on the x-axis

fig, ax = plt.subplots()

ax.scatter(data=ipl,x='budget',y='player')

n = 4

for idx, label in enumerate(ax.xaxis.get_ticklabels()):
    if idx % n != 0:
        label.set_visible(False)


问:
How to constrain Interface generic to only string or object or null?

export interface Foo<T extends string | object | null> {
  bar: T;
}

type Callback<T = any> = (res: T) => void

function hydra<T extends string | object | null>(callback: Callback<Foo<T>>) {
    callback({
        bar: 'Hello World'
    });
}

```

<p>I doesn't work. It throws this error:</p>

<pre class="lang-js prettyprint-override"><code>Type '"Hello World"' is not assignable to type 'T'.
  '"Hello World"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | object | null'.
</code>```

Playground Link

How can I solve this issue?

答:
You can make a subtype which contains your constraints, and have that declared as the value of bar. This way you don't have the constraint issues where T could be something else than the provided string:

```<code>export type FooType = string | object | null;

export interface Foo {
  bar: FooType;
}

type Callback<T = any> = (res: T) => void

function returnResponse(callback: Callback<Foo>) {
  callback({
    bar: 'INVAILD_REQUEST'
  });
}
</code>```

This will make your lose your generic type hinting though. So another solution would be to use as T.

```<code>export interface Foo<T extends string | object | null> {
  bar: T;
}

type Callback<T = any> = (res: T) => void

function hydra<T extends string | object | null>(callback: Callback<Foo<T>>) {
  callback({
    bar: 'Hello World' as T
  });
}
</code>```

The reason you have to do that is because if a consumer of the hydra function passes in a callback with a different generic type, your type string does not suffice anymore. Like the error message says:

'"Hello World"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | object | null'.

If you have an error like this, you always need to do a as T to make the compiler happy

Body:
export interface Foo<T extends string | object | null> {
  bar: T;
}

type Callback<T = any> = (res: T) => void

function hydra<T extends string | object | null>(callback: Callback<Foo<T>>) {
    callback({
        bar: 'Hello World'
    });
}

I doesn't work. It throws this error:

Type '"Hello World"' is not assignable to type 'T'.
  '"Hello World"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | object | null'.

Playground Link

How can I solve this issue?

Body:
You can make a subtype which contains your constraints, and have that declared as the value of bar. This way you don't have the constraint issues where T could be something else than the provided string:

export type FooType = string | object | null;

export interface Foo {
  bar: FooType;
}

type Callback<T = any> = (res: T) => void

function returnResponse(callback: Callback<Foo>) {
  callback({
    bar: 'INVAILD_REQUEST'
  });
}

This will make your lose your generic type hinting though. So another solution would be to use as T.

export interface Foo<T extends string | object | null> {
  bar: T;
}

type Callback<T = any> = (res: T) => void

function hydra<T extends string | object | null>(callback: Callback<Foo<T>>) {
  callback({
    bar: 'Hello World' as T
  });
}

The reason you have to do that is because if a consumer of the hydra function passes in a callback with a different generic type, your type string does not suffice anymore. Like the error message says:

'"Hello World"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | object | null'.

If you have an error like this, you always need to do a as T to make the compiler happy


问:
Retrieving a property from an action value in Angular 9 & NgRx reducer
I'm having trouble retrieving the property of a value in an NgRx reducer. I'm trying to extract the accessToken of the user object and store it in the state. However, despite the user object being valid and containing a valid accessToken, when I try to retrieve the accessToken it returns undefined.

In the debugger if I hover over the user object, I can see the full value with all the properties including accessToken, but if I skip to the next line and hover over accessToken object it shows undefined.

```<code>import { createReducer, on } from '@ngrx/store';
import { User } from 'src/app/models/user.model';
import { AuthActions } from '../action-types';

export const authFeatureKey = 'auth';

export interface AuthState {
  user: User;
  accessToken: string;
}

export const initialAuthState: AuthState = {
  user: undefined,
  accessToken: undefined,
};

const reducer = createReducer(
  initialAuthState,

  on(AuthActions.signup, (state, action) => {
    return {
      user: action.user,
      accessToken: action.user.accessToken,
    };
  }),

  on(AuthActions.signin, (state, action) => {
    // split out to debug.
    const user = <User>action.user; // action.user returns a valid object
    const token = user.accessToken; // despite this being valid in the user object, returns undefined.
    return {
      user: action.user,
      accessToken: token,
    };
  }),

  on(AuthActions.signOut, () => {
    return {
      user: undefined,
      accessToken: undefined,
    };
  }),
);

export function authReducer(state, action) {
  return reducer(state, action);
}
</code>```

These are the actions:

```<code>import { createAction, props } from '@ngrx/store';
import { User } from '../../models/user.model';

export const signup = createAction('[SignUp Page] User SignUp', props<{ user: User }>());

export const signin = createAction('[SignIn Page] User SignIn', props<{ user: User }>());

export const signOut = createAction('[Top Menu] User SignOut');
</code>```

and these are the selectors:

```<code>import { createFeatureSelector, createSelector } from '@ngrx/store';
import * as fromAuth from './reducers';

export const selectAuthState = createFeatureSelector<fromAuth.AuthState>(fromAuth.authFeatureKey);

export const isLoggedIn = createSelector(selectAuthState, (auth) => !!auth.user);

export const isLoggedOut = createSelector(isLoggedIn, (loggedIn) => !loggedIn);

export const getCurrentUser = createSelector(selectAuthState, (auth) => auth.user);

export const getAccessToken = createSelector(selectAuthState, (auth) => auth.accessToken);
</code>```

This is the auth.module.ts, showing the import of the authReducer (as requested)

```<code>import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { AuthRoutingModule } from './auth-routing.module';
import { AuthService } from './services/auth.service';
import * as fromAuth from './store/reducers';
import { AuthEffects } from './store/auth-effects';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    AuthRoutingModule,
    HttpClientModule,
    StoreModule.forFeature(fromAuth.authFeatureKey, fromAuth.authReducer),
    EffectsModule.forFeature([AuthEffects]),
  ],
  providers: [AuthService],
})
export class AuthModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: AuthModule,
      providers: [AuthService],
    };
  }
}
</code>```

I have noticed that in the state, it's storing the value somewhat weirdly:

```<code>auth
    user
      user
         userName: "username1"
         email: "email@email.com"
         accessToken: "ey......7z"
         refreshToken: "xxx"
</code>```

So it looks like it's somehow nesting the user object.

答:
This was my mistake, the service was passing the result back as a User object:

```<code>  signin(credentials: SignInCredentials): Observable<User> {
    return this.http.post<User>('/api/signin', credentials);
  }
</code>```

However, it was actually the user inside an object:

```<code>{
   user: {
      userName:
      ...
   }
}
</code>```

This is where it all went wrong. So I changed the service to return an any:

```<code>  signin(credentials: SignInCredentials): Observable<any> {
    return this.http.post<User>('/api/signin', credentials);
  }
</code>```

and changed the action dispatch:

```<code>this.authService
  .signin(this.credentials)
  .pipe(
    tap((data: any) => {
      this.store.dispatch(AuthActions.signin({ user: data.user }));
      this.router.navigateByUrl('/');
    }),
</code>```

Feeling like an idiot.

Body:
I'm having trouble retrieving the property of a value in an NgRx reducer. I'm trying to extract the accessToken of the user object and store it in the state. However, despite the user object being valid and containing a valid accessToken, when I try to retrieve the accessToken it returns undefined.

In the debugger if I hover over the user object, I can see the full value with all the properties including accessToken, but if I skip to the next line and hover over accessToken object it shows undefined.

import { createReducer, on } from '@ngrx/store';
import { User } from 'src/app/models/user.model';
import { AuthActions } from '../action-types';

export const authFeatureKey = 'auth';

export interface AuthState {
  user: User;
  accessToken: string;
}

export const initialAuthState: AuthState = {
  user: undefined,
  accessToken: undefined,
};

const reducer = createReducer(
  initialAuthState,

  on(AuthActions.signup, (state, action) => {
    return {
      user: action.user,
      accessToken: action.user.accessToken,
    };
  }),

  on(AuthActions.signin, (state, action) => {
    // split out to debug.
    const user = <User>action.user; // action.user returns a valid object
    const token = user.accessToken; // despite this being valid in the user object, returns undefined.
    return {
      user: action.user,
      accessToken: token,
    };
  }),

  on(AuthActions.signOut, () => {
    return {
      user: undefined,
      accessToken: undefined,
    };
  }),
);

export function authReducer(state, action) {
  return reducer(state, action);
}

These are the actions:

import { createAction, props } from '@ngrx/store';
import { User } from '../../models/user.model';

export const signup = createAction('[SignUp Page] User SignUp', props<{ user: User }>());

export const signin = createAction('[SignIn Page] User SignIn', props<{ user: User }>());

export const signOut = createAction('[Top Menu] User SignOut');

and these are the selectors:

import { createFeatureSelector, createSelector } from '@ngrx/store';
import * as fromAuth from './reducers';

export const selectAuthState = createFeatureSelector<fromAuth.AuthState>(fromAuth.authFeatureKey);

export const isLoggedIn = createSelector(selectAuthState, (auth) => !!auth.user);

export const isLoggedOut = createSelector(isLoggedIn, (loggedIn) => !loggedIn);

export const getCurrentUser = createSelector(selectAuthState, (auth) => auth.user);

export const getAccessToken = createSelector(selectAuthState, (auth) => auth.accessToken);

This is the auth.module.ts, showing the import of the authReducer (as requested)

import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { AuthRoutingModule } from './auth-routing.module';
import { AuthService } from './services/auth.service';
import * as fromAuth from './store/reducers';
import { AuthEffects } from './store/auth-effects';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    AuthRoutingModule,
    HttpClientModule,
    StoreModule.forFeature(fromAuth.authFeatureKey, fromAuth.authReducer),
    EffectsModule.forFeature([AuthEffects]),
  ],
  providers: [AuthService],
})
export class AuthModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: AuthModule,
      providers: [AuthService],
    };
  }
}

I have noticed that in the state, it's storing the value somewhat weirdly:

auth
    user
      user
         userName: "username1"
         email: "email@email.com"
         accessToken: "ey......7z"
         refreshToken: "xxx"

So it looks like it's somehow nesting the user object.

Body:
This was my mistake, the service was passing the result back as a User object:

  signin(credentials: SignInCredentials): Observable<User> {
    return this.http.post<User>('/api/signin', credentials);
  }

However, it was actually the user inside an object:

{
   user: {
      userName:
      ...
   }
}

This is where it all went wrong. So I changed the service to return an any:

  signin(credentials: SignInCredentials): Observable<any> {
    return this.http.post<User>('/api/signin', credentials);
  }

and changed the action dispatch:

this.authService
  .signin(this.credentials)
  .pipe(
    tap((data: any) => {
      this.store.dispatch(AuthActions.signin({ user: data.user }));
      this.router.navigateByUrl('/');
    }),

Feeling like an idiot.


问:
I can't write into the shell of the PyCharm when I can write to the shell of Online Python Compiler (Interpreter) of Programiz
I'm doing the tutorial by Programiz and I'm using Pycharm to exercise my knowledge but it seems that I can't write into the Run tab of the Pycharm (or the Shell).

Here's my code:

class PowTwo:
    """Class to implement an iterator
    of powers of two"""

```<code>def __init__(self, max = 0):
    self.max = max

def __iter__(self):
    self.n = 0
    return self

def __next__(self):
    if self.n <= self.max:
        result = 2 ** self.n
        self.n += 1
        return result
    else:
        raise StopIteration
</code>```

I can clearly write to the shell of the Online Compiler but I can't to the PyCharm. What's the problem?

enter image description here

 unlink

答:
Okay :)

Pycharm is for more complex projects. While you are learning the basics you can use python's built-in IDLE.

Read this article, I think it will help you understand how it works.

I suppose you have installed python (else you can download it from hear). If you installed it, you need to either open the python IDLE and create a new file or create a new file with .py extension and open it with the IDLE. Then when you wrote your PowTwo class there, you can simply run it with F5 and use the interactive shell.

In pycharm, it is not a python shell, instead it is a cmd terminal. If you really want to use pycharm, you have two options:

Use the python console instead of run and import your file (import test) or use the terminal and type python to launch the console and import your file. (I suggest the first option)

Hope it helps :)

Body:
I'm doing the tutorial by Programiz and I'm using Pycharm to exercise my knowledge but it seems that I can't write into the Run tab of the Pycharm (or the Shell).

Here's my code:

class PowTwo:
    """Class to implement an iterator
    of powers of two"""

def __init__(self, max = 0):
    self.max = max

def __iter__(self):
    self.n = 0
    return self

def __next__(self):
    if self.n <= self.max:
        result = 2 ** self.n
        self.n += 1
        return result
    else:
        raise StopIteration

I can clearly write to the shell of the Online Compiler but I can't to the PyCharm. What's the problem?

enter image description here

 unlink


问:
Recursive depth function on an array
I have an array of objects like this input, and I want to nest some objects inside another objects (based if their parentId is the parents' forumId),

I got the function working but up to 1 depth, how can I get it working for n depth? Any idea or optimizations are appreciated!

EDIT: After pointing out, the input isn't necessarily ordered.

const input = [
  {
    forumId: 1,
    parentId: null,
    forumName: "Main",
    forumDescription: "",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 2,
    parentId: 1,
    forumName: "Announcements",
    forumDescription: "Announcements & Projects posted here",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 3,
    parentId: 1,
    forumName: "General",
    forumDescription: "General forum, talk whatever you want here",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 4,
    parentId: 3,
    forumName: "Introduction",
    forumDescription: "A warming introduction for newcomers here",
    forumLocked: false,
    forumDisplay: true,
  },
];

function processInput(forumInput) {
  const topLevelForums = forumInput.filter(function (forum) {
    return forum.parentId === null;
  });

  let output = topLevelForums;

  forumInput.forEach(function (forum) {
    if (forum.parentId !== null) {
      const forumParentId = forum.parentId;
      output.forEach(function (parentForum, idx) {
        if (parentForum.forumId === forumParentId) {
          if (!output[idx].hasOwnProperty("subForums")) {
            output[idx].subForums = [];
          }
          parentForum.subForums.push(forum);
        }
      });
    }
  });

  return output;
}
```

<p>This is the <strong>expected output</strong>:</p>

```[
  {
    forumId: 1,
    parentId: null,
    forumName: "Main",
    forumDescription: "",
    forumLocked: false,
    forumDisplay: true,
    subForums: [
      {
        forumId: 2,
        parentId: 1,
        forumName: "Announcements",
        forumDescription: "Announcements & Projects posted here",
        forumLocked: false,
        forumDisplay: true,
      },
      {
        forumId: 3,
        parentId: 1,
        forumName: "General",
        forumDescription: "General forum, talk whatever you want here",
        forumLocked: false,
        forumDisplay: true,
        subForums: [
          {
            forumId: 4,
            parentId: 3,
            forumName: "Introduction",
            forumDescription: "A warming introduction for newcomers here",
            forumLocked: false,
            forumDisplay: true,
          },
        ],
      },
    ],
  },
]
```

<p>This is the <strong>current output</strong>:</p>

```[
  {
    forumDescription: "",
    forumDisplay: true,
    forumId: 1,
    forumLocked: false,
    forumName: "Main",
    parentId: null,
    subForums: [
      {
        forumDescription: "Announcements & Projects posted here",
        forumDisplay: true,
        forumId: 2,
        forumLocked: false,
        forumName: "Announcements",
        parentId: 1,
      },
      {
        forumDescription: "General forum, talk whatever you want here",
        forumDisplay: true,
        forumId: 3,
        forumLocked: false,
        forumName: "General",
        parentId: 1,
      },
    ],
  },
]
```

答:
You could take an object which takes all relation from an object with child to parent and parent to childand get the nodes which have no parent.

This approach works for any depth, unsorted data and uses only a single loop.

const
    input = [{ forumId: 3, parentId: 1, forumName: "General", forumDescription: "General forum, talk whatever you want here", forumLocked: false, forumDisplay: true }, { forumId: 2, parentId: 1, forumName: "Announcements", forumDescription: "Announcements & Projects posted here", forumLocked: false, forumDisplay: true }, { forumId: 4, parentId: 3, forumName: "Introduction", forumDescription: "A warming introduction for newcomers here", forumLocked: false, forumDisplay: true }, { forumId: 1, parentId: null, forumName: "Main", forumDescription: "", forumLocked: false, forumDisplay: true }],
    tree = function(data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.forumId] = t[o.forumId] || {}, o);
            t[o.parentId] = t[o.parentId] || {};
            t[o.parentId].subForums = t[o.parentId].subForums || [];
            t[o.parentId].subForums.push(t[o.forumId]);
        });
        return t[root].subForums;
    }(input, null);

console.log(tree);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Title: Recursive depth function on an array

Body:
I have an array of objects like this input, and I want to nest some objects inside another objects (based if their parentId is the parents' forumId),

I got the function working but up to 1 depth, how can I get it working for n depth? Any idea or optimizations are appreciated!

EDIT: After pointing out, the input isn't necessarily ordered.

const input = [
  {
    forumId: 1,
    parentId: null,
    forumName: "Main",
    forumDescription: "",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 2,
    parentId: 1,
    forumName: "Announcements",
    forumDescription: "Announcements & Projects posted here",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 3,
    parentId: 1,
    forumName: "General",
    forumDescription: "General forum, talk whatever you want here",
    forumLocked: false,
    forumDisplay: true,
  },
  {
    forumId: 4,
    parentId: 3,
    forumName: "Introduction",
    forumDescription: "A warming introduction for newcomers here",
    forumLocked: false,
    forumDisplay: true,
  },
];

function processInput(forumInput) {
  const topLevelForums = forumInput.filter(function (forum) {
    return forum.parentId === null;
  });

  let output = topLevelForums;

  forumInput.forEach(function (forum) {
    if (forum.parentId !== null) {
      const forumParentId = forum.parentId;
      output.forEach(function (parentForum, idx) {
        if (parentForum.forumId === forumParentId) {
          if (!output[idx].hasOwnProperty("subForums")) {
            output[idx].subForums = [];
          }
          parentForum.subForums.push(forum);
        }
      });
    }
  });

  return output;
}

This is the expected output:

[
  {
    forumId: 1,
    parentId: null,
    forumName: "Main",
    forumDescription: "",
    forumLocked: false,
    forumDisplay: true,
    subForums: [
      {
        forumId: 2,
        parentId: 1,
        forumName: "Announcements",
        forumDescription: "Announcements & Projects posted here",
        forumLocked: false,
        forumDisplay: true,
      },
      {
        forumId: 3,
        parentId: 1,
        forumName: "General",
        forumDescription: "General forum, talk whatever you want here",
        forumLocked: false,
        forumDisplay: true,
        subForums: [
          {
            forumId: 4,
            parentId: 3,
            forumName: "Introduction",
            forumDescription: "A warming introduction for newcomers here",
            forumLocked: false,
            forumDisplay: true,
          },
        ],
      },
    ],
  },
]

This is the current output:

[
  {
    forumDescription: "",
    forumDisplay: true,
    forumId: 1,
    forumLocked: false,
    forumName: "Main",
    parentId: null,
    subForums: [
      {
        forumDescription: "Announcements & Projects posted here",
        forumDisplay: true,
        forumId: 2,
        forumLocked: false,
        forumName: "Announcements",
        parentId: 1,
      },
      {
        forumDescription: "General forum, talk whatever you want here",
        forumDisplay: true,
        forumId: 3,
        forumLocked: false,
        forumName: "General",
        parentId: 1,
      },
    ],
  },
]

Body:
You could take an object which takes all relation from an object with child to parent and parent to childand get the nodes which have no parent.

This approach works for any depth, unsorted data and uses only a single loop.

const
    input = [{ forumId: 3, parentId: 1, forumName: "General", forumDescription: "General forum, talk whatever you want here", forumLocked: false, forumDisplay: true }, { forumId: 2, parentId: 1, forumName: "Announcements", forumDescription: "Announcements & Projects posted here", forumLocked: false, forumDisplay: true }, { forumId: 4, parentId: 3, forumName: "Introduction", forumDescription: "A warming introduction for newcomers here", forumLocked: false, forumDisplay: true }, { forumId: 1, parentId: null, forumName: "Main", forumDescription: "", forumLocked: false, forumDisplay: true }],
    tree = function(data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.forumId] = t[o.forumId] || {}, o);
            t[o.parentId] = t[o.parentId] || {};
            t[o.parentId].subForums = t[o.parentId].subForums || [];
            t[o.parentId].subForums.push(t[o.forumId]);
        });
        return t[root].subForums;
    }(input, null);

console.log(tree);

.as-console-wrapper { max-height: 100% !important; top: 0; }


问:
use of uninitialized value in concatenation (.) or string at Extract data from a spreadshit.pl line 8
I have perl code:

```<code>#!/usr/bin/perl
use strict;
use warnings;

use Spreadsheet::Read;

my $workbook = ReadData ("test.xls");
print $workbook->[1]{A3} . "\n";
</code>```

And get this error: use of uninitialized value in concatenation (.) or string at Extract data from a spreadshit.pl line 8.

Please advice.

答:
If you don't know whether your cell contains data, usually you do something like

```<code>print $workbook->[1]{A3} . "\n" if defined $workbook->[1]{A3};
</code>```

You need the 'defined' otherwise things like '0' will not print.

Another way, if you still want to print an empty line and in more modern language:

```<code>use v5.10;
say $workbook->[1]{A3} // '';
</code>```

say is like print but adds a new line, //, the slash slash operator, uses the left item if it is defined, otherwise the right one.

But yeah, uninitialized value just means your variable is undef.

PS. You probably want to change you script name to spreadsheet.pl ...

Body:
I have perl code:

#!/usr/bin/perl
use strict;
use warnings;

use Spreadsheet::Read;

my $workbook = ReadData ("test.xls");
print $workbook->[1]{A3} . "\n";

And get this error: use of uninitialized value in concatenation (.) or string at Extract data from a spreadshit.pl line 8.

Please advice.

Body:
If you don't know whether your cell contains data, usually you do something like

print $workbook->[1]{A3} . "\n" if defined $workbook->[1]{A3};

You need the 'defined' otherwise things like '0' will not print.

Another way, if you still want to print an empty line and in more modern language:

use v5.10;
say $workbook->[1]{A3} // '';

say is like print but adds a new line, //, the slash slash operator, uses the left item if it is defined, otherwise the right one.

But yeah, uninitialized value just means your variable is undef.

PS. You probably want to change you script name to spreadsheet.pl ...


问:
Android Studio Tab to Spacing in Flutter(Dart)
How can I change tab to space in Android Studio 4.0 ?

答:
Since Dart does not have language-specific settings in Android Studio. Change use tab character or not in Other File Types options, which is for all file types that aren't separately available for options.

Editor > Code Styles > Other File Types > Uncheck Use tab character.


问:
IntelliJ - - How do apply entire file as a change?
The git diff view allows me to see the two different revisions of the same file.  It also allows me to pick individual changes and apply them from the other revision to mine.  I do that by pressing the >> button between them.  BUT, when the change is either creating or deleting an entire file, only that file shows up.  There is no >> button!

How do I apply the change if it's a deletion or creation of a file?  For example, the other branch has a new file F.  I just want F ported to my current branch.  How can I use the RubyMine's "Git Compare to Another Branch" interface to achieve that? (I already know how to do it in shell)

picture of what I'm talking about

答:
To Get a file from another branch, you can use Show Diff with the Working Tree action from Branches popup (in earlier versions, this is the Files tab of the Compare with current dialog.)

And from there call Get from Branch

It is not available when comparing individual files - https://youtrack.jetbrains.com/issue/IDEA-156485.


问:
How to programmatically hide the wp-login.php in Wordpress?
I managed to create the /login url to redirect me in /wp-login.php page

In my .httacces I have the following code

```<code>RewriteRule ^login$ wp-login.php [NC,L]
</code>```

In the functions.php (in my custom theme) I added this

```<code> add_filter('site_url',  'wplogin_filter', 10, 3);
function wplogin_filter( $url, $path, $orig_scheme )
{
 $old  = array( "/(wp-login\.php)/");
 $new  = array( "login");
 return preg_replace( $old, $new, $url, 1);
}
</code>```

The problem is how to disallow access to wp-login.php page without disabling it.  With the solution above both url's are visible /login and /wp-login.php

How can I "hide" the wp-login.php permenantly without usign a plugin?

答:
You don't really have to hide it. Just redirect access to the home page - or any other page.</p>

```<code>add_filter( 'login_url', 'my_redirect_login', 10, 3 );
function my_redirect_login(){
    if ($_SERVER['REQUEST_URI']!='/wp-login.php') return;
    header( 'Location: '.home_url(null, 'https') );
    exit;
}
</code>```

Body:
I managed to create the /login url to redirect me in /wp-login.php page

In my .httacces I have the following code

RewriteRule ^login$ wp-login.php [NC,L]

In the functions.php (in my custom theme) I added this

 add_filter('site_url',  'wplogin_filter', 10, 3);
function wplogin_filter( $url, $path, $orig_scheme )
{
 $old  = array( "/(wp-login\.php)/");
 $new  = array( "login");
 return preg_replace( $old, $new, $url, 1);
}

The problem is how to disallow access to wp-login.php page without disabling it.  With the solution above both url's are visible /login and /wp-login.php

How can I "hide" the wp-login.php permenantly without usign a plugin?

Body:
You don't really have to hide it. Just redirect access to the home page - or any other page.

add_filter( 'login_url', 'my_redirect_login', 10, 3 );
function my_redirect_login(){
    if ($_SERVER['REQUEST_URI']!='/wp-login.php') return;
    header( 'Location: '.home_url(null, 'https') );
    exit;
}


问:
String manipulation, removing a single comma
UPDATE 1:

This is how I am attempting to build the string:

```<code>header('Content-type:application/json');

function getdata($the_query)
{
    $connection = mysql_connect('server', 'user', 'pass') or die (mysql_error());
    $db = mysql_select_db('db_name', $connection) or die (mysql_error());

    $results = mysql_query($the_query) or die(mysql_error());

    $the_data = "{
            \"rss\": {
                \"channels\" : [
                    {
                        \"title\" : \"".$title."\",
                        \"link\": \"http://www.mycompany.com/external.php\",
                        \"description\": \"company description goes here\",";

                        while($row = mysql_fetch_array($results))
                        {
                            extract($row);

                            $the_data .= "\"items\" : [
                                {
                                    \"title\": \"".$title."\",
                                    \"link\": \"".$link."\",
                                    \"guid\": \"".$link."\",
                                    \"pubDate\": \"".$date."\",
                                    \"description\": \"".$description."\"
                                } ],";
                        }

                    $the_data .= "} ]
                }
                 }";

    mysql_close($connection);

    return $the_data;
}
</code>```

ORIGINAL QUESTION:

I have a string similar to this:

```<code>$mystring = "{
      \"rss\": {
        \"channels\" : [
          {
            \"title" : \"title goes here\",
            \"link": \"link goes here\",
            \"description": \"description goes here\",
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
         } ]
      }
    }";
</code>```

How do I remove the last comma?

答:
To make as little modification as it is possible (lazy and wrong way) you could change the way $the_data string is created:

```<code>      $pieces = array();
      while($row = mysql_fetch_array($results))
                    {
                        extract($row);

                        $pieces[] = "\"items\" : [
                            {
                                \"title\": \"".$title."\",
                                \"link\": \"".$link."\",
                                \"guid\": \"".$link."\",
                                \"pubDate\": \"".$date."\",
                                \"description\": \"".$description."\"
                            } ]";
                    }

                $the_data .= implode(',', $pieces);
</code>```

but overall it is better rewrite whole chunk of your code according with answers above with use of  json_encode function.

Body:
UPDATE 1:

This is how I am attempting to build the string:

header('Content-type:application/json');

function getdata($the_query)
{
    $connection = mysql_connect('server', 'user', 'pass') or die (mysql_error());
    $db = mysql_select_db('db_name', $connection) or die (mysql_error());

    $results = mysql_query($the_query) or die(mysql_error());

    $the_data = "{
            \"rss\": {
                \"channels\" : [
                    {
                        \"title\" : \"".$title."\",
                        \"link\": \"http://www.mycompany.com/external.php\",
                        \"description\": \"company description goes here\",";

                        while($row = mysql_fetch_array($results))
                        {
                            extract($row);

                            $the_data .= "\"items\" : [
                                {
                                    \"title\": \"".$title."\",
                                    \"link\": \"".$link."\",
                                    \"guid\": \"".$link."\",
                                    \"pubDate\": \"".$date."\",
                                    \"description\": \"".$description."\"
                                } ],";
                        }

                    $the_data .= "} ]
                }
                 }";

    mysql_close($connection);

    return $the_data;
}

ORIGINAL QUESTION:

I have a string similar to this:

$mystring = "{
      \"rss\": {
        \"channels\" : [
          {
            \"title" : \"title goes here\",
            \"link": \"link goes here\",
            \"description": \"description goes here\",
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
            \"items\" : [
              {
                \"title\": \"title goes here\",
                \"link\": \"url goes here\",
                \"guid\": \"id goes here\",
                \"pubDate\": \"data goes her\",
                \"description\": \"description goes here\"
              } ],
         } ]
      }
    }";

How do I remove the last comma?

Body:
To make as little modification as it is possible (lazy and wrong way) you could change the way $the_data string is created:

      $pieces = array();
      while($row = mysql_fetch_array($results))
                    {
                        extract($row);

                        $pieces[] = "\"items\" : [
                            {
                                \"title\": \"".$title."\",
                                \"link\": \"".$link."\",
                                \"guid\": \"".$link."\",
                                \"pubDate\": \"".$date."\",
                                \"description\": \"".$description."\"
                            } ]";
                    }

                $the_data .= implode(',', $pieces);

but overall it is better rewrite whole chunk of your code according with answers above with use of  json_encode function.


问:
How do I avoid "Access Violation" during asynchronous database connections?

Goal: Using ExecuteAsync correctly.

I know my application itself is at least pretty close to correct because it executes correctly once, so I know I can eliminate the usual suspects of firewalls, wrong database passwords, procedure names, etc.

```<code>private async Task<T> executeAsyncHelper<T>(Func<IDataReader, T> then)
{
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(name, conn))
        {
            parameters.Select(p => cmd.Parameters.Add(p))
                .ToImmutableList();
            cmd.CommandType = CommandType.StoredProcedure;
            using (IDataReader rdr = await cmd.ExecuteReaderAsync())
            {
                return then(rdr);
            }
        }
    }
}
</code>```

The Issue: Access Violation on the Second SqlConnection.Open()

The method gets called twice on the same procedure. The first time, it successfully updates the database. The second time, the whole thing dumps out on conn.Open() with "Access violation." Importantly, it's not throwing an exception. Rather, the whole debugger exits with a negative status code.

These are the last two lines of the debugger output (The rest of the debugger output looks normal):

```<code>The program '[6904] dotnet.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
The program '[6904] dotnet.exe: Program Trace' has exited with code 0 (0x0).
</code>```

This behavior is 100% repeatable.

Hypothesis: Connection Pooling and Asynchronicity

As far as I can see, the most probable cause is that there's some problem with opening two connections asynchronously, but I don't immediately know what to do with that hypothesis. I've written the method as safely as I know how.

Secondarily, I checked to see if my Azure SQL Server instance had any unusual limitations on it. It's a basic instance, but I doubt that's the issue since I would expect a SQL exception (that the debugger will break on and show a normal stack trace) if that were the problem.

Environmental information

Azure SQL Server 2016

Windows 10

.NET Core 2.1

Visual Studio 2017

Conclusion

Does anyone see any problem with the way I've implemented this or have any suggestions to learn more about the error?

答: Just so you can check that you're not hitting a connection limit, you can do exec sp_who2 and see how many connections are on your sql server. If there are a lot of connections shown on the sql server, that maybe the cause due to resource issues. Have you try running this code in the regular synchronously and did it cause the same issue? Is there anything on your connection string that limits the number of connections? Just some theory to throw out since I don't see the context of this code. </p>

Body:
Goal: Using ExecuteAsync correctly.

I know my application itself is at least pretty close to correct because it executes correctly once, so I know I can eliminate the usual suspects of firewalls, wrong database passwords, procedure names, etc.

private async Task<T> executeAsyncHelper<T>(Func<IDataReader, T> then)
{
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(name, conn))
        {
            parameters.Select(p => cmd.Parameters.Add(p))
                .ToImmutableList();
            cmd.CommandType = CommandType.StoredProcedure;
            using (IDataReader rdr = await cmd.ExecuteReaderAsync())
            {
                return then(rdr);
            }
        }
    }
}

The Issue: Access Violation on the Second SqlConnection.Open()

The method gets called twice on the same procedure. The first time, it successfully updates the database. The second time, the whole thing dumps out on conn.Open() with "Access violation." Importantly, it's not throwing an exception. Rather, the whole debugger exits with a negative status code.

These are the last two lines of the debugger output (The rest of the debugger output looks normal):

The program '[6904] dotnet.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
The program '[6904] dotnet.exe: Program Trace' has exited with code 0 (0x0).

This behavior is 100% repeatable.

Hypothesis: Connection Pooling and Asynchronicity

As far as I can see, the most probable cause is that there's some problem with opening two connections asynchronously, but I don't immediately know what to do with that hypothesis. I've written the method as safely as I know how.

Secondarily, I checked to see if my Azure SQL Server instance had any unusual limitations on it. It's a basic instance, but I doubt that's the issue since I would expect a SQL exception (that the debugger will break on and show a normal stack trace) if that were the problem.

Environmental information

Azure SQL Server 2016

Windows 10

.NET Core 2.1

Visual Studio 2017

Conclusion

Does anyone see any problem with the way I've implemented this or have any suggestions to learn more about the error?


问:
JMeter : IF condition in the controller is not working
I have a BeanShell Sampler in which I decide/set a path out of 3 paths (See the picture). But the control never comes into the following IF condition at all. I don't know what am I missing?
enter image description here

答:
Don't use Beanshell, since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting

Don't inline JMeter Functions or Variables into scripts, either use "Parameters" section of the JSR223 Sampler or go for code-based equivalents. Replace this line (at least)

```<code>if ( ${matchNr} >= 20 )
</code>```

with this one:

```<code>if ( (vars.get('matchNr') as int) >= 20)
</code>```

If your script doesn't do what it  is supposed to be doing most probably there should be a relevant message in the jmeter.log file, either look into it yourself or include it in the question if you don't understand what's going on there

Body:
Don't use Beanshell, since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting

Don't inline JMeter Functions or Variables into scripts, either use "Parameters" section of the JSR223 Sampler or go for code-based equivalents. Replace this line (at least)

if ( ${matchNr} >= 20 )

with this one:

if ( (vars.get('matchNr') as int) >= 20)

If your script doesn't do what it  is supposed to be doing most probably there should be a relevant message in the jmeter.log file, either look into it yourself or include it in the question if you don't understand what's going on there


问:
how to create a DF from a DF based on a condition
My current DF looks like this

```<code>Combinations               Count
1   ('IDLY', 'VADA')       3734
6   ('DOSA', 'IDLY')        2020
9   ('CHAPPATHI', 'DOSA')   1297
10  ('IDLY', 'POORI')       1297
11  ('COFFEE', 'TEA')       1179
13  ('DOSA', 'VADA')        1141
15  ('CHAPPATHI', 'IDLY')   1070
16  ('COFFEE', 'SAMOSA')    1061
17  ('COFFEE', 'IDLY')      1016
18  ('POORI', 'VADA')       1008
</code>```

Lets say I filter by the keyword 'DOSA' from above data frame I get the below OP

```<code>    Combinations           Count
6   ('DOSA', 'IDLY')        2020
9   ('CHAPPATHI', 'DOSA')   1297
13  ('DOSA', 'VADA')        1141
</code>```

But I would like the output to be like the df below(which has ignored the filter key word as its common,

```<code>    Combinations    Count
6   IDLY            2020
9   CHAPPATHI       1297
13  VADA            1141
</code>```

What concept of pandas needs to be used here? How can this be achieved?

答:
What I will do </p>

```<code>x=df.explode('Combinations')
x=x.loc[x.index[x.Combinations=='DOSA']].query('Combinations !="DOSA"')
x
   Combinations  Count
6          IDLY   2020
9     CHAPPATHI   1297
13         VADA   1141
</code>```

Body:
My current DF looks like this

Combinations               Count
1   ('IDLY', 'VADA')       3734
6   ('DOSA', 'IDLY')        2020
9   ('CHAPPATHI', 'DOSA')   1297
10  ('IDLY', 'POORI')       1297
11  ('COFFEE', 'TEA')       1179
13  ('DOSA', 'VADA')        1141
15  ('CHAPPATHI', 'IDLY')   1070
16  ('COFFEE', 'SAMOSA')    1061
17  ('COFFEE', 'IDLY')      1016
18  ('POORI', 'VADA')       1008

Lets say I filter by the keyword 'DOSA' from above data frame I get the below OP

    Combinations           Count
6   ('DOSA', 'IDLY')        2020
9   ('CHAPPATHI', 'DOSA')   1297
13  ('DOSA', 'VADA')        1141

But I would like the output to be like the df below(which has ignored the filter key word as its common,

    Combinations    Count
6   IDLY            2020
9   CHAPPATHI       1297
13  VADA            1141

What concept of pandas needs to be used here? How can this be achieved?

Body:
What I will do

x=df.explode('Combinations')
x=x.loc[x.index[x.Combinations=='DOSA']].query('Combinations !="DOSA"')
x
   Combinations  Count
6          IDLY   2020
9     CHAPPATHI   1297
13         VADA   1141


问:
Setting value if two conditions are true
I have a table that contains three columns. I need to set a value in column C that depends on column A and B. If all the values in column B are the same for a fixed value in column A then each row in column C needs to say "Pass" otherwise "Fail".

In the example screenshot the status is "Pass" for all values with ID = 2 because all values in the column "Name" are the same e.g. C

Example Table

答:
Without VBA
formula in C2 and copy down
(Maybe you have to replace the semicolon with comma)</p>

```<code>=IF(COUNTIF($A$2:$A$11;A2)=COUNTIFS($A$2:$A$11;A2;$B$2:$B$11;B2);"Pass";"Fail")
</code>```

Body:
Without VBA
formula in C2 and copy down
(Maybe you have to replace the semicolon with comma)

=IF(COUNTIF($A$2:$A$11;A2)=COUNTIFS($A$2:$A$11;A2;$B$2:$B$11;B2);"Pass";"Fail")


问:
pyspark's "between" function: range search on timestamps is not inclusive
pyspark's 'between' function is not inclusive for timestamp input.

For example, if we want all rows between two dates, say, '2017-04-13' and '2017-04-14', then it performs an "exclusive" search when the dates are passed as strings. i.e., it omits the '2017-04-14 00:00:00' fields

However, the document seem to hint that it is inclusive (no reference on timestamp though)

Of course, one way is to add a microsecond from the upper bound and pass it to the function. However, not a great fix. Any clean way of doing inclusive search?

Example:

```<code>import pandas as pd
from pyspark.sql import functions as F
... sql_context creation ...
test_pd=pd.DataFrame([{"start":'2017-04-13 12:00:00', "value":1.0},{"start":'2017-04-14 00:00:00', "value":1.1}])
test_df = sql_context.createDataFrame(test_pd).withColumn("start", F.col("start").cast('timestamp'))
test_df.show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+

test_df.filter(F.col("start").between('2017-04-13','2017-04-14')).show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
+--------------------+-----+
</code>```

答:
.between() method is always inclusive. The problem in your example is that when you pass string to .between() method, it treats your data as strings as well. For string comparison, '2017-04-14 00:00:00' is strictly greater than '2017-04-14' because the former is a longer string than the latter, this is why  the second date is filtered out in your example. To avoid the "inconsistency", you should pass arguments in datetime format to .between() as follows:

```<code>filtered_df = (test_df.filter(F.col("start")
                .between(dt.strptime('2017-04-13 12:00:00', '%Y-%m-%d %H:%M:%S'),
                         dt.strptime('2017-04-14 00:00:00', '%Y-%m-%d %H:%M:%S'))))
</code>```

This will produce the expected result:

```<code>+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+
</code>```

Body:
pyspark's 'between' function is not inclusive for timestamp input.

For example, if we want all rows between two dates, say, '2017-04-13' and '2017-04-14', then it performs an "exclusive" search when the dates are passed as strings. i.e., it omits the '2017-04-14 00:00:00' fields

However, the document seem to hint that it is inclusive (no reference on timestamp though)

Of course, one way is to add a microsecond from the upper bound and pass it to the function. However, not a great fix. Any clean way of doing inclusive search?

Example:

import pandas as pd
from pyspark.sql import functions as F
... sql_context creation ...
test_pd=pd.DataFrame([{"start":'2017-04-13 12:00:00', "value":1.0},{"start":'2017-04-14 00:00:00', "value":1.1}])
test_df = sql_context.createDataFrame(test_pd).withColumn("start", F.col("start").cast('timestamp'))
test_df.show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+

test_df.filter(F.col("start").between('2017-04-13','2017-04-14')).show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
+--------------------+-----+

Body:
.between() method is always inclusive. The problem in your example is that when you pass string to .between() method, it treats your data as strings as well. For string comparison, '2017-04-14 00:00:00' is strictly greater than '2017-04-14' because the former is a longer string than the latter, this is why  the second date is filtered out in your example. To avoid the "inconsistency", you should pass arguments in datetime format to .between() as follows:

filtered_df = (test_df.filter(F.col("start")
                .between(dt.strptime('2017-04-13 12:00:00', '%Y-%m-%d %H:%M:%S'),
                         dt.strptime('2017-04-14 00:00:00', '%Y-%m-%d %H:%M:%S'))))

This will produce the expected result:

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+


问:
BlackBerry - height of available screen excluding banner & title fields
I would like to know how much vertical real estate is available to my manager on a screen (without scrolling).

I would like to have this manager in a separate class, not in the Screen subclass. Ideally, my manager would be able to be placed on any screen, without any knowledge of the screen specifics being passed to it - this manager would be able to find out how much space has been left unused by the Screen's title / banner fields.

I can get the screen size with many methods. That is the easy part. But it does not take account of title / banner fields.

What I would like to know is how to find the part of the screen that is not covered by any title or banner fields? But I would like to have a general solution, that can be used in a separate class file, with no prior knowledge of the screen it is to be displayed on.

(workaround: I would have to tell my manager what the height of the title / banner fields was, and then I could use these heights, with Display.getHeight() to calculate the available space)

答:
I have a separate class (call it CobiPainter) which is able to be used by any manager or screen class - it implements one method which I have called paintBackground(Graphics g). I call this method from within any related paintBackground(Graphics g) override of the screen whose background I want to paint.

In order to be able to be used by any MainScreen, with minimal coupling & extra work, I have made it so that the CobiPainter class is able to calculate how much screen is available, without needing to be given any knowledge of the title / banner / status fields.

The code I have used relies on the fact that the MainScreen has an internal manager to which we normally add the fields. This manager knows the height that I am looking for.

This is the hack/code I used:

```<code>Screen activeScreen = UiApplication.getUiApplication().getActiveScreen();
if (activeScreen instanceof MainScreen)
{
    // get available height excluding banner / title
    XYRect xy = ((MainScreen) activeScreen).getMainManager()
        .getExtent();
    heightOfTitleAndBanner = xy.y;  // <---- can be useful too
    availableHeight = xy.height;    // <---- this is what I wanted
}
</code>```

This code will not work until the manager in question is displayed, since it relies on calling the getActiveScreen() method. It also requires that the MainScreen was created with the parameter Manager.NO_VERTICAL_SCROLL to force it to take the screen's size (thanks to Himanshu).

Body:
I have a separate class (call it CobiPainter) which is able to be used by any manager or screen class - it implements one method which I have called paintBackground(Graphics g). I call this method from within any related paintBackground(Graphics g) override of the screen whose background I want to paint.

In order to be able to be used by any MainScreen, with minimal coupling & extra work, I have made it so that the CobiPainter class is able to calculate how much screen is available, without needing to be given any knowledge of the title / banner / status fields.

The code I have used relies on the fact that the MainScreen has an internal manager to which we normally add the fields. This manager knows the height that I am looking for.

This is the hack/code I used:

Screen activeScreen = UiApplication.getUiApplication().getActiveScreen();
if (activeScreen instanceof MainScreen)
{
    // get available height excluding banner / title
    XYRect xy = ((MainScreen) activeScreen).getMainManager()
        .getExtent();
    heightOfTitleAndBanner = xy.y;  // <---- can be useful too
    availableHeight = xy.height;    // <---- this is what I wanted
}

This code will not work until the manager in question is displayed, since it relies on calling the getActiveScreen() method. It also requires that the MainScreen was created with the parameter Manager.NO_VERTICAL_SCROLL to force it to take the screen's size (thanks to Himanshu).


问:
Multiple errors when adding tracks to playlist using Spotipy
I am trying to add tracks to one of my Spotify playlists, and I'm pretty sure I have all of the code exactly right as described in the Spotipy documentation:

```<code>username = '*myusername*'
scope = 'playlist-modify-public'

playlist_id = '*myplaylistid*'
track_ids = *array of track ids*

token = util.prompt_for_user_token(username,
                           scope,
                           client_id='*myclientid*',
                           client_secret='*mysecretclientid*',
                           redirect_uri='http://localhost:8888/callback/')
spotify = spotipy.Spotify(auth=token)

results = spotify.user_playlist_add_tracks(username, playlist_id, track_ids)
</code>```

However, these are the following errors two errors that I receive no matter what I try:

```<code>HTTPError: 400 Client Error: Bad Request for url: https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks

During handling of the above exception, another exception occurred:

SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks:
 Invalid track uri: spotify:track:*trackid*
</code>```

It specifies Invalid track uri, however for each of the tracks in my list I have tested by searching the uri in Spotify and it is indeed valid.

Solutions I have tried to no avail:

1. Changing between ID and URIs for both playlists and track list

2. Authenticating using OAuth

3. Using different playlists and tracks

4. Using different redirect_uri

5 example track URIs for reference:

```<code>spotify:track:1rdHsnsGmleo6MRctkkFmm?si=7R0IKQ9xTgiwfLAJO7eFCw
spotify:track:70CMnzQ3FjMmUk5NPdQJBe?si=qL_WwgWVRTaSZ2oOBg2eCA
spotify:track:6bbx7nYlixYuElKMbYCzMm?si=Wu64S-obRaOOh3mFP3zWwA
spotify:track:6DZNQKNUskiWVSXs3cQPk3?si=SIW3hBU1SiWd_h1gpXwijg
spotify:track:2FMPIU8FdP9kCi5kUCSGnE?si=jtJOkQhsSF6GoD3otgtV3A
</code>```

Would appreciate any help!! Thank you

答:
The track URIs should not contain ?si= but only what's before that. See https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids

You can fix your code to only keep the first part:

```<code>track_uris = [uri.split("?si=")[0] for uri in track_uris]
</code>```

Body:
I am trying to add tracks to one of my Spotify playlists, and I'm pretty sure I have all of the code exactly right as described in the Spotipy documentation:

username = '*myusername*'
scope = 'playlist-modify-public'

playlist_id = '*myplaylistid*'
track_ids = *array of track ids*

token = util.prompt_for_user_token(username,
                           scope,
                           client_id='*myclientid*',
                           client_secret='*mysecretclientid*',
                           redirect_uri='http://localhost:8888/callback/')
spotify = spotipy.Spotify(auth=token)

results = spotify.user_playlist_add_tracks(username, playlist_id, track_ids)

However, these are the following errors two errors that I receive no matter what I try:

HTTPError: 400 Client Error: Bad Request for url: https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks

During handling of the above exception, another exception occurred:

SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks:
 Invalid track uri: spotify:track:*trackid*

It specifies Invalid track uri, however for each of the tracks in my list I have tested by searching the uri in Spotify and it is indeed valid.

Solutions I have tried to no avail:

1. Changing between ID and URIs for both playlists and track list

2. Authenticating using OAuth

3. Using different playlists and tracks

4. Using different redirect_uri

5 example track URIs for reference:

spotify:track:1rdHsnsGmleo6MRctkkFmm?si=7R0IKQ9xTgiwfLAJO7eFCw
spotify:track:70CMnzQ3FjMmUk5NPdQJBe?si=qL_WwgWVRTaSZ2oOBg2eCA
spotify:track:6bbx7nYlixYuElKMbYCzMm?si=Wu64S-obRaOOh3mFP3zWwA
spotify:track:6DZNQKNUskiWVSXs3cQPk3?si=SIW3hBU1SiWd_h1gpXwijg
spotify:track:2FMPIU8FdP9kCi5kUCSGnE?si=jtJOkQhsSF6GoD3otgtV3A

Would appreciate any help!! Thank you

Body:
The track URIs should not contain ?si= but only what's before that. See https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids

You can fix your code to only keep the first part:

track_uris = [uri.split("?si=")[0] for uri in track_uris]


问:
How to generate a unique id in a recursive function in PHP?
In my recursive function I can't generate a unique id (via an incremented variable) for my multidimensional array, here is what I tried.

I need to assign a unique ID for each directory name I find: $data[] = ['id'=>$i,'text'=>$dir];

```<code>    function scandir_rec($root, $i)
    {
        $data = [];

        if (!is_dir($root)) {
            return;
        }

        $dirs = scandir($root);

        foreach ($dirs as $dir) {

            $i++;

            if ($dir == '.' || $dir == '..') {
                continue;
            }

            $path = $root . '/' . $dir;

            if (is_file($path)) {
                continue;
            }

            if (is_dir($path)) {

                $nodes = scandir_rec($path, $i); // <--- unique ID

                if (!empty($nodes)) $chunk['children'] = $nodes;
            }

            $data[] = [ 'id' =>  $i, 'text' =>  $dir ]; // <--- unique ID
        }

        return $data;
    }

    $rootDir = '/var/www/html';
    $i = 0;
    $json_data = json_encode(scandir_rec($rootDir, $i), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); // <--- unique ID
    file_put_contents('tree.json', $json_data);
</code>```

Desired result

```<code>    [
    {
       "id":1,
       "text":"Root folder",
       "children":[
          {
             "id":2,
             "text":"Child folder 1"
          },
          {
             "id":3,
             "text":"Child folder 2"
          }
       ]
    },
    {
        "id":4,
        "text":"Root folder"
     },
    {
       "id":5,
       "text":"Root folder",
       "children":[
          {
             "id":6,
             "text":"Child folder 1"
          },
          {
             "id":7,
             "text":"Child folder 2"
          }
       ]
    }
 ]
</code>```

答:
The issue is that each recursive call starts it's own count. Let's say $i is 10 inside the loop at a given time. You start a recursive call that increases it up to 15 but when the call ends and returns to parent function, $i there is still 10.

Perhaps the simplest fix is to pass the counter by reference:

```<code>function scandir_rec($root, &$i)
{
}
</code>```

Another solution is to avoid recursion altogether. PHP has builtin iterators that can walk a three without recursion, e.g.:

```<code>$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootDir),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach ($files as $name => $object) {
    echo sprintf("[%s] %s\n", $object->isDir() ? 'DIR' : '   ', $name);
}
</code>```

Body:
In my recursive function I can't generate a unique id (via an incremented variable) for my multidimensional array, here is what I tried.

I need to assign a unique ID for each directory name I find: $data[] = ['id'=>$i,'text'=>$dir];

    function scandir_rec($root, $i)
    {
        $data = [];

        if (!is_dir($root)) {
            return;
        }

        $dirs = scandir($root);

        foreach ($dirs as $dir) {

            $i++;

            if ($dir == '.' || $dir == '..') {
                continue;
            }

            $path = $root . '/' . $dir;

            if (is_file($path)) {
                continue;
            }

            if (is_dir($path)) {

                $nodes = scandir_rec($path, $i); // <--- unique ID

                if (!empty($nodes)) $chunk['children'] = $nodes;
            }

            $data[] = [ 'id' =>  $i, 'text' =>  $dir ]; // <--- unique ID
        }

        return $data;
    }

    $rootDir = '/var/www/html';
    $i = 0;
    $json_data = json_encode(scandir_rec($rootDir, $i), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); // <--- unique ID
    file_put_contents('tree.json', $json_data);

Desired result

    [
    {
       "id":1,
       "text":"Root folder",
       "children":[
          {
             "id":2,
             "text":"Child folder 1"
          },
          {
             "id":3,
             "text":"Child folder 2"
          }
       ]
    },
    {
        "id":4,
        "text":"Root folder"
     },
    {
       "id":5,
       "text":"Root folder",
       "children":[
          {
             "id":6,
             "text":"Child folder 1"
          },
          {
             "id":7,
             "text":"Child folder 2"
          }
       ]
    }
 ]

Body:
The issue is that each recursive call starts it's own count. Let's say $i is 10 inside the loop at a given time. You start a recursive call that increases it up to 15 but when the call ends and returns to parent function, $i there is still 10.

Perhaps the simplest fix is to pass the counter by reference:

function scandir_rec($root, &$i)
{
}

Another solution is to avoid recursion altogether. PHP has builtin iterators that can walk a three without recursion, e.g.:

$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootDir),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach ($files as $name => $object) {
    echo sprintf("[%s] %s\n", $object->isDir() ? 'DIR' : '   ', $name);
}