问:
UITextView in UITableViewCell how to scroll table view to keep cursor visible while typing
I have a custom UITableViewCell which contains a UITextView. The cell is fairly large. How can I autoscroll the table to ensure the current selection point is always visible?

Note the UITextView is the size of the cell so it won't autoscroll itself.

I can call firstRectForRange on the selectedTextRange, but this doesn't work if the insertion point is at the end (you get inf,inf,0,0 for the CGRect). If I had the rect I could calculate the offset in the table and adjust its scroll contentOffset. is there a good way to do this or is messing with the contentOffset the only way?

答:
use this in the textviewdidchange</p>

```<code>if let confirmedTextViewCursorPosition = textView.selectedTextRange?.end {

            let caretPosition = textView.caretRect(for: confirmedTextViewCursorPosition)
            var textViewActualPosition = tableView.convert(caretPosition, from: textView.superview?.superview)
            textViewActualPosition.origin.y += 20.0 // give the actual padding of textview inside the cell
            tableView.scrollRectToVisible(textViewActualPosition, animated: false)

        }
</code>```

Body:
use this in the textviewdidchange

if let confirmedTextViewCursorPosition = textView.selectedTextRange?.end {

            let caretPosition = textView.caretRect(for: confirmedTextViewCursorPosition)
            var textViewActualPosition = tableView.convert(caretPosition, from: textView.superview?.superview)
            textViewActualPosition.origin.y += 20.0 // give the actual padding of textview inside the cell
            tableView.scrollRectToVisible(textViewActualPosition, animated: false)

        }


来源: stackexchange

问:
Why moodle after installation is giving blank page on localhost:8080
I installed moodle on localhost with all the instructions given at that time. After installation, page is getting redirected to following url and blank page is shown.

URL: http://localhost:8080/moodle/user/editadvanced.php?id=2

答: I fixed my problem after I upgraded my PHP version from  7.1.7 to 7.1.11 using moodle 3.4 version</p>

ContentLicense: CC BY-SA 3.0


问:
How to rename a file using Python
I want to change a.txt to b.kml.

答:
Use os.rename. But you have to pass full path of both files to the function. If I have a file a.txt on my desktop so I will do and also I have to give full of renamed file too.

```<code>os.rename('C:\\Users\\Desktop\\a.txt', 'C:\\Users\\Desktop\\b.kml')
</code>```

Title: How to rename a file using Python

Body: I want to change a.txt to b.kml.

Body:
Use os.rename. But you have to pass full path of both files to the function. If I have a file a.txt on my desktop so I will do and also I have to give full of renamed file too.

os.rename('C:\\Users\\Desktop\\a.txt', 'C:\\Users\\Desktop\\b.kml')

ContentLicense: CC BY-SA 4.0


问:
SQL: find missing IDs in a table
I have table with a unique auto-incremental primary key. Over time, entries may be deleted from the table, so there are "holes" in this field's values. For example, table data may be as follows:

```<code> ID  | Value    | More fields...
---------------------------------
 2   | Cat      | ...
 3   | Fish     | ...
 6   | Dog      | ...
 7   | Aardvark | ...
 9   | Owl      | ...
 10  | Pig      | ...
 11  | Badger   | ...
 15  | Mongoose | ...
 19  | Ferret   | ...
</code>```

I'm interested in a query that will return the list of missing IDs in the table. For the data above, the expected results are:

```<code> ID
----
 1
 4
 5
 8
 12
 13
 14
 16
 17
 18
</code>```

Notes:

It is assumed that the initial first ID was 1

The maximum ID that should be examined is the final one, i.e. it's okay to assume that there were no additional entries after the current last one (see additional data on this point below)

A drawback of the above requirements is that the list will not return IDs that were created after ID 19 and that were deleted. I'm currently solving this case in code, because I hold the max ID created. However, if the query can take as a parameter MaxID, and also return those IDs between the current max and MaxID, that would be a nice "bonus" (but certainly not a must).

I'm currently working with MySQL, but consider moving to SQL Server, so I would like the query to fit both. Also, if you are using anything that can't run on SQLite, please mention it, thanks.

答:
```<code>SELECT DISTINCT id -1
FROM users
WHERE id != 1 AND id - 1 NOT IN (SELECT DISTINCT id FROM users)
</code>```

Explanation:  ( id - 1 )..... checking for any previous id present in table

( id != 1 ).....neglecting when current id is 1 as its previous id will be 0 zero.

ContentLicense: CC BY-SA 2.5

Title: SQL: find missing IDs in a table

Body:
I have table with a unique auto-incremental primary key. Over time, entries may be deleted from the table, so there are "holes" in this field's values. For example, table data may be as follows:

 ID  | Value    | More fields...
---------------------------------
 2   | Cat      | ...
 3   | Fish     | ...
 6   | Dog      | ...
 7   | Aardvark | ...
 9   | Owl      | ...
 10  | Pig      | ...
 11  | Badger   | ...
 15  | Mongoose | ...
 19  | Ferret   | ...

I'm interested in a query that will return the list of missing IDs in the table. For the data above, the expected results are:

 ID
----
 1
 4
 5
 8
 12
 13
 14
 16
 17
 18

Notes:

It is assumed that the initial first ID was 1

The maximum ID that should be examined is the final one, i.e. it's okay to assume that there were no additional entries after the current last one (see additional data on this point below)

A drawback of the above requirements is that the list will not return IDs that were created after ID 19 and that were deleted. I'm currently solving this case in code, because I hold the max ID created. However, if the query can take as a parameter MaxID, and also return those IDs between the current max and MaxID, that would be a nice "bonus" (but certainly not a must).

I'm currently working with MySQL, but consider moving to SQL Server, so I would like the query to fit both. Also, if you are using anything that can't run on SQLite, please mention it, thanks.

Body:
SELECT DISTINCT id -1
FROM users
WHERE id != 1 AND id - 1 NOT IN (SELECT DISTINCT id FROM users)

Explanation:  ( id - 1 )..... checking for any previous id present in table

( id != 1 ).....neglecting when current id is 1 as its previous id will be 0 zero.


问:
Running .webtest tests results in ".webtest is not a valid extension"
I'm using VS2017 - is there any way to get webtests working without installing VS2017 Enterprise?  All I need is mstest.exe - not the GUI or IDE.

答:
No, for unit test you can install Agents For Visual Studio 2017.

But for   Web Load & Performance Testing, it is only supported in Visual Studio Enterprise 2017, So you need to install Visual Studio Enterprise 2017 with Web Performance and Load testing tools.

More information about VS 2017 supported features, you can refer to: Compare Visual Studio 2017 IDEs

Reference below threads:

Getting error: File extension specified '.webtest' is not a valid test extension

Can I use mstest.exe without installing Visual Studio?


问:
"Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set WindowActionBar to false in your theme to use a toolbar instead"
I get the error "Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set WindowActionBar to false in your theme to use a toolbar instead" whenever I try to run my app in the emulator on Android Studio and it crashes upon startup. I understand that this question has been asked before, but when I remove the extends AppCompatActivity as I am told to do in other posts it then gives me an error for the setSupportActionBar(toolbar) line a bit further down in the code.

As far as I understand this is an error with Android Studio getting confused about the native toolbar and the toolbar that I'm trying to implement. Perhaps I'm misunderstanding the crux of the problem? Why is it giving me an error for setSupportActionBar(toolbar) once I get rid of the extends statement?

The main activity is using the "AppTheme"

Thanks.

MainActivity Code for reference:

```<code>package com.treehouse.android.movies;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

import java.util.ArrayList;

//extends AppCompatActivity

public class MainActivity extends AppCompatActivity
{
    static public ArrayList<Movie> moviesList;
    static public ArrayList<String> images;
    public String mostPopular="http://api.themoviedb.org/3/movie/popular?api_key=";
    public String highRated="http://api.themoviedb.org/3/movie/top_rated?api_key=";
    //Make both GridAdapter and GridView non-Static?
    static public GridAdapter gridAdapter;
    static public GridView gridView;
    public static boolean connectionEnabled;
    public Context currentContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        String result="";
        moviesList=new ArrayList<>();
        images=new ArrayList<>();
        currentContext=getApplicationContext();

        if (isNetworkAvailable()!= false) {
            connectionEnabled=true;
            getJsonData(0);
            new GetMovies(currentContext);
            gridView =(GridView) findViewById(R.id.moviesGridView);
            gridAdapter =new GridAdapter(MainActivity.this,moviesList,images);
            gridView.setAdapter(gridAdapter);

            gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Intent movieIntent=new Intent(getApplicationContext(),DetailsActivity.class);
                    Log.i("Default position ", String.valueOf(position));
                    movieIntent.putExtra("position",position);
                    startActivity(movieIntent);
                }
            });
        }
        else{
            Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            connectionEnabled=false;
        }

    }

    public boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    //get json file
    //0 for most popular
    //1 for highest-rated
    public void getJsonData(int searchBy){
        GetMovies downloadTask=new GetMovies(currentContext);
        try {
            if (searchBy == 0 ){
                downloadTask.execute(mostPopular);
            }
            else if(searchBy == 1){
                downloadTask.execute(highRated);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.mostpopular_button) {
            if (isNetworkAvailable()!= false) {
                new GetMovies(currentContext).execute(mostPopular);
                gridAdapter.notifyDataSetChanged();
            }
            else{
                Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            }
        }
        else if (id== R.id.highrated_button){
            if (isNetworkAvailable()!= false) {
                new GetMovies(currentContext).execute(highRated);
                gridAdapter.notifyDataSetChanged();
            }
            else{
                Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            }
        }

        return super.onOptionsItemSelected(item);
    }
}
</code>```

Styles Code for reference:

```<code><resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

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

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>
</code>```

Manifest Code for reference:

```<code><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.treehouse.android.movies" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true" >
        <!-- android:theme="@style/AppTheme" part of application -->
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN"
                        android:theme="@style/AppTheme"
                    />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
</code>```

答:
change your style.xml

```<code><!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</code>```

replace to this :

```<code><!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="windowActionBar">true</item>
        <item name="windowNoTitle">true</item>
    </style>
</code>```

Body:
I get the error "Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set WindowActionBar to false in your theme to use a toolbar instead" whenever I try to run my app in the emulator on Android Studio and it crashes upon startup. I understand that this question has been asked before, but when I remove the extends AppCompatActivity as I am told to do in other posts it then gives me an error for the setSupportActionBar(toolbar) line a bit further down in the code.

As far as I understand this is an error with Android Studio getting confused about the native toolbar and the toolbar that I'm trying to implement. Perhaps I'm misunderstanding the crux of the problem? Why is it giving me an error for setSupportActionBar(toolbar) once I get rid of the extends statement?

The main activity is using the "AppTheme"

Thanks.

MainActivity Code for reference:

package com.treehouse.android.movies;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

import java.util.ArrayList;

//extends AppCompatActivity

public class MainActivity extends AppCompatActivity
{
    static public ArrayList<Movie> moviesList;
    static public ArrayList<String> images;
    public String mostPopular="http://api.themoviedb.org/3/movie/popular?api_key=";
    public String highRated="http://api.themoviedb.org/3/movie/top_rated?api_key=";
    //Make both GridAdapter and GridView non-Static?
    static public GridAdapter gridAdapter;
    static public GridView gridView;
    public static boolean connectionEnabled;
    public Context currentContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        String result="";
        moviesList=new ArrayList<>();
        images=new ArrayList<>();
        currentContext=getApplicationContext();

        if (isNetworkAvailable()!= false) {
            connectionEnabled=true;
            getJsonData(0);
            new GetMovies(currentContext);
            gridView =(GridView) findViewById(R.id.moviesGridView);
            gridAdapter =new GridAdapter(MainActivity.this,moviesList,images);
            gridView.setAdapter(gridAdapter);

            gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Intent movieIntent=new Intent(getApplicationContext(),DetailsActivity.class);
                    Log.i("Default position ", String.valueOf(position));
                    movieIntent.putExtra("position",position);
                    startActivity(movieIntent);
                }
            });
        }
        else{
            Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            connectionEnabled=false;
        }

    }

    public boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    //get json file
    //0 for most popular
    //1 for highest-rated
    public void getJsonData(int searchBy){
        GetMovies downloadTask=new GetMovies(currentContext);
        try {
            if (searchBy == 0 ){
                downloadTask.execute(mostPopular);
            }
            else if(searchBy == 1){
                downloadTask.execute(highRated);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.mostpopular_button) {
            if (isNetworkAvailable()!= false) {
                new GetMovies(currentContext).execute(mostPopular);
                gridAdapter.notifyDataSetChanged();
            }
            else{
                Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            }
        }
        else if (id== R.id.highrated_button){
            if (isNetworkAvailable()!= false) {
                new GetMovies(currentContext).execute(highRated);
                gridAdapter.notifyDataSetChanged();
            }
            else{
                Toast.makeText(this, "Network Is Not Available", Toast.LENGTH_LONG).show();
            }
        }

        return super.onOptionsItemSelected(item);
    }
}

Styles Code for reference:

<resources>

Body:
change your style.xml

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

replace to this :

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="windowActionBar">true</item>
        <item name="windowNoTitle">true</item>
    </style>


问:
Create list of dictionaries from CSV in the same order using Python
Consider a CSV,

```<code>col1, col2, col3
1000, Star, True
2000, Moon, False
</code>```

How to create a list of dictionaries in the same order like this

```<code>[{'col1': '1000', 'col2': 'Star', 'col3': 'TRUE'}, {'col1': '2000', 'col2': 'Moon', 'col3': 'FALSE'}]
</code>```

I have tried with following code but not getting in the same order

```<code>with open('sample.csv') as f:
    rows = [{k: v for k, v in row.items()}
        for row in csv.DictReader(f, skipinitialspace=True)]
</code>```

Output of above code,

```<code>[{'col2': 'Star', 'col3': 'TRUE', 'col1': '1000'}, {'col2': 'Moon', 'col3': 'FALSE', 'col1': '2000'}]
</code>```

Is there any solution to get in the same order?

Thanks!

答:
Since dictionaries are inherently unordered, you need wrap an OrderedDict on each of the dictionaries in your list, which need to be sorted beforehand:

```<code>import csv
from collections import OrderedDict

with open('sample.csv') as f:
    rows = [OrderedDict(sorted(dict((k, v) for k, v in row.items()).items())) for row in csv.DictReader(f, skipinitialspace=True)]

>>> print(rows)
[OrderedDict([('col1', '1000'), ('col2', 'Star'), ('col3', 'True')]), OrderedDict([('col1', '2000'), ('col2', 'Moon'), ('col3', 'False')])]
</code>```

And works normally:

```<code>>>> print(rows[0]['col1'])
1000
>>> print(rows[1]['col1'])
2000
print([key for key in rows[0]])
['col1', 'col2', 'col3']
</code>```

Note: You can't replace the OrderedDict() wrapping in the output with a normal dictionary, otherwise it will be unordered again. This is one of the prices we have to pay if we want ordered dictionaries in python.

Body:
Consider a CSV,

col1, col2, col3
1000, Star, True
2000, Moon, False

How to create a list of dictionaries in the same order like this

[{'col1': '1000', 'col2': 'Star', 'col3': 'TRUE'}, {'col1': '2000', 'col2': 'Moon', 'col3': 'FALSE'}]

I have tried with following code but not getting in the same order

with open('sample.csv') as f:
    rows = [{k: v for k, v in row.items()}
        for row in csv.DictReader(f, skipinitialspace=True)]

Output of above code,

[{'col2': 'Star', 'col3': 'TRUE', 'col1': '1000'}, {'col2': 'Moon', 'col3': 'FALSE', 'col1': '2000'}]

Is there any solution to get in the same order?

Thanks!

Body:
Since dictionaries are inherently unordered, you need wrap an OrderedDict on each of the dictionaries in your list, which need to be sorted beforehand:

import csv
from collections import OrderedDict

with open('sample.csv') as f:
    rows = [OrderedDict(sorted(dict((k, v) for k, v in row.items()).items())) for row in csv.DictReader(f, skipinitialspace=True)]

>>> print(rows)
[OrderedDict([('col1', '1000'), ('col2', 'Star'), ('col3', 'True')]), OrderedDict([('col1', '2000'), ('col2', 'Moon'), ('col3', 'False')])]

And works normally:

>>> print(rows[0]['col1'])
1000
>>> print(rows[1]['col1'])
2000
print([key for key in rows[0]])
['col1', 'col2', 'col3']

Note: You can't replace the OrderedDict() wrapping in the output with a normal dictionary, otherwise it will be unordered again. This is one of the prices we have to pay if we want ordered dictionaries in python.


问:
Implementing a custom Angular service that uses $location and $emit

I am trying to register a custom service in Angularjs that gets the URL, and then emits it back up to the higher level controller. I have 1. Registered the service with app.service 2. Passed in the name of the service to the lower controller 3. Am listening for the change in the higher level controller. I have it working when I duplicate the function in each controller, but I'm trying to refactor.

module.js registers the service

var app = angular.module('demo', ['ngRoute']);
app.service('changedUrlService', function() {
    this.getUrl = function(url) {
        $scope.emit('urlChange', url);
    }
});```
</div>
</div>
</p>

<p><strong>lowerController.js</strong> controller that uses the service</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>angular.module('demo').controller("lowerController", ['$scope', '$http','$location' 'changedUrlService', function ($scope, $http, $location, changedUrlService)
{
  $scope.url = $location.url();
  $scope.findUrl = changedUrlService.getUrl($scope.url);
  $scope.findUrl();
}</code>```

higherController.js listening for the emit

$scope.$on('urlChange', function (event, item) {
  $scope.myUrl = item;
  console.log($scope.myUrl);
});```

I have received a variety of errors as I tweaked this, including Unknown Provider, $scope not defined and more.

答:
If you see this below code, you will understand you have not injected anything to the service. First you need to inject any other service and then only you can use it. But service is not the correct place to inject $scope.

```<code>var app = angular.module('demo', ['ngRoute']);
app.service('changedUrlService', function() { // No dependencies injected
    this.getUrl = function(url) {
        $scope.emit('urlChange', url); // Incorrect
    }
});
</code>```

What you can do is, return the string from the string. Inject this service changedUrlService into the controller and use this to get the string. And not from the controller call the emit function.

Please let me know if it helps.

Body:
I am trying to register a custom service in Angularjs that gets the URL, and then emits it back up to the higher level controller. I have 1. Registered the service with app.service 2. Passed in the name of the service to the lower controller 3. Am listening for the change in the higher level controller. I have it working when I duplicate the function in each controller, but I'm trying to refactor.

module.js registers the service

var app = angular.module('demo', ['ngRoute']);
app.service('changedUrlService', function() {
    this.getUrl = function(url) {
        $scope.emit('urlChange', url);
    }
});

lowerController.js controller that uses the service

angular.module('demo').controller("lowerController", ['$scope', '$http','$location' 'changedUrlService', function ($scope, $http, $location, changedUrlService)
{
  $scope.url = $location.url();
  $scope.findUrl = changedUrlService.getUrl($scope.url);
  $scope.findUrl();
}

higherController.js listening for the emit

$scope.$on('urlChange', function (event, item) {
  $scope.myUrl = item;
  console.log($scope.myUrl);
});

I have received a variety of errors as I tweaked this, including Unknown Provider, $scope not defined and more.

Body:
If you see this below code, you will understand you have not injected anything to the service. First you need to inject any other service and then only you can use it. But service is not the correct place to inject $scope.

var app = angular.module('demo', ['ngRoute']);
app.service('changedUrlService', function() { // No dependencies injected
    this.getUrl = function(url) {
        $scope.emit('urlChange', url); // Incorrect
    }
});

What you can do is, return the string from the string. Inject this service changedUrlService into the controller and use this to get the string. And not from the controller call the emit function.

Please let me know if it helps.


问:
Object prototype can't access properties with `this`
So, I saw several examples that this should work. But obviously, I'm missing something, because it doesn't. :/

Could somebody please explain to me what I'm doing wrong here? :)

```<code>function Code (b) {
  this.b = b
  this.arr = []
}

Code.prototype.add = (v) => {
  console.log(this.b)
  this.arr.forEach(element => {
    console.log(element)
  });
  this.arr.push(v)
}

var c = new Code('bla')
console.log(c.add('asdf'))
</code>```

So this throws an error with:

```<code>this.arr.forEach(element => {
  ^

TypeError: Cannot read property 'forEach' of undefined
</code>```

Obviously, I'm doing something wrong here. But I don't know what.

Thanks!
Gergely.

答:
```<code>function Code (b) {
  this.b = b
  this.arr = []
}
Code.prototype.add =function(v){
  console.log(this.b)
  this.arr.forEach(function(element){
    console.log(element)
  });
  this.arr.push(v)
  console.log(this.arr)
}

var c = new Code('bla')
console.log(c.add('asdf'))
</code>```

You should use function(), instaed of () => arrow fucntion, since arrow function's this works differently.

this of an arrow function only refers to this that exists in the outer scope.

Body:
So, I saw several examples that this should work. But obviously, I'm missing something, because it doesn't. :/

Could somebody please explain to me what I'm doing wrong here? :)

function Code (b) {
  this.b = b
  this.arr = []
}

Code.prototype.add = (v) => {
  console.log(this.b)
  this.arr.forEach(element => {
    console.log(element)
  });
  this.arr.push(v)
}

var c = new Code('bla')
console.log(c.add('asdf'))

So this throws an error with:

this.arr.forEach(element => {
  ^

TypeError: Cannot read property 'forEach' of undefined

Obviously, I'm doing something wrong here. But I don't know what.

Thanks!
Gergely.

Body:
function Code (b) {
  this.b = b
  this.arr = []
}
Code.prototype.add =function(v){
  console.log(this.b)
  this.arr.forEach(function(element){
    console.log(element)
  });
  this.arr.push(v)
  console.log(this.arr)
}

var c = new Code('bla')
console.log(c.add('asdf'))

You should use function(), instaed of () => arrow fucntion, since arrow function's this works differently.

this of an arrow function only refers to this that exists in the outer scope.


问:
How to use headers common for all api requests using service in angular?
Iam working in angular4 ecommerce project.Here I need different api calls from backend having common headers with key and secret key.I have kept all the api urls in a service and whenever there is a api call,I am using that service.Here Iam declaring headers every time of api call.But I want to place those headers as global in that same service,so that I can use the headers too using that service.My problem is Iam unable use the headers in the service that are common to all api requests.How can I implement this one in angular?Please help me.Here is my code:
//service...</p>

```<code>import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import {Http, Headers} from '@angular/http';

@Injectable()
export class SharedServiceService {
public static headers = new Headers();
    public static baseUrl='https://www.t3stores.com/mystores/wordpress/';
    public static baseUrl2='https://colourssoftware.com/T3Liquors/';
    public static newCollections=SharedServiceService.baseUrl+'wp-json/wc/v2/products?tag=882';
public static productsApi=SharedServiceService.baseUrl+'wp-json/wc/v2/products?page=1&per_page=100';
    public static products=SharedServiceService.baseUrl;
    }

    //headers:
      createAuthorizationHeader(headers: Headers) {
        headers.append('Authorization', 'Basic ' +
            btoa('ck_543700d9f8c08268d75d3efefb302df4fad70a8f:cs_f1514261bbe154d662eb5053880d40518367c901'));
        headers.append("Content-Type", "application/json");
    }
     let headers = new Headers();
        this.createAuthorizationHeader(headers);
</code>```

答:
So here is how you would do it, as given above in Rahul's example you can define your interceptor that way. But you need to clone the request and add the header, see the example below that does it, In this example I have my service that gets the common headers, which is instantiated as mser.

```<code>@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {

  constructor(private mser: myService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const url: string = request.url;
    const method: string = request.method;
    request = request.clone({
      setHeaders: {
        'org-id': this.mser.feId,
        'source-id': this.mser.get().sourceId,
        'application-id': this.mser.get().applicationId,
        locale: this.mser.primaryLocale,
        uuid: uuid()
      }
    });
    return next.handle(request);
  }
}
</code>```

In order to do the setup for the interceptor you need to provide this in your provider array in your module.ts file. Something like given below,

```<code>provider :[  { provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true }]
</code>```

After you start the app and you try to hit any service you will find that code given in interceptor will be executed.

Alternatively you can setup the header information in hard coded manner also in which case you will have to remove the mser in my code example below and provide the hardcoded values instead.

Something like this,

```<code>request = request.clone({
          setHeaders: {
            'org-id': 'MyHardcodedValue1',
            'source-id': 'MyHardcodedValue2',
            'application-id': 'MyHardcodedValue3',
            locale: 'MyHardcodedValue4',
            uuid: 'MyHardcodedValue5',
          }
        });
</code>```

Body:
Iam working in angular4 ecommerce project.Here I need different api calls from backend having common headers with key and secret key.I have kept all the api urls in a service and whenever there is a api call,I am using that service.Here Iam declaring headers every time of api call.But I want to place those headers as global in that same service,so that I can use the headers too using that service.My problem is Iam unable use the headers in the service that are common to all api requests.How can I implement this one in angular?Please help me.Here is my code:
//service...

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import {Http, Headers} from '@angular/http';

@Injectable()
export class SharedServiceService {
public static headers = new Headers();
    public static baseUrl='https://www.t3stores.com/mystores/wordpress/';
    public static baseUrl2='https://colourssoftware.com/T3Liquors/';
    public static newCollections=SharedServiceService.baseUrl+'wp-json/wc/v2/products?tag=882';
public static productsApi=SharedServiceService.baseUrl+'wp-json/wc/v2/products?page=1&per_page=100';
    public static products=SharedServiceService.baseUrl;
    }

    //headers:
      createAuthorizationHeader(headers: Headers) {
        headers.append('Authorization', 'Basic ' +
            btoa('ck_543700d9f8c08268d75d3efefb302df4fad70a8f:cs_f1514261bbe154d662eb5053880d40518367c901'));
        headers.append("Content-Type", "application/json");
    }
     let headers = new Headers();
        this.createAuthorizationHeader(headers);

Body:
So here is how you would do it, as given above in Rahul's example you can define your interceptor that way. But you need to clone the request and add the header, see the example below that does it, In this example I have my service that gets the common headers, which is instantiated as mser.

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {

  constructor(private mser: myService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const url: string = request.url;
    const method: string = request.method;
    request = request.clone({
      setHeaders: {
        'org-id': this.mser.feId,
        'source-id': this.mser.get().sourceId,
        'application-id': this.mser.get().applicationId,
        locale: this.mser.primaryLocale,
        uuid: uuid()
      }
    });
    return next.handle(request);
  }
}

In order to do the setup for the interceptor you need to provide this in your provider array in your module.ts file. Something like given below,

provider :[  { provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true }]

After you start the app and you try to hit any service you will find that code given in interceptor will be executed.

Alternatively you can setup the header information in hard coded manner also in which case you will have to remove the mser in my code example below and provide the hardcoded values instead.

Something like this,

request = request.clone({
          setHeaders: {
            'org-id': 'MyHardcodedValue1',
            'source-id': 'MyHardcodedValue2',
            'application-id': 'MyHardcodedValue3',
            locale: 'MyHardcodedValue4',
            uuid: 'MyHardcodedValue5',
          }
        });


问:
Chrome alert pop up not detected in Selenium
I am having issues with handling Authentication pop up in Chrome via Selenium.

```<code>from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get('URL')
time.sleep(5)
alert = driver.switch_to_alert()
alert.send_keys('Username')
alert.send_keys(Keys.TAB)
alert.send_keys('Password')
</code>```

This returns an error--

"selenium.common.exceptions.NoAlertPresentException: Message: no alert open"

Alternatively, I also tried the following code:

```<code>from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get('https://Username:Password@URL')
</code>```

The second code works partially-

In Chrome the user is logged in but the page does not load. Only a blank page is displayed. Once the blank page is loaded, i passed only the URL(without user credentials) and it works fine.

In Firefox, the webpage loads perfectly.

Basically, the issue is with Chrome.

Any help is appreciated.

Thanks!

答:
The second code you have tried is correct with a slight mistake.</p>

```<code>public void loginToSystem(String username,String password, String url){
driver = webdriver.Chrome()

driver.get("https://"+username+":"+password+"@ "+URL);
}
</code>```

Body:
I am having issues with handling Authentication pop up in Chrome via Selenium.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get('URL')
time.sleep(5)
alert = driver.switch_to_alert()
alert.send_keys('Username')
alert.send_keys(Keys.TAB)
alert.send_keys('Password')

This returns an error--

"selenium.common.exceptions.NoAlertPresentException: Message: no alert open"

Alternatively, I also tried the following code:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get('https://Username:Password@URL')

The second code works partially-

In Chrome the user is logged in but the page does not load. Only a blank page is displayed. Once the blank page is loaded, i passed only the URL(without user credentials) and it works fine.

In Firefox, the webpage loads perfectly.

Basically, the issue is with Chrome.

Any help is appreciated.

Thanks!

Body:
The second code you have tried is correct with a slight mistake.

public void loginToSystem(String username,String password, String url){
driver = webdriver.Chrome()

driver.get("https://"+username+":"+password+"@ "+URL);
}


问:
Toolbar behaving really strangely
In my app I have two activities right now. The first one, LoginActivity, has Theme.AppCompat.Light.DarkActionBar as its theme. The other one, ClientesActivity, has an <item name="windowActionBar">false</item> and a custom android.support.v7.widget.Toolbar. They used to behave correctly. When I updated to Build Tools 27.0.1, Gradle 3.0.1 and Support Library 27.0.2, they all started looking like this:

LoginActivity

ClientesActivity

Here's the code:

styles.xml

```<code><resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:background">#FAFAFA</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

    </style>

    <style name="AppThemeNoBar" parent="AppTheme">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>
</code>```

clientes_activity.xml

```<code><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:theme="@style/AppThemeNoBar"
    tools:context="melamed.soldeloesteapp.ClientesActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/tb_clientes"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/toolbar_clientes"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:minHeight="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:title="Carrito">

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

        <!-- Some more irrelevant stuff -->

    </RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
</code>```

Please someone tell me how to fix them back!

PS: They were blue and with white text, as any toolbar (the custom one had white buttons).

答:
OK, I found the solution by myself while removing stuff. I discovered that from some support library version, android:background in a style affects only the Toolbar (WTF?). I removed the <item name="android:background">#FAFAFA</item>
and it worked. Now, how can I default a background colour from a theme? (Answer in the comments, cba to make a whole new question about this)

Title: Toolbar behaving really strangely

Body:
In my app I have two activities right now. The first one, LoginActivity, has Theme.AppCompat.Light.DarkActionBar as its theme. The other one, ClientesActivity, has an <item name="windowActionBar">false</item> and a custom android.support.v7.widget.Toolbar. They used to behave correctly. When I updated to Build Tools 27.0.1, Gradle 3.0.1 and Support Library 27.0.2, they all started looking like this:

LoginActivity

ClientesActivity

Here's the code:

styles.xml

<resources>

</resources>

clientes_activity.xml

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:theme="@style/AppThemeNoBar"
    tools:context="melamed.soldeloesteapp.ClientesActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/tb_clientes"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/toolbar_clientes"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:minHeight="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:title="Carrito">

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

    </RelativeLayout>
</android.support.design.widget.CoordinatorLayout>

Please someone tell me how to fix them back!

PS: They were blue and with white text, as any toolbar (the custom one had white buttons).


问:
Error when using npm vue-cli
Windows 10

node v8.9.2

npm 5.5.1

installed vue-cli through the use of npm but entering 'npm run dev' resulted in an error.

this is error message

```<code>npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! webpack-simple@1.0.0 dev: `cross-env NODE_ENV=development webpack-dev-server --open --hot`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the webpack-simple@1.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\hansol\AppData\Roaming\npm-cache\_logs\2017-12-08T04_14_50_859Z-debug.log
</code>```

答:
It appears as though you havent installed the node modules / dependencies.

Please try and run a

```<code>npm install
</code>```

And see if that works

Title: Error when using npm vue-cli

Body:
Windows 10

node v8.9.2

npm 5.5.1

installed vue-cli through the use of npm but entering 'npm run dev' resulted in an error.

this is error message

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! webpack-simple@1.0.0 dev: `cross-env NODE_ENV=development webpack-dev-server --open --hot`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the webpack-simple@1.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\hansol\AppData\Roaming\npm-cache\_logs\2017-12-08T04_14_50_859Z-debug.log

Body:
It appears as though you havent installed the node modules / dependencies.

Please try and run a

npm install

And see if that works


问:
How do I use cvResize/resize correctly?
I have trouble resizing a 6x6 image to 120x120. It looks like the resized image is somewhat shifted by 1 pixel. This happens with the cvResize and with cv::resize. My code looks like this:

```<code>warpPerspective(greyImg, warpedImg, homography, Size(6, 6));
Mat bigWarpedImg = Mat(120,120,CV_8UC1);
resize(warpedImg, bigWarpedImg, Size(0,0), 20, 20, INTER_NEAREST);
</code>```

warpedImg looks like this (I resized it with gimp to make it easier to recognize): http://picasaweb.google.com/103165673068768416583/Opencv#5565090881969794706

bigWarpedImg looks like this: http://picasaweb.google.com/103165673068768416583/Opencv#5565090880773608210

As you can see, in bigWarpedImg the left and upper border is to small whereas the right and bottom border is too thick. It looks like a bug in OpenCV. Is this one or do I use this function incorrectly?

答:
```<code>Mat bigWarpedImg = Mat(120,120,CV_8UC1);
</code>```

this line is unneccessary - resize will allocate the target Mat to make it fit, so Mat bigWarpedImg would be fine.

Not sure about the resizing - I always use the

```<code>resize(warpedImg, bigWarpedImg, Size(120,120), 0, 0, INTER_NEAREST);
</code>```

form of resize and never noticed such behaviour. I'd say it's a bug though, from the documentation it shouldn't act like that.

Title: How do I use cvResize/resize correctly?

Body:
I have trouble resizing a 6x6 image to 120x120. It looks like the resized image is somewhat shifted by 1 pixel. This happens with the cvResize and with cv::resize. My code looks like this:

warpPerspective(greyImg, warpedImg, homography, Size(6, 6));
Mat bigWarpedImg = Mat(120,120,CV_8UC1);
resize(warpedImg, bigWarpedImg, Size(0,0), 20, 20, INTER_NEAREST);

warpedImg looks like this (I resized it with gimp to make it easier to recognize): http://picasaweb.google.com/103165673068768416583/Opencv#5565090881969794706

bigWarpedImg looks like this: http://picasaweb.google.com/103165673068768416583/Opencv#5565090880773608210

As you can see, in bigWarpedImg the left and upper border is to small whereas the right and bottom border is too thick. It looks like a bug in OpenCV. Is this one or do I use this function incorrectly?

Body:
Mat bigWarpedImg = Mat(120,120,CV_8UC1);

this line is unneccessary - resize will allocate the target Mat to make it fit, so Mat bigWarpedImg would be fine.

Not sure about the resizing - I always use the

resize(warpedImg, bigWarpedImg, Size(120,120), 0, 0, INTER_NEAREST);

form of resize and never noticed such behaviour. I'd say it's a bug though, from the documentation it shouldn't act like that.


问:
multiple dynamically created buttons with same name using ajax
I'm trying to implement a comment section and after button-press I want to update the comment section with ajax so the page doesn't have to refresh...

In this comment section I have 1 textarea + 1 button + a couple of hidden fields for every comment so users can answer specific comments...

so if there are 50 comments there are also 50 answer-fields, 1 for each...

And every thing works except for 1 thing...

- either I name all id's of the buttons and fields the same name (ie. id="sendAnswer" and id="answer", id="userID", ...) and then only the first one works...

-or I dynamically name them all (ie. id="sendAnswer(echo $i) ) thereby naming them all id="sendAnswer0", "sendAnswer1", "sendAnswer2", ... and then I do that for the textarea and hidden fields too (ie. id="answer(echo $i), id="userID(echo $i), ...)

And that works great too... except for now I have to make a jQuery-script for each... and since they are dynamically created that's difficult - as how many there are changes as more comments comes in...

Code for approach 1: naming them all the same...

```<code>$(document).ready(function(){
    "use strict";
    $("#sendAnswer").click(function(){
        var comment = $("#comment").val();
        var userID = $("#userID").val();
        var randomStringVideo = $("#randomStringVideo").val();
        var commentID = $("#commentID").val();
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                $("#commentDiv").load(location.href + " #commentDiv>*", "");
                $("#commentsDiv").load(location.href + " #commentsDiv>*", "");
                $("#comment").val('');
            }
        });
    });
});
</code>```

And as I said... this works fine for the first one and the rest are duds...

Code for approach 2: I dynamically name all values...

```<code>$(document).ready(function(){
    "use strict";
    $("#sendAnswer"+$(this).val()).click(function(){ // this +$(this).val() doesn't work, only if I put #sendAnswer3 - then the 4th works and the rest are duds etc.
        var comment = $("#comment"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var userID = $("#userID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var randomStringVideo = $("#randomStringVideo"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var commentID = $("#commentID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                $("#commentDiv").load(location.href + " #commentDiv>*", "");
                $("#commentsDiv").load(location.href + " #commentsDiv>*", "");
                $("#comment"+$(this).val()).val(''); // this +$(this).val() doesn't work, only if I put #comment3 (matching the #sendAnswer)- then the 4th works and the rest are duds etc.
            }
        });
    });
});
</code>```

With this I would have to name every single possible #sendAnswer-number + #comment-number for it to work... and with an infinite set of numbers to choose from 0-(infinite) - that's not viable...

If of any interest...

Php that dynamically creates the buttons and fields in question

```<code>.
.
.
<?php if ($_SESSION[numberOfComments] != 0) {
    for ($i=0; $i<$_SESSION[numberOfComments]; $i++) ?> // run through all comments that aren't answers to other comments
        // show comment info
        <div class="media">// answer comment box starts here
            <img class="mr-3 rounded" src="<?php $file = USER . $_SESSION['randomString'] . THUMBNAIL; if ( file_exists ( $file ) ) {echo $file; } else { echo USER . "default" . THUMBNAIL; } ?>" width="50" height="50" data-toggle="tooltip" data-placement="left" title="<?php echo $_SESSION['username']; ?>">
            <div class="media-body">
                <textarea class="form-control" rows="2" type="text" name="comment<?php echo $i; ?>" id="comment<?php echo $i; ?>" value="" placeholder="Great video!"></textarea>
                <input type="hidden" name="userID<?php echo $i; ?>" id="userID<?php echo $i; ?>" value="<?php if ( isset ( $_SESSION['id'] ) ) { echo $_SESSION['id']; } ?>">
                <input type="hidden" name="randomStringVideo<?php echo $i; ?>" id="randomStringVideo<?php echo $i; ?>" value="<?php echo $_GET['v']; ?>">
                <input type="hidden" name="commentID<?php echo $i; ?>" id="commentID<?php echo $i; ?>" value="<?php echo $_SESSION['commentID_getComment']; ?>">
                <button type="button" class="btn btn-primary float-right margin-top-5" id="sendComment<?php echo $i; ?>" value="<?php echo $i; ?>">
                    Answer
                </button>
            </div>
        </div> // answer comment box ends here
        <?php if ($_SESSION[numberOfAnswers][$i] != 0) {
            for ($j=0; $j<$_SESSION[numberOfAnswers][$i]; $j++) { ?> // run through all answer to this comment
                // show answer info
            <?php }
        }
    }
} ?>
.
.
.
</code>```

答:
two ways .. 1st use classes instead of ids .OR. 2nd use selector id starts with [id^="something"] .. and on both ways you need to use $(this) to refer to the same section .. And for me its bad practice to use .load() to refresh the whole comment section you can directly get the specific comment and append it to the #commentDiv

by using $("#sendAnswer"+$(this).val()) $(this) in this case refer to nothing/window or something else but not to your element

$(document).ready(function(){
    "use strict";
    $('button[id^="sendAnswer"]').on('click',function(){
        var ThisIs = $(this);
        var ClosestDiv = ThisIs.closest('.media-body');
        var comment = ClosestDiv.find('textarea').val();
        var userID = ClosestDiv.find('[id^="userID"]').val();
        var randomStringVideo = ClosestDiv.find('[id^="randomStringVideo"]').val();
        var commentID = ClosestDiv.find('[id^="commentID"]').val();
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                var commentDiv = ThisIs.closest('.BigDiv').find('[id^="commentDiv"]'); // change `.BigDiv` with the div id/class which hold both commentDiv and comment section
                commentDiv.load(location.href + " #commentDiv>*", "");
                ClosestDiv.find('textarea').val('');
            }
        });
    });
});```

Note: Change .BigDiv with the div id/class which hold both
  commentDiv and comment section

Body:
I'm trying to implement a comment section and after button-press I want to update the comment section with ajax so the page doesn't have to refresh...

In this comment section I have 1 textarea + 1 button + a couple of hidden fields for every comment so users can answer specific comments...

so if there are 50 comments there are also 50 answer-fields, 1 for each...

And every thing works except for 1 thing...

- either I name all id's of the buttons and fields the same name (ie. id="sendAnswer" and id="answer", id="userID", ...) and then only the first one works...

-or I dynamically name them all (ie. id="sendAnswer(echo $i) ) thereby naming them all id="sendAnswer0", "sendAnswer1", "sendAnswer2", ... and then I do that for the textarea and hidden fields too (ie. id="answer(echo $i), id="userID(echo $i), ...)

And that works great too... except for now I have to make a jQuery-script for each... and since they are dynamically created that's difficult - as how many there are changes as more comments comes in...

Code for approach 1: naming them all the same...

$(document).ready(function(){
    "use strict";
    $("#sendAnswer").click(function(){
        var comment = $("#comment").val();
        var userID = $("#userID").val();
        var randomStringVideo = $("#randomStringVideo").val();
        var commentID = $("#commentID").val();
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                $("#commentDiv").load(location.href + " #commentDiv>*", "");
                $("#commentsDiv").load(location.href + " #commentsDiv>*", "");
                $("#comment").val('');
            }
        });
    });
});

And as I said... this works fine for the first one and the rest are duds...

Code for approach 2: I dynamically name all values...

$(document).ready(function(){
    "use strict";
    $("#sendAnswer"+$(this).val()).click(function(){ // this +$(this).val() doesn't work, only if I put #sendAnswer3 - then the 4th works and the rest are duds etc.
        var comment = $("#comment"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var userID = $("#userID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var randomStringVideo = $("#randomStringVideo"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        var commentID = $("#commentID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                $("#commentDiv").load(location.href + " #commentDiv>*", "");
                $("#commentsDiv").load(location.href + " #commentsDiv>*", "");
                $("#comment"+$(this).val()).val(''); // this +$(this).val() doesn't work, only if I put #comment3 (matching the #sendAnswer)- then the 4th works and the rest are duds etc.
            }
        });
    });
});

With this I would have to name every single possible #sendAnswer-number + #comment-number for it to work... and with an infinite set of numbers to choose from 0-(infinite) - that's not viable...

If of any interest...

Php that dynamically creates the buttons and fields in question

.
.
.
<?php if ($_SESSION[numberOfComments] != 0) {
    for ($i=0; $i<$_SESSION[numberOfComments]; $i++) ?> // run through all comments that aren't answers to other comments
        // show comment info

// answer comment box starts here
            <img class="mr-3 rounded" src="<?php $file = USER . $_SESSION['randomString'] . THUMBNAIL; if ( file_exists ( $file ) ) {echo $file; } else { echo USER . "default" . THUMBNAIL; } ?>" width="50" height="50" data-toggle="tooltip" data-placement="left" title="<?php echo $_SESSION['username']; ?>">

                <textarea class="form-control" rows="2" type="text" name="comment<?php echo $i; ?>" id="comment<?php echo $i; ?>" value="" placeholder="Great video!"></textarea>
                <input type="hidden" name="userID<?php echo $i; ?>" id="userID<?php echo $i; ?>" value="<?php if ( isset ( $_SESSION['id'] ) ) { echo $_SESSION['id']; } ?>">
                <input type="hidden" name="randomStringVideo<?php echo $i; ?>" id="randomStringVideo<?php echo $i; ?>" value="<?php echo $_GET['v']; ?>">
                <input type="hidden" name="commentID<?php echo $i; ?>" id="commentID<?php echo $i; ?>" value="<?php echo $_SESSION['commentID_getComment']; ?>">
                <button type="button" class="btn btn-primary float-right margin-top-5" id="sendComment<?php echo $i; ?>" value="<?php echo $i; ?>">
                    Answer
                </button>

 // answer comment box ends here
        <?php if ($_SESSION[numberOfAnswers][$i] != 0) {
            for ($j=0; $j<$_SESSION[numberOfAnswers][$i]; $j++) { ?> // run through all answer to this comment
                // show answer info
            <?php }
        }
    }
} ?>
.
.
.

Body:
two ways .. 1st use classes instead of ids .OR. 2nd use selector id starts with [id^="something"] .. and on both ways you need to use $(this) to refer to the same section .. And for me its bad practice to use .load() to refresh the whole comment section you can directly get the specific comment and append it to the #commentDiv

by using $("#sendAnswer"+$(this).val()) $(this) in this case refer to nothing/window or something else but not to your element

$(document).ready(function(){
    "use strict";
    $('button[id^="sendAnswer"]').on('click',function(){
        var ThisIs = $(this);
        var ClosestDiv = ThisIs.closest('.media-body');
        var comment = ClosestDiv.find('textarea').val();
        var userID = ClosestDiv.find('[id^="userID"]').val();
        var randomStringVideo = ClosestDiv.find('[id^="randomStringVideo"]').val();
        var commentID = ClosestDiv.find('[id^="commentID"]').val();
        $.ajax({
            type: "POST",
            url:'../scripts/comment.php',
            data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
            success:function(){
                var commentDiv = ThisIs.closest('.BigDiv').find('[id^="commentDiv"]'); // change `.BigDiv` with the div id/class which hold both commentDiv and comment section
                commentDiv.load(location.href + " #commentDiv>*", "");
                ClosestDiv.find('textarea').val('');
            }
        });
    });
});

Note: Change .BigDiv with the div id/class which hold both
  commentDiv and comment section


问:
Where-Object with Get-Content not working
I have a file, say a.txt with the following content:

```<code>STATUS
-----
Pending
</code>```

I am running the following query:

```<code>Get-Content a.txt | Where-Object Status -Match 'Pending'
</code>```

The above query returns nothing.

Adding to my requirement:

I need to get the content in a variable, like

$contentOfFile = Get-Content a.txt

This variable is passed to a function that verifies if it has the match

$contentOfFile | **Where-Object Status -Match 'Pending'**

Note: Where-Object Status -Match 'Pending' cannot be changed to Select-String because the function is used by many sources.

FIX:

```<code>$contentOfFile = ConvertFrom-Csv (Get-Content a.txt)
$contentOfFile | Where-Object Status -Match 'Pending'
</code>```

答:
When you use Get-Content , the STATUS in your text file is stored as a plain text and not as a property. If you intend to use Get-Content, you can use Select-String cmdlet like

Get-Content a.txt | Select-String -pattern 'Pending'

But if you want to get the output as you desire, you can use the Import-Csv. What it will do is, it will make your STATUS as a -Header property and then you can use the where-object as you have used earlier. After all, a csv file is a text file, just comma-separated. Below works for me:-

Import-Csv a.txt | Where-Object Status -Match 'Pending'

Body:
I have a file, say a.txt with the following content:

STATUS
-----
Pending

I am running the following query:

Get-Content a.txt | Where-Object Status -Match 'Pending'

The above query returns nothing.

Adding to my requirement:

I need to get the content in a variable, like

$contentOfFile = Get-Content a.txt

This variable is passed to a function that verifies if it has the match

$contentOfFile | **Where-Object Status -Match 'Pending'**

Note: Where-Object Status -Match 'Pending' cannot be changed to Select-String because the function is used by many sources.

FIX:

$contentOfFile = ConvertFrom-Csv (Get-Content a.txt)
$contentOfFile | Where-Object Status -Match 'Pending'


问:
How do I make an SOQL Query with Spaces in Column Names?
I'm trying to make an SOQL query using the simple_salesforce python package. I'm having a bit of trouble querying columns which have spaces in the column names:

```<code>sf.query_all("SELECT Id, Name, Email FROM Lead WHERE `Lead Source`=Calculator (Website)")
</code>```

I'm trying to use the conventional SQL syntax of dealing with pesky column names (I have also tried [] brackets) but I keep getting a SalesforceMalformedRequest.

I want to get a python dict which contains the IDs, Names and Emails of any leads that have a lead source of 'Calculator (Website)'.

I don't have privileges to change the column names, so any help on how to query, or how to access the column names in some other way, would be a lot of help!

答:
As @user2864740 mentioned in the comments above, Salesforce doesn't allow spaces in field api names. In this situation, assuming you are trying to query the standard field with the English label of "Lead Source", the api name is LeadSource

You would want your query to be:

```<code>sf.query_all("SELECT Id, Name, Email FROM Lead WHERE LeadSource = 'Calculator (Website)'")
</code>```

Body:
I'm trying to make an SOQL query using the simple_salesforce python package. I'm having a bit of trouble querying columns which have spaces in the column names:

sf.query_all("SELECT Id, Name, Email FROM Lead WHERE `Lead Source`=Calculator (Website)")

I'm trying to use the conventional SQL syntax of dealing with pesky column names (I have also tried [] brackets) but I keep getting a SalesforceMalformedRequest.

I want to get a python dict which contains the IDs, Names and Emails of any leads that have a lead source of 'Calculator (Website)'.

I don't have privileges to change the column names, so any help on how to query, or how to access the column names in some other way, would be a lot of help!

Body:
As @user2864740 mentioned in the comments above, Salesforce doesn't allow spaces in field api names. In this situation, assuming you are trying to query the standard field with the English label of "Lead Source", the api name is LeadSource

You would want your query to be:

sf.query_all("SELECT Id, Name, Email FROM Lead WHERE LeadSource = 'Calculator (Website)'")


答:
function Code (b) {
  this.b = b
  this.arr = []
}

Code.prototype.add = function(v) {
  console.log(this.b)
  this.arr.forEach(element => {
    console.log(element)
  });
  this.arr.push(v)
}

var c = new Code('bla')
console.log(c.add('asdf'))```

Title: Object prototype can't access properties with `this`


问:
Rails migration strategies on horizontally scaled apps
Assume I have an OpsWorks Rails application running with load and time based scaling.

What happens if I deploy code where there are multiple application servers running, in which multiple rake db:migrate is executed across the application servers?

Does Rails have any guard against this? OR would I specifically need to specify a single server that is responsible for running the migrations?

I am also curious to hear about migration strategies for Rails + RDS (Postgresql) on AWS.

答:
The answer is Yes, Rails had a guard against this situation

First, the RDS itself can cache your queries. So for example, 2 of your instances running one CREATE INDEX query at the same time, the RDS itself can handle it.

Second, Rails automatically create a table named schema_migrations. When one of your instances running db:migrate, the table schema_migrations can help the other instances know that the database is already migrated up ( just like a version management system )

But, there is a bad practice that you wrote some custom queries in db/migrate/***.rb file, then your query might not be handled correctly by RDS.

If you have to do something like update data by custom domain, you should write a rake task and manually execute it.

So, if you only use db:migrate to update data structure, then everything already handled for you, even you had hundreds instances.

For more information, please refer Rails's document


问:
What's the use of magic method __wakeup as I can reconstruct any resources that the object may have using unserizlize() only?
According to the documentation :

unserialize() checks for the presence of a function with the magic
  name __wakeup(). If present, this function can reconstruct any
  resources that the object may have.

The intended use of __wakeup() is to reestablish any database
  connections that may have been lost during serialization and perform
  other reinitialization tasks.

If my object has not defined __wakeup() method I can still have reconstructed form of my object using unserialize() then why this magic method is there in PHP?

Documentation is also saying the same thing that __wakeup() function can reconstruct any resources that the object may have just like unserialize() do.

When this magic method __wakeup() gets called before unserialization starts or after unserialization finished?

答:
Maybe this code can help you, when you serialize one object instance of Test the database connection is closed and is not saved in serialized form, when you unserialize this object the __wakeup() method reestablish  the database connection upon unserialization, so you can use these resources inmediatly, you can see the use of $objTest->getUserInfo() upon unserialization. You can use __wakeup to do calculus or open files connections, etc...</p>

```<code>class Test
{
    public $userId;

    private $_db = null;

    public function __wakeup()
    {
        if (null === $this->_db)
        {
            $this->_db = getConnection();
        }
    }

    public function getUserInfo(){
        $info = $this->_db->query("SELECT * FROM users WHERE id = " . intval($this->userId, 10));
        return $info;
    }
}

function getConnection(){
    $user = "my_user_db";
    $password = "my_password_db";
    return new PDO('mysql:host=my_host_db;dbname=my_database', $user, $password);
}

$objTest = unserialize("O:4:\"Test\":2:{s:6:\"userId\";s:2:\"43\";s:9:\" Test _db\";N;}", ['Test']);
$userInfo = $objTest->getUserInfo();
</code>```

Body:
Maybe this code can help you, when you serialize one object instance of Test the database connection is closed and is not saved in serialized form, when you unserialize this object the __wakeup() method reestablish  the database connection upon unserialization, so you can use these resources inmediatly, you can see the use of $objTest->getUserInfo() upon unserialization. You can use __wakeup to do calculus or open files connections, etc...

class Test
{
    public $userId;

    private $_db = null;

    public function __wakeup()
    {
        if (null === $this->_db)
        {
            $this->_db = getConnection();
        }
    }

    public function getUserInfo(){
        $info = $this->_db->query("SELECT * FROM users WHERE id = " . intval($this->userId, 10));
        return $info;
    }
}

function getConnection(){
    $user = "my_user_db";
    $password = "my_password_db";
    return new PDO('mysql:host=my_host_db;dbname=my_database', $user, $password);
}

$objTest = unserialize("O:4:\"Test\":2:{s:6:\"userId\";s:2:\"43\";s:9:\" Test _db\";N;}", ['Test']);
$userInfo = $objTest->getUserInfo();


问:
Spaces between CardView
I am working on a RecycleView and CardView, but there are spaces between cards that seem are too long, can you show me how to fix it please i have 2 files

friends_list_item.xml

```<code>    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="16dp"
    >

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/friendsList"
        >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        >

    <ImageView
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:id="@+id/picture"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="16dp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/username"
            android:layout_toRightOf="@+id/picture"
            android:layout_alignParentTop="true"

            android:textStyle="bold" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/status"
            android:layout_toRightOf="@+id/picture"
            android:layout_below="@+id/username"
            />

    </RelativeLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>
</code>```

fragment_find_friends.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<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:background="#e6e6e6"
              android:orientation="vertical"
              tools:ignore="TextFields,ContentDescription,UselessParent">

    <LinearLayout
        android:id="@+id/searchFieldContainer"
        android:background="@color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/searchField"

            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:layout_weight="1"
            android:hint="@string/search_elipses"/>

        <ImageButton
            android:id="@+id/searchBtn"
            android:layout_width="46dp"
            android:layout_height="46dp"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:background="@drawable/bg_follow_button"
            android:src="@drawable/ic_done_white_24dp"/>
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/friendsList"/>

</LinearLayout>
</code>```

here is the screenshot:

答:
You can change Linearlayout padding value 16dp to distance which you want</p>

```<code> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="16dp"
    >
</code>```

Title: Spaces between CardView

Body:
I am working on a RecycleView and CardView, but there are spaces between cards that seem are too long, can you show me how to fix it please i have 2 files

friends_list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="16dp"
    >

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/friendsList"
        >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        >

    <ImageView
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:id="@+id/picture"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="16dp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/username"
            android:layout_toRightOf="@+id/picture"
            android:layout_alignParentTop="true"

            android:textStyle="bold" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/status"
            android:layout_toRightOf="@+id/picture"
            android:layout_below="@+id/username"
            />

    </RelativeLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

fragment_find_friends.xml

<?xml version="1.0" encoding="utf-8"?>
<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:background="#e6e6e6"
              android:orientation="vertical"
              tools:ignore="TextFields,ContentDescription,UselessParent">

    <LinearLayout
        android:id="@+id/searchFieldContainer"
        android:background="@color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/searchField"

            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:layout_weight="1"
            android:hint="@string/search_elipses"/>

        <ImageButton
            android:id="@+id/searchBtn"
            android:layout_width="46dp"
            android:layout_height="46dp"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:background="@drawable/bg_follow_button"
            android:src="@drawable/ic_done_white_24dp"/>
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/friendsList"/>

</LinearLayout>

here is the screenshot:

Body:
You can change Linearlayout padding value 16dp to distance which you want

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="16dp"
    >


问:
How to identify a word with a dollar sign $
I am trying to extract information based on if a string starts with a dollar sign.

I have a string "I bought $BTC"

I am trying to get if word in string starts with dollar sign, get me the word. So I am trying to get in this case "BTC". I tried, string.replace methods and findall, however cannot extract this information. I further read that dollar sign is used as interpolation in Python, I am assuming this is causing the issue.

Are there any ideas that can help me with this?

答:
Try this for your regex:

```<code>(?<=\$)\w+
</code>```

It will capture any alphanumeric characters after the $. You can experiment your regex using pythex.org

Body:
Try this for your regex:

(?<=\$)\w+

It will capture any alphanumeric characters after the $. You can experiment your regex using pythex.org