问:
Child process inherits a handle from its parent process but fails to write in it
I want to have 2 processes write in the same file. I created a file in the first process (parent) and call the second process (child) . I have made the file inheritable and the second process inherits the handle as a command line argument.

Although the handle is not equal to INVALID_HANDLE_VALUE, the second process can't do anything with the file. WriteFile() ends with Error 6(the handle is invalid). The same is for LockFile(),Unlockfile().

What is wrong with the code and how can I fix it? I want to make 2 processes work with the same file.

Process 1:

```<code>#include <Windows.h>
#include <process.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _SECURITY_ATTRIBUTES sec_attr;
    sec_attr.nLength = sizeof(_SECURITY_ATTRIBUTES);
    sec_attr.bInheritHandle = true;
    sec_attr.lpSecurityDescriptor = 0;
    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1],GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE |
             FILE_SHARE_READ,&sec_attr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo,sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;

    char cmd[300] = "PATH to process 2";
    CreateProcess(0,cmd,0,0,true,NORMAL_PRIORITY_CLASS,0,0,&sinfo,&pinfo);
    char c = '1';
    DWORD w;
    WriteFile(h,&c,1,&w,0); //works fine
    ...
}
</code>```

Process 2:

```<code>#include <Windows.h>
#include <process.h>

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE h = argv[1];
    if(h == INVALID_HANDLE_VALUE) {
        //it's okay, h is NOT equal to INVALID_HANDLE_VALUE
    }
    char c = '2';
    DWORD w;
    WriteFile(h,&c,1,&w,0);  //error 6
    ...
}
</code>```

P.S. The first process succeeds in writing in the file. By that time the second process has already failed.

答:
You may be creating the child process with an inheritable file handle, but you are not actually telling the child what the value of that handle is!  The child is looking for that value in argv[1], but the code you have shown is not passing any value in that parameter!  Even if there were, you are not retrieving the value correctly anyway.

Command-line parameters are always strings, so argv[1] is a pointer to a null-terminated string, not a handle.  You have to convert the handle pointer to a string representation when you put it on the command-line, and then you have to parse that string back to a pointer when processing the command-line.

Try something more like this:

Process 1:

```<code>#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    SECURITY_ATTRIBUTES sec_attr = {};
    sec_attr.nLength = sizeof(sec_attr);
    sec_attr.bInheritHandle = TRUE;
    sec_attr.lpSecurityDescriptor = 0;

    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, &sec_attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo, sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;
    ZeroMemory(&pinfo, sizeof(pinfo));

    _TCHAR cmd[MAX_PATH + 16] = {};
    _tsprintf(cmd, _T("\"%s\" %p"), _T("PATH to process 2"), h);

    // TODO: consider using STARTUPINFOEX instead so the child inherits
    // ONLY the file handle and not ALL inheritable handles it doesn't
    // care about:
    //
    // Programmatically controlling which handles are inherited by new processes in Win32
    // https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873
    //
    if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
    {
        // handle the error ...
        return 1;
    }

    CloseHandle(pinfo.hThread);
    CloseHandle(pinfo.hProcess);

    char c = '1';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}
</code>```

Process 2:

```<code>#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - string representation of a handle to an open file
    HANDLE h = INVALID_HANDLE_VALUE;
    _stscanf(argv[1], _T("%p"), &h);

    char c = '2';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}
</code>```

That being said, having two threads, let alone two processes, share a single file handle is NOT a good idea.  A given file handle only has 1 read/write position in it, so sharing that handle is going to risk the threads/processes stepping all over each other, unless you provide some kind of synchronization between them so only one can access the file at a time.

Consider passing the target filename to the child process and let it open its own unique handle to the file, eg:

Process 1:

```<code>#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo, sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;
    ZeroMemory(&pinfo, sizeof(pinfo));

    _TCHAR cmd[(MAX_PATH *2) + 10] = {};
    _tsprintf(cmd, _T("\"%s\" \"%s\""), _T("PATH to process 2"), argv[1]);

    if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
    {
        // handle the error ...
        return 1;
    }

    char c = '1';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}
</code>```

Process 2:

```<code>#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - the name of the file I want to open
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    char c = '2';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}
</code>```

Otherwise, consider having process 1 duplicate the file handle and then have process 2 inherit the duplicate instead of the original.

Body:
I want to have 2 processes write in the same file. I created a file in the first process (parent) and call the second process (child) . I have made the file inheritable and the second process inherits the handle as a command line argument.

Although the handle is not equal to INVALID_HANDLE_VALUE, the second process can't do anything with the file. WriteFile() ends with Error 6(the handle is invalid). The same is for LockFile(),Unlockfile().

What is wrong with the code and how can I fix it? I want to make 2 processes work with the same file.

Process 1:

#include <Windows.h>
#include <process.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _SECURITY_ATTRIBUTES sec_attr;
    sec_attr.nLength = sizeof(_SECURITY_ATTRIBUTES);
    sec_attr.bInheritHandle = true;
    sec_attr.lpSecurityDescriptor = 0;
    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1],GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE |
             FILE_SHARE_READ,&sec_attr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo,sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;

    char cmd[300] = "PATH to process 2";
    CreateProcess(0,cmd,0,0,true,NORMAL_PRIORITY_CLASS,0,0,&sinfo,&pinfo);
    char c = '1';
    DWORD w;
    WriteFile(h,&c,1,&w,0); //works fine
    ...
}

Process 2:

#include <Windows.h>
#include <process.h>

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE h = argv[1];
    if(h == INVALID_HANDLE_VALUE) {
        //it's okay, h is NOT equal to INVALID_HANDLE_VALUE
    }
    char c = '2';
    DWORD w;
    WriteFile(h,&c,1,&w,0);  //error 6
    ...
}

P.S. The first process succeeds in writing in the file. By that time the second process has already failed.

Body:
You may be creating the child process with an inheritable file handle, but you are not actually telling the child what the value of that handle is!  The child is looking for that value in argv[1], but the code you have shown is not passing any value in that parameter!  Even if there were, you are not retrieving the value correctly anyway.

Command-line parameters are always strings, so argv[1] is a pointer to a null-terminated string, not a handle.  You have to convert the handle pointer to a string representation when you put it on the command-line, and then you have to parse that string back to a pointer when processing the command-line.

Try something more like this:

Process 1:

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    SECURITY_ATTRIBUTES sec_attr = {};
    sec_attr.nLength = sizeof(sec_attr);
    sec_attr.bInheritHandle = TRUE;
    sec_attr.lpSecurityDescriptor = 0;

    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, &sec_attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo, sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;
    ZeroMemory(&pinfo, sizeof(pinfo));

    _TCHAR cmd[MAX_PATH + 16] = {};
    _tsprintf(cmd, _T("\"%s\" %p"), _T("PATH to process 2"), h);

    // TODO: consider using STARTUPINFOEX instead so the child inherits
    // ONLY the file handle and not ALL inheritable handles it doesn't
    // care about:
    //
    // Programmatically controlling which handles are inherited by new processes in Win32
    // https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873
    //
    if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
    {
        // handle the error ...
        return 1;
    }

    CloseHandle(pinfo.hThread);
    CloseHandle(pinfo.hProcess);

    char c = '1';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}

Process 2:

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - string representation of a handle to an open file
    HANDLE h = INVALID_HANDLE_VALUE;
    _stscanf(argv[1], _T("%p"), &h);

    char c = '2';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}

That being said, having two threads, let alone two processes, share a single file handle is NOT a good idea.  A given file handle only has 1 read/write position in it, so sharing that handle is going to risk the threads/processes stepping all over each other, unless you provide some kind of synchronization between them so only one can access the file at a time.

Consider passing the target filename to the child process and let it open its own unique handle to the file, eg:

Process 1:

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - the name of the file I want to create
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    STARTUPINFO sinfo;
    ZeroMemory(&sinfo, sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);

    PROCESS_INFORMATION pinfo;
    ZeroMemory(&pinfo, sizeof(pinfo));

    _TCHAR cmd[(MAX_PATH *2) + 10] = {};
    _tsprintf(cmd, _T("\"%s\" \"%s\""), _T("PATH to process 2"), argv[1]);

    if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
    {
        // handle the error ...
        return 1;
    }

    char c = '1';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}

Process 2:

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        // ...
        return 1;
    }

    //argv[1] - the name of the file I want to open
    HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE)
    {
        // handle the error ...
        return 1;
    }

    char c = '2';
    DWORD w;
    WriteFile(h, &c, 1, &w, 0);
    ...

    CloseHandle(h);
    return 0;
}

Otherwise, consider having process 1 duplicate the file handle and then have process 2 inherit the duplicate instead of the original.


来源: stackexchange

问:
addEventListener + setTimeout
It's the first time I encounter such an issue with the addEventListener() method.
When I try to use it with a setTimeout, the function is automatically called, even though the addEventListener has a "click" property.

<button id="test">Test</button>

```<code>document.getElementById("test").addEventListener("click", setTimeout(myFunc, 2000));

function myFunc() {
  console.log("Hello");
}
</code>```

答:
You could keep the exact same code you have now but curry your function via bind vs. trying to invoke it while also trying to pass it as an argument.

document.getElementById("test").addEventListener("click", setTimeout.bind(null, myFunc, 2000));

function myFunc() {
  console.log("Hello");
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><button id="test">Click</button></code>```

ContentLicense: CC BY-SA 3.0

Title: addEventListener + setTimeout

Body:
It's the first time I encounter such an issue with the addEventListener() method.
When I try to use it with a setTimeout, the function is automatically called, even though the addEventListener has a "click" property.

<button id="test">Test</button>

document.getElementById("test").addEventListener("click", setTimeout(myFunc, 2000));

function myFunc() {
  console.log("Hello");
}

Body:
You could keep the exact same code you have now but curry your function via bind vs. trying to invoke it while also trying to pass it as an argument.

document.getElementById("test").addEventListener("click", setTimeout.bind(null, myFunc, 2000));

function myFunc() {
  console.log("Hello");
}

<button id="test">Click</button>


问:
How to convert messages from socket streaming source to custom domain object?
I'm very new to spark streaming. I have a Spark Standalone 2.2 running with one worker. I'm using a socket source and trying to read the incoming stream into an object called MicroserviceMessage.

val message = spark.readStream
  .format("socket")
  .option("host", host)
  .option("port", port)
  .load()

val df = message.as[MicroserviceMessage].flatMap(microserviceMessage =>
    microserviceMessage.DataPoints.map(datapoint => (datapoint, microserviceMessage.ServiceProperties, datapoint.EpochUTC)))
  .toDF("datapoint", "properties", "timestamp")
```

<p>I'm hoping this will a DataFrame with columns of "datapoint", "properties" and "timestamp"</p>

<p>The data i'm pasting into my netcat terminal looks like this (this is what I'm trying to read in as MicroserviceMessage):</p>

<pre class="lang-scala prettyprint-override"><code>{
  "SystemType": "mytype",
  "SystemGuid": "6c84fb90-12c4-11e1-840d-7b25c5ee775a",
  "TagType": "Raw Tags",
  "ServiceType": "FILTER",
  "DataPoints": [
    {
      "TagName": "013FIC003.PV",
      "EpochUTC": 1505247956001,
      "ItemValue": 25.47177,
      "ItemValueStr": "NORMAL",
      "Quality": "Good",
      "TimeOffset": "P0000"
    },
    {
      "TagName": "013FIC003.PV",
      "EpochUTC": 1505247956010,
      "ItemValue": 26.47177,
      "ItemValueStr": "NORMAL",
      "Quality": "Good",
      "TimeOffset": "P0000"
    }
  ],
  "ServiceProperties": [
    {
      "Key": "OutputTagName",
      "Value": "FI12102.PV_CL"
    },
    {
      "Key": "OutputTagType",
      "Value": "Cleansing Flow Tags"
    }
  ]
}
</code>```

Instead what I see is:

Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve '`SystemType`' given input columns: [value];
```

<p>MicroserviceMessage case class looks like this:</p>

<pre class="lang-scala prettyprint-override"><code>case class DataPoints
(
  TagName: String,
  EpochUTC: Double,
  ItemValue: Double,
  ItemValueStr: String,
  Quality: String,
  TimeOffset: String
)

case class ServiceProperties
(
  Key: String,
  Value: String
)

case class MicroserviceMessage
(
  SystemType: String,
  SystemGuid: String,
  TagType: String,
  ServiceType: String,
  DataPoints: List[DataPoints],
  ServiceProperties: List[ServiceProperties]
)
</code>```

EDIT:
After reading this post I was able to start the job by doing

val messageEncoder = Encoders.bean(classOf[MicroserviceMessage])

val df = message.select($"value").as(messageEncoder).map(
  msmg => (msmg.ServiceType, msmg.SystemGuid)
).toDF("service", "guid")
```

<p>But this causes issues when I start sending data.</p>

<pre class="lang-scala prettyprint-override"><code>Caused by: java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: scala/runtime/LambdaDeserialize
</code>```

Full stacktrace

答:
This:

```<code>message.as[MicroserviceMessage]
</code>```

is incorrect as explained by the error message:

cannot resolve 'SystemType' given input columns: [value];

Data that comes from SocketStream is just string (or string and timestamp). To make it usable for strongly typed Dataset you have to parse it, for example with org.apache.spark.sql.functions.from_json.

ContentLicense: CC BY-SA 4.0

Body:
I'm very new to spark streaming. I have a Spark Standalone 2.2 running with one worker. I'm using a socket source and trying to read the incoming stream into an object called MicroserviceMessage.

val message = spark.readStream
  .format("socket")
  .option("host", host)
  .option("port", port)
  .load()

val df = message.as[MicroserviceMessage].flatMap(microserviceMessage =>
    microserviceMessage.DataPoints.map(datapoint => (datapoint, microserviceMessage.ServiceProperties, datapoint.EpochUTC)))
  .toDF("datapoint", "properties", "timestamp")

I'm hoping this will a DataFrame with columns of "datapoint", "properties" and "timestamp"

The data i'm pasting into my netcat terminal looks like this (this is what I'm trying to read in as MicroserviceMessage):

{
  "SystemType": "mytype",
  "SystemGuid": "6c84fb90-12c4-11e1-840d-7b25c5ee775a",
  "TagType": "Raw Tags",
  "ServiceType": "FILTER",
  "DataPoints": [
    {
      "TagName": "013FIC003.PV",
      "EpochUTC": 1505247956001,
      "ItemValue": 25.47177,
      "ItemValueStr": "NORMAL",
      "Quality": "Good",
      "TimeOffset": "P0000"
    },
    {
      "TagName": "013FIC003.PV",
      "EpochUTC": 1505247956010,
      "ItemValue": 26.47177,
      "ItemValueStr": "NORMAL",
      "Quality": "Good",
      "TimeOffset": "P0000"
    }
  ],
  "ServiceProperties": [
    {
      "Key": "OutputTagName",
      "Value": "FI12102.PV_CL"
    },
    {
      "Key": "OutputTagType",
      "Value": "Cleansing Flow Tags"
    }
  ]
}

Instead what I see is:

Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve '`SystemType`' given input columns: [value];

MicroserviceMessage case class looks like this:

case class DataPoints
(
  TagName: String,
  EpochUTC: Double,
  ItemValue: Double,
  ItemValueStr: String,
  Quality: String,
  TimeOffset: String
)

case class ServiceProperties
(
  Key: String,
  Value: String
)

case class MicroserviceMessage
(
  SystemType: String,
  SystemGuid: String,
  TagType: String,
  ServiceType: String,
  DataPoints: List[DataPoints],
  ServiceProperties: List[ServiceProperties]
)

EDIT:
After reading this post I was able to start the job by doing

val messageEncoder = Encoders.bean(classOf[MicroserviceMessage])

val df = message.select($"value").as(messageEncoder).map(
  msmg => (msmg.ServiceType, msmg.SystemGuid)
).toDF("service", "guid")

But this causes issues when I start sending data.

Caused by: java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: scala/runtime/LambdaDeserialize

Full stacktrace

Body:
This:

message.as[MicroserviceMessage]

is incorrect as explained by the error message:

cannot resolve 'SystemType' given input columns: [value];

Data that comes from SocketStream is just string (or string and timestamp). To make it usable for strongly typed Dataset you have to parse it, for example with org.apache.spark.sql.functions.from_json.


问:
What does this symbol mean in C++? "~"
If we use ~ before a function like this: ~func();, what does this mean?

Thanks.

答: Its the Destructor. A function guarenteed to be called when the object is destroyed.</p>

ContentLicense: CC BY-SA 2.5

Title: What does this symbol mean in C++? "~"


问:
Remove "add to cart" button without removing Woocommerce Product Add-ons
I am usig WooCommerce with WooCommerce product add-ons plugin. I have seen many answers that remove the "add to cart" button on single product pages. They also remove WooCommerce product add-ons as well.

Can anyone provide insight how to add back "add-ons" while removing "add to cart" button?

Here is what I have to remove the "add to cart" button but removes add-ons as well:

```<code>add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_buttons', 1 );

function remove_add_to_cart_buttons() {
    remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
</code>```

答:
WooCommerce product Add-Ons needs woocommerce_before_add_to_cart_button action hook to display all Add-ons fields and data.

So in the code below will work for simple and variable products, just removing the add-to-cart and quantity fields, allowing product Add-ons fields and data to be displayed.

```<code>add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_buttons', 1 );
function remove_add_to_cart_buttons() {
    global $product;

    // For simple product types
    if( $product->is_type( 'simple' ) ) {
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
        add_action( 'woocommerce_single_product_summary', 'custom_before_single_add_to_cart', 30 );
    }
    // For variable product types (keeping attribute select fields)
    elseif( $product->is_type( 'variable' ) ) {
        remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
    }
}
function custom_before_single_add_to_cart(){
    global $product;

    if ( ! $product->is_purchasable() ) return;

    // Simple Products
    if ( $product->is_in_stock() ) {
        do_action( 'woocommerce_before_add_to_cart_form' ); // (Optional)

        echo '<form class="cart" method="post" enctype="multipart/form-data">'; // (Optiona

            ## @since 2.1.0.
            do_action( 'woocommerce_before_add_to_cart_button' ); // <== NEEDED by Add-ons

            ## @since 3.0.0.
            do_action( 'woocommerce_before_add_to_cart_quantity' ); // Optional

            ## @since 3.0.0.
            do_action( 'woocommerce_after_add_to_cart_quantity' ); // Optional

            ## @since 2.1.0.
            do_action( 'woocommerce_after_add_to_cart_button' ); // Optional

        echo '</form>'; // Optional

        do_action( 'woocommerce_after_add_to_cart_form' ); // Optional
    }
}
</code>```

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.

As the add to cart button is removed, you will not be able to submit the Add-ons data

Body:
I am usig WooCommerce with WooCommerce product add-ons plugin. I have seen many answers that remove the "add to cart" button on single product pages. They also remove WooCommerce product add-ons as well.

Can anyone provide insight how to add back "add-ons" while removing "add to cart" button?

Here is what I have to remove the "add to cart" button but removes add-ons as well:

add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_buttons', 1 );

function remove_add_to_cart_buttons() {
    remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}

Body:
WooCommerce product Add-Ons needs woocommerce_before_add_to_cart_button action hook to display all Add-ons fields and data.

So in the code below will work for simple and variable products, just removing the add-to-cart and quantity fields, allowing product Add-ons fields and data to be displayed.

add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_buttons', 1 );
function remove_add_to_cart_buttons() {
    global $product;

    // For simple product types
    if( $product->is_type( 'simple' ) ) {
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
        add_action( 'woocommerce_single_product_summary', 'custom_before_single_add_to_cart', 30 );
    }
    // For variable product types (keeping attribute select fields)
    elseif( $product->is_type( 'variable' ) ) {
        remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
    }
}
function custom_before_single_add_to_cart(){
    global $product;

    if ( ! $product->is_purchasable() ) return;

    // Simple Products
    if ( $product->is_in_stock() ) {
        do_action( 'woocommerce_before_add_to_cart_form' ); // (Optional)

        echo '<form class="cart" method="post" enctype="multipart/form-data">'; // (Optiona

            ## @since 2.1.0.
            do_action( 'woocommerce_before_add_to_cart_button' ); // <== NEEDED by Add-ons

            ## @since 3.0.0.
            do_action( 'woocommerce_before_add_to_cart_quantity' ); // Optional

            ## @since 3.0.0.
            do_action( 'woocommerce_after_add_to_cart_quantity' ); // Optional

            ## @since 2.1.0.
            do_action( 'woocommerce_after_add_to_cart_button' ); // Optional

        echo '</form>'; // Optional

        do_action( 'woocommerce_after_add_to_cart_form' ); // Optional
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.

As the add to cart button is removed, you will not be able to submit the Add-ons data


问:
Django 2.0 multiselect issue
I am testing 2.0 and have encountered the same error in two different places.

It has to do with multi-select.  I get the following error.

```<code>Exception Value: not enough values to unpack (expected 2, got 0)
</code>```

here is the code from crispy-forms-foundation

```<code>{% if not field|is_checkbox and not field|is_checkboxselectmultiple %}
  {% crispy_field field %}
{% endif %}
</code>```

the other package error was from: localflavor.us.models import USStateField, PhoneNumberField, USZipCodeField

What do I need to change to get these to work properly in 2.0?

Cheers

答:
I finally got it to work. Appears to be a Django 2 thing.

My previous code worked perfectly fine with the CharField.  Now you have to use ChoiceField.

I hope this helps.  Cheers.

```<code># before
case = forms.CharField ( label = "", widget = forms.Select ( choices = qs ) )

# now
case = forms.ChoiceField ( label = "", widget = forms.Select, choices = qs  )
</code>```

Title: Django 2.0 multiselect issue

Body:
I am testing 2.0 and have encountered the same error in two different places.

It has to do with multi-select.  I get the following error.

Exception Value: not enough values to unpack (expected 2, got 0)

here is the code from crispy-forms-foundation

{% if not field|is_checkbox and not field|is_checkboxselectmultiple %}
  {% crispy_field field %}
{% endif %}

the other package error was from: localflavor.us.models import USStateField, PhoneNumberField, USZipCodeField

What do I need to change to get these to work properly in 2.0?

Cheers

Body:
I finally got it to work. Appears to be a Django 2 thing.

My previous code worked perfectly fine with the CharField.  Now you have to use ChoiceField.

I hope this helps.  Cheers.

# before
case = forms.CharField ( label = "", widget = forms.Select ( choices = qs ) )

# now
case = forms.ChoiceField ( label = "", widget = forms.Select, choices = qs  )


问:
How to make the async.each wait for the .save() to be completed?
I am trying to save some data into my collection, using mongoose.

//tried with async each
async.each(indexes, function(index, callback) {
            newChampion.ID = champions[index].id;
            newChampion.Key = champions[index].key;
            newChampion.Name = champions[index].name;
            newChampion.Title = champions[index].title;
            Champion.addChampion(newChampion, function(err) {
                if (err) {
                    console.log(err.message);
                    callback();
                } else {
                    callback();
                }
});```
</div>
</div>
</p>

<p>The problem is that it pushes me only the value corresponding to the last index.(out of 133 values). I have the ID unique, so that is why there is only one value saved in the data base. I placed a console.log into the addChampion function and for 133 times I see the same value. Add champion snippet added below: </p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>module.exports.addChampion = function(newChampion, callback) {
    newChampion.save(callback);
}</code>```

How I solve this problem, in order to have all 133 values pushed into the DB?

答:
Async job with my local mysql:

```<code>let async = require('async');
let mysql = require('mysql');

var conn = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'xxxxx',
    database: 'xxxxx',
    port: 3306
});

var sqls = [
    'select id from record where id = 1',
    'select id from record where id = 2',
    'select id from record where id = 3',
    'select id from record where id = 4',
    'select id from record where id = 5'
];

async.each(sqls, function(sql, callback) {
    console.log(sql);
    conn.query(sql, function (err, res) {
        console.log(res);
    });
});
### output ###
select id from record where id = 1
select id from record where id = 2
select id from record where id = 3
select id from record where id = 4
select id from record where id = 5
[ RowDataPacket { id: 1 } ]
[ RowDataPacket { id: 2 } ]
[ RowDataPacket { id: 3 } ]
[ RowDataPacket { id: 4 } ]
[ RowDataPacket { id: 5 } ]
</code>```

Simple case with not a really async job :

```<code>let async = require('async');

let addChampion = function(newChampion, callback) {
    console.log(newChampion)
}

indexes = [1, 2, 3];
async.each(indexes, function(index, callback) {
    newChampion = {};
    newChampion.ID = index;
    addChampion(newChampion, function(err) {
        if (err) {
            console.log(err.message);
        }
    })
});

### output ###
{ ID: 1 }
{ ID: 2 }
{ ID: 3 }
</code>```

Would you check your newChampion before passing into the addChampion function? It's really wired you can the same index at console in it.

Body:
I am trying to save some data into my collection, using mongoose.

//tried with async each
async.each(indexes, function(index, callback) {
            newChampion.ID = champions[index].id;
            newChampion.Key = champions[index].key;
            newChampion.Name = champions[index].name;
            newChampion.Title = champions[index].title;
            Champion.addChampion(newChampion, function(err) {
                if (err) {
                    console.log(err.message);
                    callback();
                } else {
                    callback();
                }
});

The problem is that it pushes me only the value corresponding to the last index.(out of 133 values). I have the ID unique, so that is why there is only one value saved in the data base. I placed a console.log into the addChampion function and for 133 times I see the same value. Add champion snippet added below:

module.exports.addChampion = function(newChampion, callback) {
    newChampion.save(callback);
}

How I solve this problem, in order to have all 133 values pushed into the DB?

Body:
Async job with my local mysql:

let async = require('async');
let mysql = require('mysql');

var conn = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'xxxxx',
    database: 'xxxxx',
    port: 3306
});

var sqls = [
    'select id from record where id = 1',
    'select id from record where id = 2',
    'select id from record where id = 3',
    'select id from record where id = 4',
    'select id from record where id = 5'
];

async.each(sqls, function(sql, callback) {
    console.log(sql);
    conn.query(sql, function (err, res) {
        console.log(res);
    });
});
### output ###
select id from record where id = 1
select id from record where id = 2
select id from record where id = 3
select id from record where id = 4
select id from record where id = 5
[ RowDataPacket { id: 1 } ]
[ RowDataPacket { id: 2 } ]
[ RowDataPacket { id: 3 } ]
[ RowDataPacket { id: 4 } ]
[ RowDataPacket { id: 5 } ]

Simple case with not a really async job :

let async = require('async');

let addChampion = function(newChampion, callback) {
    console.log(newChampion)
}

indexes = [1, 2, 3];
async.each(indexes, function(index, callback) {
    newChampion = {};
    newChampion.ID = index;
    addChampion(newChampion, function(err) {
        if (err) {
            console.log(err.message);
        }
    })
});

### output ###
{ ID: 1 }
{ ID: 2 }
{ ID: 3 }

Would you check your newChampion before passing into the addChampion function? It's really wired you can the same index at console in it.


问:
Exception during generic container clearing, C++
I am having problems with clearing of the generic container. In carrying out the function clear() the program fails.

Base class:

```<code>//Generic container
template <class Item>
struct TList
{
    typedef std::vector <Item> Type;
};

template <class Item>
class GContainer
{
protected:
            typename TList <Item>::Type items;

public:
            GContainer() : items (0) {}
    virtual ~GContainer() = 0;

public:
            typename TList <Item>::Type ::iterator begin() { return items.begin(); }
            typename TList <Item>::Type ::iterator end() { return items.end(); }
...
};
</code>```

Derived class:

```<code>//Generic container for points
template <class Point>
class ContPoints : public GContainer <Point>
{
public:
    void clear();
            ...
};

//Specialization
template <class Point>
class ContPoints <Point *> : public GContainer <Point>
{
public:
    void clear();
            ...
};
</code>```

Implementation of the method clear()

```<code>template <class Point>
void ContPoints <Point *>::clear()
{
        for ( typename TItemsList <Point>::Type ::iterator i_items = items.begin(); i_items != items.end(); ++i_items )
        {
                //Delete each node
                if ( &(i_items) != NULL )
                {
                          delete * i_items //Compile error, not usable, why ???
                          delete &*i_items; //Usable, but exception
                  *i_items) = 0; //Than exception
                }
        }
        items.clear(); //vector clear
}
</code>```

Suprisingly:

A] I am not able to delete *i_items...

```<code>delete *i_items; //Error C2440: 'delete' : cannot convert from 'Point<T>' to 'void *
</code>```

B] I am able to delete only &*i_items...

```<code>int _tmain(int argc, _TCHAR* argv[])
{
  ContPoints <Point<double> *> pll;
  pll.push_back (new Point <double>(0,0));
  pll.push_back (new Point <double>(10,10));
  pll.clear(); //Exception
  return 0;
}
</code>```

Thanks for your help...

答:
As far as I can see from this

```<code>template <class Point>
class ContPoints <Point *> : public GContainer <Point>
</code>```

the GContainer is storing instances of Point by value, not pointers to Point.

This is confirmed by the error message: cannot convert a Point<T> to a pointer.

Body:
I am having problems with clearing of the generic container. In carrying out the function clear() the program fails.

Base class:

//Generic container
template <class Item>
struct TList
{
    typedef std::vector <Item> Type;
};

template <class Item>
class GContainer
{
protected:
            typename TList <Item>::Type items;

public:
            GContainer() : items (0) {}
    virtual ~GContainer() = 0;

public:
            typename TList <Item>::Type ::iterator begin() { return items.begin(); }
            typename TList <Item>::Type ::iterator end() { return items.end(); }
...
};

Derived class:

//Generic container for points
template <class Point>
class ContPoints : public GContainer <Point>
{
public:
    void clear();
            ...
};

//Specialization
template <class Point>
class ContPoints <Point *> : public GContainer <Point>
{
public:
    void clear();
            ...
};

Implementation of the method clear()

template <class Point>
void ContPoints <Point *>::clear()
{
        for ( typename TItemsList <Point>::Type ::iterator i_items = items.begin(); i_items != items.end(); ++i_items )
        {
                //Delete each node
                if ( &(i_items) != NULL )
                {
                          delete * i_items //Compile error, not usable, why ???
                          delete &*i_items; //Usable, but exception
                  *i_items) = 0; //Than exception
                }
        }
        items.clear(); //vector clear
}

Suprisingly:

A] I am not able to delete *i_items...

delete *i_items; //Error C2440: 'delete' : cannot convert from 'Point<T>' to 'void *

B] I am able to delete only &*i_items...

int _tmain(int argc, _TCHAR* argv[])
{
  ContPoints <Point<double> *> pll;
  pll.push_back (new Point <double>(0,0));
  pll.push_back (new Point <double>(10,10));
  pll.clear(); //Exception
  return 0;
}

Thanks for your help...

Body:
As far as I can see from this

template <class Point>
class ContPoints <Point *> : public GContainer <Point>

the GContainer is storing instances of Point by value, not pointers to Point.

This is confirmed by the error message: cannot convert a Point<T> to a pointer.


问:
Cant connect dynamo Db from my vpc configured lambda function
i need to connect elastic cache and dynamo db from a single lambda function. My code is

```<code>exports.handler = (event, context, callback) => {

    var redis = require("redis");
    var client;
    function connectRedisClient() {
        client = redis.createClient(6379, "dgdfgdfgdfgdfgdfgfd.use1.cache.amazonaws.com", { no_ready_check: true });
    }

    connectRedisClient();
    client.set('sampleKey', 'Hello World', redis.print);
    console.log("set worked");
    client.quit();

    var AWS = require("aws-sdk");
    var docClient = new AWS.DynamoDB.DocumentClient();
    var table = "dummy";
    var year = 2015;
    var title = "The Big New Movie";
    var params = {
        TableName: table,
        Item: {
            "userid": "manafcj",
            "year": year,
            "title": title,
            "test1": [645645, 7988],
            "info": {
                "plot": "Nothing happens at all.",
                "rating": 0
            }
        }
    };

    console.log("Adding a new item...");
    docClient.put(params, function (err, data) {
        if (err) {
            console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("Added item:", JSON.stringify(data, null, 2));
        }
    });
    callback(null, 'Hello from Lambda');
 };
</code>```

I executed this lambda code without configuring vpc, elastic cache section is not working , but dynamo insertion is done perfectly.

after that i made setup for VPC in my account by following steps.

create vpc
name : test-vpc-name
CIDR block:172.31.0.0/16
Tenancy:Default

Create a new subnet.
name tag : test-subnet-1a
CIDR block :172.31.0.0/20

name tag : test-subnet-1b
CIDR block :172.31.16.0/20

Create a route table
name tag : test-route-table

Create a internet gateway
name:test-internet-gateway

Attach VPC

Route all outbound 0.0.0.0/0 traffic in routes

Create a route table subnet association

Create a NAT Gateway
subnet : test-subnet-1a

also i have configured my elastic cache setup by following steps

Create subnet cache group
name : test-cache-group

Create elastic cache

type: redis
Cluster Name : test-cache

subnet cache group :  test-cache-group

Finally, i have configured newly created vpc on my lambda function. Then redis-elastic cache connection is working fine, but dynamo db connection is lost. I need both working fine from a single lambda function.

I think, some fault in VPC configuration with NAT Gateway.

What is the actual issue in this setup?

答:
There is now a relatively easy solution: VPC Endpoints.

"Previously, if you wanted your EC2 (elroy: or lambda)  instances in your VPC to be able to access DynamoDB, you had two options. You could use an Internet Gateway (with a NAT Gateway or assigning your instances public IPs) or you could route all of your traffic to your local infrastructure via VPN or AWS Direct Connect and then back to DynamoDB."

"A VPC endpoint for DynamoDB enables Amazon EC2 instances in your VPC to use their private IP addresses to access DynamoDB with no exposure to the public Internet...Your EC2 instances do not require public IP addresses, and you do not need an Internet gateway, a NAT device, or a virtual private gateway in your VPC. You use endpoint policies to control access to DynamoDB. Traffic between your VPC and the AWS service does not leave the Amazon network. "

The above quotes come from the links below.  Note the the references to "EC2 instances" apply to lambda contexts as well.

See https://aws.amazon.com/blogs/aws/new-vpc-endpoints-for-dynamodb/

and

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/vpc-endpoints-dynamodb.html

Edited to provide more details in line.

Body:
i need to connect elastic cache and dynamo db from a single lambda function. My code is

exports.handler = (event, context, callback) => {

    var redis = require("redis");
    var client;
    function connectRedisClient() {
        client = redis.createClient(6379, "dgdfgdfgdfgdfgdfgfd.use1.cache.amazonaws.com", { no_ready_check: true });
    }

    connectRedisClient();
    client.set('sampleKey', 'Hello World', redis.print);
    console.log("set worked");
    client.quit();

    var AWS = require("aws-sdk");
    var docClient = new AWS.DynamoDB.DocumentClient();
    var table = "dummy";
    var year = 2015;
    var title = "The Big New Movie";
    var params = {
        TableName: table,
        Item: {
            "userid": "manafcj",
            "year": year,
            "title": title,
            "test1": [645645, 7988],
            "info": {
                "plot": "Nothing happens at all.",
                "rating": 0
            }
        }
    };

    console.log("Adding a new item...");
    docClient.put(params, function (err, data) {
        if (err) {
            console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("Added item:", JSON.stringify(data, null, 2));
        }
    });
    callback(null, 'Hello from Lambda');
 };

I executed this lambda code without configuring vpc, elastic cache section is not working , but dynamo insertion is done perfectly.

after that i made setup for VPC in my account by following steps.

create vpc
name : test-vpc-name
CIDR block:172.31.0.0/16
Tenancy:Default

Create a new subnet.
name tag : test-subnet-1a
CIDR block :172.31.0.0/20

name tag : test-subnet-1b
CIDR block :172.31.16.0/20

Create a route table
name tag : test-route-table

Create a internet gateway
name:test-internet-gateway

Attach VPC

Route all outbound 0.0.0.0/0 traffic in routes

Create a route table subnet association

Create a NAT Gateway
subnet : test-subnet-1a

also i have configured my elastic cache setup by following steps

Create subnet cache group
name : test-cache-group

Create elastic cache

type: redis
Cluster Name : test-cache

subnet cache group :  test-cache-group

Finally, i have configured newly created vpc on my lambda function. Then redis-elastic cache connection is working fine, but dynamo db connection is lost. I need both working fine from a single lambda function.

I think, some fault in VPC configuration with NAT Gateway.

What is the actual issue in this setup?


问:
Best database architecture for schedule
So far I have a table for a shift schedule which looks like this

```<code>id | shift_id | start      | finish
1  | 1        | 2017-11-20 | 2017-11-24
2  | 2        | 2017-11-20 | 2017-11-24
3  | 1        | 2017-11-27 | 2017-12-01
4  | 2        | 2017-11-27 | 2017-12-01
5  | 1        | 2017-12-04 | 2017-12-08
6  | 6        | 2017-12-04 | 2017-12-08
</code>```

I would like to search the database by either a single date or by using a date range and have been using the following to do so:-

```<code>// Query shift data
$sql = "SELECT * FROM " . SCHEDULE_TABLE . "
        INNER JOIN " . SHIFTS_TABLE . " ON " . SCHEDULE_TABLE . ".shift_id = " . SHIFTS_TABLE . ".shift_id
        WHERE :startDate >= start AND start < :endDate";
$stmt = $pdo->prepare($sql);
$stmt->execute(['startDate' => $startDate, 'endDate' => $endDate]);
</code>```

so if I set $startdate to "2017-11-21" and $endDate to "2017-11-21" I would expect the query to return results with id 1 and 2 (which it does)

However if I search for a range that goes beyond a given week I only get 1 weeks results for example if I set $startDate to "2017-11-22" and endDate to "2017-12-06" I would expect the query to return all 6 rows but it onl returns the first 2 rows.

I know this is likely to be a problem with my query as I am only searching the start column and never using the finish column.

ultimately when the query is returned I will be putting each shift within the date range into an array so if I search "2017-11-20" - "2017-11-24" I would end up with an array:-

```<code>        {
        date: 2017-11-20
        shift: 1
        date: 2017-11-20
        shift: 2
        date: 2017-11-21
        shift: 1
        date: 2017-11-21
        shift: 2
etc...
}
</code>```

should I be looking to fix my sql query or should I re-structure the table so that I store every single day instead of in 5 day blocks?

答:
This looks like an overlapping range problem.  Try this logic in your WHERE clause:

```<code>WHERE :startDate < finish AND :endDate > start
</code>```

Here is a demo for the following query which shows that all six records are returned for the date range you mentioned.

```<code>SELECT *
FROM yourTable
WHERE '2017-11-22' < finish AND '2017-12-06' > start;
</code>```

Demo

Title: Best database architecture for schedule

Body:
So far I have a table for a shift schedule which looks like this

id | shift_id | start      | finish
1  | 1        | 2017-11-20 | 2017-11-24
2  | 2        | 2017-11-20 | 2017-11-24
3  | 1        | 2017-11-27 | 2017-12-01
4  | 2        | 2017-11-27 | 2017-12-01
5  | 1        | 2017-12-04 | 2017-12-08
6  | 6        | 2017-12-04 | 2017-12-08

I would like to search the database by either a single date or by using a date range and have been using the following to do so:-

// Query shift data
$sql = "SELECT * FROM " . SCHEDULE_TABLE . "
        INNER JOIN " . SHIFTS_TABLE . " ON " . SCHEDULE_TABLE . ".shift_id = " . SHIFTS_TABLE . ".shift_id
        WHERE :startDate >= start AND start < :endDate";
$stmt = $pdo->prepare($sql);
$stmt->execute(['startDate' => $startDate, 'endDate' => $endDate]);

so if I set $startdate to "2017-11-21" and $endDate to "2017-11-21" I would expect the query to return results with id 1 and 2 (which it does)

However if I search for a range that goes beyond a given week I only get 1 weeks results for example if I set $startDate to "2017-11-22" and endDate to "2017-12-06" I would expect the query to return all 6 rows but it onl returns the first 2 rows.

I know this is likely to be a problem with my query as I am only searching the start column and never using the finish column.

ultimately when the query is returned I will be putting each shift within the date range into an array so if I search "2017-11-20" - "2017-11-24" I would end up with an array:-

        {
        date: 2017-11-20
        shift: 1
        date: 2017-11-20
        shift: 2
        date: 2017-11-21
        shift: 1
        date: 2017-11-21
        shift: 2
etc...
}

should I be looking to fix my sql query or should I re-structure the table so that I store every single day instead of in 5 day blocks?

Body:
This looks like an overlapping range problem.  Try this logic in your WHERE clause:

WHERE :startDate < finish AND :endDate > start

Here is a demo for the following query which shows that all six records are returned for the date range you mentioned.

SELECT *
FROM yourTable
WHERE '2017-11-22' < finish AND '2017-12-06' > start;

Demo


问:
Triggering a script on a google sheet after editing a separate sheet

Hello, I am making an initiative table for D&D using google sheets.
At the moment I have a Mainsheet in which myself (the DM) can edit and change, and Playersheet that has the data the players need using IMPORTRANGE.

I am attempting to write a script that will automatically hide all empty "initiative" cells in PlayerSheet .
I have successfully coded this script, however I would like it to trigger any time I edit the MainSheet.
Because all the date in the sheet comes from using IMPORTRANGE I am not able to use the on edit trigger, as the PlayerSheet is never edited.

Is it possible to have the script located in PlayerSheet run whenever I edit MainSheet?
On top of that would it be possible to have the script only run when I edit data in the F column?

答:
To run the script whenever you edit your spreadsheet, you can create a fonction on edit.

```<code>function onEdit(e){
    var range = e.range;
    //here you can check if the column if F or not and run your code.
}
</code>```

Tu change the values of another spreadsheet, when selecting the spreadsheet you want to do the actions on, instead of selecting the active one, you can edit one with the url. Something like :

```<code>var doc = SpreadsheetApp.openByUrl("paste the url here");
var sheet = doc.getSheetByName("Name of the sheet");
etc...
</code>```

And then do the modifications you need to do on the players spreadsheet.

Body:
To run the script whenever you edit your spreadsheet, you can create a fonction on edit.

function onEdit(e){
    var range = e.range;
    //here you can check if the column if F or not and run your code.
}

Tu change the values of another spreadsheet, when selecting the spreadsheet you want to do the actions on, instead of selecting the active one, you can edit one with the url. Something like :

var doc = SpreadsheetApp.openByUrl("paste the url here");
var sheet = doc.getSheetByName("Name of the sheet");
etc...

And then do the modifications you need to do on the players spreadsheet.


问:
FB Graph API: Grabbing all mutual friends - (#200) You do not have sufficient permissions to perform this action
I am using AWS Lambda to ask for all mutual friends between current user and another user as stated here: https://developers.facebook.com/docs/graph-api/reference/user-context/all_mutual_friends/

I have looked through all the other stackoverflow answers and can't really find one close enough and have followed each of their answers to still get errors like these:
Facebook Graph All Mutual Friends
and
"Requires a valid user is specified ..." error when using getCount

and my code looks like the below in AWS, note that I have used this node.js third-party sdk (https://github.com/node-facebook/facebook-node-sdk):

```<code>// Imports third-party fb graph api node.js sdk: https://github.com/node-facebook/facebook-node-sdk
const fbGraph = require('fb');

// Grabs app secret and app ID
const appSecret = process.env.APP_SECRET;
const appID = process.env.APP_ID;

// Uses user access token and grabs total count of all relevant mutual friends
exports.handler = (event, context, callback) => {
    // Grabs relevant details from request
    // const accessToken = event.accessToken;
    const friendUserID = event.friendUserID;

    fbGraph.api('oauth/access_token', {
        client_id: appID,
        client_secret: appSecret,
        grant_type: 'client_credentials'
    }, function (res) {
        if(!res || res.error) {
            console.log(!res ? 'error occurred' : res.error);
            return;
        }

        let access_token = res.access_token;

        // Sets options for fb graph api to work
        fbGraph.options({accessToken: access_token, appId: appID, appSecret: appSecret, timeout: 12000});

        // Sets up fields and query string for request
        const friendUserIDQueryString = '/' + friendUserID;
        const fields = {
            fields: 'context.fields(all_mutual_friends.limit(10))'
        };

        // Sends api request to get all mutual friends
        fbGraph.api(friendUserIDQueryString, 'post', fields, function(response) {
            console.log(response);

            // Error handling
            if (response.error) {
                // Logs error
                context.done(null, { MutualFriendsTotalCountError: 'Error: not able to receive response' });

                // Returns error message
                return callback(new Error(`Mutual friends total count error: ${response.error}`));
            }

            // Logs successful operation
            context.done(null, { MutualFriendsTotalCountSuccess: `Success: grabbed total mutual friend count for ${friendUserID}`});

            // Returns total count of mutual friends between current and other user as integer
            return callback(null, { total_count: response.context.all_mutual_friends.summary.total_count });
        });
    });
}
</code>```

but my response is now this:

```<code>{ error:
   { message: '(#200) You do not have sufficient permissions to perform this action',
     type: 'OAuthException',
     code: 200,
     ...
}
</code>```

I don't really understand it, I've used my own access token on my IOS app I'm using this for, the application app token through OAuth, and also the other user ID who exists on my app and is the one thats specific for my app and other recommended solutions to no avail.

答:
Ok now it works, I followed exactly with the example from this stackoverflow:
Facebook Graph All Mutual Friends

I don't know whats explicitly the difference as it still looks similar to something I had before but this is what my current code looks like and works:

```<code>// Imports third-party fb graph api node.js sdk: https://github.com/node-facebook/facebook-node-sdk
const fbGraph = require('fb');

// Grabs app secret and app ID
const appSecret = process.env.APP_SECRET;
const appID = process.env.APP_ID;

// Uses user access token and grabs total count of all relevant mutual friends
exports.handler = (event, context, callback) => {
    // Grabs relevant details from request
    const accessToken = event.accessToken;
    const friendUserID = event.friendUserID;

    // Sets options for fb graph api to work
    fbGraph.options({accessToken: accessToken, appId: appID, appSecret: appSecret, timeout: 12000});

    // Sends api request to get all mutual friends
    fbGraph.api('/' + friendUserID, { fields: 'context.fields(all_mutual_friends.limit(0))'}, function(response) {

        // Error handling
        if (!response || response.error) {
            // Logs error
            console.log('MutualFriendsTotalCountError: Error: not able to receive response');

            // Returns error message
            return callback(new Error(`Mutual friends total count error: ${response.error.message}`));
        }

        // Logs successful operation
        console.log(`Success: grabbed total mutual friend count for ${friendUserID}`);

        // Returns total count of mutual friends between current and other user as integer
        return callback(null, { total_count: response.context.all_mutual_friends.summary.total_count });
    });
}
</code>```

By the way, this returns the total number of app-using and non-app using mutual friends between current user and another user on AWS Lambda

Body:
I am using AWS Lambda to ask for all mutual friends between current user and another user as stated here: https://developers.facebook.com/docs/graph-api/reference/user-context/all_mutual_friends/

I have looked through all the other stackoverflow answers and can't really find one close enough and have followed each of their answers to still get errors like these:
Facebook Graph All Mutual Friends
and
"Requires a valid user is specified ..." error when using getCount

and my code looks like the below in AWS, note that I have used this node.js third-party sdk (https://github.com/node-facebook/facebook-node-sdk):

// Imports third-party fb graph api node.js sdk: https://github.com/node-facebook/facebook-node-sdk
const fbGraph = require('fb');

// Grabs app secret and app ID
const appSecret = process.env.APP_SECRET;
const appID = process.env.APP_ID;

// Uses user access token and grabs total count of all relevant mutual friends
exports.handler = (event, context, callback) => {
    // Grabs relevant details from request
    // const accessToken = event.accessToken;
    const friendUserID = event.friendUserID;

    fbGraph.api('oauth/access_token', {
        client_id: appID,
        client_secret: appSecret,
        grant_type: 'client_credentials'
    }, function (res) {
        if(!res || res.error) {
            console.log(!res ? 'error occurred' : res.error);
            return;
        }

        let access_token = res.access_token;

        // Sets options for fb graph api to work
        fbGraph.options({accessToken: access_token, appId: appID, appSecret: appSecret, timeout: 12000});

        // Sets up fields and query string for request
        const friendUserIDQueryString = '/' + friendUserID;
        const fields = {
            fields: 'context.fields(all_mutual_friends.limit(10))'
        };

        // Sends api request to get all mutual friends
        fbGraph.api(friendUserIDQueryString, 'post', fields, function(response) {
            console.log(response);

            // Error handling
            if (response.error) {
                // Logs error
                context.done(null, { MutualFriendsTotalCountError: 'Error: not able to receive response' });

                // Returns error message
                return callback(new Error(`Mutual friends total count error: ${response.error}`));
            }

            // Logs successful operation
            context.done(null, { MutualFriendsTotalCountSuccess: `Success: grabbed total mutual friend count for ${friendUserID}`});

            // Returns total count of mutual friends between current and other user as integer
            return callback(null, { total_count: response.context.all_mutual_friends.summary.total_count });
        });
    });
}

but my response is now this:

{ error:
   { message: '(#200) You do not have sufficient permissions to perform this action',
     type: 'OAuthException',
     code: 200,
     ...
}

I don't really understand it, I've used my own access token on my IOS app I'm using this for, the application app token through OAuth, and also the other user ID who exists on my app and is the one thats specific for my app and other recommended solutions to no avail.

Body:
Ok now it works, I followed exactly with the example from this stackoverflow:
Facebook Graph All Mutual Friends

I don't know whats explicitly the difference as it still looks similar to something I had before but this is what my current code looks like and works:

// Imports third-party fb graph api node.js sdk: https://github.com/node-facebook/facebook-node-sdk
const fbGraph = require('fb');

// Grabs app secret and app ID
const appSecret = process.env.APP_SECRET;
const appID = process.env.APP_ID;

// Uses user access token and grabs total count of all relevant mutual friends
exports.handler = (event, context, callback) => {
    // Grabs relevant details from request
    const accessToken = event.accessToken;
    const friendUserID = event.friendUserID;

    // Sets options for fb graph api to work
    fbGraph.options({accessToken: accessToken, appId: appID, appSecret: appSecret, timeout: 12000});

    // Sends api request to get all mutual friends
    fbGraph.api('/' + friendUserID, { fields: 'context.fields(all_mutual_friends.limit(0))'}, function(response) {

        // Error handling
        if (!response || response.error) {
            // Logs error
            console.log('MutualFriendsTotalCountError: Error: not able to receive response');

            // Returns error message
            return callback(new Error(`Mutual friends total count error: ${response.error.message}`));
        }

        // Logs successful operation
        console.log(`Success: grabbed total mutual friend count for ${friendUserID}`);

        // Returns total count of mutual friends between current and other user as integer
        return callback(null, { total_count: response.context.all_mutual_friends.summary.total_count });
    });
}

By the way, this returns the total number of app-using and non-app using mutual friends between current user and another user on AWS Lambda


问:
What is the difference between iterator and iterable and how to use them?
I am new in Java and I'm really confused with iterator and iterable. Can anyone explain to me and give some examples?</p>

答:
I will answer the question especially about ArrayList as an example in order to help you understand better..

Iterable interface forces its subclasses to implement abstract method 'iterator()'.

```<code>public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
</code>```

Iterator interface forces its subclasses to implement abstract method 'hasNext()' and 'next()'.

```<code>public interface Iterator {
  ...
  abstract boolean hasNext(); //Returns true if the iteration has more elements.
  abstract E next();          //Returns the next element in the iteration.
  ...
}
</code>```

ArrayList implements List, List extends Collection and Collection extends Iterable..
That is, you could see the relationship like

'Iterable <- Collection <- List <- ArrayList'

.
And Iterable, Collection and List just declare abstract method 'iterator()' and ArrayList alone implements it.

I am going to show ArrayList source code with 'iterator()' method as follows for more detailed information.

'iterator()' method returns an object of class 'Itr' which implements 'Iterator'.

```<code>public class ArrayList<E> ... implements List<E>, ...
{
  ...
  public Iterator<E> iterator() {
              return new Itr();
  }

  private class Itr implements Iterator<E> {
          ...

          public boolean hasNext() {
              return cursor != size;
          }
          @SuppressWarnings("unchecked")
          public E next() {
              checkForComodification();
              int i = cursor;
              if (i >= size)
                  throw new NoSuchElementException();
              Object[] elementData = ArrayList.this.elementData;
              if (i >= elementData.length)
                  throw new ConcurrentModificationException();
              cursor = i + 1;
              return (E) elementData[lastRet = i];
          }
          ...
  }
}
</code>```

Some other methods or classes will iterate elements of collections like ArrayList through making use of Iterator (Itr).

Here is a simple example.

```<code>public static void main(String[] args) {

    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String string = iterator.next();
        System.out.println(string);
    }
}
</code>```

Now, is it clear? :)

Body:
I will answer the question especially about ArrayList as an example in order to help you understand better..

Iterable interface forces its subclasses to implement abstract method 'iterator()'.

public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}

Iterator interface forces its subclasses to implement abstract method 'hasNext()' and 'next()'.

public interface Iterator {
  ...
  abstract boolean hasNext(); //Returns true if the iteration has more elements.
  abstract E next();          //Returns the next element in the iteration.
  ...
}

ArrayList implements List, List extends Collection and Collection extends Iterable..
That is, you could see the relationship like

'Iterable <- Collection <- List <- ArrayList'

.
And Iterable, Collection and List just declare abstract method 'iterator()' and ArrayList alone implements it.

I am going to show ArrayList source code with 'iterator()' method as follows for more detailed information.

'iterator()' method returns an object of class 'Itr' which implements 'Iterator'.

public class ArrayList<E> ... implements List<E>, ...
{
  ...
  public Iterator<E> iterator() {
              return new Itr();
  }

  private class Itr implements Iterator<E> {
          ...

          public boolean hasNext() {
              return cursor != size;
          }
          @SuppressWarnings("unchecked")
          public E next() {
              checkForComodification();
              int i = cursor;
              if (i >= size)
                  throw new NoSuchElementException();
              Object[] elementData = ArrayList.this.elementData;
              if (i >= elementData.length)
                  throw new ConcurrentModificationException();
              cursor = i + 1;
              return (E) elementData[lastRet = i];
          }
          ...
  }
}

Some other methods or classes will iterate elements of collections like ArrayList through making use of Iterator (Itr).

Here is a simple example.

public static void main(String[] args) {

    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String string = iterator.next();
        System.out.println(string);
    }
}

Now, is it clear? :)


问:
How to use ? : if statements with Razor and inline code blocks
I'm updating my old .aspx views with the new Razore view engine. I have a bunch of places where I have code like this:

```<code><span class="vote-up<%= puzzle.UserVote == VoteType.Up ? "-selected" : "" %>">Vote Up</span>
</code>```

Ideally I'd like to do this:

```<code><span class="vote-up@{puzzle.UserVote == VoteType.Up ? "-selected" : ""}">Vote Up</span>
</code>```

However there's two problems here:

vote-up@{puzzle.UserVote .... is not treating the @ symbol as a start of a code block

@puzzle.UserVote == VoteType.Up looks at the first part @puzzle.UserVote as if it's supposed to render the value of the variable.

Anyone know how to address these issues?

答:
This should work:</p>

```<code><span class="vote-up@(puzzle.UserVote == VoteType.Up ? "-selected" : "")">Vote Up</span>
</code>```

Body:
I'm updating my old .aspx views with the new Razore view engine. I have a bunch of places where I have code like this:

<span class="vote-up<%= puzzle.UserVote == VoteType.Up ? "-selected" : "" %>">Vote Up

Ideally I'd like to do this:

Vote Up

However there's two problems here:

vote-up@{puzzle.UserVote .... is not treating the @ symbol as a start of a code block

@puzzle.UserVote == VoteType.Up looks at the first part @puzzle.UserVote as if it's supposed to render the value of the variable.

Anyone know how to address these issues?

Body:
This should work:

<span class="vote-up@(puzzle.UserVote == VoteType.Up ? "-selected" : "")">Vote Up</span>


问:
selenium python get weird
This code is meant to scrape  google translate, I use selenium to scrape every possible translation for a given word.

Here is the code:

```<code>from selenium import webdriver

driver = webdriver.Chrome("E:\Tutorial\Driver\chromedriver.exe")

words = ['girl', 'cat', 'dog', 'bird', 'man']
for word in words:
    driver.get("https://translate.google.com.eg/?hl=en&tab=wT#en/fr/" + word)

translations = driver.find_elements_by_class_name('gt-baf-word-clickable')

for text in translations:
    print(text.text)
</code>```

And the thing is the scraper just do the job for the first word only.

答:
Code works for me if I use correct indentions and add time.sleep(1) so browser has time to load page. If I don't use time.sleep(1) then it can't find element and I get error message.

```<code>from selenium import webdriver
import time

driver = webdriver.Chrome("E:\Tutorial\Driver\chromedriver.exe")

words = ['girl', 'cat', 'dog', 'bird', 'man']
for word in words:
    driver.get("https://translate.google.com.eg/?hl=en&tab=wT#en/fr/" + word)
    time.sleep(1)
    try:
        translations = driver.find_elements_by_class_name('gt-baf-word-clickable')

        for text in translations:
            print(text.text)
    except Exception as ex:
        print(ex)
</code>```

Tested on Linux Mint 18 / Python 3.6.2 / Selenium 3.6.0

Title: selenium python get weird

Body:
This code is meant to scrape  google translate, I use selenium to scrape every possible translation for a given word.

Here is the code:

from selenium import webdriver

driver = webdriver.Chrome("E:\Tutorial\Driver\chromedriver.exe")

words = ['girl', 'cat', 'dog', 'bird', 'man']
for word in words:
    driver.get("https://translate.google.com.eg/?hl=en&tab=wT#en/fr/" + word)

translations = driver.find_elements_by_class_name('gt-baf-word-clickable')

for text in translations:
    print(text.text)

And the thing is the scraper just do the job for the first word only.

Body:
Code works for me if I use correct indentions and add time.sleep(1) so browser has time to load page. If I don't use time.sleep(1) then it can't find element and I get error message.

from selenium import webdriver
import time

driver = webdriver.Chrome("E:\Tutorial\Driver\chromedriver.exe")

words = ['girl', 'cat', 'dog', 'bird', 'man']
for word in words:
    driver.get("https://translate.google.com.eg/?hl=en&tab=wT#en/fr/" + word)
    time.sleep(1)
    try:
        translations = driver.find_elements_by_class_name('gt-baf-word-clickable')

        for text in translations:
            print(text.text)
    except Exception as ex:
        print(ex)

Tested on Linux Mint 18 / Python 3.6.2 / Selenium 3.6.0


问:
Setting word wrap on QLabel breaks size constrains for the window
I have the following code:

```<code>import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " \
       "Nullam malesuada tellus in ex elementum, vitae rutrum enim vestibulum."

#==============================================================================
class Window(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        # Widgets
        self.label = QLabel(TEXT, self)
#         self.label.setWordWrap(True)
        self.text = QTextEdit(self)
        self.text.setMinimumSize(480, 320)
        self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Layout
        self.layout = QGridLayout()
        self.layout.addWidget(self.label, 0, 0)
        self.layout.addWidget(self.text, 1, 0)
        self.layout.setContentsMargins(5, 5, 5, 5)
        self.layout.setSpacing(5)

        self.setLayout(self.layout)

        self.adjustSize()
        self.show()

#==============================================================================
if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Window()
    sys.exit(app.exec_())
</code>```

It works as expected, producing a window, which cannot be resized to be smaller:

However, when I uncomment the self.label.setWordWrap(True) line, these constrains seem to disappear. I can resize the window to smaller, completely breaking the layout, as QTextEdit still retains its size constrain:

I tried to fix this using self.setMinimumSize(self.size()). This works for this particular example, however breaks if the size is bigger, such as self.text.setMinimumSize(480, 800). That makes the window too small even when it is being created, so setMinimumSize does not help:

Is there a way how to fix it and make the window / layout still match the minimum size of QTextEdit even when word wrap is enabled?

Version information:

```<code>OS: Windows-7-SP1 (32bit)
Python: 3.4.1
PyQt: 5.3.1
Qt: 5.3.1
</code>```

答:
I also had this problem, with QT 4.8, and I couldn't upgrade my QT, since I was working on a plugin of QGIS 2.18 that still use QT 4.8.

My work around is manipulating the maximumHeight of the QWebView (or in your case, your QTextEdit) when the resize happen. You will need to emit custom signal for resized, since it's not available in QT (see: PyQt: Detect resizing in Widget-window resized signal)

So, my code is something like this:

```<code>class MetadataConverterDialog(QDialog):
    resized = pyqtSignal()
        # Adapted from https://stackoverflow.com/a/43126946/1198772
    def resizeEvent(self, event):
        """Emit custom signal when the window is re-sized.

        :param event: The re-sized event.
        :type event: QResizeEvent
        """
        self.resized.emit()
        return super(MetadataConverterDialog, self).resizeEvent(event)

    def after_resize(self):
        """Method after resizing the window."""
        max_height = self.height() - 275  # Magic number, to make it pretty
        self.metadata_preview_web_view.setMaximumHeight(max_height)
</code>```

The 275 is the value that I need to spare to show the dialog properly (for the widget before the QWebView. You will need to find the value that fits with your dialog.

Body:
I have the following code:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " \
       "Nullam malesuada tellus in ex elementum, vitae rutrum enim vestibulum."

#==============================================================================
class Window(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        # Widgets
        self.label = QLabel(TEXT, self)
#         self.label.setWordWrap(True)
        self.text = QTextEdit(self)
        self.text.setMinimumSize(480, 320)
        self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Layout
        self.layout = QGridLayout()
        self.layout.addWidget(self.label, 0, 0)
        self.layout.addWidget(self.text, 1, 0)
        self.layout.setContentsMargins(5, 5, 5, 5)
        self.layout.setSpacing(5)

        self.setLayout(self.layout)

        self.adjustSize()
        self.show()

#==============================================================================
if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Window()
    sys.exit(app.exec_())

It works as expected, producing a window, which cannot be resized to be smaller:

However, when I uncomment the self.label.setWordWrap(True) line, these constrains seem to disappear. I can resize the window to smaller, completely breaking the layout, as QTextEdit still retains its size constrain:

I tried to fix this using self.setMinimumSize(self.size()). This works for this particular example, however breaks if the size is bigger, such as self.text.setMinimumSize(480, 800). That makes the window too small even when it is being created, so setMinimumSize does not help:

Is there a way how to fix it and make the window / layout still match the minimum size of QTextEdit even when word wrap is enabled?

Version information:

OS: Windows-7-SP1 (32bit)
Python: 3.4.1
PyQt: 5.3.1
Qt: 5.3.1

Body:
I also had this problem, with QT 4.8, and I couldn't upgrade my QT, since I was working on a plugin of QGIS 2.18 that still use QT 4.8.

My work around is manipulating the maximumHeight of the QWebView (or in your case, your QTextEdit) when the resize happen. You will need to emit custom signal for resized, since it's not available in QT (see: PyQt: Detect resizing in Widget-window resized signal)

So, my code is something like this:

class MetadataConverterDialog(QDialog):
    resized = pyqtSignal()
        # Adapted from https://stackoverflow.com/a/43126946/1198772
    def resizeEvent(self, event):
        """Emit custom signal when the window is re-sized.

        :param event: The re-sized event.
        :type event: QResizeEvent
        """
        self.resized.emit()
        return super(MetadataConverterDialog, self).resizeEvent(event)

    def after_resize(self):
        """Method after resizing the window."""
        max_height = self.height() - 275  # Magic number, to make it pretty
        self.metadata_preview_web_view.setMaximumHeight(max_height)

The 275 is the value that I need to spare to show the dialog properly (for the widget before the QWebView. You will need to find the value that fits with your dialog.


问:
python3 class generates same random value with unittest
This is an exercise from exorcism.io that I need to generate a random name with the class is initialized. One of the unit test cases is failing because the random string is same across two instances of the class. If I run the code outside of unittest, it appears to work correctly. Could it be that the var is pointing to the same address space in unittest?</p>

```<code>import string
import random
import unittest

class Robot(object):
    def __init__(self):
        self.name = None
        self.reset()
        print('Name at Init', self.name)

    def reset(self):
        for _ in range(5):
            new = random.choice(string.ascii_uppercase) + random.choice(string.ascii_uppercase) + str(random.randint(100, 999))

        self.name = new

class SimpleTest(unittest.TestCase):
    if not hasattr(unittest.TestCase, "assertRegex"):
        assertRegex = unittest.TestCase.assertRegexpMatches

    name_re = r'^[A-Z]{2}\d{3}$'

    def test_names(self):
        # Set a seed
        seed = "This is some seed text"

        # Initialize RNG using the seed
        random.seed(seed)

        # Call the generator
        robot = Robot()
        name = robot.name

        # Reinitialize RNG using seed
        random.seed(seed)

        # Call the generator again
        robot.reset()
        name2 = robot.name
        self.assertNotEqual(name, name2)
        self.assertRegex(name2, self.name_re)

if __name__ == '__main__':
    unittest.main()
    # print(Robot().name == Robot().name)   # Returns False

F
Name at Init WY294
======================================================================
FAIL: test_names (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/.......robot.py", line 42, in test_names
    self.assertNotEqual(name, name2)
AssertionError: 'WY294' == 'WY294'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)
</code>```

答: Take out the second call to seed in your test. The random number generator will always generate the same sequence for a given seed, so by calling the seed twice you are rewinding the sequence and that is why you get the same values.</p>

Body:
This is an exercise from exorcism.io that I need to generate a random name with the class is initialized. One of the unit test cases is failing because the random string is same across two instances of the class. If I run the code outside of unittest, it appears to work correctly. Could it be that the var is pointing to the same address space in unittest?

import string
import random
import unittest

class Robot(object):
    def __init__(self):
        self.name = None
        self.reset()
        print('Name at Init', self.name)

    def reset(self):
        for _ in range(5):
            new = random.choice(string.ascii_uppercase) + random.choice(string.ascii_uppercase) + str(random.randint(100, 999))

        self.name = new

class SimpleTest(unittest.TestCase):
    if not hasattr(unittest.TestCase, "assertRegex"):
        assertRegex = unittest.TestCase.assertRegexpMatches

    name_re = r'^[A-Z]{2}\d{3}$'

    def test_names(self):
        # Set a seed
        seed = "This is some seed text"

        # Initialize RNG using the seed
        random.seed(seed)

        # Call the generator
        robot = Robot()
        name = robot.name

        # Reinitialize RNG using seed
        random.seed(seed)

        # Call the generator again
        robot.reset()
        name2 = robot.name
        self.assertNotEqual(name, name2)
        self.assertRegex(name2, self.name_re)

if __name__ == '__main__':
    unittest.main()
    # print(Robot().name == Robot().name)   # Returns False

F
Name at Init WY294
======================================================================
FAIL: test_names (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/.......robot.py", line 42, in test_names
    self.assertNotEqual(name, name2)
AssertionError: 'WY294' == 'WY294'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)


问:
How to view realm database tables in android using Stetho?
How to view database tables created using realm,for testing purpose.Is there any tool avilable to view the tables?.Anyone knows the answer please help.Thanks in advance.</p>

答:
Updating for future people that will face the same issue:

the stetho-realm original by uPhyca is not supporting latest versions of realm (when you open at chrome, the app crashes)

So, you should install a fork working, see:

https://github.com/uPhyca/stetho-realm/issues/62#issuecomment-346927558

Thanks to @WickedDev


问:
How to run this code in series using verilog
The following code is compiled and is working in parallel, Please help me to make these code work sequentially, i.e after stage1 counter should reset itself and starts from 0 for the stage2. The following codes has Module1- stage1 and module2-stage2. This is the process flow in which one stage occur after completion of another. For example when stage 1 is done then counter reset itself and then stage 2 starts with count zero.Here stage 1 module has counter that counts till 18 and stage 2 counter counts 8.  </p>

```<code>    module stage1(
                input Clk, //50 Hz clock
                input x0,
                input reset,
                output reg y0,y1,y2,y3,y5,y7,y10,y15,
                output reg stage1_done
                );
        reg [15:0] counter = 0;
        parameter F = 50;
        always@ (posedge Clk or posedge reset)
            if(reset) begin
                counter <= 0;
                {y0,y1,y2,y3,y5,y7,y10,y15} <= 8'b00000000;
                stage1_done <= 0;
            end else begin
                if(x0 == 1) begin
                    if(counter == 18*F)
                        stage1_done <= 1;
                    else begin
                        counter <= counter + 1;
                        stage1_done <= 0;
                    end
                    if(counter >= 1*F && counter < 10*F)
                        y0 <= 1;
                    else
                        y0 <= 0;
                    if(counter >= 1*F && counter < 17*F)
                        y1 <= 1;
                    else
                        y1 <= 0;
                    if(counter >= 1*F && counter < 9*F)
                        y2 <= 1;
                    else
                        y2 <= 0;
                    if(counter >= 11*F && counter < 16*F)
                        y3 <= 1;
                    else
                        y3 <= 0;
                    if(counter >= 1*F && counter < 18*F)
                        y5 <= 1;
                    else
                        y5 <= 0;
                    if(counter >= 1*F && counter < 5*F)
                        y7 <= 1;
                    else
                        y7 <= 0;
                    if(counter >= 1*F && counter < 5*F)
                        y10 <= 1;
                    else
                        y10 <= 0;
                    if((counter >= 2*F && counter < 9*F) || (counter >= 13*F && counter < 17*F))
                        y15 <= 1;
                    else
                        y15 <= 0;
                end
            end

        endmodule
</code>```

<p>//Module for stage 2;</p>

```<code>    module stage2(
            input x0,
            input Clk, //50 Hz clock
            input reset,
            output reg y1,y3,y5,
            output reg stage2_done
            );
    reg [15:0] counter = 0;
    parameter F = 50;
    always@ (posedge Clk or posedge reset)
        if(reset) begin
            counter <= 0;
            {y1,y3,y5} <= 3'b000;
            stage2_done <= 0;
        end
    else begin   if(x0 == 1) begin
            if(counter == 8*F)
                stage2_done <= 1;
            else begin
                counter <= counter + 1;
                stage2_done <= 0;
            end
            if(counter >= 1*F && counter < 8*F)
                y1 <= 1;
            else
                y1 <= 0;
            if(counter >= 1*F && counter < 8*F)
                y3 <= 1;
            else
                y3 <= 0;
            if(counter >= 1*F && counter < 8*F)
                y5 <= 1;
            else
                y5 <= 0;
            end
        end

    endmodule
</code>```

答:
Think of it as a state machine. with 2 or 3 states, i.e. reset, stage1, stage2. You need to think over the conditions which would move from one stage to another. You provided one condition: stage1 counter overflow has to go from stage1 to stage2. There are definitely few question: what happens to stage1 while stage2 is running, what what happens when stage 2 is finished. What happens during reset?

So, I suggest that you create yest another module to implement the state machine logic:

```<code>module control(clk, ...);
    enum { reset, stage1, stage2} state, next_state;

    always_ff @( posedge clk)
        case (state)
        reset:
              if (!resetSig) next_state <= stage1;
              else if (resetSig) next_state <= reset;
        stage1:
              if (stage1Done) next)state <= stage2;
              ...
       endcase

   assign state = next_state;
</code>```

Now in every stage you just use state as an enable condition.

```<code>  module stage1(clk, state, stageDone, ...)
     always_ff
         if (state == reset)
              do reset
         else if (state == stage1)
              do stage1

     assign stageDone = counter == max_value;
</code>```

and so on. Yes, you will need to pass extra ports for the state machine controls, but you will make your code much more manageable and readable and confirm to industry practices.

Body:
The following code is compiled and is working in parallel, Please help me to make these code work sequentially, i.e after stage1 counter should reset itself and starts from 0 for the stage2. The following codes has Module1- stage1 and module2-stage2. This is the process flow in which one stage occur after completion of another. For example when stage 1 is done then counter reset itself and then stage 2 starts with count zero.Here stage 1 module has counter that counts till 18 and stage 2 counter counts 8.

    module stage1(
                input Clk, //50 Hz clock
                input x0,
                input reset,
                output reg y0,y1,y2,y3,y5,y7,y10,y15,
                output reg stage1_done
                );
        reg [15:0] counter = 0;
        parameter F = 50;
        always@ (posedge Clk or posedge reset)
            if(reset) begin
                counter <= 0;
                {y0,y1,y2,y3,y5,y7,y10,y15} <= 8'b00000000;
                stage1_done <= 0;
            end else begin
                if(x0 == 1) begin
                    if(counter == 18*F)
                        stage1_done <= 1;
                    else begin
                        counter <= counter + 1;
                        stage1_done <= 0;
                    end
                    if(counter >= 1*F && counter < 10*F)
                        y0 <= 1;
                    else
                        y0 <= 0;
                    if(counter >= 1*F && counter < 17*F)
                        y1 <= 1;
                    else
                        y1 <= 0;
                    if(counter >= 1*F && counter < 9*F)
                        y2 <= 1;
                    else
                        y2 <= 0;
                    if(counter >= 11*F && counter < 16*F)
                        y3 <= 1;
                    else
                        y3 <= 0;
                    if(counter >= 1*F && counter < 18*F)
                        y5 <= 1;
                    else
                        y5 <= 0;
                    if(counter >= 1*F && counter < 5*F)
                        y7 <= 1;
                    else
                        y7 <= 0;
                    if(counter >= 1*F && counter < 5*F)
                        y10 <= 1;
                    else
                        y10 <= 0;
                    if((counter >= 2*F && counter < 9*F) || (counter >= 13*F && counter < 17*F))
                        y15 <= 1;
                    else
                        y15 <= 0;
                end
            end

        endmodule

//Module for stage 2;

    module stage2(
            input x0,
            input Clk, //50 Hz clock
            input reset,
            output reg y1,y3,y5,
            output reg stage2_done
            );
    reg [15:0] counter = 0;
    parameter F = 50;
    always@ (posedge Clk or posedge reset)
        if(reset) begin
            counter <= 0;
            {y1,y3,y5} <= 3'b000;
            stage2_done <= 0;
        end
    else begin   if(x0 == 1) begin
            if(counter == 8*F)
                stage2_done <= 1;
            else begin
                counter <= counter + 1;
                stage2_done <= 0;
            end
            if(counter >= 1*F && counter < 8*F)
                y1 <= 1;
            else
                y1 <= 0;
            if(counter >= 1*F && counter < 8*F)
                y3 <= 1;
            else
                y3 <= 0;
            if(counter >= 1*F && counter < 8*F)
                y5 <= 1;
            else
                y5 <= 0;
            end
        end

    endmodule

Body:
Think of it as a state machine. with 2 or 3 states, i.e. reset, stage1, stage2. You need to think over the conditions which would move from one stage to another. You provided one condition: stage1 counter overflow has to go from stage1 to stage2. There are definitely few question: what happens to stage1 while stage2 is running, what what happens when stage 2 is finished. What happens during reset?

So, I suggest that you create yest another module to implement the state machine logic:

module control(clk, ...);
    enum { reset, stage1, stage2} state, next_state;

    always_ff @( posedge clk)
        case (state)
        reset:
              if (!resetSig) next_state <= stage1;
              else if (resetSig) next_state <= reset;
        stage1:
              if (stage1Done) next)state <= stage2;
              ...
       endcase

   assign state = next_state;

Now in every stage you just use state as an enable condition.

  module stage1(clk, state, stageDone, ...)
     always_ff
         if (state == reset)
              do reset
         else if (state == stage1)
              do stage1

     assign stageDone = counter == max_value;

and so on. Yes, you will need to pass extra ports for the state machine controls, but you will make your code much more manageable and readable and confirm to industry practices.


问:
How do I grant Azure Cloud Shell access to my Azure SQL Server using least-privilege?
Suppose I create an Azure SQL Database and want to use the Azure Cloud Shell to administer it.

The first port of call would be the 'allow access to Azure services' option. However it is implied that this is rather too liberal as it allows access from any Azure service. I don't want to do that. I only want to grant access to the Cloud Shell.

The documentation describes setting up a server-level firewall rule - setting an IP address range of 0.0.0.0 to 255.255.255.255 would permit any IP to connect to the database. I don't want to do that either - this is clearly not production-ready and even more liberal than allowing access to any service within Azure.

I don't know the IP address of Cloud Shell, it's presumably dynamically allocated.

How do I grant access to just the Cloud Shell?

答: The PowerShell/CLI commands you execute in Azure Cloud Shell use the same management APIs as the Portal, so if you can manage a database in the portal than you can the exact same in Azure Cloud Shell. Firewall rules apply to data connections (i.e. T-SQL connections for running queries on the DB), not management operations.</p>