问:
How to open/save docx file to be aditted as xml and save the result as docx after editting using python
I have a docx file in which I need to edit its paragraphs (the paragraphs might contain equations). I tried to do these jobs using python-docx but it was not successful since editing the text of each paragraph and replacing it with the edited new paragraph needs to call p.add_paragraphs(editText(paragraph.text)) which ignores and omits any mathematical equation.

By searching for a method to gain this goal I found that this job is possible through XML codes by finding <w:t> tags and editing their content like this:

```<code>tree= ET.parse(filename)
root=tree.getroot()

for par in root.findall('w:p'):
   if par.find('w:r'):
   myText= par.find('w:r').find('w:t')
   myText.text= editText(myText.text)
</code>```

Then I must save the result as docx.
My quation is: what the format of filename is? should it be a document.xml file? If so, how can I reach that from my original document.docx file? and one more question is that how can I save the result as a .docx file again?

For saving docx as xml, I have given a try to save it by document.save('Document2.xml'). But the content of the result was not correct.

Would you give me some advice how to do them?

答:
Python is not the best tool for this.  Use VBA if you need to automate something in a Word document, or multiple Word documents.  I can't tell what you are even trying to do here, but let's start at the beginning, with something simple.  If, for instance, you want to loop through all paragraphs in your Word document, and select only the equations, you can run the code below to do just that.

```<code>Sub SelectAllEquations()
Dim xMath As OMath
Dim I As Integer
With ActiveDocument
    .DeleteAllEditableRanges wdEditorEveryone
    For I = 1 To .OMaths.Count
        Set xMath = .OMaths.Item(I)
        xMath.Range.Paragraphs(1).Range.Editors.Add wdEditorEveryone
    Next
    .SelectAllEditableRanges wdEditorEveryone
    .DeleteAllEditableRanges wdEditorEveryone
End With
End Sub
</code>```

Again, I don't know what your end game is, but I think it's worthwhile to start with something like that, and build on your foundation.

Body:
I have a docx file in which I need to edit its paragraphs (the paragraphs might contain equations). I tried to do these jobs using python-docx but it was not successful since editing the text of each paragraph and replacing it with the edited new paragraph needs to call p.add_paragraphs(editText(paragraph.text)) which ignores and omits any mathematical equation.

By searching for a method to gain this goal I found that this job is possible through XML codes by finding <w:t> tags and editing their content like this:

tree= ET.parse(filename)
root=tree.getroot()

for par in root.findall('w:p'):
   if par.find('w:r'):
   myText= par.find('w:r').find('w:t')
   myText.text= editText(myText.text)

Then I must save the result as docx.
My quation is: what the format of filename is? should it be a document.xml file? If so, how can I reach that from my original document.docx file? and one more question is that how can I save the result as a .docx file again?

For saving docx as xml, I have given a try to save it by document.save('Document2.xml'). But the content of the result was not correct.

Would you give me some advice how to do them?

Body:
Python is not the best tool for this.  Use VBA if you need to automate something in a Word document, or multiple Word documents.  I can't tell what you are even trying to do here, but let's start at the beginning, with something simple.  If, for instance, you want to loop through all paragraphs in your Word document, and select only the equations, you can run the code below to do just that.

Sub SelectAllEquations()
Dim xMath As OMath
Dim I As Integer
With ActiveDocument
    .DeleteAllEditableRanges wdEditorEveryone
    For I = 1 To .OMaths.Count
        Set xMath = .OMaths.Item(I)
        xMath.Range.Paragraphs(1).Range.Editors.Add wdEditorEveryone
    Next
    .SelectAllEditableRanges wdEditorEveryone
    .DeleteAllEditableRanges wdEditorEveryone
End With
End Sub

Again, I don't know what your end game is, but I think it's worthwhile to start with something like that, and build on your foundation.


来源: stackexchange

问:
How to detect if view controller is being popped of from the navigation controller?
I currently need to implement some code when the top view controller is being popped off from my navigation controller. Is there a way to detect when the view controller is being popped off the navigation controller stack?

As much as possible I want to stay away from using viewWillDisappear or viewDidDisappear because I'm using a splitview in my project, and selecting a different row in the master view will also trigger the viewWillDisappear/viewDidDisappear methods.

答:
My experience with iOS 13 is that the property value of isMovingFromParent is not always consistent. When you have search controller being in active mode (search text field is tapped), back to parent view will have false value for this property.

Here is my way to determine if a view is from parent or not:

```<code>class MyBaseViewController: UIViewController {
    private var _isPushedToAnotherView = false
    var isPushedToAnotherView: Bool {
      return _isPushedToAnotherView
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      super.prepare(for: segue, sender: sender)
      ...
      _isPushedToAnotherView = true
    }
    override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)
      ...
      _isPushedToAnotherView = false
    }
    ...
}

class MyExtendedClass: MyBaseViewController {
  ...
  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    ...
    if !isPushedToAnotherView {
        // clear resources hold by this class
    }
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
My experience with iOS 13 is that the property value of isMovingFromParent is not always consistent. When you have search controller being in active mode (search text field is tapped), back to parent view will have false value for this property.

Here is my way to determine if a view is from parent or not:

class MyBaseViewController: UIViewController {
    private var _isPushedToAnotherView = false
    var isPushedToAnotherView: Bool {
      return _isPushedToAnotherView
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      super.prepare(for: segue, sender: sender)
      ...
      _isPushedToAnotherView = true
    }
    override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)
      ...
      _isPushedToAnotherView = false
    }
    ...
}

class MyExtendedClass: MyBaseViewController {
  ...
  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    ...
    if !isPushedToAnotherView {
        // clear resources hold by this class
    }
}

ContentLicense: CC BY-SA 4.0


问:
AVD Manager: can't see "wipe data" or "Emulated Performance"?
I'm getting error message qemu-system-i386.exe has stopped working when debugging Xamarin.Forms app.

Searching the web, I found this solution: error message "qemu-system-i386.exe has stopped working". It basically says to "Wipe Data" and/or change Emulated Performance to Software GLES 2.0

The problem is that I don't see the options "Wipe Data" in this screenshot and I don't see AVD Edit -> change the Emulated Performance to Software GLES 2.0.

Am I missing something?

This is the screen I'm seeing when I go to Android Device Manager and click Edit. I don't see anything there that says "Wipe Data" or "Emulated Performance".

I have Visual Studio 2017 15.9.5.

答:
I had same problem, unable to find wipe data action anywhere. Factory reset doesn't work for me. My problem is "To Start Android, enter your password" but i didnt found any ways to solve it without wipe data. This steps has solved this issure:

Run cmd.exe as administrator

My android-sdk folder location is E:\Android\android-sdk**, so change it to **E:\Android\android-sdk\tools

There is emulator.exe file, run it with emulator.exe -list-avds parameter for find your real avd names.

Now, if you have got your avd in list run emulator.exe -avd YOUR_AVD_NAME -wipe-data

Here is what i have:


问:
Using service principal to access Azure blob storage
I want to access a private blob store, from python, by using credentials from an active directory service principal.

I am aware of this related question How do I authenticate a user against an Azure storage blob in python? This has helped me get this far but now I'm stuck.

I can authenticate and get a token which let me list containers, create new containers, but will not let me list or access any blobs.

I wish to set this up via the az cli.

Service principal has been set up like so:

az ad sp create-for-rbac -n "http://$NAME" --role Contributor \
    --scopes "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP"
```

<p>Which I believe should give full access but I also added this to be sure:</p>

<pre class="lang-sh prettyprint-override"><code>az role assignment create \
    --role "Storage Blob Data Contributor" \
    --assignee-object-id "$OBJECT_ID" \
    --assignee-principal-type "ServicePrincipal" \
    --scope "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT/blobServices/default/containers/$CONTAINER"
</code>```

I am then authenticating like so:

from azure.common.credentials import ServicePrincipalCredentials
import adal
from azure.storage.blob import (
    BlockBlobService,
    ContainerPermissions,
)
from azure.storage.common import (
    TokenCredential
)

# Tenant ID for your Azure Subscription
TENANT_ID = TENANT

# Your Service Principal App ID
CLIENT = APP_ID

# Your Service Principal Password
KEY = PASSWORD

# RESOURCE = "https://storage.azure.com/" # using this resource has the same behaviour as uncommented one. Using no resource fails with authentication errors
RESOURCE = f"https://{ACCOUNT_NAME}.blob.core.windows.net"

credentials = ServicePrincipalCredentials(
    client_id = CLIENT,
    secret = KEY,
    tenant = TENANT_ID,
    resource = RESOURCE
)
tokenCre = TokenCredential(credentials.token["access_token"])
```

<p>I then try to use the blob service as so</p>

<pre class="lang-py prettyprint-override"><code>blobService = BlockBlobService(account_name=ACCOUNT_NAME, token_credential=tokenCre)

print ([c.name for c in blobService.list_containers()]) # successfully lists containers
print(blobService.create_container('test')) # prints "True" and the container is created

blobService.list_blobs(CONTAINER_NAME) # fails with AzureHttpError: This request is not authorized to perform this operation using this permission. ErrorCode: AuthorizationPermissionMismatch

blobService.get_blob_to_bytes("test", "hello.txt") # fails with same error
</code>```

As shown in the code block above I seem to be able to take 'container' level actions but no 'blob' level actions. Any thing like listing blobs, reading a blob etc gets the error:

```<code>AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ErrorCode: AuthenticationFailed
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:86ff0241-c01e-00d4-512c-6e22b5000000
Time:2019-09-18T14:20:23.5619727Z</Message><AuthenticationErrorDetail>Audience validation failed. Audience did not match.</AuthenticationErrorDetail></Error>
</code>```

Any ideas?

答:
With Python library azure-storage-blob 12.2, and azure-identity (latest API as of Jan 2020)
(modified version from Jack Lia's answer)

from azure.identity import ClientSecretCredential
from azure.storage.blob import BlobServiceClient

# Tenant ID for your Azure Subscription
TENANT_ID = "e4c9****-****-****-****-230b****57fb"

# Your Service Principal App ID
CLIENT = "3bee****-****-****-****-b0b8****f7a4"

# Your Service Principal Password
KEY = "*******************"

ACCOUNT_NAME = "storagetest789"

CONTAINER_NAME = "newcontainer"

RESOURCE = "https://storage.azure.com/"

credentials = ClientSecretCredential(TENANT_ID, CLIENT, KEY)
blobService = BlobServiceClient(
   "https://{}.blob.core.windows.net".format(ACCOUNT_NAME),
   credential=credentials
)

print("\nList blobs in the container")

container = blobService.get_container_client(CONTAINER_NAME)
for blob in container.list_blobs():
    print("\t Blob name: " + blob.name)

print("\nOutput test.txt")
blob = container.get_blob_client("test.txt")
print(blob.download_blob().readall())
```

Body:
I want to access a private blob store, from python, by using credentials from an active directory service principal.

I am aware of this related question How do I authenticate a user against an Azure storage blob in python? This has helped me get this far but now I'm stuck.

I can authenticate and get a token which let me list containers, create new containers, but will not let me list or access any blobs.

I wish to set this up via the az cli.

Service principal has been set up like so:

az ad sp create-for-rbac -n "http://$NAME" --role Contributor \
    --scopes "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP"

Which I believe should give full access but I also added this to be sure:

az role assignment create \
    --role "Storage Blob Data Contributor" \
    --assignee-object-id "$OBJECT_ID" \
    --assignee-principal-type "ServicePrincipal" \
    --scope "/subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT/blobServices/default/containers/$CONTAINER"

I am then authenticating like so:

from azure.common.credentials import ServicePrincipalCredentials
import adal
from azure.storage.blob import (
    BlockBlobService,
    ContainerPermissions,
)
from azure.storage.common import (
    TokenCredential
)

# Tenant ID for your Azure Subscription
TENANT_ID = TENANT

# Your Service Principal App ID
CLIENT = APP_ID

# Your Service Principal Password
KEY = PASSWORD

# RESOURCE = "https://storage.azure.com/" # using this resource has the same behaviour as uncommented one. Using no resource fails with authentication errors
RESOURCE = f"https://{ACCOUNT_NAME}.blob.core.windows.net"

credentials = ServicePrincipalCredentials(
    client_id = CLIENT,
    secret = KEY,
    tenant = TENANT_ID,
    resource = RESOURCE
)
tokenCre = TokenCredential(credentials.token["access_token"])

I then try to use the blob service as so

blobService = BlockBlobService(account_name=ACCOUNT_NAME, token_credential=tokenCre)

print ([c.name for c in blobService.list_containers()]) # successfully lists containers
print(blobService.create_container('test')) # prints "True" and the container is created

blobService.list_blobs(CONTAINER_NAME) # fails with AzureHttpError: This request is not authorized to perform this operation using this permission. ErrorCode: AuthorizationPermissionMismatch

blobService.get_blob_to_bytes("test", "hello.txt") # fails with same error

As shown in the code block above I seem to be able to take 'container' level actions but no 'blob' level actions. Any thing like listing blobs, reading a blob etc gets the error:

AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ErrorCode: AuthenticationFailed
<?xml version="1.0" encoding="utf-8"?><Error>AuthenticationFailed<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:86ff0241-c01e-00d4-512c-6e22b5000000
Time:2019-09-18T14:20:23.5619727Z</Message><AuthenticationErrorDetail>Audience validation failed. Audience did not match.</AuthenticationErrorDetail></Error>

Any ideas?


问:
IE 7 & 8 jqplot misalignment while printing
I am having some trouble getting the graph created with jqplot to print with proper alignment in IE 7 & 8. It looks great on the screen, but once I click print preview it get's all messed up.

Help me please

Alignment in IE 9, Firefox and Chrome is perfect. Any help would be greatly appreciated

答:
Added a class iterator to the canvases and then use browser hacks to perfectly alignment the bars for different browsers.

This is the modified excanvas : http://pastebin.com/mgHUbe3S

Line 309 is where the magic happens

```<code>    var el = surfaceElement.ownerDocument.createElement('div');
    **el.className = "seriesContainer_"+counter;**
    el.style.width =  surfaceElement.clientWidth + 'px';
    el.style.height = surfaceElement.clientHeight + 'px';
    el.style.overflow = 'hidden';
    el.style.position = 'absolute';
    surfaceElement.appendChild(el);

    this.element_ = el;
    this.arcScaleX_ = 1;
    this.arcScaleY_ = 1;
    this.lineScale_ = 1;
    counter++;
  }
</code>```

Body:
Added a class iterator to the canvases and then use browser hacks to perfectly alignment the bars for different browsers.

This is the modified excanvas : http://pastebin.com/mgHUbe3S

Line 309 is where the magic happens

    var el = surfaceElement.ownerDocument.createElement('div');
    **el.className = "seriesContainer_"+counter;**
    el.style.width =  surfaceElement.clientWidth + 'px';
    el.style.height = surfaceElement.clientHeight + 'px';
    el.style.overflow = 'hidden';
    el.style.position = 'absolute';
    surfaceElement.appendChild(el);

    this.element_ = el;
    this.arcScaleX_ = 1;
    this.arcScaleY_ = 1;
    this.lineScale_ = 1;
    counter++;
  }


问:
How to convert an array of data into an array of Leaflet LatLngs?
I GET all the locations (latitude + longitude) that works good I can print them an work with them one by one but the problem is that I want to add all locations ligne by ligne in waypoints in one function like in the exemple bellow :

```<code> for (i in response.data) {
    if (response.data.hasOwnProperty(i)) {
      console.log( response.data[i].latitude  +' , '+  response.data[i].longitude );
    }
  }

  L.Routing.control({
    waypoints: [
      L.latLng(33.86477205,-5.57643056),
      L.latLng(33.86494131,-5.57304561),
      L.latLng(33.86425534,-5.57063162),
    ],
    show: false
  }).addTo(map);
</code>```

I want to add all latitudes and longitudes printed by FOR but in one step not one by one , because I think there is no other way to work with this Leaflet method.

答:
This looks like a simple case of Array manipulation in Javascript. Given an array with arbitrary data, you want a second array with instances of L.LatLng.

A straightforward approach is to map() the array, e.g.:

```<code>  // For every data point in response.data, create a LatLng
  var waypoints = response.data.map(function(dataPoint){
    // console.log(dataPoint); // It might be useful to inspect these values
    return L.latLng(dataPoint.latitude, dataPoint.longitude);
  });

  // console.log(waypoints);  // Uncommenting this should display an Array of LatLngs

  L.Routing.control({
    waypoints: waypoints,
    show: false
  }).addTo(map);
</code>```

Body:
I GET all the locations (latitude + longitude) that works good I can print them an work with them one by one but the problem is that I want to add all locations ligne by ligne in waypoints in one function like in the exemple bellow :

 for (i in response.data) {
    if (response.data.hasOwnProperty(i)) {
      console.log( response.data[i].latitude  +' , '+  response.data[i].longitude );
    }
  }

  L.Routing.control({
    waypoints: [
      L.latLng(33.86477205,-5.57643056),
      L.latLng(33.86494131,-5.57304561),
      L.latLng(33.86425534,-5.57063162),
    ],
    show: false
  }).addTo(map);

I want to add all latitudes and longitudes printed by FOR but in one step not one by one , because I think there is no other way to work with this Leaflet method.

Body:
This looks like a simple case of Array manipulation in Javascript. Given an array with arbitrary data, you want a second array with instances of L.LatLng.

A straightforward approach is to map() the array, e.g.:

  // For every data point in response.data, create a LatLng
  var waypoints = response.data.map(function(dataPoint){
    // console.log(dataPoint); // It might be useful to inspect these values
    return L.latLng(dataPoint.latitude, dataPoint.longitude);
  });

  // console.log(waypoints);  // Uncommenting this should display an Array of LatLngs

  L.Routing.control({
    waypoints: waypoints,
    show: false
  }).addTo(map);


问:
Can I create a for loop with two variables and still have time complexity of O(n)?
Say I have a for loop as:

```<code>for(int i=0,j=i+1;i<n-1,j<n;j++)
{
    //some code
    if(condition)
    {
        i++;
        j=i;
    }
}
</code>```

What will be the time complexity and why?

Edited:

```<code>void printAllAPTriplets(int arr[], int n)
{
    for (int i = 1; i < n - 1; i++)
    {

        // Search other two elements of
        // AP with arr[i] as middle.
        for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
        {

            // if a triplet is found
            if (arr[j] + arr[k] == 2 * arr[i])
            {
                cout << arr[j] << " " << arr[i]
                     << " " << arr[k] << endl;

                // Since elements are distinct,
                // arr[k] and arr[j] cannot form
                // any more triplets with arr[i]
                k++;
                j--;
            }

            // If middle element is more move to
            // higher side, else move lower side.
            else if (arr[j] + arr[k] < 2 * arr[i])
                k++;
            else
                j--;
        }
    }
}
</code>```

What would be the time complexity of this particular function and why?? @walnut @DeducibleSteak @Acorn .This is the code for "Printing all triplets in sorted array that form AP"

答:
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:

```<code>for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}
</code>```

In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)

Body:
Say I have a for loop as:

for(int i=0,j=i+1;i<n-1,j<n;j++)
{
    //some code
    if(condition)
    {
        i++;
        j=i;
    }
}

What will be the time complexity and why?

Edited:

void printAllAPTriplets(int arr[], int n)
{
    for (int i = 1; i < n - 1; i++)
    {

        // Search other two elements of
        // AP with arr[i] as middle.
        for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
        {

            // if a triplet is found
            if (arr[j] + arr[k] == 2 * arr[i])
            {
                cout << arr[j] << " " << arr[i]
                     << " " << arr[k] << endl;

                // Since elements are distinct,
                // arr[k] and arr[j] cannot form
                // any more triplets with arr[i]
                k++;
                j--;
            }

            // If middle element is more move to
            // higher side, else move lower side.
            else if (arr[j] + arr[k] < 2 * arr[i])
                k++;
            else
                j--;
        }
    }
}

What would be the time complexity of this particular function and why?? @walnut @DeducibleSteak @Acorn .This is the code for "Printing all triplets in sorted array that form AP"

Body:
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:

for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}

In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)


问:
Robocopy not functioning in Powershell script
I'm having some trouble using RoboCopy.exe through a Powershell script. The function is as follows...

```<code>function copyFiles{
    Start-Process "RoboCopy.exe" -ArgumentList "'C:\Test' 'C:\test2' /copyall"
    Write-Host 'Test'
}
</code>```

"Test" is output to console but the copy does not run. I was initially attempting to copy with variables as the directories, but I've boiled it down to this since that was not working. In the directory 'test1' there is a single .txt file and 'test2' exists but is empty. I have tried it without that directory existing as well.

It is called in another file via:

```<code>. .\rCopy.ps1
copyFiles
</code>```

Now, I tried outputting the log to a file with the code below, but it gives me a permissions error. "Out-File : Access to the path 'C:\Users\Me\Desktop' is denied". I also tried outputting direct to C:\ but that gives the same error. Powershell IS running as administrator.

```<code>$testCopy = Start-Process "RoboCopy.exe" -ArgumentList "'C:\Test' 'C:\test2' /copyall"
$testCopy | Out-File -LiteralPath "C:\Users\Me\
</code>```

And to close, I have also tried running "Start-Process 'RoboCopy.exe' -ArgumentList 'C:\test' 'C:\test2' /copyall" in the main script, without calling the function from another.

Any help would be greatly appreciated.

答:
Your own solution is effective: quoted arguments passed to external programs such as Robocopy.exe inside a (single) -ArgumentList argument require embedded double quotes ("), not single quotes (').

Generally, external programs do not recognize ' as string delimiters on the command line, and that even applies to calling PowerShell itself via its CLI's -File parameter.

Even if you were to pass the arguments one by one to -ArgumentList:

```<code># Note the individual arguments.
# !! Works in this case, but with paths that have *embedded spaces*
# !! you  would still need embedded "..." quoting.
Start-Process Robocopy.exe -ArgumentList 'C:\Test', 'C:\test2', '/copyall'
</code>```

you'd still have to use embedded "..." quoting in individual arguments that (may) contain embedded spaces (e.g., '"C:\Test 1"' or, with a variable reference, "`"$dir`"", due to a long-standing bug.

See this answer for background information.

Body:
I'm having some trouble using RoboCopy.exe through a Powershell script. The function is as follows...

function copyFiles{
    Start-Process "RoboCopy.exe" -ArgumentList "'C:\Test' 'C:\test2' /copyall"
    Write-Host 'Test'
}

"Test" is output to console but the copy does not run. I was initially attempting to copy with variables as the directories, but I've boiled it down to this since that was not working. In the directory 'test1' there is a single .txt file and 'test2' exists but is empty. I have tried it without that directory existing as well.

It is called in another file via:

. .\rCopy.ps1
copyFiles

Now, I tried outputting the log to a file with the code below, but it gives me a permissions error. "Out-File : Access to the path 'C:\Users\Me\Desktop' is denied". I also tried outputting direct to C:\ but that gives the same error. Powershell IS running as administrator.

$testCopy = Start-Process "RoboCopy.exe" -ArgumentList "'C:\Test' 'C:\test2' /copyall"
$testCopy | Out-File -LiteralPath "C:\Users\Me\

And to close, I have also tried running "Start-Process 'RoboCopy.exe' -ArgumentList 'C:\test' 'C:\test2' /copyall" in the main script, without calling the function from another.

Any help would be greatly appreciated.

Body:
Your own solution is effective: quoted arguments passed to external programs such as Robocopy.exe inside a (single) -ArgumentList argument require embedded double quotes ("), not single quotes (').

Generally, external programs do not recognize ' as string delimiters on the command line, and that even applies to calling PowerShell itself via its CLI's -File parameter.

Even if you were to pass the arguments one by one to -ArgumentList:

# Note the individual arguments.
# !! Works in this case, but with paths that have *embedded spaces*
# !! you  would still need embedded "..." quoting.
Start-Process Robocopy.exe -ArgumentList 'C:\Test', 'C:\test2', '/copyall'

you'd still have to use embedded "..." quoting in individual arguments that (may) contain embedded spaces (e.g., '"C:\Test 1"' or, with a variable reference, "`"$dir`"", due to a long-standing bug.

See this answer for background information.


问:
React update state in a new form
How can I update the state in a new form?
I want to convert an image into base64 when uploaded and push it to the firebase.

However, I got an TypeError: this.setState is not a function error.

I also tried to update the value of input, but didn't work.
document.getelementbyid("image").value = reader.result

Thank you!

```<code>import React from 'react'
import PropTypes from 'prop-types'
import { Formik, Field, Form } from 'formik'
import { TextField } from 'formik-material-ui'
import { makeStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogTitle from '@material-ui/core/DialogTitle'
import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import styles from './NewProjectDialog.styles'

const useStyles = makeStyles(styles)

function NewProjectDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()

  function handleSubmit(values, { setSubmitting }) {
    return onSubmit(values).then(() => {
      setSubmitting(false)
    })
  }

  function previewFile() {
    const preview = document.querySelector('img');
    const file = document.querySelector('input[type=file]').files[0];
    const reader = new FileReader();

    reader.addEventListener("load", function () {
      // convert image file to base64 string
      preview.src = reader.result;
      this.setState({image: reader.result})
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }

    this.previewFile = this.preview.bind(this)
  }

  return (
    <Dialog open={open} onClose={onRequestClose}>
      <DialogTitle id="new-project-dialog-title">New Project</DialogTitle>
      <Formik initialValues={{ name: '' }} onSubmit={handleSubmit}>
        {({ errors, isSubmitting }) => (
          <Form className={classes.root}>
            <DialogContent>
              <Field
                name="isbn"
                label="ISBN"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="title"
                label="Title"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="status"
                label="Status"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="price"
                label="Price"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                id="image"
                name="image"
                component={TextField}
                style={{display:"none"}}
              />
              <input type="file" onChange={previewFile}/>
              <img src="" height="200" alt="Image preview..."></img>
            </DialogContent>
            <DialogActions>
              <Button onClick={onRequestClose} color="secondary">
                Cancel
              </Button>
              <Button type="submit" color="primary" disabled={isSubmitting}>
                {isSubmitting ? 'Creating...' : 'Create'}
              </Button>
            </DialogActions>
          </Form>
        )}
      </Formik>
    </Dialog>
  )
}

NewProjectDialog.propTypes = {
  onSubmit: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
  onRequestClose: PropTypes.func.isRequired
}

export default NewProjectDialog
</code>```

I modified the code but the image was not stored in the firebase...

```<code>function NewProjectDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()
  const [image, setImage] = useState({image: null});

(Omitted)

  function previewFile() {
    const preview = document.querySelector('img');
    const file = document.querySelector('input[type=file]').files[0];
    const reader = new FileReader();

    reader.addEventListener("load", function () {
      // convert image file to base64 string
      preview.src = reader.result;
      setImage({image: reader.result});
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }

  }

</code>```

```<code>-M0EVfPfzF1vjQ4wLXLU
createdAt: 1581881931504
createdBy: "YcGWgfdbk2hs8CcWSdtsicYncyB3"
isbn: "asdfa"
name: ""
price: "asdfasd"
status: "asfdasfd"
title: "asfdasfd"
</code>```

Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text

答:
I guess this issue is coming from that this.setState can be used only in class based component. In function components like what you have - NewProjectDialog - you can use useState hook where you can create your state and the updater function.

What does useState return? It returns a pair of values: the current state and a function that updates it.

So you could have the defined state as:

```<code>const [image, setImage] = useState({image: null});
</code>```

And instead of this.setState({image: reader.result}) you would modify as the following:

```<code>// updating value
setImage({image: reader.result});
</code>```

Read further here: Using the State Hook

I hope that helps!

Title: React update state in a new form

Body:
How can I update the state in a new form?
I want to convert an image into base64 when uploaded and push it to the firebase.

However, I got an TypeError: this.setState is not a function error.

I also tried to update the value of input, but didn't work.
document.getelementbyid("image").value = reader.result

Thank you!

import React from 'react'
import PropTypes from 'prop-types'
import { Formik, Field, Form } from 'formik'
import { TextField } from 'formik-material-ui'
import { makeStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogTitle from '@material-ui/core/DialogTitle'
import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import styles from './NewProjectDialog.styles'

const useStyles = makeStyles(styles)

function NewProjectDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()

  function handleSubmit(values, { setSubmitting }) {
    return onSubmit(values).then(() => {
      setSubmitting(false)
    })
  }

  function previewFile() {
    const preview = document.querySelector('img');
    const file = document.querySelector('input[type=file]').files[0];
    const reader = new FileReader();

    reader.addEventListener("load", function () {
      // convert image file to base64 string
      preview.src = reader.result;
      this.setState({image: reader.result})
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }

    this.previewFile = this.preview.bind(this)
  }

  return (
    <Dialog open={open} onClose={onRequestClose}>
      <DialogTitle id="new-project-dialog-title">New Project</DialogTitle>
      <Formik initialValues={{ name: '' }} onSubmit={handleSubmit}>
        {({ errors, isSubmitting }) => (
          <Form className={classes.root}>
            <DialogContent>
              <Field
                name="isbn"
                label="ISBN"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="title"
                label="Title"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="status"
                label="Status"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="price"
                label="Price"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                id="image"
                name="image"
                component={TextField}
                style={{display:"none"}}
              />
              <input type="file" onChange={previewFile}/>

            </DialogContent>
            <DialogActions>
              <Button onClick={onRequestClose} color="secondary">
                Cancel
              </Button>
              <Button type="submit" color="primary" disabled={isSubmitting}>
                {isSubmitting ? 'Creating...' : 'Create'}
              </Button>
            </DialogActions>
          </Form>
        )}
      </Formik>
    </Dialog>
  )
}

NewProjectDialog.propTypes = {
  onSubmit: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
  onRequestClose: PropTypes.func.isRequired
}

export default NewProjectDialog

I modified the code but the image was not stored in the firebase...

function NewProjectDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()
  const [image, setImage] = useState({image: null});

(Omitted)

  function previewFile() {
    const preview = document.querySelector('img');
    const file = document.querySelector('input[type=file]').files[0];
    const reader = new FileReader();

    reader.addEventListener("load", function () {
      // convert image file to base64 string
      preview.src = reader.result;
      setImage({image: reader.result});
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }

  }

-M0EVfPfzF1vjQ4wLXLU
createdAt: 1581881931504
createdBy: "YcGWgfdbk2hs8CcWSdtsicYncyB3"
isbn: "asdfa"
name: ""
price: "asdfasd"
status: "asfdasfd"
title: "asfdasfd"

Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text

Body:
I guess this issue is coming from that this.setState can be used only in class based component. In function components like what you have - NewProjectDialog - you can use useState hook where you can create your state and the updater function.

What does useState return? It returns a pair of values: the current state and a function that updates it.

So you could have the defined state as:

const [image, setImage] = useState({image: null});

And instead of this.setState({image: reader.result}) you would modify as the following:

// updating value
setImage({image: reader.result});

Read further here: Using the State Hook

I hope that helps!


问:
Selenium 1 to Selenium 2 Migration
Selenium 2 has been in beta phase for last few months. I would like to know learning’s if any of our us have analyzed/migrated from selenium 1 to selenium 2

How much was the effort involved in terms of Changes# to accomodates 2 features. Methods/API changes#

How much was perf improvements in terms of run time of tests in Selenium 2

Any best practices/learning shared would be useful

答:
Going through the transition myself. If you had Selenium 1 experience, Selenium 2 feels quite different actually. Here is my Selenium 2 pros/cons vs. Selenium 1 I see so far (I use Python so some of them are Python specific):

Pros:

Much faster.

No need to run a separate server.

Gone are wait_for_page_to_load(), wait_for_element_present(), etc. All element interactions, clicks, etc. are blocking now, which is good. The only problem is with asynchronously loaded content (Ajax) though, see Con bellow.

Cons:

Loading/waiting for asynchronous content which used to be "free" with wait_for_page_to_load() requires coding now. These are the solutions I found so far:

use PageFactory/AjaxElementLocatorFactory like explained here, unfortunately I couldn't find the equivalent for Python.

use webdriver.implicitly_wait(N), this seems to be doing the trick with Python but using that seems to cause my script to miss changing elements which it used to detect before.

don't do sleep(T), loop until element appears, etc, that defeats the purpose of the whole thing (and makes wait_for_page_to_load look beautiful)...

The whole thing still feels a bit raw. Different drivers and bindings seem to miss different functionality. Not to say you can't use it but be ready to find 'alternate solutions' for certain problems.

The documentation is a bit dubious (related to the prev. point I guess). Especially for Python. Be ready to read code and experiment a lot (which luckily is easy with Python). Most of the 'tutorials' you'll find on the web (again, esp. Python, Java seems to be much better covered) are just to get you started with the plainest of web applications.

No PHP bindings, not a big one I prefer Python but our original suite was PHP so I noticed.

SeleniumIDE seems to be useless with Selenium 2.

Other differences:

The page elements you are accessing have to be 'visible' on the page at the moment when you ask selenium to find them. For example if you have a menu (containing a list of links) which opens when you hover your mouse over, you have to make sure it is open/visible before you click on a link inside (which wasn't the case in Selenium 1). This has it's uses since you'd be testing what an user would see on the page but requires the extra code. I found two solutions:

run a Javascript which would open your menu, in my case driver.execute_script("document.getElementById('dashboard_menu_navigation').show()") then click the menu item driver.find_element_by_link_text('Orders').click()

use the Mouse / Keyboard classes to simulate actual interaction, this seems to be broken in the Python bindings though (see Cons above):

Example (which throws 'WebElement' object has no attribute 'mouse_move_to' today):

```<code>element=driver.find_element_by_id('mn_dashboard')
mouse=Mouse()
mouse.move_to(element)
</code>```

The Cons list seems longer but that is mostly if you are coming from Selenium 1. I do prefer the lightness and speed of Selenium 2 and despite the early code (using 2.0b4 at the time of writing) the whole thing is quite usable.

Hope to save someone some time...

Title: Selenium 1 to Selenium 2 Migration

Body:
Going through the transition myself. If you had Selenium 1 experience, Selenium 2 feels quite different actually. Here is my Selenium 2 pros/cons vs. Selenium 1 I see so far (I use Python so some of them are Python specific):

Pros:

Much faster.

No need to run a separate server.

Gone are wait_for_page_to_load(), wait_for_element_present(), etc. All element interactions, clicks, etc. are blocking now, which is good. The only problem is with asynchronously loaded content (Ajax) though, see Con bellow.

Cons:

Loading/waiting for asynchronous content which used to be "free" with wait_for_page_to_load() requires coding now. These are the solutions I found so far:

use PageFactory/AjaxElementLocatorFactory like explained here, unfortunately I couldn't find the equivalent for Python.

use webdriver.implicitly_wait(N), this seems to be doing the trick with Python but using that seems to cause my script to miss changing elements which it used to detect before.

don't do sleep(T), loop until element appears, etc, that defeats the purpose of the whole thing (and makes wait_for_page_to_load look beautiful)...

The whole thing still feels a bit raw. Different drivers and bindings seem to miss different functionality. Not to say you can't use it but be ready to find 'alternate solutions' for certain problems.

The documentation is a bit dubious (related to the prev. point I guess). Especially for Python. Be ready to read code and experiment a lot (which luckily is easy with Python). Most of the 'tutorials' you'll find on the web (again, esp. Python, Java seems to be much better covered) are just to get you started with the plainest of web applications.

No PHP bindings, not a big one I prefer Python but our original suite was PHP so I noticed.

SeleniumIDE seems to be useless with Selenium 2.

Other differences:

The page elements you are accessing have to be 'visible' on the page at the moment when you ask selenium to find them. For example if you have a menu (containing a list of links) which opens when you hover your mouse over, you have to make sure it is open/visible before you click on a link inside (which wasn't the case in Selenium 1). This has it's uses since you'd be testing what an user would see on the page but requires the extra code. I found two solutions:

run a Javascript which would open your menu, in my case driver.execute_script("document.getElementById('dashboard_menu_navigation').show()") then click the menu item driver.find_element_by_link_text('Orders').click()

use the Mouse / Keyboard classes to simulate actual interaction, this seems to be broken in the Python bindings though (see Cons above):

Example (which throws 'WebElement' object has no attribute 'mouse_move_to' today):

element=driver.find_element_by_id('mn_dashboard')
mouse=Mouse()
mouse.move_to(element)

The Cons list seems longer but that is mostly if you are coming from Selenium 1. I do prefer the lightness and speed of Selenium 2 and despite the early code (using 2.0b4 at the time of writing) the whole thing is quite usable.

Hope to save someone some time...


问:
How to calculate total precipitation per day using hourly data for whole year?
I have hourly data from ERA5 for each day in a specific year. I want to convert that data from hourly to daily. I know the long and hard way to do it, but I need something which does that easily.

Copernicus has a code for this here https://confluence.ecmwf.int/display/CKB/ERA5%3A+How+to+calculate+daily+total+precipitation, which works fine if the data set is only converted for one day, but when converting for the whole year, i am having problems with that.

Link to download ERA5 dataset which is available at https://cds.climate.copernicus.eu/cdsapp#!/home

Follow the steps to use copernicus server here

https://confluence.ecmwf.int/display/CKB/How+to+download+ERA5

This script downloads the houly data for only 2 days (1st and 2nd of January 2017):

#!/usr/bin/env python
"""
Save as get-tp.py, then run "python get-tp.py".

Input file : None
Output file: tp_20170101-20170102.nc
"""
import cdsapi

c = cdsapi.Client()
r = c.retrieve(
    'reanalysis-era5-single-levels', {
            'variable'    : 'total_precipitation',
            'product_type': 'reanalysis',
            'year'        : '2017',
            'month'       : '01',
            'day'         : ['01', '02'],
            'time'        : [
                '00:00','01:00','02:00',
                '03:00','04:00','05:00',
                '06:00','07:00','08:00',
                '09:00','10:00','11:00',
                '12:00','13:00','14:00',
                '15:00','16:00','17:00',
                '18:00','19:00','20:00',
                '21:00','22:00','23:00'
            ],
            'format'      : 'netcdf'
    })
r.download('tp_20170101-20170102.nc')
## Add multiple days and multiple months to donload more data
```
Below script will create a netCDF file for only one day
<pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python
"""
Save as file calculate-daily-tp.py and run "python calculate-daily-tp.py".

Input file : tp_20170101-20170102.nc
Output file: daily-tp_20170101.nc
"""
import time, sys
from datetime import datetime, timedelta

from netCDF4 import Dataset, date2num, num2date
import numpy as np

day = 20170101
d = datetime.strptime(str(day), '%Y%m%d')
f_in = 'tp_%d-%s.nc' % (day, (d + timedelta(days = 1)).strftime('%Y%m%d'))
f_out = 'daily-tp_%d.nc' % day

time_needed = []
for i in range(1, 25):
    time_needed.append(d + timedelta(hours = i))

with Dataset(f_in) as ds_src:
    var_time = ds_src.variables['time']
    time_avail = num2date(var_time[:], var_time.units,
            calendar = var_time.calendar)

    indices = []
    for tm in time_needed:
        a = np.where(time_avail == tm)[0]
        if len(a) == 0:
            sys.stderr.write('Error: precipitation data is missing/incomplete - %s!\n'
                    % tm.strftime('%Y%m%d %H:%M:%S'))
            sys.exit(200)
        else:
            print('Found %s' % tm.strftime('%Y%m%d %H:%M:%S'))
            indices.append(a[0])

    var_tp = ds_src.variables['tp']
    tp_values_set = False
    for idx in indices:
        if not tp_values_set:
            data = var_tp[idx, :, :]
            tp_values_set = True
        else:
            data += var_tp[idx, :, :]

    with Dataset(f_out, mode = 'w', format = 'NETCDF3_64BIT_OFFSET') as ds_dest:
        # Dimensions
        for name in ['latitude', 'longitude']:
            dim_src = ds_src.dimensions[name]
            ds_dest.createDimension(name, dim_src.size)
            var_src = ds_src.variables[name]
            var_dest = ds_dest.createVariable(name, var_src.datatype, (name,))
            var_dest[:] = var_src[:]
            var_dest.setncattr('units', var_src.units)
            var_dest.setncattr('long_name', var_src.long_name)

        ds_dest.createDimension('time', None)
        var = ds_dest.createVariable('time', np.int32, ('time',))
        time_units = 'hours since 1900-01-01 00:00:00'
        time_cal = 'gregorian'
        var[:] = date2num([d], units = time_units, calendar = time_cal)
        var.setncattr('units', time_units)
        var.setncattr('long_name', 'time')
        var.setncattr('calendar', time_cal)

        # Variables
        var = ds_dest.createVariable(var_tp.name, np.double, var_tp.dimensions)
        var[0, :, :] = data
        var.setncattr('units', var_tp.units)
        var.setncattr('long_name', var_tp.long_name)

        # Attributes
        ds_dest.setncattr('Conventions', 'CF-1.6')
        ds_dest.setncattr('history', '%s %s'
                % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                ' '.join(time.tzname)))

        print('Done! Daily total precipitation saved in %s' % f_out)
</code>```

What I want is a code which will follows the same step as above data but assuming that I have an input file with one year houly data and convert that to one year daily data.

The result should be daily values for the calculate variable (such as precipitation, etc) for the whole year.

Example: Let's say I have a precipitation data for the whole year as 1mm/hr every day, I would have 2928 values for the whole year.

What I want is 24mm/day for the whole year with only 365 values for a non-leap year.

Example input dataset: Subset of the data can be downloaded from here (for 1st and 2nd January 2017) https://www.dropbox.com/sh/0vdfn20p355st3i/AABKYO4do_raGHC34VnsXGPqa?dl=0. Just use the 2nd script after this to check the code. {the code for the whole year is >10 GB thus can't be uploaded

Thanks in advance

答:
An alternative quick method from the command line using CDO would be:

```<code>cdo daysum -shifttime,-1hour era5_hourly.nc era5_daily.nc
</code>```

Note, as per this answer/discussion here: Calculating ERA5 Daily Total Precipitation using CDO
the ERA5 hourly data has the timestep at the end of the hourly window, so you need to shift the timestamp before making the sum, I'm not sure the xarray solution handles that.  Also to have mm/day, I think one needs to sum, not take the mean.

Body:
I have hourly data from ERA5 for each day in a specific year. I want to convert that data from hourly to daily. I know the long and hard way to do it, but I need something which does that easily.

Copernicus has a code for this here https://confluence.ecmwf.int/display/CKB/ERA5%3A+How+to+calculate+daily+total+precipitation, which works fine if the data set is only converted for one day, but when converting for the whole year, i am having problems with that.

Link to download ERA5 dataset which is available at https://cds.climate.copernicus.eu/cdsapp#!/home

Follow the steps to use copernicus server here

https://confluence.ecmwf.int/display/CKB/How+to+download+ERA5

This script downloads the houly data for only 2 days (1st and 2nd of January 2017):

#!/usr/bin/env python
"""
Save as get-tp.py, then run "python get-tp.py".

Input file : None
Output file: tp_20170101-20170102.nc
"""
import cdsapi

c = cdsapi.Client()
r = c.retrieve(
    'reanalysis-era5-single-levels', {
            'variable'    : 'total_precipitation',
            'product_type': 'reanalysis',
            'year'        : '2017',
            'month'       : '01',
            'day'         : ['01', '02'],
            'time'        : [
                '00:00','01:00','02:00',
                '03:00','04:00','05:00',
                '06:00','07:00','08:00',
                '09:00','10:00','11:00',
                '12:00','13:00','14:00',
                '15:00','16:00','17:00',
                '18:00','19:00','20:00',
                '21:00','22:00','23:00'
            ],
            'format'      : 'netcdf'
    })
r.download('tp_20170101-20170102.nc')
## Add multiple days and multiple months to donload more data

Below script will create a netCDF file for only one day

#!/usr/bin/env python
"""
Save as file calculate-daily-tp.py and run "python calculate-daily-tp.py".

Input file : tp_20170101-20170102.nc
Output file: daily-tp_20170101.nc
"""
import time, sys
from datetime import datetime, timedelta

from netCDF4 import Dataset, date2num, num2date
import numpy as np

day = 20170101
d = datetime.strptime(str(day), '%Y%m%d')
f_in = 'tp_%d-%s.nc' % (day, (d + timedelta(days = 1)).strftime('%Y%m%d'))
f_out = 'daily-tp_%d.nc' % day

time_needed = []
for i in range(1, 25):
    time_needed.append(d + timedelta(hours = i))

with Dataset(f_in) as ds_src:
    var_time = ds_src.variables['time']
    time_avail = num2date(var_time[:], var_time.units,
            calendar = var_time.calendar)

    indices = []
    for tm in time_needed:
        a = np.where(time_avail == tm)[0]
        if len(a) == 0:
            sys.stderr.write('Error: precipitation data is missing/incomplete - %s!\n'
                    % tm.strftime('%Y%m%d %H:%M:%S'))
            sys.exit(200)
        else:
            print('Found %s' % tm.strftime('%Y%m%d %H:%M:%S'))
            indices.append(a[0])

    var_tp = ds_src.variables['tp']
    tp_values_set = False
    for idx in indices:
        if not tp_values_set:
            data = var_tp[idx, :, :]
            tp_values_set = True
        else:
            data += var_tp[idx, :, :]

    with Dataset(f_out, mode = 'w', format = 'NETCDF3_64BIT_OFFSET') as ds_dest:
        # Dimensions
        for name in ['latitude', 'longitude']:
            dim_src = ds_src.dimensions[name]
            ds_dest.createDimension(name, dim_src.size)
            var_src = ds_src.variables[name]
            var_dest = ds_dest.createVariable(name, var_src.datatype, (name,))
            var_dest[:] = var_src[:]
            var_dest.setncattr('units', var_src.units)
            var_dest.setncattr('long_name', var_src.long_name)

        ds_dest.createDimension('time', None)
        var = ds_dest.createVariable('time', np.int32, ('time',))
        time_units = 'hours since 1900-01-01 00:00:00'
        time_cal = 'gregorian'
        var[:] = date2num([d], units = time_units, calendar = time_cal)
        var.setncattr('units', time_units)
        var.setncattr('long_name', 'time')
        var.setncattr('calendar', time_cal)

        # Variables
        var = ds_dest.createVariable(var_tp.name, np.double, var_tp.dimensions)
        var[0, :, :] = data
        var.setncattr('units', var_tp.units)
        var.setncattr('long_name', var_tp.long_name)

        # Attributes
        ds_dest.setncattr('Conventions', 'CF-1.6')
        ds_dest.setncattr('history', '%s %s'
                % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                ' '.join(time.tzname)))

        print('Done! Daily total precipitation saved in %s' % f_out)

What I want is a code which will follows the same step as above data but assuming that I have an input file with one year houly data and convert that to one year daily data.

The result should be daily values for the calculate variable (such as precipitation, etc) for the whole year.

Example: Let's say I have a precipitation data for the whole year as 1mm/hr every day, I would have 2928 values for the whole year.

What I want is 24mm/day for the whole year with only 365 values for a non-leap year.

Example input dataset: Subset of the data can be downloaded from here (for 1st and 2nd January 2017) https://www.dropbox.com/sh/0vdfn20p355st3i/AABKYO4do_raGHC34VnsXGPqa?dl=0. Just use the 2nd script after this to check the code. {the code for the whole year is >10 GB thus can't be uploaded

Thanks in advance

Body:
An alternative quick method from the command line using CDO would be:

cdo daysum -shifttime,-1hour era5_hourly.nc era5_daily.nc

Note, as per this answer/discussion here: Calculating ERA5 Daily Total Precipitation using CDO
the ERA5 hourly data has the timestep at the end of the hourly window, so you need to shift the timestamp before making the sum, I'm not sure the xarray solution handles that.  Also to have mm/day, I think one needs to sum, not take the mean.


问:
Append with input value with <li> tag
Thanks in advance.
I am trying to append a list using the input value. I can append a list using predefined string, and I can append using input value to non list item. But I'm having trouble combining these, it seems to add extra list items.
This is the code I'm using:</p>

```<code>    <ol>
  <li>List item 1</li>
  <li>List item 2</li>
  <li>List item 3</li>
</ol>
<form>
    <div><textarea class="example-default-value" id="example-textarea" style="width: 400px; height: 50px;">Type some text in here to be appended</textarea></div>
    <div><input type="button" value="Append" onclick="example_append()" /></div>
</form>
<script language="javascript">
$('.example-default-value').each(function() {
    var default_value = this.value;
    $(this).focus(function() {
        if(this.value == default_value) {
            this.value = '';
        }
    });
    $(this).blur(function() {
        if(this.value == '') {
            this.value = default_value;
        }
    });
});
function example_append() {
    $('ol').append("<li>"+($('#example-textarea').val())+"<li>");
}
</script>
</code>```

答:
You have to use the close tag for li in your example_append() function.

$('ol').append("
"+($('#example-textarea').val())+"
");

to

$('ol').append("
"+($('#example-textarea').val())+"
");

Title: Append with input value with <li> tag

Body:
Thanks in advance.
I am trying to append a list using the input value. I can append a list using predefined string, and I can append using input value to non list item. But I'm having trouble combining these, it seems to add extra list items.
This is the code I'm using:

List item 1

List item 2

List item 3

<form>

<textarea class="example-default-value" id="example-textarea" style="width: 400px; height: 50px;">Type some text in here to be appended</textarea>

<input type="button" value="Append" onclick="example_append()" />

</form>

Body:
You have to use the close tag for li in your example_append() function.

$('ol').append("<li>"+($('#example-textarea').val())+"<li>");

to

$('ol').append("<li>"+($('#example-textarea').val())+"</li>");


答:
The loop you have written does not make sense, because you are using the comma operator and discarding one of the conditions, so it is equivalent to j < n.

Even if the condition gets triggered many times (but a constant number w.r.t. n, i.e. not becoming larger as n grows), then you can easily show you will do <= k*n iterations, which means O(n) iterations.

If that is not true, but the condition is at least side-effect free, then you can only bound it by O(n^2), e.g. as @walnut suggests with j == n - 1 (like in a triangle matrix).

If you allow for side-effects in the condition (e.g. j = 0, with an equals sign), then it can be an infinite loop, so there is no possible bound.

Title: Can I create a for loop with two variables and still have time complexity of O(n)?


问:
Python itertools permutations without repetitions
I have a string show the step going in m x n grid like this problem:
https://leetcode.com/problems/unique-paths/

```<code>step = 'DDRR'
</code>```

D mean go Down and R mean go to Right
I want to show permutations without replacement, and i found the itertools built-in on Python.But it's say:

Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values.

So that when I using itertools.permutation(step,4), it's contain many replications.

```<code>>>> itertools.permutations(step,4)
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')
</code>```

I want something like:

```<code>('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('R', 'R', 'D', 'D')
</code>```

I found some answer using set(itertools.permutations(step,4)), but because apply set() method, the itertools.permutation() method still calculate all possibilities. Is there anyway to avoid it, or is there any built-in function can do permutation without repetitions in Python?

答:
It's a terribly inefficient solution anyway. Just compute the number directly:</p>

```<code>math.comb(m + n - 2, m - 1)
</code>```

Body:
I have a string show the step going in m x n grid like this problem:
https://leetcode.com/problems/unique-paths/

step = 'DDRR'

D mean go Down and R mean go to Right
I want to show permutations without replacement, and i found the itertools built-in on Python.But it's say:

Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values.

So that when I using itertools.permutation(step,4), it's contain many replications.

>>> itertools.permutations(step,4)
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')

I want something like:

('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('R', 'R', 'D', 'D')

I found some answer using set(itertools.permutations(step,4)), but because apply set() method, the itertools.permutation() method still calculate all possibilities. Is there anyway to avoid it, or is there any built-in function can do permutation without repetitions in Python?

Body:
It's a terribly inefficient solution anyway. Just compute the number directly:

math.comb(m + n - 2, m - 1)


问:
Compare Txt Files in Linux and Return Elements in File 1 for Elements in File 2
Here is the problem.

Host.txt file has only Hostnames as follows:

```
GVC-CH-ZRH-BRA-5H81-PELE
GVC-US-NYC-9TH-4C101-MEDROOM
GVC-US-NYC-9TH-4C101E-EXTRA
GVC-US-NYC-9TH-5E117-STUDIO54
```

2.HosandIp.txt has the Hostnames and Ip as follows (HostandIP has hostname,IP Address Note the Comma (,)):

```
GVC-CH-ZRH-BRA-5H81-PELE,170.16.75.101
GVC-US-NYC-9TH-4C101-MEDROOM,170.26.114.242
GVC-US-NYC-9TH-4C101E-EXTRA,170.26.108.224
GVC-US-NYC-9TH-5E117-STUDIO54,170.26.108.95
beta-gvc-personal-antoniop-526,170.26.107.180
beta-gvc-personal-antoniop-9100,170.26.106.206
beta-gvc-personal-antoniop-9100b,170.26.106.41
beta-gvc-personal-antoniop-office,170.26.107.192
```

I need to compare these two files and get only the IP Address in another text file called IPOnly.txt

IPOnly.txt has only the IP's common to both Host.txt and HostandIp.txt as follows:

```
170.16.75.101
170.26.114.242
170.26.108.224
170.26.108.95
```

It can be done in JAVA using HASH MAP. Is there a Linux Command to do this ? Please Help!

答:
Here is my 0.02$ in perl</p>

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

open (HOST, '<Host.txt') || die;
open (HOSTANDIP, '<HostAndIp.txt') || die;

my %host2ip;
map { chomp; my ($h,$i) = split /,/; $host2ip{$h} = $i } (<HOSTANDIP>);

map { chomp; print "$host2ip{$_}\n" if exists($host2ip{$_}) } (<HOST>);
</code>```

Body:
Here is the problem.

Host.txt file has only Hostnames as follows:

GVC-CH-ZRH-BRA-5H81-PELE
GVC-US-NYC-9TH-4C101-MEDROOM
GVC-US-NYC-9TH-4C101E-EXTRA
GVC-US-NYC-9TH-5E117-STUDIO54

2.HosandIp.txt has the Hostnames and Ip as follows (HostandIP has hostname,IP Address Note the Comma (,)):

GVC-CH-ZRH-BRA-5H81-PELE,170.16.75.101
GVC-US-NYC-9TH-4C101-MEDROOM,170.26.114.242
GVC-US-NYC-9TH-4C101E-EXTRA,170.26.108.224
GVC-US-NYC-9TH-5E117-STUDIO54,170.26.108.95
beta-gvc-personal-antoniop-526,170.26.107.180
beta-gvc-personal-antoniop-9100,170.26.106.206
beta-gvc-personal-antoniop-9100b,170.26.106.41
beta-gvc-personal-antoniop-office,170.26.107.192

I need to compare these two files and get only the IP Address in another text file called IPOnly.txt

IPOnly.txt has only the IP's common to both Host.txt and HostandIp.txt as follows:

170.16.75.101
170.26.114.242
170.26.108.224
170.26.108.95

It can be done in JAVA using HASH MAP. Is there a Linux Command to do this ? Please Help!

Body:
Here is my 0.02$ in perl

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

open (HOST, '<Host.txt') || die;
open (HOSTANDIP, '<HostAndIp.txt') || die;

my %host2ip;
map { chomp; my ($h,$i) = split /,/; $host2ip{$h} = $i } (<HOSTANDIP>);

map { chomp; print "$host2ip{$_}\n" if exists($host2ip{$_}) } (<HOST>);


问:
React Performance: What is a good strategy to maintain constant references for event handler props?
Assuming I have a slow component, it makes sense to memoize it, e.g.

```<code>const SlowButton = ({onClick}) => {
    // make some heat
    const value = (function f(n) { return n < 2 ? Math.random() : f(n-1) + f(n-2)})(32)|0;
    return <button onClick={() => onClick(value)}>{value}</button>
}
const MemoButton = React.memo(SlowButton);
</code>```

If I use the MemoButton in a component like:

```<code>const Counter = () => {
    const [clicks, setClicks ] = useState(0);
    const handleClick = () => {
        setClicks(clicks + 1);
    }
    return <div>
            <div>{clicks}</div>
            <MemoButton onClick={handleClick} />
        </div>
}
</code>```

Then the MemoButton still re-renders every time because the onClick property is a new function every render.  It is pretty easy to resolve this with:

```<code>const Counter2 = () => {
    const [clicks, setClicks] = useState(0);
    const handleClick = useCallback(() => {
        setClicks(c => c + 1);
    },[]);

    return <div>
            <div>{clicks}</div>
            <MemoButton onClick={handleClick} />
        </div>
}
</code>```

The above works fine, but with a more complicated component, it doesn't work so well:

```<code>const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = (val, idx) => setMessage(`button ${idx} clicked: ${val}`);
    return <div>
        <div>{message}</div>
        {Array(numButtons).fill(0).map((_, i) =>
            <MemoButton key={i} onClick={(v) => handleClick(v,i)} />)
        }
        </div>
}
</code>```

In the above code, (v) => handleClick(i,v) is always going to be a new function reference.  Is there a good technique to keep this from changing every render?

One possibility is to just ignore changes to 'on...' props, but this just creates new problems:

```<code>const compareValuePropsOnly = (prev, next) => Object.entries(prev).every(
    ([k, v]) => k.substr(0, 2) === "on" || v === next[k]
);
const MemoOnlyValsButton = React.memo(SlowButton, compareValuePropsOnly);
</code>```

Here is a codesandbox version:
https://codesandbox.io/s/memoization-function-reference-changes-9c1fy

答:
One solution is to let your SlowButton pass the i value, instead of getting it from the loop, and memoize handleClick

const SlowButton = ({onClick, i}) => {
    // make some heat
    const value = (function f(n) { return n < 2 ? Math.random() : f(n-1) + f(n-2)})(32)|0;
    return <button onClick={() => onClick(value, i)}>{value}</button>
}
const MemoButton = React.memo(SlowButton);

const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = React.useCallback((val, idx) => setMessage(`button ${idx} clicked: ${val}`), []);
    return

{message}

        {Array(numButtons).fill(0).map((_, i) =>
            <MemoButton key={i} i={i} onClick={handleClick} />)
        }

}

```

<p>Another way is to exclude 'onClick' props in your <code>React.memo</code> (since it's an event handler, it shouldn't impact how the component looks like).</p>

<pre class="lang-js prettyprint-override"><code>  const MemoButton = React.memo(SlowButton, (props1, props2) => {
    // assume that SlowButton have some props that affect it's UI
    // we don't compare onClick because it won't affect UI
    return props1.someUIProps === props2.someUIProps;
})
</code>```

Or you can use the useEventCallback hook to memo your function. In this case, you need to make a component between CounterGroup and MemoButton

```<code>const useEventCallback = (callback) => {
  // store latest callback
  const ref = useRef(callback);
  useEffect(() => ref.current = callback);

  // memoize the callback to maintain its identity
  return useCallback((...args) => ref.current(...args), []);
}
const FastButton = ({onClick} => {
 // FastButton will be re-rendered multiple times, but since memoOnClick have same identity
 // on sub sequence re-renders, MemoButton should not be re-rendered
 const memoOnClick = useEventCallback(onClick);

 return <MemoButton onClick={memoOnClick} />
});

const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = (val, idx) => setMessage(`button ${idx} clicked: ${val}`);
    return <div>
        <div>{message}</div>
        {Array(numButtons).fill(0).map((_, i) =>
            <FastButton key={i} onClick={(v) => handleClick(v,i)} />)
        }
        </div>
}

</code>```

Body:
Assuming I have a slow component, it makes sense to memoize it, e.g.

const SlowButton = ({onClick}) => {
    // make some heat
    const value = (function f(n) { return n < 2 ? Math.random() : f(n-1) + f(n-2)})(32)|0;
    return <button onClick={() => onClick(value)}>{value}</button>
}
const MemoButton = React.memo(SlowButton);

If I use the MemoButton in a component like:

const Counter = () => {
    const [clicks, setClicks ] = useState(0);
    const handleClick = () => {
        setClicks(clicks + 1);
    }
    return

{clicks}

            <MemoButton onClick={handleClick} />

}

Then the MemoButton still re-renders every time because the onClick property is a new function every render.  It is pretty easy to resolve this with:

const Counter2 = () => {
    const [clicks, setClicks] = useState(0);
    const handleClick = useCallback(() => {
        setClicks(c => c + 1);
    },[]);

    return

{clicks}

            <MemoButton onClick={handleClick} />

}

The above works fine, but with a more complicated component, it doesn't work so well:

const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = (val, idx) => setMessage(`button ${idx} clicked: ${val}`);
    return

{message}

        {Array(numButtons).fill(0).map((_, i) =>
            <MemoButton key={i} onClick={(v) => handleClick(v,i)} />)
        }

}

In the above code, (v) => handleClick(i,v) is always going to be a new function reference.  Is there a good technique to keep this from changing every render?

One possibility is to just ignore changes to 'on...' props, but this just creates new problems:

const compareValuePropsOnly = (prev, next) => Object.entries(prev).every(
    ([k, v]) => k.substr(0, 2) === "on" || v === next[k]
);
const MemoOnlyValsButton = React.memo(SlowButton, compareValuePropsOnly);

Here is a codesandbox version:
https://codesandbox.io/s/memoization-function-reference-changes-9c1fy

Body:
One solution is to let your SlowButton pass the i value, instead of getting it from the loop, and memoize handleClick

const SlowButton = ({onClick, i}) => {
    // make some heat
    const value = (function f(n) { return n < 2 ? Math.random() : f(n-1) + f(n-2)})(32)|0;
    return <button onClick={() => onClick(value, i)}>{value}</button>
}
const MemoButton = React.memo(SlowButton);

const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = React.useCallback((val, idx) => setMessage(`button ${idx} clicked: ${val}`), []);
    return <div>
        <div>{message}</div>
        {Array(numButtons).fill(0).map((_, i) =>
            <MemoButton key={i} i={i} onClick={handleClick} />)
        }
        </div>
}

Another way is to exclude 'onClick' props in your React.memo (since it's an event handler, it shouldn't impact how the component looks like).

  const MemoButton = React.memo(SlowButton, (props1, props2) => {
    // assume that SlowButton have some props that affect it's UI
    // we don't compare onClick because it won't affect UI
    return props1.someUIProps === props2.someUIProps;
})

Or you can use the useEventCallback hook to memo your function. In this case, you need to make a component between CounterGroup and MemoButton

const useEventCallback = (callback) => {
  // store latest callback
  const ref = useRef(callback);
  useEffect(() => ref.current = callback);

  // memoize the callback to maintain its identity
  return useCallback((...args) => ref.current(...args), []);
}
const FastButton = ({onClick} => {
 // FastButton will be re-rendered multiple times, but since memoOnClick have same identity
 // on sub sequence re-renders, MemoButton should not be re-rendered
 const memoOnClick = useEventCallback(onClick);

 return <MemoButton onClick={memoOnClick} />
});

const CounterGroup = () => {
    const numButtons = 3;
    const [message, setMessage] = useState('button X clicked');
    const handleClick = (val, idx) => setMessage(`button ${idx} clicked: ${val}`);
    return <div>
        <div>{message}</div>
        {Array(numButtons).fill(0).map((_, i) =>
            <FastButton key={i} onClick={(v) => handleClick(v,i)} />)
        }
        </div>
}


问:
How can I use regex to find data between quotation marks?
I need to extract data which is between the single quotes.

```<code>"request='fgj234fgj9da41c76a8bc7d470kjykl89a5d'>"
</code>```

I did try:
^"request="'*' but doesn;t work

答:
The regex:

```<code>^"request='([^']*)'>"$
</code>```

^ Matches the start of the string.

"request=' Matches "request='.

([^']*) Capture group 1: Matches 0 or more characters that are not a '.

'>" Matches '>".

$ Matches the end of the string.

let text = "\"request='fgj234fgj9da41c76a8bc7d470kjykl89a5d'>\"";
let matches = text.match(/^"request='([^']*)'>"$/);
console.log(matches[1]);```

Body:
I need to extract data which is between the single quotes.

"request='fgj234fgj9da41c76a8bc7d470kjykl89a5d'>"

I did try:
^"request="'*' but doesn;t work

Body:
The regex:

^"request='([^']*)'>"$

^ Matches the start of the string.

"request=' Matches "request='.

([^']*) Capture group 1: Matches 0 or more characters that are not a '.

'>" Matches '>".

$ Matches the end of the string.

let text = "\"request='fgj234fgj9da41c76a8bc7d470kjykl89a5d'>\"";
let matches = text.match(/^"request='([^']*)'>"$/);
console.log(matches[1]);


问:
If condition not working for text strikethrough in iOS tableview ToDo app
I have an iOS ToDo app that is based on the iBook App Development with Swift. I extended it to use CoreData (to be able to sort by date). I also added a feature to strikethrough the taskTitleLabel when an isCompleteButton is toggled. Everything seems to work ok until the last item on the tableview is toggled complete, then toggled not complete. If a new item is added to the list after the toggled one, the title has the strikethrough applied without the isCompleteButton being selected.  Here's the code:

TaskCell.swift

```<code>import UIKit

@objc protocol TaskCellDelegate: class {
    func checkmarkTapped(sender: TaskCell)
}

class TaskCell: UITableViewCell {

    var delegate: TaskCellDelegate?

    @IBOutlet weak var isCompleteButton: UIButton!

    @IBOutlet weak var taskTitleLabel: UILabel!

    @IBAction func isCompleteButtonTapped(_ sender: UIButton) {
        delegate?.checkmarkTapped(sender: self)

    }
    override func prepareForReuse() {
        super.prepareForReuse()

        isCompleteButton.isSelected = !isCompleteButton.isSelected
    }
}
</code>```

TasksTableViewController

```<code>    ...
 func checkmarkTapped(sender: TaskCell) {

        if let indexPath = tableView.indexPath(for: sender){
            let task = fetchedResultsController.object(at: indexPath) as? Task
            task?.isComplete = !task!.isComplete
            coreDataStack.saveContext()
        }
    }
...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell") as? TaskCell else { fatalError("Could not dequeue a celL")}

        cell.delegate = self

        let task = fetchedResultsController.object(at: indexPath) as! Task
        cell.taskTitleLabel.text = task.title
        cell.isCompleteButton.isSelected = task.isComplete

        if  task.isComplete {
            let strikeThroughTask = NSMutableAttributedString(string: task.title!)
            strikeThroughTask.addAttributes([
                NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue,
                NSAttributedString.Key.strikethroughColor: UIColor.darkGray,
                NSAttributedString.Key.font : UIFont.systemFont(ofSize: 12.0)
            ], range: NSMakeRange(0, strikeThroughTask.length))
            cell.taskTitleLabel.attributedText = strikeThroughTask
        }

        if task.hasDueDate {
            if task.dueDate! < Date().startOfDay {
              cell.taskTitleLabel.textColor = .red
            } else if task.dueDate! > Date().startOfDay && task.dueDate! < Date().endOfDay {
                if #available(iOS 13.0, *) {
                    cell.taskTitleLabel.textColor = .label
                } else {
                    // Fallback on earlier versions
                    cell.taskTitleLabel.textColor = .black
                }
            } else {
                // future due date
                cell.taskTitleLabel.textColor = UIColor(red: 100/255.0, green: 100/255.0, blue: 100/255.0, alpha: 1)
            }
        } else {
            //no dueDate
            cell.taskTitleLabel.textColor = UIColor(red: 125/255.0, green: 125/255.0, blue: 125/255.0, alpha: 1)
        }

        return cell
    }
</code>```

I am also using a NSFetchResultsController

```<code>extension TasksTableViewController: NSFetchedResultsControllerDelegate {

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        let index = indexPath ?? (newIndexPath ?? nil)
        guard let cellIndex = index else { return }

        switch type {
            case .insert:
                tableView.insertRows(at: [cellIndex], with: .automatic)
            case .delete:
                tableView.deleteRows(at: [cellIndex], with: .automatic)
            case .update:
                tableView.reloadRows(at: [cellIndex], with: .automatic)
            default:
                break
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

}
</code>```

From AddTaskTableViewController

```<code>...
func updateTaskEntry() {
        guard let task = task else { return }

        task.title = taskTitleTextField.text
        task.isComplete = isCompleteButton.isSelected
        task.hasDueDate = hasDueDateSwitch.isOn
        if hasDueDateSwitch.isOn {
            task.dueDate = dueDatePicker.date
        } else {
            task.dueDate = nil
        }
        task.notes = notesTextView.text
        coreDataStack.saveContext()
    }

    @IBAction func saveButtonTapped(_ sender: UIBarButtonItem) {

    }

    func saveNewTask() {
        let task = Task(context: coreDataStack.managedObjectContext)
            task.title = taskTitleTextField.text
            task.isComplete = isCompleteButton.isSelected
            task.hasDueDate = hasDueDateSwitch.isOn
            if hasDueDateSwitch.isOn {
                task.dueDate = dueDatePicker.date
            } else {
                task.dueDate = nil
            }
            task.notes = notesTextView.text
            task.createdOn = Date()

            coreDataStack.saveContext()
    }
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard segue.identifier == "saveUnwind" else {return}

        if navigationItem.title == "Add Task" {

            saveNewTask()

        } else if navigationItem.title == "Update Task" {

            updateTaskEntry()
        }
    }
}
</code>```

So my question is: why is the text in the titleLabel have the strikethrough without the isCompleteButton selected or task.isComplete? What am I missing?

答:
I solved the problem with help from here Can't reset UILabel attributedText when a UITableViewCell is reused
I added taskTitleLabel.attributedText = nil to the prepareForReuse function.</p>

Body:
I have an iOS ToDo app that is based on the iBook App Development with Swift. I extended it to use CoreData (to be able to sort by date). I also added a feature to strikethrough the taskTitleLabel when an isCompleteButton is toggled. Everything seems to work ok until the last item on the tableview is toggled complete, then toggled not complete. If a new item is added to the list after the toggled one, the title has the strikethrough applied without the isCompleteButton being selected.  Here's the code:

TaskCell.swift

import UIKit

@objc protocol TaskCellDelegate: class {
    func checkmarkTapped(sender: TaskCell)
}

class TaskCell: UITableViewCell {

    var delegate: TaskCellDelegate?

    @IBOutlet weak var isCompleteButton: UIButton!

    @IBOutlet weak var taskTitleLabel: UILabel!

    @IBAction func isCompleteButtonTapped(_ sender: UIButton) {
        delegate?.checkmarkTapped(sender: self)

    }
    override func prepareForReuse() {
        super.prepareForReuse()

        isCompleteButton.isSelected = !isCompleteButton.isSelected
    }
}

TasksTableViewController

    ...
 func checkmarkTapped(sender: TaskCell) {

        if let indexPath = tableView.indexPath(for: sender){
            let task = fetchedResultsController.object(at: indexPath) as? Task
            task?.isComplete = !task!.isComplete
            coreDataStack.saveContext()
        }
    }
...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell") as? TaskCell else { fatalError("Could not dequeue a celL")}

        cell.delegate = self

        let task = fetchedResultsController.object(at: indexPath) as! Task
        cell.taskTitleLabel.text = task.title
        cell.isCompleteButton.isSelected = task.isComplete

        if  task.isComplete {
            let strikeThroughTask = NSMutableAttributedString(string: task.title!)
            strikeThroughTask.addAttributes([
                NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue,
                NSAttributedString.Key.strikethroughColor: UIColor.darkGray,
                NSAttributedString.Key.font : UIFont.systemFont(ofSize: 12.0)
            ], range: NSMakeRange(0, strikeThroughTask.length))
            cell.taskTitleLabel.attributedText = strikeThroughTask
        }

        if task.hasDueDate {
            if task.dueDate! < Date().startOfDay {
              cell.taskTitleLabel.textColor = .red
            } else if task.dueDate! > Date().startOfDay && task.dueDate! < Date().endOfDay {
                if #available(iOS 13.0, *) {
                    cell.taskTitleLabel.textColor = .label
                } else {
                    // Fallback on earlier versions
                    cell.taskTitleLabel.textColor = .black
                }
            } else {
                // future due date
                cell.taskTitleLabel.textColor = UIColor(red: 100/255.0, green: 100/255.0, blue: 100/255.0, alpha: 1)
            }
        } else {
            //no dueDate
            cell.taskTitleLabel.textColor = UIColor(red: 125/255.0, green: 125/255.0, blue: 125/255.0, alpha: 1)
        }

        return cell
    }

I am also using a NSFetchResultsController

extension TasksTableViewController: NSFetchedResultsControllerDelegate {

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        let index = indexPath ?? (newIndexPath ?? nil)
        guard let cellIndex = index else { return }

        switch type {
            case .insert:
                tableView.insertRows(at: [cellIndex], with: .automatic)
            case .delete:
                tableView.deleteRows(at: [cellIndex], with: .automatic)
            case .update:
                tableView.reloadRows(at: [cellIndex], with: .automatic)
            default:
                break
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

}

From AddTaskTableViewController

...
func updateTaskEntry() {
        guard let task = task else { return }

        task.title = taskTitleTextField.text
        task.isComplete = isCompleteButton.isSelected
        task.hasDueDate = hasDueDateSwitch.isOn
        if hasDueDateSwitch.isOn {
            task.dueDate = dueDatePicker.date
        } else {
            task.dueDate = nil
        }
        task.notes = notesTextView.text
        coreDataStack.saveContext()
    }

    @IBAction func saveButtonTapped(_ sender: UIBarButtonItem) {

    }

    func saveNewTask() {
        let task = Task(context: coreDataStack.managedObjectContext)
            task.title = taskTitleTextField.text
            task.isComplete = isCompleteButton.isSelected
            task.hasDueDate = hasDueDateSwitch.isOn
            if hasDueDateSwitch.isOn {
                task.dueDate = dueDatePicker.date
            } else {
                task.dueDate = nil
            }
            task.notes = notesTextView.text
            task.createdOn = Date()

            coreDataStack.saveContext()
    }
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard segue.identifier == "saveUnwind" else {return}

        if navigationItem.title == "Add Task" {

            saveNewTask()

        } else if navigationItem.title == "Update Task" {

            updateTaskEntry()
        }
    }
}

So my question is: why is the text in the titleLabel have the strikethrough without the isCompleteButton selected or task.isComplete? What am I missing?


问:
Thinking Sphinx returns "bad multi-query count 0 (must be in 1..32 range)"
I'm trying to use Sphinx (2.0.1 beta) with Thinking Sphinx 2.0.4 (on Rails 3.0.3). I have one model so far that I'd like to add to my index and the indexing has worked. I can also start searchd through rake and see the process running.

However, when trying a simple search in Rails (like User.search "name"), searchd complains about
"bad multi-query count 0 (must be in 1..32 range)"

And here is the backtrace:

```<code>from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:663:in `request'
from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:226:in `run'
from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:333:in `query'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:397:in `populate'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications.rb:52:in `instrument'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications.rb:52:in `instrument'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:499:in `log'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:507:in `log'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:396:in `populate'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:548:in `call'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:548:in `retry_on_stale_index'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:394:in `populate'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:176:in `method_missing'
from /usr/lib/ruby/1.8/irb.rb:310:in `output_value'
from /usr/lib/ruby/1.8/irb.rb:159:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:271:in `signal_status'
from /usr/lib/ruby/1.8/irb.rb:155:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:154:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:71:in `start'
from /usr/lib/ruby/1.8/irb.rb:70:in `catch'
from /usr/lib/ruby/1.8/irb.rb:70:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands.rb:23
from script/rails:7:in `require'
</code>```

答:
Ah, I just answered on the Google Group, but here again, for anyone else who finds this question:

This is a bug in Riddle 1.3.2, which is fixed in edge, but there's no new gem release just yet. Add Riddle to your Gemfile (above your thinking-sphinx reference):

```<code>gem 'riddle', :git => 'git://github.com/freelancing-god/riddle.git'
</code>```

Body:
I'm trying to use Sphinx (2.0.1 beta) with Thinking Sphinx 2.0.4 (on Rails 3.0.3). I have one model so far that I'd like to add to my index and the indexing has worked. I can also start searchd through rake and see the process running.

However, when trying a simple search in Rails (like User.search "name"), searchd complains about
"bad multi-query count 0 (must be in 1..32 range)"

And here is the backtrace:

from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:663:in `request'
from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:226:in `run'
from /vendor/bundle/ruby/1.8/gems/riddle-1.3.2/lib/riddle/client.rb:333:in `query'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:397:in `populate'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications.rb:52:in `instrument'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
from /vendor/bundle/ruby/1.8/gems/activesupport-3.0.3/lib/active_support/notifications.rb:52:in `instrument'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:499:in `log'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:507:in `log'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:396:in `populate'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:548:in `call'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:548:in `retry_on_stale_index'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:394:in `populate'
from /vendor/bundle/ruby/1.8/gems/thinking-sphinx-2.0.4/lib/thinking_sphinx/search.rb:176:in `method_missing'
from /usr/lib/ruby/1.8/irb.rb:310:in `output_value'
from /usr/lib/ruby/1.8/irb.rb:159:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:271:in `signal_status'
from /usr/lib/ruby/1.8/irb.rb:155:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:154:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:71:in `start'
from /usr/lib/ruby/1.8/irb.rb:70:in `catch'
from /usr/lib/ruby/1.8/irb.rb:70:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in `start'
from /vendor/bundle/ruby/1.8/gems/railties-3.0.3/lib/rails/commands.rb:23
from script/rails:7:in `require'

Body:
Ah, I just answered on the Google Group, but here again, for anyone else who finds this question:

This is a bug in Riddle 1.3.2, which is fixed in edge, but there's no new gem release just yet. Add Riddle to your Gemfile (above your thinking-sphinx reference):

gem 'riddle', :git => 'git://github.com/freelancing-god/riddle.git'