问:
Adding variables with currency formatting and the best solution to search a list
I have the following code:

Full code listing: https://repl.it/JSUN/1

I am looking, for teaching purposes, to obtaining the best method/solution for two things:

Q1. working with currency variables, such as the ones stored in the basket list below

```<code>basket=[['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]
</code>```

In the checkout sub, the intention is to add the COSTS for the corresponding item together.

So if the basket contained the items above, the required output would be £900+£1020+£700
=£2620

I have tried various things like converting to integer, which obviously doesn't work and I imagine that some sort of string manipulation may be the only way forward (which seems unnecessarily complex). A language like VB.Net has a currency data type which would make this task considerably simpler. What would be the pythonic way of solving this?

Q2. For looping through the entire basket to produce all items in the basket on checkout, and not just the first 2

I tried this, which didn't work:

```<code>  for items in basket:
    print("Your total bill is:", basket[items][1])
    items=items+1
</code>```

and this, also erroneous:

```<code>for i in len(basket):
    print("Your total bill is:", basket[i][1])
</code>```

Error:

```<code>TypeError: 'int' object is not iterable
</code>```

Both questions are linked, as they both pertain to the checkout() sub, in which the addition of all the currency variables in the basket list is the objective!

答:
Q1:

Given that it is only for a basic teaching purpose, you could just strip out the pound sign (assuming consistent representation):

```<code>def extract_cost(money_in_pounds):
    return int(money_in_pounds[1:])

basket = [['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]
total_cost = 0
for items in basket:
    total_cost = total_cost + extract_cost(items[1])

print(total_cost)
</code>```

Without writing another function

```<code>basket = [['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]
total_cost = 0
for items in basket:
    # items[1] selects the cost
    # items[1][1:] selects the sub-string of that cost from the 1st index to the end, i.e. remove the currency notation
    # int() then converts it into an integer
    cost_in_pounds = int(items[1][1:])
    total_cost = total_cost + cost_in_pounds

print(total_cost)
</code>```

More concise code (Suggested by Jon Clements below)

```<code>total_cost = sum(int(cost[1:]) for item_name, cost in basket)
</code>```

Q2:

items is not the index, it is the content of the list, so items itself is the inner list:

```<code>for items in basket:
    print("Your total bill is:", items[1])
</code>```

Body:
I have the following code:

Full code listing: https://repl.it/JSUN/1

I am looking, for teaching purposes, to obtaining the best method/solution for two things:

Q1. working with currency variables, such as the ones stored in the basket list below

basket=[['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]

In the checkout sub, the intention is to add the COSTS for the corresponding item together.

So if the basket contained the items above, the required output would be £900+£1020+£700
=£2620

I have tried various things like converting to integer, which obviously doesn't work and I imagine that some sort of string manipulation may be the only way forward (which seems unnecessarily complex). A language like VB.Net has a currency data type which would make this task considerably simpler. What would be the pythonic way of solving this?

Q2. For looping through the entire basket to produce all items in the basket on checkout, and not just the first 2

I tried this, which didn't work:

  for items in basket:
    print("Your total bill is:", basket[items][1])
    items=items+1

and this, also erroneous:

for i in len(basket):
    print("Your total bill is:", basket[i][1])

Error:

TypeError: 'int' object is not iterable

Both questions are linked, as they both pertain to the checkout() sub, in which the addition of all the currency variables in the basket list is the objective!

Body:
Q1:

Given that it is only for a basic teaching purpose, you could just strip out the pound sign (assuming consistent representation):

def extract_cost(money_in_pounds):
    return int(money_in_pounds[1:])

basket = [['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]
total_cost = 0
for items in basket:
    total_cost = total_cost + extract_cost(items[1])

print(total_cost)

Without writing another function

basket = [['Iphone', '£900'], ['Samsung', '£1020'], ['Toshiba', '£700']]
total_cost = 0
for items in basket:
    # items[1] selects the cost
    # items[1][1:] selects the sub-string of that cost from the 1st index to the end, i.e. remove the currency notation
    # int() then converts it into an integer
    cost_in_pounds = int(items[1][1:])
    total_cost = total_cost + cost_in_pounds

print(total_cost)

More concise code (Suggested by Jon Clements below)

total_cost = sum(int(cost[1:]) for item_name, cost in basket)

Q2:

items is not the index, it is the content of the list, so items itself is the inner list:

for items in basket:
    print("Your total bill is:", items[1])


来源: stackexchange

问:
Changing SelectedItem property of a ListView programatically
I have a 2 ListViews with same items in both of them. What I want to do is that when a selection is made in one ListView, the same selection should be reflected in the other ListView also. The two ListViews are bound to two different ViewModels but both the ViewModels implement the same interface.
I've overridden the Equals methods in both ViewModels.

The two ListViews are on different XAML pages. The first ListView say LV1 is in Page1.xaml and LV2 is in Page2.xaml. What I want is that when I am changing the selection in LV2 the selection in LV1 should also change( one way only ). I've set x:FieldModifier="public" on LV1 and exposing through a static property of Page1 like this:

```<code>public sealed partial class Page1 : Page
{
    public static Page1 page1 { get; private set; }
}
</code>```

And on Page2, I have this :

```<code>private async void LV2_ItemClick(object sender, ItemClickEventArgs e)
{
    var selected = e.ClickedItem as ISomeCommonInterface;
    //Comparision is successful --> Contains() always returns corect value;
    if (Page1.page1.LV1.Items.ToList().Contains(selected))
    {
        Page1.page1.LV1.SelectedItem = null; // this works
        Page1.page1.LV1.SelectedItem = selected; // this doesn't work
    }
}
</code>```

I've found that inside the if condition, assignment to null changes the SelectedItem of LV1 to null but the next line doesn't change it to selected ( it remains null ).

答:
Method 1 - SelectionMode="Multiple" - both ListViews in sync

You should subscribe the SelectionChanged event on both ListViews - item may not get selected only by click - and there (when selection is changed) you should sync the selection.

```<code>private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    ListView listViewToAdd = ReferenceEquals(sender, firstListView) ? secondListView : firstListView;

    foreach (var item in e.AddedItems)
    {
        if (!listViewToAdd.SelectedItems.Contains(item))
        {
            listViewToAdd.SelectedItems.Add(item);
        }
    }

    foreach (var item in e.RemovedItems)
    {
        listViewToAdd.SelectedItems.Remove(item);
    }
}
</code>```

Method 2 - SelectionMode="Multiple" - update one after selecting in the other

You should subscribe the SelectionChanged event only on the ListView where items could be selected.

```<code>private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    foreach (var item in e.AddedItems)
    {
        secondListView.SelectedItems.Add(item);
    }

    foreach (var item in e.RemovedItems)
    {
        secondListView.SelectedItems.Remove(item);
    }
}
</code>```

Method 3 - SelectionMode="Single"

Subscribe the SelectionChanged event on both if you want to make them be in sync or only on the selectable one if you only want to update the second based on the first.

```<code>private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    ListView senderListView = (ListView)sender;
    ListView listViewToAdd = ReferenceEquals(sender, firstListView) ? secondListView : firstListView;
    listViewToAdd.SelectedItem = senderListView.SelectedItem;
}
</code>```

You may need to replace var with your interface to make it work.

ContentLicense: CC BY-SA 3.0

Body:
I have a 2 ListViews with same items in both of them. What I want to do is that when a selection is made in one ListView, the same selection should be reflected in the other ListView also. The two ListViews are bound to two different ViewModels but both the ViewModels implement the same interface.
I've overridden the Equals methods in both ViewModels.

The two ListViews are on different XAML pages. The first ListView say LV1 is in Page1.xaml and LV2 is in Page2.xaml. What I want is that when I am changing the selection in LV2 the selection in LV1 should also change( one way only ). I've set x:FieldModifier="public" on LV1 and exposing through a static property of Page1 like this:

public sealed partial class Page1 : Page
{
    public static Page1 page1 { get; private set; }
}

And on Page2, I have this :

private async void LV2_ItemClick(object sender, ItemClickEventArgs e)
{
    var selected = e.ClickedItem as ISomeCommonInterface;
    //Comparision is successful --> Contains() always returns corect value;
    if (Page1.page1.LV1.Items.ToList().Contains(selected))
    {
        Page1.page1.LV1.SelectedItem = null; // this works
        Page1.page1.LV1.SelectedItem = selected; // this doesn't work
    }
}

I've found that inside the if condition, assignment to null changes the SelectedItem of LV1 to null but the next line doesn't change it to selected ( it remains null ).

Body:
Method 1 - SelectionMode="Multiple" - both ListViews in sync

You should subscribe the SelectionChanged event on both ListViews - item may not get selected only by click - and there (when selection is changed) you should sync the selection.

private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    ListView listViewToAdd = ReferenceEquals(sender, firstListView) ? secondListView : firstListView;

    foreach (var item in e.AddedItems)
    {
        if (!listViewToAdd.SelectedItems.Contains(item))
        {
            listViewToAdd.SelectedItems.Add(item);
        }
    }

    foreach (var item in e.RemovedItems)
    {
        listViewToAdd.SelectedItems.Remove(item);
    }
}

Method 2 - SelectionMode="Multiple" - update one after selecting in the other

You should subscribe the SelectionChanged event only on the ListView where items could be selected.

private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    foreach (var item in e.AddedItems)
    {
        secondListView.SelectedItems.Add(item);
    }

    foreach (var item in e.RemovedItems)
    {
        secondListView.SelectedItems.Remove(item);
    }
}

Method 3 - SelectionMode="Single"

Subscribe the SelectionChanged event on both if you want to make them be in sync or only on the selectable one if you only want to update the second based on the first.

private void SyncSelection(object sender, SelectionChangedEventArgs e)
{
    ListView senderListView = (ListView)sender;
    ListView listViewToAdd = ReferenceEquals(sender, firstListView) ? secondListView : firstListView;
    listViewToAdd.SelectedItem = senderListView.SelectedItem;
}

You may need to replace var with your interface to make it work.


问:
Trouble getting a .NET Publisher Policy Assembly to work
I created fresh projects for this as a proof of concept but I cannot get it to work.

I created a ClassLibrary1.dll with a simple method in it, at version 1.0.0.0.
I created a WindowsFormsApplication1 that calls that method, also at version 1.0.0.0.
I created associated setup projects for each solution and installed the MSIs. Everything good so far.

Then, I incremented all the version numbers of ClassLibrary1 to 1.0.1.0.
I created a config file to redirect to the new version:

```<code><?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

    <dependentAssembly>
        <assemblyIdentity name="ClassLibrary1" publicKeyToken="99e3abf647b4f724" culture="neutral" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="1.0.1.0"/>
      </dependentAssembly>

      </assemblyBinding>
  </runtime>
</configuration>
</code>```

I used that to create a policy.1.0.ClassLibrary1.dll publisher policy with this command:

```<code>al /embed:ClassLibrary1.dll.config /out:Policy.1.0.ClassLibrary1.dll /keyfile:TestKey.snk /platform:anycpu /v:1.0.1.0
</code>```

I inserted that into the GAC, both using the setup program, and manually after the DLL was installed by the setup program. Both ways the result is the same:
A gacutil /l policy.1.0.ClassLibrary1 returns one instance of the policy in the GAC, but running the program fails to use the new version.

```<code>C:\Program Files (x86)\Liberty Testing\ClassLibrary1>gacutil /l Policy.1.0.ClassLibrary1
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

The Global Assembly Cache contains the following assemblies:
  Policy.1.0.ClassLibrary1, Version=1.0.1.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724, processorArchitecture=MSIL

Number of items = 1
</code>```

Though, I would note that manually looking in C:\Windows\Assembly does not show that the policy assembly exists anywhere in that subtree.
I uninstalled all the libraries and reinstalled just the new version, and the program now crashes instead of using the new DLL.
The fuslogvw output looks like this:

```<code>*** Assembly Binder Log Entry  (6/26/2017 @ 2:31:59 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable  C:\Program Files (x86)\Liberty Testing\Test Form\WindowsFormsApplication1.exe
--- A detailed error log follows.

=== Pre-bind state information ===
LOG: User = DOMAIN\user
LOG: DisplayName = ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Liberty Testing/Test Form/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : WindowsFormsApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).
</code>```

It does not appear to be looking at for a publisher policy at all.
We have spent days trying to figure out what we are doing wrong. Does anyone else have any ideas?

答:
It turns out the trouble was because we were running the al.exe command when the working directory was on a mapped drive.

We have our Visual Studio project folders on a network share, and set up the Visual Studio command prompt to use pushd to automatically map a drive. No errors were generated during the whole process, but the policy config was not being installed because of the map drive.

We copied one of the folders locally and went through the process with positive results.

Since we don't want the project folders to be local, we resolved the issue by instead using powershell, which natively supports UNC paths as working directories, and everything works.

I created a guide to help anyone else trying to do this. It doesn't address the UNC issue, but it seems not many people do that.

Creating a Publisher Policy Assembly for Custom Libraries

Body:
I created fresh projects for this as a proof of concept but I cannot get it to work.

I created a ClassLibrary1.dll with a simple method in it, at version 1.0.0.0.
I created a WindowsFormsApplication1 that calls that method, also at version 1.0.0.0.
I created associated setup projects for each solution and installed the MSIs. Everything good so far.

Then, I incremented all the version numbers of ClassLibrary1 to 1.0.1.0.
I created a config file to redirect to the new version:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

    <dependentAssembly>
        <assemblyIdentity name="ClassLibrary1" publicKeyToken="99e3abf647b4f724" culture="neutral" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="1.0.1.0"/>
      </dependentAssembly>

      </assemblyBinding>
  </runtime>
</configuration>

I used that to create a policy.1.0.ClassLibrary1.dll publisher policy with this command:

al /embed:ClassLibrary1.dll.config /out:Policy.1.0.ClassLibrary1.dll /keyfile:TestKey.snk /platform:anycpu /v:1.0.1.0

I inserted that into the GAC, both using the setup program, and manually after the DLL was installed by the setup program. Both ways the result is the same:
A gacutil /l policy.1.0.ClassLibrary1 returns one instance of the policy in the GAC, but running the program fails to use the new version.

C:\Program Files (x86)\Liberty Testing\ClassLibrary1>gacutil /l Policy.1.0.ClassLibrary1
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

The Global Assembly Cache contains the following assemblies:
  Policy.1.0.ClassLibrary1, Version=1.0.1.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724, processorArchitecture=MSIL

Number of items = 1

Though, I would note that manually looking in C:\Windows\Assembly does not show that the policy assembly exists anywhere in that subtree.
I uninstalled all the libraries and reinstalled just the new version, and the program now crashes instead of using the new DLL.
The fuslogvw output looks like this:

*** Assembly Binder Log Entry  (6/26/2017 @ 2:31:59 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable  C:\Program Files (x86)\Liberty Testing\Test Form\WindowsFormsApplication1.exe
--- A detailed error log follows.

=== Pre-bind state information ===
LOG: User = DOMAIN\user
LOG: DisplayName = ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Liberty Testing/Test Form/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : WindowsFormsApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=99e3abf647b4f724
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

It does not appear to be looking at for a publisher policy at all.
We have spent days trying to figure out what we are doing wrong. Does anyone else have any ideas?


问:
How to pass file pointers in Python
I have this situation in a certain class -

```<code>def f1(self, xxx):
    do stuff with lines from file

def f0(self, filename):
    with open(filename) as fp:
        for lineContent in fp:
            if re.match(lineContent):
                do stuff with next 100+ lines from file
                continue
            else:
                do other stuff while parsing lines
</code>```

The question: What is the best way to use the function f1(...)?

Option 1: Capture lines in an array until there is a sentinel, and then pass this array as the xxx argument for f1().

Option 2: Embed the code contents of f1() into f0(). This also works, but f0() becomes very large and difficult to read.

Looking for: Some way to call f1() with the file pointer, so the method can read/process lines, watch for the sentinel and return control to f0() after it is done.

The perl equivalent code (for what I am looking for) would be:

```<code>sub f1 { ... }
sub f0 { ...
    while (<$fp>) {
        f1($fp) if /$re2match/;
        continue with other stuff
    }
}
</code>```

Thank you for helping out a novice pythonian.

答:
```<code>def f1(self, filepointer):
    for _, line in zip(range(100), filepointer):
        # do stuff with the line

def f0(self, filename):
    with open(filename) as infile:
        for lineContent in infile:
            if re.match(lineContent):
                f1(infile)  # only works because of the way file iterators are set up. Otherwise, that for-loop's scoping iterator will bork you here
                # that continue is unnecessary here
            else:
                # do other stuff while parsing lines
</code>```

UPDATE: Clarification based on comments

zip is a function that takes multiple iterables (like lists, files, dictionaries, etc) and returns a single iterable of tuples, where the i-th element of each tuple comes from the i-th iterable inputted to zip. zip also terminates when the smallest of the iterables is exhausted. So, check this out:

```<code>In [14]: for t in zip('asdf', '1234'): print(t)

('a', '1')
('s', '2')
('d', '3')
('f', '4')

In [15]: for t in zip('asdf', '123'): print(t)
('a', '1')
('s', '2')
('d', '3')
</code>```

Since you asked to process the next 100 lines, range(100) seemed to be the ideal tool. for _, line in ... is similar to saying for a, line in ..., it's just that the underscore is used to denote a variable that we don't want to keep track of (try printing _ to see what its value is in each iteration of that loop).

If you don't know the exact count of how many lines to process, this is a wrong solution for you.

Title: How to pass file pointers in Python

Body:
I have this situation in a certain class -

def f1(self, xxx):
    do stuff with lines from file

def f0(self, filename):
    with open(filename) as fp:
        for lineContent in fp:
            if re.match(lineContent):
                do stuff with next 100+ lines from file
                continue
            else:
                do other stuff while parsing lines

The question: What is the best way to use the function f1(...)?

Option 1: Capture lines in an array until there is a sentinel, and then pass this array as the xxx argument for f1().

Option 2: Embed the code contents of f1() into f0(). This also works, but f0() becomes very large and difficult to read.

Looking for: Some way to call f1() with the file pointer, so the method can read/process lines, watch for the sentinel and return control to f0() after it is done.

The perl equivalent code (for what I am looking for) would be:

sub f1 { ... }
sub f0 { ...
    while (<$fp>) {
        f1($fp) if /$re2match/;
        continue with other stuff
    }
}

Thank you for helping out a novice pythonian.

Body:
def f1(self, filepointer):
    for _, line in zip(range(100), filepointer):
        # do stuff with the line

def f0(self, filename):
    with open(filename) as infile:
        for lineContent in infile:
            if re.match(lineContent):
                f1(infile)  # only works because of the way file iterators are set up. Otherwise, that for-loop's scoping iterator will bork you here
                # that continue is unnecessary here
            else:
                # do other stuff while parsing lines

UPDATE: Clarification based on comments

zip is a function that takes multiple iterables (like lists, files, dictionaries, etc) and returns a single iterable of tuples, where the i-th element of each tuple comes from the i-th iterable inputted to zip. zip also terminates when the smallest of the iterables is exhausted. So, check this out:

In [14]: for t in zip('asdf', '1234'): print(t)

('a', '1')
('s', '2')
('d', '3')
('f', '4')

In [15]: for t in zip('asdf', '123'): print(t)
('a', '1')
('s', '2')
('d', '3')

Since you asked to process the next 100 lines, range(100) seemed to be the ideal tool. for _, line in ... is similar to saying for a, line in ..., it's just that the underscore is used to denote a variable that we don't want to keep track of (try printing _ to see what its value is in each iteration of that loop).

If you don't know the exact count of how many lines to process, this is a wrong solution for you.


问:
Issues using setSupportActionBar() + android.support.v7.widget.Toolbar
I have experiencing some issues using the android.support.v7.widget.Toolbar and have been pulling my hair out for several days trying to get this working.

Specifically, I cannot modify the title or load menu items into the app/action bar.

Any help that you can provide would be most appreciated!  Otherwise, I am going to chunk all of this and try to build a custom application toolbar with dedicated text icons.  If this is the right approach, let me know!  Thanks!

I believe that I building the toolbar correctly, but when I attempt to update the title, nothing happens.  Furthermore, no menus are loaded via onOptionsItemSelected().  In fact, onOptionsItemSelected is not even called.

compileSdkVersion 25

buildToolsVersion '25.0.3'

minSdkVersion 21

targetSdkVersion 25

Interestingly enough, if I place the same setSupportActionBar() related code into the onOptionsItemSelected() method, it works.  Of course, that assumes that you have menu key to hit, since I have not seen how to call onOptionsItemSelected() on some handsets without a menu key.

I have tested it using both the emulated Nexus 6 API 25 built-into Android Studio and a Samsung Galaxy S6 API 22 via Genymotion.

Same results.

toolbar_main.xml

```<code>android.support.v7.widget.Toolbar
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:minHeight="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:titleTextColor="@color/White"
  android:elevation="4dp"
  android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
  app:popupTheme="@style/ThemeOverlay.AppCompat"
  app:titleTextAppearance="@style/Toolbar.TitleText"
  app:layout_collapseMode="pin">
</code>```

activity_main.xml

```<code>    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:fitsSystemWindows="true"
              android:background="@color/Black"
              android:orientation="vertical">

   <include
         android:id="@+id/main_custom_toolbar"
         layout="@layout/toolbar_main"/>

   <TextView
         android:id="@+id/test_header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@color/Black"
         android:layout_marginTop="15sp"
         android:gravity="center"
         android:text="HoneyDo Tasks"
         android:textColor="@color/Yellow"
         android:textSize="30dp"
         android:textStyle="bold">
   </TextView>
</LinearLayout>
</code>```

MainActivity.java

```<code>  @Override
   protected void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

      Toolbar toolbar = (Toolbar) findViewById(R.id.main_custom_toolbar);
      setSupportActionBar(toolbar);
      getSupportActionBar().setTitle("New Title");
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu)
   {
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return super.onCreateOptionsMenu(menu);
   }
</code>```

答:
I am giving you minimal code that works for me:

xml:

```<code><android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>
</code>```

You can skip AppBarLayout and only use ToolBar

Also make changes in your AndroidManifest:

```<code><activity
        android:name="YourActivityName"
        android:theme="@style/AppTheme.NoActionBar"></activity>
</code>```

and in your styles.xml:

```<code> <style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>
</code>```

Body:
I have experiencing some issues using the android.support.v7.widget.Toolbar and have been pulling my hair out for several days trying to get this working.

Specifically, I cannot modify the title or load menu items into the app/action bar.

Any help that you can provide would be most appreciated!  Otherwise, I am going to chunk all of this and try to build a custom application toolbar with dedicated text icons.  If this is the right approach, let me know!  Thanks!

I believe that I building the toolbar correctly, but when I attempt to update the title, nothing happens.  Furthermore, no menus are loaded via onOptionsItemSelected().  In fact, onOptionsItemSelected is not even called.

compileSdkVersion 25

buildToolsVersion '25.0.3'

minSdkVersion 21

targetSdkVersion 25

Interestingly enough, if I place the same setSupportActionBar() related code into the onOptionsItemSelected() method, it works.  Of course, that assumes that you have menu key to hit, since I have not seen how to call onOptionsItemSelected() on some handsets without a menu key.

I have tested it using both the emulated Nexus 6 API 25 built-into Android Studio and a Samsung Galaxy S6 API 22 via Genymotion.

Same results.

toolbar_main.xml

android.support.v7.widget.Toolbar
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:minHeight="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:titleTextColor="@color/White"
  android:elevation="4dp"
  android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
  app:popupTheme="@style/ThemeOverlay.AppCompat"
  app:titleTextAppearance="@style/Toolbar.TitleText"
  app:layout_collapseMode="pin">

activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:fitsSystemWindows="true"
              android:background="@color/Black"
              android:orientation="vertical">

   <include
         android:id="@+id/main_custom_toolbar"
         layout="@layout/toolbar_main"/>

   <TextView
         android:id="@+id/test_header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@color/Black"
         android:layout_marginTop="15sp"
         android:gravity="center"
         android:text="HoneyDo Tasks"
         android:textColor="@color/Yellow"
         android:textSize="30dp"
         android:textStyle="bold">
   </TextView>
</LinearLayout>

MainActivity.java

  @Override
   protected void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

      Toolbar toolbar = (Toolbar) findViewById(R.id.main_custom_toolbar);
      setSupportActionBar(toolbar);
      getSupportActionBar().setTitle("New Title");
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu)
   {
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return super.onCreateOptionsMenu(menu);
   }

Body:
I am giving you minimal code that works for me:

xml:

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

You can skip AppBarLayout and only use ToolBar

Also make changes in your AndroidManifest:

<activity
        android:name="YourActivityName"
        android:theme="@style/AppTheme.NoActionBar"></activity>

and in your styles.xml:

 <style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>


问:
Wix throws away components that are marked as NeverOverWrite="yes"
I've created an installer that upgrades our software, but for some reason the XML configuration files (those of our software) are removed when upgrading.

This appears to happen if all features of the software are upgraded.
Our software is an archive type thing. If I install just that feature and upgrade it everything is fine.

However, if I install all services accompanying the archive and upgrade those then all configuration files (and each is in a different folder!) are gone.

As an example:

```<code><ComponentGroup Id="AutoArchiveTool" Directory="AutoArchiverFolder">
     <Component Id="C_AutoArchivingTool_Gateway_exe_config" NeverOverwrite="yes" Guid="{A62D5200-FDE0-4DA1-A04A-7FBDACEA83B2}">
       <File Id="F_AutoArchivingTool_Gateway_exe_config" Source="$(var.Gateway.TargetDir)Gateway.exe.config" KeyPath="yes"/>
     </Component>
... more script
</ComponentGroup>
</code>```

If you log the installer you can even see that it's recognized as "never overwrite":

```<code>Disallowing installation of component: {A62D5200-FDE0-4DA1-A04A-7FBDACEA83B2} since the keyfile exists and the component is marked to never overwrite existing installations
</code>```

Yet it's gone after the upgrade. What am I missing?
I've see the "Permanent" property, but that's not what I want. I want the installer to leave the config files alone during an upgrade. Not leave them (config files) after removal.

答:
NeverOverwrite does not mean "don't uninstall" so:

a) if the component ID changes between the original install and the new one the sharing won't work as you intend and the ref count will decrement and the file will be removed, this being when the upgrade is scheduled "late", such as afterInstallExecute.

b) If the upgrade is scheduled early (such as afterInstallInitialize) all the old product is uninstalled first, then the new product is installed. You haven't said where your upgrade is sequenced, but sometimes Windows Installer screws up in an "early" upgrade: it decides that the file won't be overwritten, but fails to re-evaluate this when the install turns out to be an upgrade. In this case your upgrade will complete and the file will be missing. If you have this issue then a repair of the product will restore the file from the new version of the product (because that is the current owner of the component). This won't help.

So make sure that the component ID didn't change and your upgrade is scheduled late, such as afterInstallExecute. In addition, do the upgrade with verbose logging to verify what's going on.

Having said all that, NeverOverwrite is often used to solve a problem that doesn't exist. The file overwrite rules (that are invoked by a "late" upgrade) say that modified files won't be overwritten:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx

So if the first setup installs the file, then it gets updated by the app, then your upgrade runs it will not replace the modified file anyway, and there is no need to set NeverOverwrite.

Body:
I've created an installer that upgrades our software, but for some reason the XML configuration files (those of our software) are removed when upgrading.

This appears to happen if all features of the software are upgraded.
Our software is an archive type thing. If I install just that feature and upgrade it everything is fine.

However, if I install all services accompanying the archive and upgrade those then all configuration files (and each is in a different folder!) are gone.

As an example:

<ComponentGroup Id="AutoArchiveTool" Directory="AutoArchiverFolder">
     <Component Id="C_AutoArchivingTool_Gateway_exe_config" NeverOverwrite="yes" Guid="{A62D5200-FDE0-4DA1-A04A-7FBDACEA83B2}">
       <File Id="F_AutoArchivingTool_Gateway_exe_config" Source="$(var.Gateway.TargetDir)Gateway.exe.config" KeyPath="yes"/>
     </Component>
... more script
</ComponentGroup>

If you log the installer you can even see that it's recognized as "never overwrite":

Disallowing installation of component: {A62D5200-FDE0-4DA1-A04A-7FBDACEA83B2} since the keyfile exists and the component is marked to never overwrite existing installations

Yet it's gone after the upgrade. What am I missing?
I've see the "Permanent" property, but that's not what I want. I want the installer to leave the config files alone during an upgrade. Not leave them (config files) after removal.


问:
SpringBoot web services multiple data sources only one working
I have developed two webservices using Spring Boot framework and I have them in the same project. Each webservice use a different DB, say ws1 uses Oracle1 and ws2 uses Oracle2. I have defined a DataBaseConfig with the beans definition but when I run the app, always works one webservice ( and it's always the same ).

DataBaseConfig

```<code>@Configuration
public class DataBaseConfig {
@Bean(name = "ora1")
@ConfigurationProperties(prefix="spring.datasource")
public DataSource mysqlDataSource() {
    return DataSourceBuilder.create().build();}

@Bean(name = "ora2")
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource sqliteDataSource() {
    return DataSourceBuilder.create().build();}

 @Bean(name = "clients")
    @Autowired
    @ConfigurationProperties(prefix = "spring.datasource")
    @Qualifier("datasource")
    public JdbcTemplate slaveJdbcTemplate(DataSource datasource) {
        return new JdbcTemplate(datasource); }

    @Bean(name = "places")
    @Autowired
     @Primary
        @ConfigurationProperties(prefix = "spring.secondDatasource")
     @Qualifier("secondDatasource")
    public JdbcTemplate masterJdbcTemplate(DataSource secondDatasource) {
        return new JdbcTemplate(secondDatasource);}
}
</code>```

I have the services definition with the sql statements and the definition

```<code>@Service
public class ClientsService {

@Autowired
@Qualifier("clients")
private JdbcTemplate jdbcTemplate;
</code>```

and the other service

```<code>@Service
public class PlacesService {

@Autowired
@Qualifier("places")
private JdbcTemplate jdbcTemplate;
</code>```

Then in each controller I have de mapping @RequestMapping. When I run the app I have no connection-related errors and if I separate the webservices in 2 projects, each works fine.

答:
Instead of resolving by bean name, which is a bad idea IMO because it's not typesafe, why don't you use constructor injection and create the services in the configuration class (ditch @Service annotation). Create the DataSource and JdbcTemplate beans as usual, don't give them any names (the default is the method name), and also create new PlacesService(placesJdbcTemplate()). The result is a lot simpler code.

This is assuming you want both databases active at runtime. If not, use @Profile.

Body:
I have developed two webservices using Spring Boot framework and I have them in the same project. Each webservice use a different DB, say ws1 uses Oracle1 and ws2 uses Oracle2. I have defined a DataBaseConfig with the beans definition but when I run the app, always works one webservice ( and it's always the same ).

DataBaseConfig

@Configuration
public class DataBaseConfig {
@Bean(name = "ora1")
@ConfigurationProperties(prefix="spring.datasource")
public DataSource mysqlDataSource() {
    return DataSourceBuilder.create().build();}

@Bean(name = "ora2")
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource sqliteDataSource() {
    return DataSourceBuilder.create().build();}

 @Bean(name = "clients")
    @Autowired
    @ConfigurationProperties(prefix = "spring.datasource")
    @Qualifier("datasource")
    public JdbcTemplate slaveJdbcTemplate(DataSource datasource) {
        return new JdbcTemplate(datasource); }

    @Bean(name = "places")
    @Autowired
     @Primary
        @ConfigurationProperties(prefix = "spring.secondDatasource")
     @Qualifier("secondDatasource")
    public JdbcTemplate masterJdbcTemplate(DataSource secondDatasource) {
        return new JdbcTemplate(secondDatasource);}
}

I have the services definition with the sql statements and the definition

@Service
public class ClientsService {

@Autowired
@Qualifier("clients")
private JdbcTemplate jdbcTemplate;

and the other service

@Service
public class PlacesService {

@Autowired
@Qualifier("places")
private JdbcTemplate jdbcTemplate;

Then in each controller I have de mapping @RequestMapping. When I run the app I have no connection-related errors and if I separate the webservices in 2 projects, each works fine.


问:
ClosedXML New Workbook Styles All Sheets
I just got started with ClosedXML. When I create a new workbook with the code below, it automatically applies "Blue, Table Style Light 9" to each worksheet. I don't want any style on the worksheets.  How do I specify no style?

```<code>XLWorkbook wb = new XLWorkbook();
wb.Worksheets.Add(dt, "sheet1");
</code>```

I'm just basically filling the sheet with a SQL datatable.

答:
XLWorkbook and XLWorksheet both have a Style property. You can modify the style like so:

```<code>var workbook = new XLWorkbook();
var ws = workbook.Worksheets.Add("Style Worksheet");

ws.Style.Font.Bold = true;
ws.Style.Font.FontColor = XLColor.Red;
ws.Style.Fill.BackgroundColor = XLColor.Cyan;
</code>```

See here for the documentation: https://github.com/ClosedXML/ClosedXML/wiki/Using-Default-Styles

Body:
I just got started with ClosedXML. When I create a new workbook with the code below, it automatically applies "Blue, Table Style Light 9" to each worksheet. I don't want any style on the worksheets.  How do I specify no style?

XLWorkbook wb = new XLWorkbook();
wb.Worksheets.Add(dt, "sheet1");

I'm just basically filling the sheet with a SQL datatable.

Body:
XLWorkbook and XLWorksheet both have a Style property. You can modify the style like so:

var workbook = new XLWorkbook();
var ws = workbook.Worksheets.Add("Style Worksheet");

ws.Style.Font.Bold = true;
ws.Style.Font.FontColor = XLColor.Red;
ws.Style.Fill.BackgroundColor = XLColor.Cyan;

See here for the documentation: https://github.com/ClosedXML/ClosedXML/wiki/Using-Default-Styles


问:
Mapping Django URLs in JQuery append()
I am appending an anchor tag dynamically after an AJAX call completes, but I'm not able to set the href attribute of it as a Django URL. Here's my code:

```<code>$maincontent.append("<a id='resultslink'>Get results here</a>");
$('#resultslink').attr('href', "{% url 'results' %}");
</code>```

Django gives the following error -

```<code>The current path, InitialWebApp/hdfs/{%, didn't match any of these.
</code>```

Apparently, Django thinks {% is the href value.

答:
To resolve the url using the url template tag requires that the template be rendered again which doesn't happen after your AJAX call.

You can either hardcode the url or have the resolved url returned as part of the payload from the server for each AJAX call.

Title: Mapping Django URLs in JQuery append()

Body:
I am appending an anchor tag dynamically after an AJAX call completes, but I'm not able to set the href attribute of it as a Django URL. Here's my code:

$maincontent.append("Get results here");
$('#resultslink').attr('href', "{% url 'results' %}");

Django gives the following error -

The current path, InitialWebApp/hdfs/{%, didn't match any of these.

Apparently, Django thinks {% is the href value.


问:
Why does Order Matter for the Equality Operator ("==") in Bash with Double Brackets ("[[")?
The following command works as I'd expected, printing out "huh?":

```<code>$ if [[ "odd behavior" == *odd* ]]; then echo "huh?"; fi
huh?
</code>```

But if I switch the order of the operands, nothing is printed out:

```<code>$ if [[ *odd* == "odd behavior" ]]; then echo "huh?"; fi
<no output>
</code>```

This seems counter-intuitive to me. Can somebody explain why the behavior is different?

答:
The right argument is treated specially, it can be a wildcard pattern, but the left argument can't be. From the manual:

When the ‘==’ and ‘!=’ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob shell option were enabled. The ‘=’ operator is identical to ‘==’. If the nocasematch shell option (see the description of shopt in The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (‘==’) or does not match (‘!=’)the pattern, and 1 otherwise. Any part of the pattern may be quoted to force the quoted portion to be matched as a string.

Body:
The following command works as I'd expected, printing out "huh?":

$ if [[ "odd behavior" == *odd* ]]; then echo "huh?"; fi
huh?

But if I switch the order of the operands, nothing is printed out:

$ if [[ *odd* == "odd behavior" ]]; then echo "huh?"; fi
<no output>

This seems counter-intuitive to me. Can somebody explain why the behavior is different?


问:
Using Python's reduce() to join multiple PySpark DataFrames
Does anyone know why using Python3's functools.reduce() would lead to worse performance when joining multiple PySpark DataFrames than just iteratively joining the same DataFrames using a for loop? Specifically, this gives a massive slowdown followed by an out-of-memory error:

```<code>def join_dataframes(list_of_join_columns, left_df, right_df):
    return left_df.join(right_df, on=list_of_join_columns)

joined_df = functools.reduce(
    functools.partial(join_dataframes, list_of_join_columns), list_of_dataframes,
)
</code>```

whereas this one doesn't:

```<code>joined_df = list_of_dataframes[0]
joined_df.cache()
for right_df in list_of_dataframes[1:]:
    joined_df = joined_df.join(right_df, on=list_of_join_columns)
</code>```

Any ideas would be greatly appreciated. Thanks!

答:
One reason is that a reduce or a fold is usually functionally pure: the result of each accumulation operation is not written to the same part of memory, but rather to a new block of memory.

In principle the garbage collector could free the previous block after each accumulation, but if it doesn't you'll allocate memory for each updated version of the accumulator.

Body:
Does anyone know why using Python3's functools.reduce() would lead to worse performance when joining multiple PySpark DataFrames than just iteratively joining the same DataFrames using a for loop? Specifically, this gives a massive slowdown followed by an out-of-memory error:

def join_dataframes(list_of_join_columns, left_df, right_df):
    return left_df.join(right_df, on=list_of_join_columns)

joined_df = functools.reduce(
    functools.partial(join_dataframes, list_of_join_columns), list_of_dataframes,
)

whereas this one doesn't:

joined_df = list_of_dataframes[0]
joined_df.cache()
for right_df in list_of_dataframes[1:]:
    joined_df = joined_df.join(right_df, on=list_of_join_columns)

Any ideas would be greatly appreciated. Thanks!


问:
How to extend inner nested objects into multiple objects
In Node.js, I want to convert to extend the nested objects into an array, details as follwing:

```<code> {
"topic":"myTopic",
"content":{
    "name": {
        "tom1" : {
            "value": "String",
        },
        "tom2" : {
            "value": "String",
        },
        "tom3" : {
            "value": "String",
        }
    }
}
}
</code>```

convert and extend to following format

```<code>[{
"topic":"myTopic",
"content":{
    "name": {
        "tom1" : {
            "value": "String",
        }
    }
}
},

{
"topic":"myTopic",
"content":{
    "name": {
        "tom2" : {
            "value": "String",
        }
    }
 }
 },
{
"topic":"myTopic",
"content":{
    "name": {
        "tom3" : {
            "value": "String",
        }
    }
}
}]
</code>```

答:
You can try something like :

```<code>var result = []; // contains the array you're looking for
var test = { "topic":"myTopic", "content":{ "name": { "tom1" : { "value": "String", }, "tom2" : { "value": "String", }, "tom3" : { "value": "String", } } } };
Object.keys(test.content.name).map((e,i) => {
    let temp = {};
    temp[e] = test.content.name[e];
    result.push({topic: test.topic, content: { name: temp }});
});
</code>```

Does this help you ?

Body:
In Node.js, I want to convert to extend the nested objects into an array, details as follwing:

 {
"topic":"myTopic",
"content":{
    "name": {
        "tom1" : {
            "value": "String",
        },
        "tom2" : {
            "value": "String",
        },
        "tom3" : {
            "value": "String",
        }
    }
}
}

convert and extend to following format

[{
"topic":"myTopic",
"content":{
    "name": {
        "tom1" : {
            "value": "String",
        }
    }
}
},

{
"topic":"myTopic",
"content":{
    "name": {
        "tom2" : {
            "value": "String",
        }
    }
 }
 },
{
"topic":"myTopic",
"content":{
    "name": {
        "tom3" : {
            "value": "String",
        }
    }
}
}]

Body:
You can try something like :

var result = []; // contains the array you're looking for
var test = { "topic":"myTopic", "content":{ "name": { "tom1" : { "value": "String", }, "tom2" : { "value": "String", }, "tom3" : { "value": "String", } } } };
Object.keys(test.content.name).map((e,i) => {
    let temp = {};
    temp[e] = test.content.name[e];
    result.push({topic: test.topic, content: { name: temp }});
});

Does this help you ?


问:
How can I keep my model files from being refreshed when doing an "Update Model from Database"?
I have a project that uses Entity Framework Database First style development. I made some changes to various Model files, and now every time I do an "Update Model from Database" on my EDMX file, those changes get wiped out. I see there is a tab for Refresh and it has my model files listed, but there is no way to tell VS to not refresh these files. What should I do here? Thanks.</p>

答:
Depends on what you changed. If you made changes in the edmx model they will be overwritten every time you re-generate your model.

If you made changes in the generated poco-classes it depends.
Poco's are generated as partial classes. Just create a sub folder and extend your poco's in a separate file with the same class signature.

Same applies to the model context class (yourModelName.Context.cs).  Changes should also be done in a separate file.

Maybe you should try 'Code First from database'. This generates a Fluent model which is much easier to change to your particular needs. No graphic representation of the model though.


问:
How to generate a non-.NET Core Library NuGet package within Visual Studio 2017
If I create a .NET Core Class Library in Visual Studio 2017, I get the Package tab on project properties.  If I create an "old fashioned" Class Library, I do not get the Package tab, nor the "Pack" target in MSBuild.

NuGet is integrated into VS2017 and MSBuild to some degree, but it seems to be only for .NET Core projects.

Is there a way to use any of the NuGet integration for non-.NET Core projects or do I just need to install the NuGet CLI and use a .nuspec file?

答:
This support for integrated packaging needs "SDK-style" csproj files which are used for .NET Core and .NET Standard projects. Since a few features (like some designers) aren't yet available for these projects, there are no templates for "SDK-style" csproj-based projects for .NET Standard.

However, you can create a .NET Standard project and change the csproj file from

```<code><TargetFramework>netstandard1.6</TargetFramework>
</code>```

to a net* moniker like

```<code><TargetFramework>net461</TargetFramework>
</code>```

This gives you all the tooling for creating NuGet packages and managing versions and metadata.

Body:
This support for integrated packaging needs "SDK-style" csproj files which are used for .NET Core and .NET Standard projects. Since a few features (like some designers) aren't yet available for these projects, there are no templates for "SDK-style" csproj-based projects for .NET Standard.

However, you can create a .NET Standard project and change the csproj file from

<TargetFramework>netstandard1.6</TargetFramework>

to a net* moniker like

<TargetFramework>net461</TargetFramework>

This gives you all the tooling for creating NuGet packages and managing versions and metadata.


问:
Connecting nearby coordinates from list of coordinates
I have the following list of latitudes and longitudes.

[(52.5, 12.0), (36.0, -0.5), (50.0, -17.5), (52.0, 13.0), (52.0, 13.0), (50.0, -16.5), (37.5, 1.5), (37.5, 1.5), (46.0, 20.0), (37.5, 1.5), (46.0, 20.0), (50.0, -15.0)]

I wish to connect only the points that are near each other. I would like to also only connect if the index difference between each point is less than 5 (for example).

I was initially looking for a method of connecting all points only if the line drawn is under a certain length. Not sure if this is possible in python?

Many thanks in advance.

答:
This assumes indexes wrap and that 'near' is defined as 1 units. For each element in the list, performs a distance check on the 10 surrounding elements, and if they are within 1 of each other, adds to a dictionary.

```<code>nearby = {}                                                          # This will hold 'connected' elements
for index, element in enumerate(l):                                  # Enumerate through the list l, keeping track of index
    for other in l[index-5: index+5]:                                # For each element 5 before and 5 after
        if sum( (a - b)**2 for a, b in zip(element, other))**.5 < 1 and element != other:
                                                                     # If other < 5 away from element and other not element
            if element not in nearby.keys():                         # If element isn't already in the dicitonary
                nearby[element] = [other]                            # Add it and reference other
            else:                                                    # Otherwise
                nearby[element].append(other)                        # Add other to the list of nearby elements
</code>```

If indexes don't wrap you can change the line for other in l[index-5: index+5]: to include checks for the beginning and end of the list. Here's how I would do it:

```<code>for other in l[index-5 if index-5 > 0 else 0 : index+5 if index+5 < len(l) else len(l) -1]:
</code>```

This is quite long, so you may want to split this into several lines, but it does the trick as is.

Body:
This assumes indexes wrap and that 'near' is defined as 1 units. For each element in the list, performs a distance check on the 10 surrounding elements, and if they are within 1 of each other, adds to a dictionary.

nearby = {}                                                          # This will hold 'connected' elements
for index, element in enumerate(l):                                  # Enumerate through the list l, keeping track of index
    for other in l[index-5: index+5]:                                # For each element 5 before and 5 after
        if sum( (a - b)**2 for a, b in zip(element, other))**.5 < 1 and element != other:
                                                                     # If other < 5 away from element and other not element
            if element not in nearby.keys():                         # If element isn't already in the dicitonary
                nearby[element] = [other]                            # Add it and reference other
            else:                                                    # Otherwise
                nearby[element].append(other)                        # Add other to the list of nearby elements

If indexes don't wrap you can change the line for other in l[index-5: index+5]: to include checks for the beginning and end of the list. Here's how I would do it:

for other in l[index-5 if index-5 > 0 else 0 : index+5 if index+5 < len(l) else len(l) -1]:

This is quite long, so you may want to split this into several lines, but it does the trick as is.


问:
Angular2, "replace" scrollbar
I have an angular app with a scrollable sidenav.

This sidenav has the native ugly scrollbar. I want to replace this one with a styleable scrollbar.

Are there any good solutions for angular 2 which don't require jQuery?

Do I have to use an external JavaScript solution which doesn't rely on angular?

Thanks in advance!

PS: If important, I use Angular Material 2

PPS: I've already tried gemini-scrollbar, but this has broken the width of the sidenav and simplebar which has caused a ram overflow.

Edit:
I want to replase this ugly scrollbar:

答:
Try using the OVERVIEW EXAMPLE its better than Example tap section

this one:

Title: Angular2, "replace" scrollbar


问:
Change action of back bar button item
I want to be able to change the action of the back bar button item on a specific UIViewController in my navigation controller so that it pops to the root view controller. I've tried the following but they don't work:

```<code>let backButton = UIBarButtonItem(title: nil, style: .plain, target: self, action: #selector(back))
self.navigationItem.backBarButtonItem = backButton
</code>```

and

```<code>self.navigationItem.backBarButtonItem?.action = #selector(back)
</code>```

Any suggestions?

答:
You should use self.navigationItem.leftBarButtonItem = backButton

Good luck

Title: Change action of back bar button item

Body:
I want to be able to change the action of the back bar button item on a specific UIViewController in my navigation controller so that it pops to the root view controller. I've tried the following but they don't work:

let backButton = UIBarButtonItem(title: nil, style: .plain, target: self, action: #selector(back))
self.navigationItem.backBarButtonItem = backButton

and

self.navigationItem.backBarButtonItem?.action = #selector(back)

Any suggestions?


问:
Basic Webscraping with Python (Beautiful Soup & Requests)
So I've been working through Al Sweigart's online Automate The Boring Stuff With Python tutorials, and I've just got to the webscraping part. Here's my code with a description of what the program is supposed to do:

```<code>#! python3
# lucky.py - A small program that allows you to get search keywords from
# command line arguments, retrieve the search results page, and open
# a new browser tab for each result

# Steps:
# 1. Read the command line arguments from sys.argv
# 2. Fetch the search result page with the requests module
# 3. Find the links to each search result
# 4. Call the webbrowser.open() function to open the web browser

import sys, requests, bs4, webbrowser

# 1. Read the command line arguments from sys.argv

print('Googling...')

if len(sys.argv) > 1:
    search = ' '.join(sys.argv[1:])

url = "https://www.google.com/#q="

for i in range(len(search.split())):
    url += search.split()[i] + "+"

# 2. Fetch the search result page with the requests module

page = requests.get(url)

# 3. Find the links to each search result

soup = bs4.BeautifulSoup(page.text, 'lxml')
linkElems = soup.select('.r a')

# 4. Call the webbrowser.open() function to open the web browser

numOpen = min(5, len(linkElems))
for i in range(numOpen):
    webbrowser.open("http://google.com" + linkElems[i].get('href'))
</code>```

So the issue here is that when I check the length of linkElems, it's 0, meaning that the soup.select('.r a') command failed to aggregate the content defined under element  inside class=r (a class only used for search results in Google as can be seen when using the developer tools). As a result, no web pages of the search results open up in my browser.

I think the issue has something to do either with the HTML-parser not working correctly, or Google changing the way their HTML code works(?). Any insight into this issue would be greatly appreciated!

答: linkElems = soup.find_all('a',href=True) This returns all the relevant  tags and you can process the list to decide what to keep and what not to keep.

Body:
So I've been working through Al Sweigart's online Automate The Boring Stuff With Python tutorials, and I've just got to the webscraping part. Here's my code with a description of what the program is supposed to do:

#! python3
# lucky.py - A small program that allows you to get search keywords from
# command line arguments, retrieve the search results page, and open
# a new browser tab for each result

# Steps:
# 1. Read the command line arguments from sys.argv
# 2. Fetch the search result page with the requests module
# 3. Find the links to each search result
# 4. Call the webbrowser.open() function to open the web browser

import sys, requests, bs4, webbrowser

# 1. Read the command line arguments from sys.argv

print('Googling...')

if len(sys.argv) > 1:
    search = ' '.join(sys.argv[1:])

url = "https://www.google.com/#q="

for i in range(len(search.split())):
    url += search.split()[i] + "+"

# 2. Fetch the search result page with the requests module

page = requests.get(url)

# 3. Find the links to each search result

soup = bs4.BeautifulSoup(page.text, 'lxml')
linkElems = soup.select('.r a')

# 4. Call the webbrowser.open() function to open the web browser

numOpen = min(5, len(linkElems))
for i in range(numOpen):
    webbrowser.open("http://google.com" + linkElems[i].get('href'))

So the issue here is that when I check the length of linkElems, it's 0, meaning that the soup.select('.r a') command failed to aggregate the content defined under element  inside class=r (a class only used for search results in Google as can be seen when using the developer tools). As a result, no web pages of the search results open up in my browser.

I think the issue has something to do either with the HTML-parser not working correctly, or Google changing the way their HTML code works(?). Any insight into this issue would be greatly appreciated!

Body: linkElems = soup.find_all('a',href=True) This returns all the relevant <a> tags and you can process the list to decide what to keep and what not to keep.


问:
How to figure out a pod's namespace from within a pod?
My service X is running in a pod P with Namespace N. how do I find out namespace info from withing Service X using Kubernetes go client API?</p>

答:
I figured i can pass on pod, namespace and more using Environment variables while creating a new pod using go-client. The way to do it is by specifying environment variable key/val pair in PodSpec as below:

```<code>Env: []v1.EnvVar{
    {Name: "POD_NAME", Value: podname},
    {Name: "POD_NAMESPACE", Value: nsname},
},
</code>```

then from within a pod, i can read this env. variables using os package.

Body:
I figured i can pass on pod, namespace and more using Environment variables while creating a new pod using go-client. The way to do it is by specifying environment variable key/val pair in PodSpec as below:

Env: []v1.EnvVar{
    {Name: "POD_NAME", Value: podname},
    {Name: "POD_NAMESPACE", Value: nsname},
},

then from within a pod, i can read this env. variables using os package.


问:
Multi level cache access time
If there are 2 caches L1 and L2 where L1 is first level cache and L2 is lower level cache.
Suppose there is a miss in L1 and a hit in L2.
Now, do we need to bring the required block from L2 to L1 and then access the required byte from L1 or can we directly access the required byte from L2?

Average access time can be given as :- h1(t1) + (1-h1)(h2)(t1+t2) where

h1 : hit ratio of L1 cache,
t1  : access time of L1,
h2 : hit ratio of L2 cache ,
t2 : access time of L2.

答: We can access it directly from L2, but we will also bring it up into L1, so that next time it is accessed faster.</p>

Title: Multi level cache access time


问:
Showing a div and keep it show() if i clicked on it

$(document).ready(function() {
  $('#input').focusin(function() {
    if ($(this).val() != '') {
      $('#div').show();
    } else {
      $('#div').hide();
    }
    $('#input').keyup(function() {
      // If not empty value, show div
      if ($(this).val() != '') {
        $('#div').show();
      } else {
        $('#div').hide();
      }
    });
  });
  $('#input').focusout(function() {
    $('#div').hide();

  });

});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#div {
  display: none;
  position: absolute;
  bottom: 20px;
}</code>```

  href='website.com'>Link From AJAX
  href='website.com'>Link From AJAX
  href='website.com'>Link From AJAX

<input id='input' type='text'>```

In this jquery code, the #div shows when i type something inside the #input but if i tried to click on the #div it disappears and the link doesn't work,

How can i keep the #div shown if i clicked on #div or #input only, But anything outside will hide it as normal?

The Problem happens because of position: absolute; bottom 20px line in CSS.

Updated the code and suddenly it worked as intended after adding if statement after .focusin function, For previous error solution, remove the position and bottom in the CSS

答:
You could disable the effect of the focusout handler by the use of a flag:

var noHide = false;
$(document).ready(function() {
  $('#input').keyup(function() {
    // If not empty value, show div
    if ($(this).val() != '') {
      $('#div').show();
    } else {
      $('#div').hide();
    }
  });
  $('#div a').hover(
    function() { noHide = true; },
    function() { noHide = false; $('#input').focus(); }
  );
  $('#input').focusout(function() {
    if(!noHide) {
      $('#div').hide();
    }
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#div {
  display: none;
}</code>```

   HellWorld

<input id='input' type='text'>```

Body:
$(document).ready(function() {
  $('#input').focusin(function() {
    if ($(this).val() != '') {
      $('#div').show();
    } else {
      $('#div').hide();
    }
    $('#input').keyup(function() {
      // If not empty value, show div
      if ($(this).val() != '') {
        $('#div').show();
      } else {
        $('#div').hide();
      }
    });
  });
  $('#input').focusout(function() {
    $('#div').hide();

  });

});

#div {
  display: none;
  position: absolute;
  bottom: 20px;
}

  Link From AJAX
  Link From AJAX
  Link From AJAX

<input id='input' type='text'>

In this jquery code, the #div shows when i type something inside the #input but if i tried to click on the #div it disappears and the link doesn't work,

How can i keep the #div shown if i clicked on #div or #input only, But anything outside will hide it as normal?

The Problem happens because of position: absolute; bottom 20px line in CSS.

Updated the code and suddenly it worked as intended after adding if statement after .focusin function, For previous error solution, remove the position and bottom in the CSS

Body:
You could disable the effect of the focusout handler by the use of a flag:

var noHide = false;
$(document).ready(function() {
  $('#input').keyup(function() {
    // If not empty value, show div
    if ($(this).val() != '') {
      $('#div').show();
    } else {
      $('#div').hide();
    }
  });
  $('#div a').hover(
    function() { noHide = true; },
    function() { noHide = false; $('#input').focus(); }
  );
  $('#input').focusout(function() {
    if(!noHide) {
      $('#div').hide();
    }
  });
});

#div {
  display: none;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='div'>
   <a href='#'>HellWorld</a>
</div>
<input id='input' type='text'>


问:
IOS/Objective-C:Add another variable to a mutableArray
I have a simple array of strings such as the following:

```<code>myArray *NSArray = [NSArray arrayWithObjects: @"chevy", @"ford", @"toyota", nil];
</code>```

I want to add another dimension to the array such as @"1",@"2",@"3" in order to keep track of the order.

Is there a simple way to do this?

Edit

I found answer here.  Create 2nd array and employ loop:

```<code>//For your 2D array
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithCapacity:[homePlayersArray count]];

//populate as required
for(int i=0;i<[homePlayersArray count];i++){
    NSArray *tempArray = [[NSArray alloc] initWithObjects:[homePlayersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
    [secondArray addObject:tempArray];
}
</code>```

答:
Rather than use two arrays (as per your edit to the question), which brings with it the possibility of getting the two out of sync with each other, consider using an array of dictionaries.

For example, your array might start out as:

```<code>NSArray *myArray = @[ @{ @"make" : @"chevy" }.mutableCopy,
                      @{ @"make" : @"ford" }.mutableCopy,
                      @{ @"make" : @"toyota" }.mutableCopy
                   ];
</code>```

This produces you an NSArray (immutable) of NSMutableDictionary (mutable) - so you have the ordering of an array and the flexibility of a mutable dictionary to add your extra variable. For example to add an order number of 106249 to the first entry you could use:

```<code>NSMutableDictionary *entry = (NSMutableDictionary *)myArray[0];
entry[@"orderNumber"] = @106249;
</code>```

If you use the lightweight generics feature of Objective-C you can define your array as:

```<code>NSArray <NSMutableDictionary *> *myArray = @[ ... ];
</code>```

This informs the compiler that the array will only contain mutable dictionaries, which in turn allows setting the order number to become just:

```<code>myArray[0][@"orderNumber"] = @106249;
</code>```

without needing to use any casts.

Your next step to reduce errors is to define constants for the keys:

```<code>const NSString *kMake = @"make";
const NSString *kOrderNumber = @"orderNumber";
</code>```

and the final sample code looks like:

```<code>NSArray <NSMutableDictionary *> *myArray
   = @[ @{ kMake : @"chevy" }.mutableCopy,
        @{ kMake : @"ford" }.mutableCopy,
        @{ kMake : @"toyota" }.mutableCopy
     ];

myArray[0][kOrderNumber] = @106249;
</code>```

You can of course also make the array itself mutable should you need to add new entries to it. And the next stage is to define your own class with make and orderNumber properties rather than use dictionaries.

HTH

Body:
I have a simple array of strings such as the following:

myArray *NSArray = [NSArray arrayWithObjects: @"chevy", @"ford", @"toyota", nil];

I want to add another dimension to the array such as @"1",@"2",@"3" in order to keep track of the order.

Is there a simple way to do this?

Edit

I found answer here.  Create 2nd array and employ loop:

//For your 2D array
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithCapacity:[homePlayersArray count]];

//populate as required
for(int i=0;i<[homePlayersArray count];i++){
    NSArray *tempArray = [[NSArray alloc] initWithObjects:[homePlayersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
    [secondArray addObject:tempArray];
}

Body:
Rather than use two arrays (as per your edit to the question), which brings with it the possibility of getting the two out of sync with each other, consider using an array of dictionaries.

For example, your array might start out as:

NSArray *myArray = @[ @{ @"make" : @"chevy" }.mutableCopy,
                      @{ @"make" : @"ford" }.mutableCopy,
                      @{ @"make" : @"toyota" }.mutableCopy
                   ];

This produces you an NSArray (immutable) of NSMutableDictionary (mutable) - so you have the ordering of an array and the flexibility of a mutable dictionary to add your extra variable. For example to add an order number of 106249 to the first entry you could use:

NSMutableDictionary *entry = (NSMutableDictionary *)myArray[0];
entry[@"orderNumber"] = @106249;

If you use the lightweight generics feature of Objective-C you can define your array as:

NSArray <NSMutableDictionary *> *myArray = @[ ... ];

This informs the compiler that the array will only contain mutable dictionaries, which in turn allows setting the order number to become just:

myArray[0][@"orderNumber"] = @106249;

without needing to use any casts.

Your next step to reduce errors is to define constants for the keys:

const NSString *kMake = @"make";
const NSString *kOrderNumber = @"orderNumber";

and the final sample code looks like:

NSArray <NSMutableDictionary *> *myArray
   = @[ @{ kMake : @"chevy" }.mutableCopy,
        @{ kMake : @"ford" }.mutableCopy,
        @{ kMake : @"toyota" }.mutableCopy
     ];

myArray[0][kOrderNumber] = @106249;

You can of course also make the array itself mutable should you need to add new entries to it. And the next stage is to define your own class with make and orderNumber properties rather than use dictionaries.

HTH


问:
How to write .wav file from blob in Javascript/Node
I'm trying to write a .wav file with fs.writeFile. The file is created successfully, however it's only 8-13bytes long, so obviously I'm not doing something right.

If the blob is already audio/wav can I write to disk or do I need to convert it to Base 64?

I'm pretty much at a loss here, I found another similar thread with no answer - Here

Any input would be appreciated.

```<code>routerApp.controller('audiotest', function($scope) {
 $scope.saveToDisk = function(){
  var nw = require('nw.gui');
  var fs = require('fs');
  var path = require('path');
  fs.writeFileSync('test.wav', $scope.recordedInput)
 };
}
</code>```

console.log($scope.recordedInput) returns Blob {size: 294956, type: "audio/wav"}

It's not really relevant, but here's my HTML

```<code><div class="row" ng-controller="audiotest">
<div class="row">
    <button type="button" ng-click="saveToDisk()"> Write this sucker to disk </button>
    </div>

<ng-audio-recorder id='audioInput' audio-model='recordedInput'>
  <!-- Start controls, exposed via recorder-->
  <div ng-if="recorder.isAvailable">
    <button ng-click="recorder.startRecord()" type="button" ng-disabled="recorder.status.isRecording">
        Start Record
    </button>
    <button ng-click="recorder.stopRecord()" type="button" ng-disabled="recorder.status.isRecording === false">
        Stop Record
    </button>

</ng-audio-recorder>
</div>
</code>```

答:
I had issues getting either of these to work for me. I found success, and much easier implementation with this node module express-fileupload. Here's some code:</p>

```<code>var express = require('express');
var fileUpload = require('express-fileupload');

app.use(fileUpload());

app.post('/', function(req, res) {

  console.log(req.files.data);
  req.files.data.mv('test.wav', function(err) {
    if (err) {
      console.log(err);
    }
  });
});
</code>```

Body:
I'm trying to write a .wav file with fs.writeFile. The file is created successfully, however it's only 8-13bytes long, so obviously I'm not doing something right.

If the blob is already audio/wav can I write to disk or do I need to convert it to Base 64?

I'm pretty much at a loss here, I found another similar thread with no answer - Here

Any input would be appreciated.

routerApp.controller('audiotest', function($scope) {
 $scope.saveToDisk = function(){
  var nw = require('nw.gui');
  var fs = require('fs');
  var path = require('path');
  fs.writeFileSync('test.wav', $scope.recordedInput)
 };
}

console.log($scope.recordedInput) returns Blob {size: 294956, type: "audio/wav"}

It's not really relevant, but here's my HTML

    <button type="button" ng-click="saveToDisk()"> Write this sucker to disk </button>

<ng-audio-recorder id='audioInput' audio-model='recordedInput'>

    <button ng-click="recorder.startRecord()" type="button" ng-disabled="recorder.status.isRecording">
        Start Record
    </button>
    <button ng-click="recorder.stopRecord()" type="button" ng-disabled="recorder.status.isRecording === false">
        Stop Record
    </button>

</ng-audio-recorder>

Body:
I had issues getting either of these to work for me. I found success, and much easier implementation with this node module express-fileupload. Here's some code:

var express = require('express');
var fileUpload = require('express-fileupload');

app.use(fileUpload());

app.post('/', function(req, res) {

  console.log(req.files.data);
  req.files.data.mv('test.wav', function(err) {
    if (err) {
      console.log(err);
    }
  });
});


问:
How to add tracing/debug output to stored procedures in Sql Server (2008)
What is the closest to being able to add log4net style debug information to a set of stored procedures? Some of procedures delegate work to other procedures and I want trace information from both.

I've sprinkled print and select statements through while developing them, and ideally would like to be able to run the proc in different modes depending on whether it's normal operation of troubleshooting and get more or less output.

In this particular case the primary stored proc will be run repeatedly from an agent job, but may be run from management studio when troubleshooting.

The procs already use an error log table and email facilities to catch raised errors. The kind of thing I'm looking to be able to track down is where an input data issue means the output data is wrong but the procs don't fail completely, and it would be useful to see exactly what was done at each step.

What approaches do you know of for producing meaningful and ideally filterable output?

One per answer so we can see the final rankings ;-)

Out of the box answers welcome, such as "don't - step through with management studio when you need to"

答:
Don't add tracing output, instead just step through as needed with the sql server management studio debugger.

(Added to see if people prefer this)

ContentLicense: CC BY-SA 2.5


问:
AsyncTask and SOAP webservices
I'm new to SOAP webservices and AsyncTask, I'm developing an app which is using SOAP webservices for login.
I tried to do all work in onCreate method but I got android.os.NetworkOnMainThreadException.

So i tried to use AsyncTask,
but I'm not able to get reference to emailText and passwordText in RetrieveFeedTask class.

Here is my code:

```<code>public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private static String SOAP_ACTION = "intentionally hided";
    private static String NAMESPACE = "intentionally hided";
    private static String METHOD_NAME = "intentionally hided";
    private static String URL = "intentionally hided";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final EditText emailText = (EditText) findViewById(R.id.emailText);
        final EditText passwordText = (EditText) findViewById(R.id.passwordText);
        Button loginButton = (Button) findViewById(R.id.button_login);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new RetrieveFeedTask().execute();

            }
        });
    }

    class RetrieveFeedTask extends AsyncTask<String, String, String> {

        protected String doInBackground(String... urls) {

            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

            request.addProperty("userName", emailText.getText().toString());
            request.addProperty("userPassword", passwordText.getText().toString());

            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

            envelope.setOutputSoapObject(request);
            envelope.dotNet = true;

            try {
                HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                androidHttpTransport.call(SOAP_ACTION, envelope);

                SoapObject result = (SoapObject) envelope.bodyIn;
                if (result != null) {
                    Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
</code>```

答:
You could use this (AsyncTask with onPreExecute and onPostExecute, but without NetworkOnMainThreadException):    </p>

```<code>class RetrieveFeedTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... urls) {

        String result = "";

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        request.addProperty("userName", emailText.getText().toString());
        request.addProperty("userPassword", passwordText.getText().toString());

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        envelope.setOutputSoapObject(request);
        envelope.dotNet = true;

        try {
            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

            androidHttpTransport.call(SOAP_ACTION, envelope);

            SoapObject result = (SoapObject) envelope.bodyIn;
            if (result != null) {
                result = "Login Successful!";
            } else {
                result = "Login Failed!";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected String onPostExecute(String result) {
        super.onPostExecute(result);

        if (result.equals("Login Successful!")) {
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
        }
    }
}
</code>```

Title: AsyncTask and SOAP webservices

Body:
I'm new to SOAP webservices and AsyncTask, I'm developing an app which is using SOAP webservices for login.
I tried to do all work in onCreate method but I got android.os.NetworkOnMainThreadException.

So i tried to use AsyncTask,
but I'm not able to get reference to emailText and passwordText in RetrieveFeedTask class.

Here is my code:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private static String SOAP_ACTION = "intentionally hided";
    private static String NAMESPACE = "intentionally hided";
    private static String METHOD_NAME = "intentionally hided";
    private static String URL = "intentionally hided";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final EditText emailText = (EditText) findViewById(R.id.emailText);
        final EditText passwordText = (EditText) findViewById(R.id.passwordText);
        Button loginButton = (Button) findViewById(R.id.button_login);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new RetrieveFeedTask().execute();

            }
        });
    }

    class RetrieveFeedTask extends AsyncTask<String, String, String> {

        protected String doInBackground(String... urls) {

            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

            request.addProperty("userName", emailText.getText().toString());
            request.addProperty("userPassword", passwordText.getText().toString());

            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

            envelope.setOutputSoapObject(request);
            envelope.dotNet = true;

            try {
                HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                androidHttpTransport.call(SOAP_ACTION, envelope);

                SoapObject result = (SoapObject) envelope.bodyIn;
                if (result != null) {
                    Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Body:
You could use this (AsyncTask with onPreExecute and onPostExecute, but without NetworkOnMainThreadException):

class RetrieveFeedTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... urls) {

        String result = "";

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        request.addProperty("userName", emailText.getText().toString());
        request.addProperty("userPassword", passwordText.getText().toString());

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        envelope.setOutputSoapObject(request);
        envelope.dotNet = true;

        try {
            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

            androidHttpTransport.call(SOAP_ACTION, envelope);

            SoapObject result = (SoapObject) envelope.bodyIn;
            if (result != null) {
                result = "Login Successful!";
            } else {
                result = "Login Failed!";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected String onPostExecute(String result) {
        super.onPostExecute(result);

        if (result.equals("Login Successful!")) {
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
        }
    }
}


问:
Rtools not found by devtools, but ls and gcc are on PATH
```<code>Sys.which('gcc')
                                                                 gcc
"C:\\Users\\[redacted]\\Documents\\aps\\Rtools\\mingw_32\\bin\\gcc.exe"

Sys.which('ls')
                                                       ls
"C:\\Users\\[redacted]\\Documents\\aps\\Rtools\\bin\\ls.exe"

find_rtools(cache=FALSE,debug=TRUE)

Scanning path...
ls : C:\Users\[redacted]\Documents\aps\Rtools\bin\ls.exe
"C:/Users/[redacted]/Documents/aps/rportnov/bin/x64/R" --no-site-file --no-environ --no-save --no-restore --quiet CMD  \
  config CC

Scanning registry...
WARNING: Rtools is required to build R packages, but is not currently installed.

Please download and install Rtools 3.4 from http://cran.r-project.org/bin/windows/Rtools/.
</code>```

答: This was a problem in the registry generated during installation, so I reinstalled it and it worked.</p>


问:
com.android.phone from uid 10400 not allowed to perform OP_READ_PHONE_STATE
The line:

```<code>final TelephonyManager tm =(TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
    tmSerial = "" + tm.getSimSerialNumber();
</code>```

is throwing this error only on the Samsung Galaxy note 5 running android 7.0. And this only happened after I upgraded Google-Services to 3.1.0. I have the line

 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
In my manifest file and

```<code>ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_PHONE_STATE)
                    == PackageManager.PERMISSION_GRANTED)
</code>```

is returning true. Is this a bug with 7.0 on the Note 5 or am I getting the permissions wrong somehow?

答:
The first time the app is installed, you must enable Phone permission under Settings->Apps->App Name->Permissions.

For Android 6.0 and up, this is true for the following permissions (ref):

Body Sensors

Calendar

Camera

Contacts

Location

Microphone

Phone

SMS

Storage

Body:
The line:

final TelephonyManager tm =(TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
    tmSerial = "" + tm.getSimSerialNumber();

is throwing this error only on the Samsung Galaxy note 5 running android 7.0. And this only happened after I upgraded Google-Services to 3.1.0. I have the line

 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
In my manifest file and

ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_PHONE_STATE)
                    == PackageManager.PERMISSION_GRANTED)

is returning true. Is this a bug with 7.0 on the Note 5 or am I getting the permissions wrong somehow?