问:
Binary XML runtime exception when trying to start activity
I'm trying to launch the application, but I get a RuntimeException stating that "RuntimeException: Unable to start activity ". Can someone help me?

Here's the code:

```<code>public class MainActivity extends AppCompatActivity {
    LinearLayout splash_screen;
    WebView myWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myWebView = (WebView)findViewById(R.id.webview);
        splash_screen = (LinearLayout) findViewById(R.id.splash_screen);
        myWebView.loadUrl("https://www.africanshooting.com");
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        myWebView.setWebViewClient(new MyWebViewClient());
        if (!isConnected())
        {
            AlertDialog alert = new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle("Internet Connection")
                    .setMessage("Oups!il semblerait que vous n'etes pas connecter verifier vos parametres reseau")
                    .setPositiveButton("Fermer", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    }).create();
                    alert.show();
        }

    }
    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            splash_screen.setVisibility(View.VISIBLE);
            view.setVisibility(View.INVISIBLE);

        }
        @Override
        public void onPageFinished(WebView view, String url) {
            splash_screen.setVisibility(View.GONE);
            view.setVisibility(View.VISIBLE);
            super.onPageFinished(view, url);
        }
    }  private boolean isConnected() {
        ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo= connectivityManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}
</code>```

And here's the log:

```<code>E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.africanshooting, PID: 25248
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.africanshooting/com.example.africanshooting.MainActivity}: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.constraint.RelativeLayout" on path: DexPathList[[zip file "/data/app/com.example.africanshooting-2/base.apk"],nativeLibraryDirectories=[/data/app/com.example.africanshooting-2/lib/arm, /vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        at android.view.LayoutInflater.createView(LayoutInflater.java:583)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
        Suppressed: java.lang.ClassNotFoundException: android.support.constraint.RelativeLayout
        at java.lang.Class.classForName(Native Method)
        at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
</code>```

答:
Or add the dependency to your project. Add the dependency to your project in the build.gradle file.

Depending in which version you are using something like that:

```<code>dependencies {
  compile 'com.android.support:support-v4:23.2.1'
  compile 'com.android.support.constraint:constraint-layout:1.0.0'
}
</code>```

Body:
I'm trying to launch the application, but I get a RuntimeException stating that "RuntimeException: Unable to start activity ". Can someone help me?

Here's the code:

public class MainActivity extends AppCompatActivity {
    LinearLayout splash_screen;
    WebView myWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myWebView = (WebView)findViewById(R.id.webview);
        splash_screen = (LinearLayout) findViewById(R.id.splash_screen);
        myWebView.loadUrl("https://www.africanshooting.com");
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        myWebView.setWebViewClient(new MyWebViewClient());
        if (!isConnected())
        {
            AlertDialog alert = new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle("Internet Connection")
                    .setMessage("Oups!il semblerait que vous n'etes pas connecter verifier vos parametres reseau")
                    .setPositiveButton("Fermer", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    }).create();
                    alert.show();
        }

    }
    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            splash_screen.setVisibility(View.VISIBLE);
            view.setVisibility(View.INVISIBLE);

        }
        @Override
        public void onPageFinished(WebView view, String url) {
            splash_screen.setVisibility(View.GONE);
            view.setVisibility(View.VISIBLE);
            super.onPageFinished(view, url);
        }
    }  private boolean isConnected() {
        ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo= connectivityManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}

And here's the log:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.africanshooting, PID: 25248
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.africanshooting/com.example.africanshooting.MainActivity}: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class android.support.constraint.RelativeLayout
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.constraint.RelativeLayout" on path: DexPathList[[zip file "/data/app/com.example.africanshooting-2/base.apk"],nativeLibraryDirectories=[/data/app/com.example.africanshooting-2/lib/arm, /vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        at android.view.LayoutInflater.createView(LayoutInflater.java:583)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.africanshooting.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6309)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5788)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
        Suppressed: java.lang.ClassNotFoundException: android.support.constraint.RelativeLayout
        at java.lang.Class.classForName(Native Method)
        at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:504)

Body:
Or add the dependency to your project. Add the dependency to your project in the build.gradle file.

Depending in which version you are using something like that:

dependencies {
  compile 'com.android.support:support-v4:23.2.1'
  compile 'com.android.support.constraint:constraint-layout:1.0.0'
}


来源: stackexchange

问:
Imputer on some Dataframe columns in Python
I am learning how to use Imputer on Python.

This is my code:

```<code>df=pd.DataFrame([["XXL", 8, "black", "class 1", 22],
["L", np.nan, "gray", "class 2", 20],
["XL", 10, "blue", "class 2", 19],
["M", np.nan, "orange", "class 1", 17],
["M", 11, "green", "class 3", np.nan],
["M", 7, "red", "class 1", 22]])

df.columns=["size", "price", "color", "class", "boh"]

from sklearn.preprocessing import Imputer

imp=Imputer(missing_values="NaN", strategy="mean" )
imp.fit(df["price"])

df["price"]=imp.transform(df["price"])
</code>```

However this rises the following error:
ValueError: Length of values does not match length of index

What's wrong with my code???

Thanks for helping

答:
Here is the documentation for Simple Imputer For the fit method, it takes array-like or sparse metrix as an input parameter.
you can try this :

```<code>imp.fit(df.iloc[:,1:2])
df['price']=imp.transform(df.iloc[:,1:2])
</code>```

provide index location to fit method and then apply the transform.

```<code>>>> df
   size  price   color    class   boh
 0  XXL    8.0   black  class 1  22.0
 1    L    9.0    gray  class 2  20.0
 2   XL   10.0    blue  class 2  19.0
 3    M    9.0  orange  class 1  17.0
 4    M   11.0   green  class 3   NaN
 5    M    7.0     red  class 1  22.0
</code>```

Same way you can do for boh

```<code>imp.fit(df.iloc[:,4:5])
df['price']=imp.transform(df.iloc[:,4:5])
>>> df
    size  price   color    class   boh
 0  XXL    8.0   black  class 1  22.0
 1    L    9.0    gray  class 2  20.0
 2   XL   10.0    blue  class 2  19.0
 3    M    9.0  orange  class 1  17.0
 4    M   11.0   green  class 3  20.0
 5    M    7.0     red  class 1  22.0
</code>```

Kindly correct me if I am wrong. Suggestions will be appreciated.

ContentLicense: CC BY-SA 3.0

Body:
I am learning how to use Imputer on Python.

This is my code:

df=pd.DataFrame([["XXL", 8, "black", "class 1", 22],
["L", np.nan, "gray", "class 2", 20],
["XL", 10, "blue", "class 2", 19],
["M", np.nan, "orange", "class 1", 17],
["M", 11, "green", "class 3", np.nan],
["M", 7, "red", "class 1", 22]])

df.columns=["size", "price", "color", "class", "boh"]

from sklearn.preprocessing import Imputer

imp=Imputer(missing_values="NaN", strategy="mean" )
imp.fit(df["price"])

df["price"]=imp.transform(df["price"])

However this rises the following error:
ValueError: Length of values does not match length of index

What's wrong with my code???

Thanks for helping

Body:
Here is the documentation for Simple Imputer For the fit method, it takes array-like or sparse metrix as an input parameter.
you can try this :

imp.fit(df.iloc[:,1:2])
df['price']=imp.transform(df.iloc[:,1:2])

provide index location to fit method and then apply the transform.

>>> df
   size  price   color    class   boh
 0  XXL    8.0   black  class 1  22.0
 1    L    9.0    gray  class 2  20.0
 2   XL   10.0    blue  class 2  19.0
 3    M    9.0  orange  class 1  17.0
 4    M   11.0   green  class 3   NaN
 5    M    7.0     red  class 1  22.0

Same way you can do for boh

imp.fit(df.iloc[:,4:5])
df['price']=imp.transform(df.iloc[:,4:5])
>>> df
    size  price   color    class   boh
 0  XXL    8.0   black  class 1  22.0
 1    L    9.0    gray  class 2  20.0
 2   XL   10.0    blue  class 2  19.0
 3    M    9.0  orange  class 1  17.0
 4    M   11.0   green  class 3  20.0
 5    M    7.0     red  class 1  22.0

Kindly correct me if I am wrong. Suggestions will be appreciated.

ContentLicense: CC BY-SA 4.0


问:
Store integers as integers and not as floats
I do the following:

```<code>import pandas as pd

df_texts = pd.read_csv('data_texts.csv', keep_default_na=True)

for index, row in df_texts.iterrows():

    list_of_words = row['text'].split()

    df_texts.loc[index, '#_words'] = len(list_of_words)

    list_of_unique_words = set(list_of_words)

    df_texts.loc[index, '#_unique_words'] = len(list_of_unique_words)
</code>```

The problem is that the numbers at the #_words and at the #_unique_words columns are stored as floats even though they are integers.

Just to clarify that these two columns do not pre-exist in the .csv which I read (pd.read_csv) but I create them in the for loop.

How can I directly store them as integers?

答:
A better way to do this and directly get ints is to assign the new columns directly, and avoid iterating through the dataframe altogether.

With some dummy data for an example:

```<code>import pandas as pd
texts = ['word1 word2 word3', 'word1 word2 word1', 'word3']

df_texts = pd.DataFrame(texts, columns = ['text'])
                text
0  word1 word2 word3
1  word1 word2 word1
2              word3
</code>```

Calculate the length for all rows using the text column separately and then assign.

```<code>temp = df_texts['text'].str.split()
df_texts['#_words'] = [len(row) for row in temp] #iterates and creates a list of all lengths. assign to df
df_texts['#_unique_words'] = [len(set(row)) for row in temp]

print(df_texts)
#Output:
                text  #_words  #_unique_words
0  word1 word2 word3        3               3
1  word1 word2 word1        3               2
2              word3        1               1
</code>```

Body:
I do the following:

import pandas as pd

df_texts = pd.read_csv('data_texts.csv', keep_default_na=True)

for index, row in df_texts.iterrows():

    list_of_words = row['text'].split()

    df_texts.loc[index, '#_words'] = len(list_of_words)

    list_of_unique_words = set(list_of_words)

    df_texts.loc[index, '#_unique_words'] = len(list_of_unique_words)

The problem is that the numbers at the #_words and at the #_unique_words columns are stored as floats even though they are integers.

Just to clarify that these two columns do not pre-exist in the .csv which I read (pd.read_csv) but I create them in the for loop.

How can I directly store them as integers?

Body:
A better way to do this and directly get ints is to assign the new columns directly, and avoid iterating through the dataframe altogether.

With some dummy data for an example:

import pandas as pd
texts = ['word1 word2 word3', 'word1 word2 word1', 'word3']

df_texts = pd.DataFrame(texts, columns = ['text'])
                text
0  word1 word2 word3
1  word1 word2 word1
2              word3

Calculate the length for all rows using the text column separately and then assign.

temp = df_texts['text'].str.split()
df_texts['#_words'] = [len(row) for row in temp] #iterates and creates a list of all lengths. assign to df
df_texts['#_unique_words'] = [len(set(row)) for row in temp]

print(df_texts)
#Output:
                text  #_words  #_unique_words
0  word1 word2 word3        3               3
1  word1 word2 word1        3               2
2              word3        1               1


问:
How to add tslib plugin in qtwebbrowser application?
I'm trying to run a web based application on an embedded hardware using QT Web browser using qws eglfs frame buffer. I'm trying to include tslib for the touchscreen to work properly but couldn't figure out how to add the tslib plugin in qt web browser. Facing an issue saying that no plugin detected. Any idea on how to solve this?
P.S: There is no X11 server. It's just on frame buffer.</p>

答:
First, make sure its installed.
You then can define

```<code>export QT_QPA_EGLFS_TSLIB=1
</code>```

or start the app with

```<code>/path/to/app - plugin tslib
</code>```

Body:
First, make sure its installed.
You then can define

export QT_QPA_EGLFS_TSLIB=1

or start the app with

/path/to/app - plugin tslib


问:
How to purge test sessions in Botium
I'm trying to run Test Set but it looks like it is stucked. All 5 agents are in use and I cannot delete them. Tests fail on ESOCKETTIMEDOUT. I could run same test without problems before.

I tried to click on "Send cancellation request" to Test Session in danger zone to kill it, but I still  can't delete agents (Delete Botium Agent (only possible if not already used)).

Botium agents pic

Log from Botium:

2019-05-31T08:31:13.892Z: Job queued for execution
2019-05-31T08:31:13.886Z: 2019-05-31T08:31:13.378Z botium-box-worker-runtestcases Started processing, JobId #952.

2019-05-31T08:31:14.077Z: 2019-05-31T08:31:13.382Z botium-BotDriver Loaded Botium configuration file ./botium.json

2019-05-31T08:31:14.143Z: 2019-05-31T08:31:13.388Z botium-BotDriver BuildCompiler: Capabilites: { PROJECTNAME: 'TM new - Test Session',
  TEMPDIR: 'botiumwork',
  CLEANUPTEMPDIR: true,
  WAITFORBOTTIMEOUT: 10000,
  SIMULATE_WRITING_SPEED: false,
  DOCKERCOMPOSEPATH: 'docker-compose',
  DOCKERMACHINEPATH: 'docker-machine',
  DOCKERMACHINE: false,
  DOCKERIMAGE: 'node:boron',
  DOCKERUNIQUECONTAINERNAMES: false,
  DOCKERSYSLOGPORT_RANGE: '47100-47299',
  BOT_HEALTH_STATUS: 200,
  SLACK_PUBLISHPORT_RANGE: '46100-46299',
  FACEBOOK_PUBLISHPORT_RANGE: '46300-46499',
  FACEBOOK_SEND_DELIVERY_CONFIRMATION: true,
  BOTFRAMEWORK_PUBLISHPORT_RANGE: '46500-46699',
  BOTFRAMEWORK_WEBHOOK_PORT: 3978,
  BOTFRAMEWORK_WEBHOOK_PATH: 'api/messages',
  BOTFRAMEWORK_CHANNEL_ID: 'facebook',
  SIMPLEREST_PING_RETRIES: 6,
  SIMPLEREST_PING_TIMEOUT: 10000,
  SIMPLEREST_PING_VERB: 'GET',
  SIMPLEREST_METHOD: 'GET',
  WEBSPEECH_SERVER_PORT: 46050,
  WEBSPEECH_LANGUAGE: 'en-US',
  WEBSPEECH_CLOSEBROWSER: true,
  SCRIPTING_TXT_EOL: '\n',
  SCRIPTING_XLSX_EOL_SPLIT: '\r',
  SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  SCRIPTING_XLSX_STARTROW: 2,
  SCRIPTING_XLSX_STARTCOL: 1,
  SCRIPTING_NORMALIZE_TEXT: false,
  SCRIPTING_ENABLE_MEMORY: false,
  SCRIPTING_MATCHING_MODE: 'includeLowerCase',
  SCRIPTING_UTTEXPANSION_MODE: 'all',
  SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  RETRY_USERSAYS_ONERROR_REGEXP: [],
  RETRY_USERSAYS_NUMRETRIES: 1,
  RETRY_USERSAYS_FACTOR: 1,
  RETRY_USERSAYS_MINTIMEOUT: 1000,
  ASSERTERS:
   [ { ref: 'HASLINK',
       src: 'botium-asserter-basiclink',
       global: false,
       args: null } ],
  LOGIC_HOOKS: [],
  USER_INPUTS: [],
  CONTAINERMODE: 'webdriverio',
  WEBDRIVERIO_URL: 'https://chat.t-mobile.cz/chat/',
  WEBDRIVERIO_PROFILE: '',
  WEBDRIVERIO_INPUT_ELEMENT: '<input />',
  WEBDRIVERIO_INPUT_ELEMENT_VISIBLE_TIMEOUT: 10000,
  WEBDRIVERIO_OUTPUT_ELEMENT:
   "//div[@class='gaid-text-message gaid-text-message--isBot'][position()=last()-1]//p",
  WEBDRIVERIO_IGNOREUPFRONTMESSAGES: false,
  WEBDRIVERIO_USERNAME: '',
  WEBDRIVERIO_PASSWORD: '',
  WEBDRIVERIO_SCREENSHOTS: 'onstop',
  FBPAGERECEIVER_REDISURL: { port: '6379', host: 'redis', db: 0, options: {} },
  WEBDRIVERIO_OPTIONS:
   { desiredCapabilities: { browserName: 'chrome', name: 'TM new - Test Session' },
     protocol: 'http',
     host: '192.168.99.100',
     port: '4444',
     path: '/wd/hub' } }

2019-05-31T08:31:14.169Z: 2019-05-31T08:31:13.393Z botium-ScriptingProvider Using matching mode: includeLowerCase

2019-05-31T08:31:14.214Z: 2019-05-31T08:31:13.396Z botium-asserterUtils Loaded Default asserter - [ 'BUTTONS',
  'MEDIA',
  'PAUSE_ASSERTER',
  'ENTITIES',
  'ENTITY_VALUES',
  'INTENT',
  'INTENT_CONFIDENCE' ]

2019-05-31T08:31:14.251Z: 2019-05-31T08:31:13.402Z botium-asserterUtils Loaded Default logic hook - [ 'PAUSE',
  'WAITFORBOT',
  'SET_SCRIPTING_MEMORY',
  'CLEAR_SCRIPTING_MEMORY',
  'INCLUDE' ]

2019-05-31T08:31:14.339Z: 2019-05-31T08:31:13.403Z botium-asserterUtils Loaded Default user input - [ 'BUTTON', 'MEDIA', 'FORM' ]

2019-05-31T08:31:14.396Z: 2019-05-31T08:31:13.407Z botium-asserterUtils Trying to load HASLINK asserter from botium-asserter-basiclink

2019-05-31T08:31:14.433Z: 2019-05-31T08:31:13.410Z botium-asserterUtils Loaded HASLINK SUCCESSFULLY

2019-05-31T08:31:14.470Z: 2019-05-31T08:31:13.504Z botium-box-worker-runtestcases found 1 convos ...

2019-05-31T08:31:14.512Z: 2019-05-31T08:31:13.504Z botium-box-worker-runtestcases batchNum: 1 batchCount: 1 convosPerBatch: 1 batchStart: 0 batchEnd: 0 batchLength: 1

2019-05-31T08:31:14.548Z: 2019-05-31T08:31:13.507Z botium-BotDriver Build - Botium Core Version: 1.4.14

2019-05-31T08:31:14.586Z: 2019-05-31T08:31:13.510Z botium-BotDriver Build - Capabilites: { PROJECTNAME: 'TM new - Test Session',
  TEMPDIR: 'botiumwork',
  CLEANUPTEMPDIR: true,
  WAITFORBOTTIMEOUT: 10000,
  SIMULATE_WRITING_SPEED: false,
  DOCKERCOMPOSEPATH: 'docker-compose',
  DOCKERMACHINEPATH: 'docker-machine',
  DOCKERMACHINE: false,
  DOCKERIMAGE: 'node:boron',
  DOCKERUNIQUECONTAINERNAMES: false,
  DOCKERSYSLOGPORT_RANGE: '47100-47299',
  BOT_HEALTH_STATUS: 200,
  SLACK_PUBLISHPORT_RANGE: '46100-46299',
  FACEBOOK_PUBLISHPORT_RANGE: '46300-46499',
  FACEBOOK_SEND_DELIVERY_CONFIRMATION: true,
  BOTFRAMEWORK_PUBLISHPORT_RANGE: '46500-46699',
  BOTFRAMEWORK_WEBHOOK_PORT: 3978,
  BOTFRAMEWORK_WEBHOOK_PATH: 'api/messages',
  BOTFRAMEWORK_CHANNEL_ID: 'facebook',
  SIMPLEREST_PING_RETRIES: 6,
  SIMPLEREST_PING_TIMEOUT: 10000,
  SIMPLEREST_PING_VERB: 'GET',
  SIMPLEREST_METHOD: 'GET',
  WEBSPEECH_SERVER_PORT: 46050,
  WEBSPEECH_LANGUAGE: 'en-US',
  WEBSPEECH_CLOSEBROWSER: true,
  SCRIPTING_TXT_EOL: '\n',
  SCRIPTING_XLSX_EOL_SPLIT: '\r',
  SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  SCRIPTING_XLSX_STARTROW: 2,
  SCRIPTING_XLSX_STARTCOL: 1,
  SCRIPTING_NORMALIZE_TEXT: false,
  SCRIPTING_ENABLE_MEMORY: false,
  SCRIPTING_MATCHING_MODE: 'includeLowerCase',
  SCRIPTING_UTTEXPANSION_MODE: 'all',
  SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  RETRY_USERSAYS_ONERROR_REGEXP: [],
  RETRY_USERSAYS_NUMRETRIES: 1,
  RETRY_USERSAYS_FACTOR: 1,
  RETRY_USERSAYS_MINTIMEOUT: 1000,
  ASSERTERS:
   [ { ref: 'HASLINK',
       src: 'botium-asserter-basiclink',
       global: false,
       args: null } ],
  LOGIC_HOOKS: [],
  USER_INPUTS: [],
  CONTAINERMODE: 'webdriverio',
  WEBDRIVERIO_URL: 'https://chat.t-mobile.cz/chat/',
  WEBDRIVERIO_PROFILE: '',
  WEBDRIVERIO_INPUT_ELEMENT: '<input />',
  WEBDRIVERIO_INPUT_ELEMENT_VISIBLE_TIMEOUT: 10000,
  WEBDRIVERIO_OUTPUT_ELEMENT:
   "//div[@class='gaid-text-message gaid-text-message--isBot'][position()=last()-1]//p",
  WEBDRIVERIO_IGNOREUPFRONTMESSAGES: false,
  WEBDRIVERIO_USERNAME: '',
  WEBDRIVERIO_PASSWORD: '',
  WEBDRIVERIO_SCREENSHOTS: 'onstop',
  FBPAGERECEIVER_REDISURL: { port: '6379', host: 'redis', db: 0, options: {} },
  WEBDRIVERIO_OPTIONS:
   { desiredCapabilities: { browserName: 'chrome', name: 'TM new - Test Session' },
     protocol: 'http',
     host: '192.168.99.100',
     port: '4444',
     path: '/wd/hub' } }

2019-05-31T08:31:14.636Z: 2019-05-31T08:31:13.519Z botium-BotDriver Build - Sources : { LOCALPATH: '.',
  GITPATH: 'git',
  GITBRANCH: 'master',
  GITDIR: '.' }

2019-05-31T08:31:14.671Z: 2019-05-31T08:31:13.524Z botium-BotDriver Build - Envs : { IS_BOTIUM_CONTAINER: true }

2019-05-31T08:31:14.704Z: 2019-05-31T08:31:13.592Z botium-PluginConnectorContainer Invalid Botium plugin loaded from webdriverio, expected PluginVersion, PluginClass fields

2019-05-31T08:31:14.732Z: 2019-05-31T08:31:13.595Z botium-PluginConnectorContainer Botium plugin botium-connector-webdriverio loaded

2019-05-31T08:31:14.769Z: 2019-05-31T08:31:13.597Z botium-connector-webdriverio Validate called

2019-05-31T08:31:14.801Z: 2019-05-31T08:31:13.600Z botium-connector-webdriverio Build called

2019-05-31T08:31:14.837Z: 2019-05-31T08:31:13.603Z botium-connector-webdriverio Start called

2019-05-31T08:31:24.389Z: 2019-05-31T08:31:24.371Z botium-box-worker sending heartbeat ...

2019-05-31T08:36:24.471Z: 2019-05-31T08:36:24.420Z botium-box-worker sending heartbeat ...

2019-05-31T08:37:15.925Z: 2019-05-31T08:37:15.880Z botium-box-worker-runtestcases Test Session Run failed (Error: ESOCKETTIMEDOUT), doing additional BotDriver Clean.

2019-05-31T08:37:15.961Z: 2019-05-31T08:37:15.881Z botium-connector-webdriverio Clean called

2019-05-31T08:40:02.054Z: 2019-05-31T08:40:02.006Z botium-BaseContainer Cleanup rimrafing temp dir /app/agent/botiumwork/TM-new-Test-Session-20190531-083113-vI4Bx

2019-05-31T08:40:02.357Z: Job failed: Error: ESOCKETTIMEDOUT```
</div>
</div>
</p>

<p>Selenium hub log:</p>

<p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-html lang-html prettyprint-override"><code>08:06:36.629 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
08:06:36.849 INFO [GridLauncherV3.lambda$buildLaunchers$5] - Launching Selenium Grid hub on port 4444
2019-05-31 08:06:37.333:INFO::main: Logging initialized @1175ms to org.seleniumhq.jetty9.util.log.StdErrLog
08:06:38.033 INFO [Hub.start] - Selenium Grid hub is up and running
08:06:38.040 INFO [Hub.start] - Nodes should register to http://172.19.0.4:4444/grid/register/
08:06:38.040 INFO [Hub.start] - Clients should connect to http://172.19.0.4:4444/wd/hub
08:06:40.894 INFO [DefaultGridRegistry.add] - Registered a node http://172.19.0.3:5555
08:06:40.907 INFO [DefaultGridRegistry.add] - Registered a node http://172.19.0.2:5555
08:07:47.391 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: firefox, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:07:47.409 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=ad8a2987-e350-456e-b9cf-25ac008d5255, seleniumProtocol=WebDriver, browserName=firefox, maxInstances=1, moz:firefoxOptions={log={level=info}}, platformName=LINUX, version=67.0, applicationName=, platform=LINUX}
08:13:58.927 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: chrome, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:13:58.935 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=3f83f707-e0ad-406f-9081-bc7185515bdf, seleniumProtocol=WebDriver, browserName=chrome, maxInstances=1, platformName=LINUX, version=74.0.3729.169, applicationName=, platform=LINUX}
08:31:13.686 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: chrome, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:31:13.697 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=3f83f707-e0ad-406f-9081-bc7185515bdf, seleniumProtocol=WebDriver, browserName=chrome, maxInstances=1, platformName=LINUX, version=74.0.3729.169, applicationName=, platform=LINUX}
08:39:59.952 WARN [RequestHandler.process] - The client is gone for session ext. key b54b779b8d4cb90133cf3386ca7ef664, terminating
08:40:02.245 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: firefox, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:40:02.251 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=ad8a2987-e350-456e-b9cf-25ac008d5255, seleniumProtocol=WebDriver, browserName=firefox, maxInstances=1, moz:firefoxOptions={log={level=info}}, platformName=LINUX, version=67.0, applicationName=, platform=LINUX}
IP & PORTS
You can access this container using the following IP address and port:

DOCKER PORT ACCESS URL</code>```

答:
Deleting the agent records in Botium Box doesn't help - this is just how Botium Box keeps tracks of the connected agents, it has no influence on the actual processes.

The logs you attached are not looking bad, it's just that obviously there is a problem when connecting to the Selenium hub. In case the agent processes are really stuck or crashed, you can just restart the docker containers to bring them up again.

Title: How to purge test sessions in Botium

Body:
I'm trying to run Test Set but it looks like it is stucked. All 5 agents are in use and I cannot delete them. Tests fail on ESOCKETTIMEDOUT. I could run same test without problems before.

I tried to click on "Send cancellation request" to Test Session in danger zone to kill it, but I still  can't delete agents (Delete Botium Agent (only possible if not already used)).

Botium agents pic

Log from Botium:

2019-05-31T08:31:13.892Z: Job queued for execution
2019-05-31T08:31:13.886Z: 2019-05-31T08:31:13.378Z botium-box-worker-runtestcases Started processing, JobId #952.

2019-05-31T08:31:14.077Z: 2019-05-31T08:31:13.382Z botium-BotDriver Loaded Botium configuration file ./botium.json

2019-05-31T08:31:14.143Z: 2019-05-31T08:31:13.388Z botium-BotDriver BuildCompiler: Capabilites: { PROJECTNAME: 'TM new - Test Session',
  TEMPDIR: 'botiumwork',
  CLEANUPTEMPDIR: true,
  WAITFORBOTTIMEOUT: 10000,
  SIMULATE_WRITING_SPEED: false,
  DOCKERCOMPOSEPATH: 'docker-compose',
  DOCKERMACHINEPATH: 'docker-machine',
  DOCKERMACHINE: false,
  DOCKERIMAGE: 'node:boron',
  DOCKERUNIQUECONTAINERNAMES: false,
  DOCKERSYSLOGPORT_RANGE: '47100-47299',
  BOT_HEALTH_STATUS: 200,
  SLACK_PUBLISHPORT_RANGE: '46100-46299',
  FACEBOOK_PUBLISHPORT_RANGE: '46300-46499',
  FACEBOOK_SEND_DELIVERY_CONFIRMATION: true,
  BOTFRAMEWORK_PUBLISHPORT_RANGE: '46500-46699',
  BOTFRAMEWORK_WEBHOOK_PORT: 3978,
  BOTFRAMEWORK_WEBHOOK_PATH: 'api/messages',
  BOTFRAMEWORK_CHANNEL_ID: 'facebook',
  SIMPLEREST_PING_RETRIES: 6,
  SIMPLEREST_PING_TIMEOUT: 10000,
  SIMPLEREST_PING_VERB: 'GET',
  SIMPLEREST_METHOD: 'GET',
  WEBSPEECH_SERVER_PORT: 46050,
  WEBSPEECH_LANGUAGE: 'en-US',
  WEBSPEECH_CLOSEBROWSER: true,
  SCRIPTING_TXT_EOL: '\n',
  SCRIPTING_XLSX_EOL_SPLIT: '\r',
  SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  SCRIPTING_XLSX_STARTROW: 2,
  SCRIPTING_XLSX_STARTCOL: 1,
  SCRIPTING_NORMALIZE_TEXT: false,
  SCRIPTING_ENABLE_MEMORY: false,
  SCRIPTING_MATCHING_MODE: 'includeLowerCase',
  SCRIPTING_UTTEXPANSION_MODE: 'all',
  SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  RETRY_USERSAYS_ONERROR_REGEXP: [],
  RETRY_USERSAYS_NUMRETRIES: 1,
  RETRY_USERSAYS_FACTOR: 1,
  RETRY_USERSAYS_MINTIMEOUT: 1000,
  ASSERTERS:
   [ { ref: 'HASLINK',
       src: 'botium-asserter-basiclink',
       global: false,
       args: null } ],
  LOGIC_HOOKS: [],
  USER_INPUTS: [],
  CONTAINERMODE: 'webdriverio',
  WEBDRIVERIO_URL: 'https://chat.t-mobile.cz/chat/',
  WEBDRIVERIO_PROFILE: '',
  WEBDRIVERIO_INPUT_ELEMENT: '<input />',
  WEBDRIVERIO_INPUT_ELEMENT_VISIBLE_TIMEOUT: 10000,
  WEBDRIVERIO_OUTPUT_ELEMENT:
   "//div[@class='gaid-text-message gaid-text-message--isBot'][position()=last()-1]//p",
  WEBDRIVERIO_IGNOREUPFRONTMESSAGES: false,
  WEBDRIVERIO_USERNAME: '',
  WEBDRIVERIO_PASSWORD: '',
  WEBDRIVERIO_SCREENSHOTS: 'onstop',
  FBPAGERECEIVER_REDISURL: { port: '6379', host: 'redis', db: 0, options: {} },
  WEBDRIVERIO_OPTIONS:
   { desiredCapabilities: { browserName: 'chrome', name: 'TM new - Test Session' },
     protocol: 'http',
     host: '192.168.99.100',
     port: '4444',
     path: '/wd/hub' } }

2019-05-31T08:31:14.169Z: 2019-05-31T08:31:13.393Z botium-ScriptingProvider Using matching mode: includeLowerCase

2019-05-31T08:31:14.214Z: 2019-05-31T08:31:13.396Z botium-asserterUtils Loaded Default asserter - [ 'BUTTONS',
  'MEDIA',
  'PAUSE_ASSERTER',
  'ENTITIES',
  'ENTITY_VALUES',
  'INTENT',
  'INTENT_CONFIDENCE' ]

2019-05-31T08:31:14.251Z: 2019-05-31T08:31:13.402Z botium-asserterUtils Loaded Default logic hook - [ 'PAUSE',
  'WAITFORBOT',
  'SET_SCRIPTING_MEMORY',
  'CLEAR_SCRIPTING_MEMORY',
  'INCLUDE' ]

2019-05-31T08:31:14.339Z: 2019-05-31T08:31:13.403Z botium-asserterUtils Loaded Default user input - [ 'BUTTON', 'MEDIA', 'FORM' ]

2019-05-31T08:31:14.396Z: 2019-05-31T08:31:13.407Z botium-asserterUtils Trying to load HASLINK asserter from botium-asserter-basiclink

2019-05-31T08:31:14.433Z: 2019-05-31T08:31:13.410Z botium-asserterUtils Loaded HASLINK SUCCESSFULLY

2019-05-31T08:31:14.470Z: 2019-05-31T08:31:13.504Z botium-box-worker-runtestcases found 1 convos ...

2019-05-31T08:31:14.512Z: 2019-05-31T08:31:13.504Z botium-box-worker-runtestcases batchNum: 1 batchCount: 1 convosPerBatch: 1 batchStart: 0 batchEnd: 0 batchLength: 1

2019-05-31T08:31:14.548Z: 2019-05-31T08:31:13.507Z botium-BotDriver Build - Botium Core Version: 1.4.14

2019-05-31T08:31:14.586Z: 2019-05-31T08:31:13.510Z botium-BotDriver Build - Capabilites: { PROJECTNAME: 'TM new - Test Session',
  TEMPDIR: 'botiumwork',
  CLEANUPTEMPDIR: true,
  WAITFORBOTTIMEOUT: 10000,
  SIMULATE_WRITING_SPEED: false,
  DOCKERCOMPOSEPATH: 'docker-compose',
  DOCKERMACHINEPATH: 'docker-machine',
  DOCKERMACHINE: false,
  DOCKERIMAGE: 'node:boron',
  DOCKERUNIQUECONTAINERNAMES: false,
  DOCKERSYSLOGPORT_RANGE: '47100-47299',
  BOT_HEALTH_STATUS: 200,
  SLACK_PUBLISHPORT_RANGE: '46100-46299',
  FACEBOOK_PUBLISHPORT_RANGE: '46300-46499',
  FACEBOOK_SEND_DELIVERY_CONFIRMATION: true,
  BOTFRAMEWORK_PUBLISHPORT_RANGE: '46500-46699',
  BOTFRAMEWORK_WEBHOOK_PORT: 3978,
  BOTFRAMEWORK_WEBHOOK_PATH: 'api/messages',
  BOTFRAMEWORK_CHANNEL_ID: 'facebook',
  SIMPLEREST_PING_RETRIES: 6,
  SIMPLEREST_PING_TIMEOUT: 10000,
  SIMPLEREST_PING_VERB: 'GET',
  SIMPLEREST_METHOD: 'GET',
  WEBSPEECH_SERVER_PORT: 46050,
  WEBSPEECH_LANGUAGE: 'en-US',
  WEBSPEECH_CLOSEBROWSER: true,
  SCRIPTING_TXT_EOL: '\n',
  SCRIPTING_XLSX_EOL_SPLIT: '\r',
  SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  SCRIPTING_XLSX_STARTROW: 2,
  SCRIPTING_XLSX_STARTCOL: 1,
  SCRIPTING_NORMALIZE_TEXT: false,
  SCRIPTING_ENABLE_MEMORY: false,
  SCRIPTING_MATCHING_MODE: 'includeLowerCase',
  SCRIPTING_UTTEXPANSION_MODE: 'all',
  SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  RETRY_USERSAYS_ONERROR_REGEXP: [],
  RETRY_USERSAYS_NUMRETRIES: 1,
  RETRY_USERSAYS_FACTOR: 1,
  RETRY_USERSAYS_MINTIMEOUT: 1000,
  ASSERTERS:
   [ { ref: 'HASLINK',
       src: 'botium-asserter-basiclink',
       global: false,
       args: null } ],
  LOGIC_HOOKS: [],
  USER_INPUTS: [],
  CONTAINERMODE: 'webdriverio',
  WEBDRIVERIO_URL: 'https://chat.t-mobile.cz/chat/',
  WEBDRIVERIO_PROFILE: '',
  WEBDRIVERIO_INPUT_ELEMENT: '<input />',
  WEBDRIVERIO_INPUT_ELEMENT_VISIBLE_TIMEOUT: 10000,
  WEBDRIVERIO_OUTPUT_ELEMENT:
   "//div[@class='gaid-text-message gaid-text-message--isBot'][position()=last()-1]//p",
  WEBDRIVERIO_IGNOREUPFRONTMESSAGES: false,
  WEBDRIVERIO_USERNAME: '',
  WEBDRIVERIO_PASSWORD: '',
  WEBDRIVERIO_SCREENSHOTS: 'onstop',
  FBPAGERECEIVER_REDISURL: { port: '6379', host: 'redis', db: 0, options: {} },
  WEBDRIVERIO_OPTIONS:
   { desiredCapabilities: { browserName: 'chrome', name: 'TM new - Test Session' },
     protocol: 'http',
     host: '192.168.99.100',
     port: '4444',
     path: '/wd/hub' } }

2019-05-31T08:31:14.636Z: 2019-05-31T08:31:13.519Z botium-BotDriver Build - Sources : { LOCALPATH: '.',
  GITPATH: 'git',
  GITBRANCH: 'master',
  GITDIR: '.' }

2019-05-31T08:31:14.671Z: 2019-05-31T08:31:13.524Z botium-BotDriver Build - Envs : { IS_BOTIUM_CONTAINER: true }

2019-05-31T08:31:14.704Z: 2019-05-31T08:31:13.592Z botium-PluginConnectorContainer Invalid Botium plugin loaded from webdriverio, expected PluginVersion, PluginClass fields

2019-05-31T08:31:14.732Z: 2019-05-31T08:31:13.595Z botium-PluginConnectorContainer Botium plugin botium-connector-webdriverio loaded

2019-05-31T08:31:14.769Z: 2019-05-31T08:31:13.597Z botium-connector-webdriverio Validate called

2019-05-31T08:31:14.801Z: 2019-05-31T08:31:13.600Z botium-connector-webdriverio Build called

2019-05-31T08:31:14.837Z: 2019-05-31T08:31:13.603Z botium-connector-webdriverio Start called

2019-05-31T08:31:24.389Z: 2019-05-31T08:31:24.371Z botium-box-worker sending heartbeat ...

2019-05-31T08:36:24.471Z: 2019-05-31T08:36:24.420Z botium-box-worker sending heartbeat ...

2019-05-31T08:37:15.925Z: 2019-05-31T08:37:15.880Z botium-box-worker-runtestcases Test Session Run failed (Error: ESOCKETTIMEDOUT), doing additional BotDriver Clean.

2019-05-31T08:37:15.961Z: 2019-05-31T08:37:15.881Z botium-connector-webdriverio Clean called

2019-05-31T08:40:02.054Z: 2019-05-31T08:40:02.006Z botium-BaseContainer Cleanup rimrafing temp dir /app/agent/botiumwork/TM-new-Test-Session-20190531-083113-vI4Bx

2019-05-31T08:40:02.357Z: Job failed: Error: ESOCKETTIMEDOUT

Selenium hub log:

08:06:36.629 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
08:06:36.849 INFO [GridLauncherV3.lambda$buildLaunchers$5] - Launching Selenium Grid hub on port 4444
2019-05-31 08:06:37.333:INFO::main: Logging initialized @1175ms to org.seleniumhq.jetty9.util.log.StdErrLog
08:06:38.033 INFO [Hub.start] - Selenium Grid hub is up and running
08:06:38.040 INFO [Hub.start] - Nodes should register to http://172.19.0.4:4444/grid/register/
08:06:38.040 INFO [Hub.start] - Clients should connect to http://172.19.0.4:4444/wd/hub
08:06:40.894 INFO [DefaultGridRegistry.add] - Registered a node http://172.19.0.3:5555
08:06:40.907 INFO [DefaultGridRegistry.add] - Registered a node http://172.19.0.2:5555
08:07:47.391 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: firefox, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:07:47.409 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=ad8a2987-e350-456e-b9cf-25ac008d5255, seleniumProtocol=WebDriver, browserName=firefox, maxInstances=1, moz:firefoxOptions={log={level=info}}, platformName=LINUX, version=67.0, applicationName=, platform=LINUX}
08:13:58.927 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: chrome, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:13:58.935 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=3f83f707-e0ad-406f-9081-bc7185515bdf, seleniumProtocol=WebDriver, browserName=chrome, maxInstances=1, platformName=LINUX, version=74.0.3729.169, applicationName=, platform=LINUX}
08:31:13.686 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: chrome, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:31:13.697 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=3f83f707-e0ad-406f-9081-bc7185515bdf, seleniumProtocol=WebDriver, browserName=chrome, maxInstances=1, platformName=LINUX, version=74.0.3729.169, applicationName=, platform=LINUX}
08:39:59.952 WARN [RequestHandler.process] - The client is gone for session ext. key b54b779b8d4cb90133cf3386ca7ef664, terminating
08:40:02.245 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: firefox, handlesAlerts: true, javascriptEnabled: true, locationContextEnabled: true, loggingPrefs: org.openqa.selenium.logging..., name: TM new - Test Session, requestOrigins: {name: webdriverio, url: http://webdriver.io, version: 4.14.4}, rotatable: true}
08:40:02.251 INFO [TestSlot.getNewSession] - Trying to create a new session on test slot {server:CONFIG_UUID=ad8a2987-e350-456e-b9cf-25ac008d5255, seleniumProtocol=WebDriver, browserName=firefox, maxInstances=1, moz:firefoxOptions={log={level=info}}, platformName=LINUX, version=67.0, applicationName=, platform=LINUX}
IP & PORTS
You can access this container using the following IP address and port:

DOCKER PORT ACCESS URL


Title: python string convert into json for the bankstatement

Body:
This my input

string = '07/08/2018 07/08/2018 IMPS DR-1763308000000116-PYTM0123456-917 592674 5,000.00 39,325.93'

I need output like

{'date1':'07/08/2018','date2':'07/08/2018','remark':'IMPS DR-1763308000000116-PYTM0123456-917 592674','credit':'5,000.00','balance' : '39,325.93' }

I tried

result = { 'date1': list1[0], 'date2': list1[1], 'balance': list1[-1]}
print(result)

output

{'date1': '07/08/2018', 'date2': '07/08/2018', 'balance': '39,325.93'}

Body:
Here's a simple solution -

 string = '07/08/2018 07/08/2018 IMPS DR-1763308000000116-PYTM0123456-917 592674 5,000.00 39,325.93'

 l = string.split()

 result = {'date1': l[0],
           'date2': l[1],
           'remark': ' '.join((l[2],l[3])),
           'credit': l[4],
           'balance': l[5]}

Output

 {'date1': '07/08/2018', 'date2': '07/08/2018', 'remark': 'IMPS DR-1763308000000116-PYTM0123456-917', 'credit': '592674', 'balance':'5,000.00'}


问:
How to search for dataframes and sort each one accordingly?
I have dataframes in my local named like s1_down_threshold, s1_up_threshold, s2_down_threshold,s2_down_threshold, s19_down_threshold, s19_down_threshold and so on.

I would like to sort the dataframes having 'down_threshold' in their names in descending order based on one column and the dataframes having 'up_threshold' in their names in ascending order based on the same column.

I know that I can use .sort_values() for each and every one of them, but I would like to know if there is a more efficient way to do it?

I was hoping for something as follows:

Going through the names of all the dataframes in my local and then finding the dataframes with 'down_threshold' in their names and sorting them accordingly and then repeating the same process for 'up_threshold'

Edit 1:

答:
You can name the data frame before adding it to Dataframe dictionary like below:</p>

```<code>import numpy as np
import pandas as pd
import json

#using sample data

data = {'id': ['A', 'B', 'C', 'D'], 'value': [2000, 600, 400, 3000]}

df=pd.DataFrame(data)
df1 =df.copy()
df2=df.copy()
df3=df.copy()
df4=df.copy()

DataFrameDict=[]

df1.name='s1_down_threshold'
DataFrameDict.append(df1)
df2.name='s2_down_threshold'
DataFrameDict.append(df2)
df3.name='s1_up_threshold'
DataFrameDict.append(df3)
df4.name='s2_up_threshold'
DataFrameDict.append(df4)

for i in range(len(DataFrameDict)):
    if ('down' in DataFrameDict[i].name):
        print (DataFrameDict[i].name,'sorted down')
        DataFrameDict[i].sort_values(by='value', ascending=False,inplace=True)
    elif ('up' in DataFrameDict[i].name):
        print (DataFrameDict[i].name,'sorted up')
        DataFrameDict[i].sort_values(by='value', ascending=True,inplace=True)

>>> DataFrameDict
[  id  value
3  D   3000
0  A   2000
1  B    600
2  C    400,
   id  value
3  D   3000
0  A   2000
1  B    600
2  C    400,
   id  value
2  C    400
1  B    600
0  A   2000
3  D   3000,
   id  value
2  C    400
1  B    600
0  A   2000
3  D   3000]
</code>```

Body:
You can name the data frame before adding it to Dataframe dictionary like below:

import numpy as np
import pandas as pd
import json

#using sample data

data = {'id': ['A', 'B', 'C', 'D'], 'value': [2000, 600, 400, 3000]}

df=pd.DataFrame(data)
df1 =df.copy()
df2=df.copy()
df3=df.copy()
df4=df.copy()

DataFrameDict=[]

df1.name='s1_down_threshold'
DataFrameDict.append(df1)
df2.name='s2_down_threshold'
DataFrameDict.append(df2)
df3.name='s1_up_threshold'
DataFrameDict.append(df3)
df4.name='s2_up_threshold'
DataFrameDict.append(df4)

for i in range(len(DataFrameDict)):
    if ('down' in DataFrameDict[i].name):
        print (DataFrameDict[i].name,'sorted down')
        DataFrameDict[i].sort_values(by='value', ascending=False,inplace=True)
    elif ('up' in DataFrameDict[i].name):
        print (DataFrameDict[i].name,'sorted up')
        DataFrameDict[i].sort_values(by='value', ascending=True,inplace=True)

>>> DataFrameDict
[  id  value
3  D   3000
0  A   2000
1  B    600
2  C    400,
   id  value
3  D   3000
0  A   2000
1  B    600
2  C    400,
   id  value
2  C    400
1  B    600
0  A   2000
3  D   3000,
   id  value
2  C    400
1  B    600
0  A   2000
3  D   3000]


问:
Crystal reports returning values like one looking for instead of equal
I am creating a Report=>selectionFormulas=>Record, and then I have this:

```<code>({Facilities_ALL.Fac} IN ['S', 'H', 'E', 'J', 'SJ', 'F', 'N'])
AND
({Facilities_ALL.status} = "Active")
AND
isNull({Facilities_ALL.Department})
OR
isNull({Facilities_ALL.Section})
</code>```

For some reason, it's returning both ones that are "Active" as well as ones that are "Inactive".  It looks correct to me as well as instructions I found online.  How do I fix it so it only returns "Active" ones?  What's the issue?

答:
I figured it out.  I needed an extra set of parenthesis around the last 2 things:</p>

```<code>({Facilities_ALL.Fac} IN ['S', 'H', 'E', 'J', 'SJ', 'F', 'N'])
AND
({Facilities_ALL.status}="Active")
AND
(
isNull({Facilities_ALL.Department})
OR
isNull({Facilities_ALL.Section})
)
</code>```

Body:
I am creating a Report=>selectionFormulas=>Record, and then I have this:

({Facilities_ALL.Fac} IN ['S', 'H', 'E', 'J', 'SJ', 'F', 'N'])
AND
({Facilities_ALL.status} = "Active")
AND
isNull({Facilities_ALL.Department})
OR
isNull({Facilities_ALL.Section})

For some reason, it's returning both ones that are "Active" as well as ones that are "Inactive".  It looks correct to me as well as instructions I found online.  How do I fix it so it only returns "Active" ones?  What's the issue?

Body:
I figured it out.  I needed an extra set of parenthesis around the last 2 things:

({Facilities_ALL.Fac} IN ['S', 'H', 'E', 'J', 'SJ', 'F', 'N'])
AND
({Facilities_ALL.status}="Active")
AND
(
isNull({Facilities_ALL.Department})
OR
isNull({Facilities_ALL.Section})
)


问:
How do i remove characters in a string between two specific characters?
I want to strip all characters in my string between "_" and " "

i've tried the split command but it takes everything after my parameter. I can't make it stop at " "

```<code>string = "adamannaogfrida_dfexosnfzg PeterMadsen_deinow_pk HjaltedDrejer_Weonfiweg"
</code>```

Expected output: adamannaogfrida PeterMadsen HjaltedDrejer

答:
A regular expression sounds like a competitive candidate:</p>

```<code>import re
s = re.sub("_[^ ]*( |$)", " ", string)
print(s)
</code>```

Body:
I want to strip all characters in my string between "_" and " "

i've tried the split command but it takes everything after my parameter. I can't make it stop at " "

string = "adamannaogfrida_dfexosnfzg PeterMadsen_deinow_pk HjaltedDrejer_Weonfiweg"

Expected output: adamannaogfrida PeterMadsen HjaltedDrejer

Body:
A regular expression sounds like a competitive candidate:

import re
s = re.sub("_[^ ]*( |$)", " ", string)
print(s)


问:
HTML unordered list sucks in IE7
I've created a HTML ordered list which looks fine in FF, but pretty awful in IE.
My specific problems with the way IE displays the list are:

List markers are missing

Vertical spacing between list items is very uneven

It seems the superscripts are the cause of (2), but I'm not sure how I can fix this problem (without removing the superscripts).

EDIT: I gave up on my single-list dreams and split the list into 3 separate lists. I've removed the link from the text above to avoid confusing future readers.

Thanks,
Don

答: I can tell for certain that the superscripts are what's altering the line height. If you want to force regular line heights you'll have to wrap everything in a table to prevent flow-based layount.</p>

OwnerDisplayName: Don

ContentLicense: CC BY-SA 2.5

Title: HTML unordered list sucks in IE7

LastEditorDisplayName: Don

OwnerDisplayName: Peter Wone


问:
Java to Kotlin_ Gson.Json Conversion Error
While converting from java to kotlin the output is given as follows
 Java:

```<code>Gson gson = new Gson();
    String strObj = getIntent().getStringExtra("passdata");
    userDictionery  = gson.fromJson(strObj, Map.class);
</code>```

Kotlin:

```<code>val gson = Gson()
    val strObj = intent.getStringExtra("passdata")
    userDictionery = gson.fromJson<Map<*, *>>(strObj, Map<*, *>::class.java) as Map<String, String>?
</code>```

But second line in kotlin shows an error that - Only Classes are allowed left hand side of the class literal

variable userDictionery is declared as Map<String, String>

How to resolve this issue?

答:
You can't reference classes with their generic parameters in Kotlin the same way you can't reference them in java. So Map<*, *>::class is in the same way invalid in Kotlin as Map<?, ?>.class is in Java. Replace this:

```<code>gson.fromJson<Map<*, *>>(strObj, Map<*, *>::class.java)
</code>```

With that:

```<code>gson.fromJson<Map<*, *>>(strObj, Map::class.java)
</code>```

Body:
While converting from java to kotlin the output is given as follows
 Java:

Gson gson = new Gson();
    String strObj = getIntent().getStringExtra("passdata");
    userDictionery  = gson.fromJson(strObj, Map.class);

Kotlin:

val gson = Gson()
    val strObj = intent.getStringExtra("passdata")
    userDictionery = gson.fromJson<Map<*, *>>(strObj, Map<*, *>::class.java) as Map<String, String>?

But second line in kotlin shows an error that - Only Classes are allowed left hand side of the class literal

variable userDictionery is declared as Map<String, String>

How to resolve this issue?

Body:
You can't reference classes with their generic parameters in Kotlin the same way you can't reference them in java. So Map<*, *>::class is in the same way invalid in Kotlin as Map<?, ?>.class is in Java. Replace this:

gson.fromJson<Map<*, *>>(strObj, Map<*, *>::class.java)

With that:

gson.fromJson<Map<*, *>>(strObj, Map::class.java)


问:
How to renew Lets encrypt certificate in ejabberd configured server?
How to renew Lets encrypt certificate in ejabberd configured server? My server is Debian-jessie and I have tried to renew SSL certificates using the below command,
certbot certonly -d mydomainname

But it produced an unexpected error:

Failed authorization procedure. : urn:acme:error:connection ::Timeout
  during connect (likely firewall problem). Skipping.

Timeout during connect (likely firewall problem)

To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

答:
Found the proper answer for this:

You need to stop the service ejabberd service before you do the
  process,

```<code> service ejabberd stop
</code>```

Then move the expired ssl pem file to somewhere else,

```<code>mv /etc/ejabberd/ejabberd.pem  /etc/ejabberd/ejabberd.pem.backup
</code>```

Go to the directory where the cert boot locating,

```<code>cd /root
</code>```

Enter the below command in-order to renew the certificate for the
   required domain

```<code>certbot certonly --webroot -w /etc/ejabberd -d yourdomain.com --force-renewal --rsa-key-size 4096
</code>```

Then merge the generated ssl files to the ejabberd configuration file

```<code>cat /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/letsencrypt/live/chat.yourdomain.com/fullchain.pem > ejabberd.pem
</code>```

Then move the pem file to the ejabberd root path

```<code>mv ejabberd.pem /etc/ejabberd

chown ejabberd /etc/ejabberd/ejabberd.pem
</code>```

Enable ejabberd service

```<code>service ejabberd start

service ejabberd status
</code>```

Body:
Found the proper answer for this:

You need to stop the service ejabberd service before you do the
  process,

 service ejabberd stop

Then move the expired ssl pem file to somewhere else,

mv /etc/ejabberd/ejabberd.pem  /etc/ejabberd/ejabberd.pem.backup

Go to the directory where the cert boot locating,

cd /root

Enter the below command in-order to renew the certificate for the
   required domain

certbot certonly --webroot -w /etc/ejabberd -d yourdomain.com --force-renewal --rsa-key-size 4096

Then merge the generated ssl files to the ejabberd configuration file

cat /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/letsencrypt/live/chat.yourdomain.com/fullchain.pem > ejabberd.pem

Then move the pem file to the ejabberd root path

mv ejabberd.pem /etc/ejabberd

chown ejabberd /etc/ejabberd/ejabberd.pem

Enable ejabberd service

service ejabberd start

service ejabberd status


问:
Migration from Standalone Solar to SolrCloud in AWS
Our Developers is working in Local Standalone Solr Server and we have many cores in Local Solr. Now we are planning to migrate it to SolrCloud in AWS Infrastructure for replication purpose with numShards:3 and replicationFact:3. We don't need data to be migrated from Local Solr server to AWS SolrCloud. We only need to transfer Core from Local Solr to collection in SolrCloud. I am newbie in these can you please any help me in these.

1) In layman word we only need to transfer content in Conf folder of core to SolrCloud Collection and we don't need to transfer data(data folder).

答:
Answering the my own question ,so any one can check it, if issue arise.

Solution:

1) Create a new collection in SolrCloud with config set name same as of core.

2) Move the conf folder of the core in Local Standalone Solr Server to SolrCloud 'Collection' Folder.

3) Run zookeeper's zkCli.sh commands from bash to upload the conf file to all SolrCloud server.

```<code>cd /opt/solr/server/scripts/cloud-scripts/
bash zkcli.sh -cmd upconfig -confdir /opt/solr-7.4.0/server/solr/collectionname/conf/ -z IP1:2181,IP2:2181,IP3:2181 -confname confname
</code>```

Reference : https://lucene.apache.org/solr/guide/6_6/using-zookeeper-to-manage-configuration-files.html#UsingZooKeepertoManageConfigurationFiles-UploadingConfigurationFilesusingbin_solrorSolrJ

Body:
Answering the my own question ,so any one can check it, if issue arise.

Solution:

1) Create a new collection in SolrCloud with config set name same as of core.

2) Move the conf folder of the core in Local Standalone Solr Server to SolrCloud 'Collection' Folder.

3) Run zookeeper's zkCli.sh commands from bash to upload the conf file to all SolrCloud server.

cd /opt/solr/server/scripts/cloud-scripts/
bash zkcli.sh -cmd upconfig -confdir /opt/solr-7.4.0/server/solr/collectionname/conf/ -z IP1:2181,IP2:2181,IP3:2181 -confname confname

Reference : https://lucene.apache.org/solr/guide/6_6/using-zookeeper-to-manage-configuration-files.html#UsingZooKeepertoManageConfigurationFiles-UploadingConfigurationFilesusingbin_solrorSolrJ


问:
Recursively traverse category tree in Python
I'm new to Python and know there is a much better way to structure a recursive query.  Would appreciate someone more advanced taking a look at how best to streamline the below code.

I poured over similar examples on StackOverflow but none had the data structure I'm trying to traverse.

Sample data:

[
    {'categoryId': 100, 'parentId': 0,   'catName': 'Animals & Pet Supplies'},
    {'categoryId': 103, 'parentId': 100, 'catName': 'Pet Supplies'},
    {'categoryId': 106, 'parentId': 103, 'catName': 'Bird Supplies'},
    {'categoryId': 500, 'parentId': 0,   'catName': 'Apparel & Accessories'},
    {'categoryId': 533, 'parentId': 500, 'catName': 'Clothing'},
    {'categoryId': 535, 'parentId': 533, 'catName': 'Activewear'}
]
```

<p>Python code:</p>

<pre class="lang-py prettyprint-override"><code>def returnChildren(categoryId):
    cats  = dict()
    results = categories.find( { "parentId" : categoryId } )
    for x in results:
        cats[x['categoryId']] = x['catName']

    return cats

children = returnChildren(cat_id)

#build list of children for this node
for x in children:
    print (x, "-", children[x])
    results = returnChildren(x)
    if (len(results) > 0):
        for y in sorted(results.keys()):
            print(y, "--", results[y])
            sub_results = returnChildren(y)
            if (len(sub_results) > 0):
            for z in sorted(sub_results.keys()):
                print(z, "----", sub_results[z])
                sub_sub_results = returnChildren(z)
                if (len(sub_sub_results) > 0):
                    for a in sorted(sub_sub_results.keys()):
                        print(a, "------", sub_sub_results[a])
</code>```

This code will generate a tree similar to the below:

```<code>100 Animals & Pet Supplies
103 - Pet Supplies
106 -- Bird Supplies
500 Apparel & Accessories
533 - Clothing
535 -- Activewear
</code>```

答:
You can use a recursive function to traverse the tree.

In addition it's probably worth to precalculate the parentage tree (it can be useful for other purposes too).

I've wrapped things into a class here – it should be pretty simple to follow.

(EDIT: Instead of the callback thing in the earlier version I've changed things to use a generator instead, to be more Pythonic.)

from collections import defaultdict

class NodeTree:
    def __init__(self, nodes):
        self.nodes = nodes
        self.nodes_by_parent = defaultdict(list)

        for node in self.nodes:
            self.nodes_by_parent[node["parentId"]].append(node)

    def visit_node(self, node, level=0, parent=None):
        yield (level, node, parent)
        for child in self.nodes_by_parent.get(node["categoryId"], ()):
            yield from self.visit_node(child, level=level + 1, parent=node)

    def walk_tree(self):
        """
        Walk the tree starting from the root, returning 3-tuples (level, node, parent).
        """
        for node in self.root_nodes:
            yield from self.visit_node(node)

    @property
    def root_nodes(self):
        return self.nodes_by_parent.get(0, ())

nodes = [
    {"categoryId": 100, "parentId": 0, "catName": "Animals & Pet Supplies"},
    {"categoryId": 103, "parentId": 100, "catName": "Pet Supplies"},
    {"categoryId": 106, "parentId": 103, "catName": "Bird Supplies"},
    {"categoryId": 500, "parentId": 0, "catName": "Apparel & Accessories"},
    {"categoryId": 533, "parentId": 500, "catName": "Clothing"},
    {"categoryId": 535, "parentId": 533, "catName": "Activewear"},
]

tree = NodeTree(nodes)

for level, node, parent in tree.walk_tree():
    print(node["categoryId"], "-" * level, node["catName"])

```

<p>This code prints, almost like your original,</p>

```100  Animals & Pet Supplies
103 - Pet Supplies
106 -- Bird Supplies
500  Apparel & Accessories
533 - Clothing
535 -- Activewear
```

Body:
I'm new to Python and know there is a much better way to structure a recursive query.  Would appreciate someone more advanced taking a look at how best to streamline the below code.

I poured over similar examples on StackOverflow but none had the data structure I'm trying to traverse.

Sample data:

[
    {'categoryId': 100, 'parentId': 0,   'catName': 'Animals & Pet Supplies'},
    {'categoryId': 103, 'parentId': 100, 'catName': 'Pet Supplies'},
    {'categoryId': 106, 'parentId': 103, 'catName': 'Bird Supplies'},
    {'categoryId': 500, 'parentId': 0,   'catName': 'Apparel & Accessories'},
    {'categoryId': 533, 'parentId': 500, 'catName': 'Clothing'},
    {'categoryId': 535, 'parentId': 533, 'catName': 'Activewear'}
]

Python code:

def returnChildren(categoryId):
    cats  = dict()
    results = categories.find( { "parentId" : categoryId } )
    for x in results:
        cats[x['categoryId']] = x['catName']

    return cats

children = returnChildren(cat_id)

#build list of children for this node
for x in children:
    print (x, "-", children[x])
    results = returnChildren(x)
    if (len(results) > 0):
        for y in sorted(results.keys()):
            print(y, "--", results[y])
            sub_results = returnChildren(y)
            if (len(sub_results) > 0):
            for z in sorted(sub_results.keys()):
                print(z, "----", sub_results[z])
                sub_sub_results = returnChildren(z)
                if (len(sub_sub_results) > 0):
                    for a in sorted(sub_sub_results.keys()):
                        print(a, "------", sub_sub_results[a])

This code will generate a tree similar to the below:

100 Animals & Pet Supplies
103 - Pet Supplies
106 -- Bird Supplies
500 Apparel & Accessories
533 - Clothing
535 -- Activewear

Body:
You can use a recursive function to traverse the tree.

In addition it's probably worth to precalculate the parentage tree (it can be useful for other purposes too).

I've wrapped things into a class here – it should be pretty simple to follow.

(EDIT: Instead of the callback thing in the earlier version I've changed things to use a generator instead, to be more Pythonic.)

from collections import defaultdict

class NodeTree:
    def __init__(self, nodes):
        self.nodes = nodes
        self.nodes_by_parent = defaultdict(list)

        for node in self.nodes:
            self.nodes_by_parent[node["parentId"]].append(node)

    def visit_node(self, node, level=0, parent=None):
        yield (level, node, parent)
        for child in self.nodes_by_parent.get(node["categoryId"], ()):
            yield from self.visit_node(child, level=level + 1, parent=node)

    def walk_tree(self):
        """
        Walk the tree starting from the root, returning 3-tuples (level, node, parent).
        """
        for node in self.root_nodes:
            yield from self.visit_node(node)

    @property
    def root_nodes(self):
        return self.nodes_by_parent.get(0, ())

nodes = [
    {"categoryId": 100, "parentId": 0, "catName": "Animals & Pet Supplies"},
    {"categoryId": 103, "parentId": 100, "catName": "Pet Supplies"},
    {"categoryId": 106, "parentId": 103, "catName": "Bird Supplies"},
    {"categoryId": 500, "parentId": 0, "catName": "Apparel & Accessories"},
    {"categoryId": 533, "parentId": 500, "catName": "Clothing"},
    {"categoryId": 535, "parentId": 533, "catName": "Activewear"},
]

tree = NodeTree(nodes)

for level, node, parent in tree.walk_tree():
    print(node["categoryId"], "-" * level, node["catName"])

This code prints, almost like your original,

100  Animals & Pet Supplies
103 - Pet Supplies
106 -- Bird Supplies
500  Apparel & Accessories
533 - Clothing
535 -- Activewear


问:
Making a "Trending/Most Viewed Articles" in Vue
First time working with Vue and and making a vue app using the wordpress rest api.

What I want to do is make some sort of a "Trending/Most Viewed articles" component based on the number of views.

In wordpress, there's a plugin like WP-PostViews that stores the post views in a meta field and then you can query the posts based on that count.

Is it possible to do something like that in Vue? What would be the best approach? Maybe do a "axios.post" on click? I'm sorry I'm not very familiar with Vue

答:
Made a quick example for you with axios.
You should replace URL with your API.

new Vue({
  el: "#app",
  data: {
    articles: []
  },
  mounted() {
    axios.get("https://jsonplaceholder.typicode.com/posts")
        .then(response => {
        this.articles = response.data
      })
  }
})```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  padding: 10px 0;
  border-bottom: 1px solid #ccc;
}</code>```

Articles:

      {{article.title}}

```

Description:
Fetching resource (API) in mounted hook, so everytime component loads, will fetch for your articles
https://v2.vuejs.org/v2/api/#mounted

Body:
Made a quick example for you with axios.
You should replace URL with your API.

new Vue({
  el: "#app",
  data: {
    articles: []
  },
  mounted() {
    axios.get("https://jsonplaceholder.typicode.com/posts")
        .then(response => {
        this.articles = response.data
      })
  }
})

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  padding: 10px 0;
  border-bottom: 1px solid #ccc;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<div id="app">
  <h2>Articles:</h2>
  <ol>
    <li v-for="article in articles">
      {{article.title}}
    </li>
  </ol>
</div>

Description:
Fetching resource (API) in mounted hook, so everytime component loads, will fetch for your articles
https://v2.vuejs.org/v2/api/#mounted


答:
Given the expected output I'd use split instead of strip:

```<code>s = "adamannaogfrida_dfexosnfzg PeterMadsen_deinow_pk HjaltedDrejer_Weonfiweg"

out = [x.split("_")[0] for x in s.split()]
out
# ['adamannaogfrida', 'PeterMadsen', 'HjaltedDrejer']

</code>```

Title: How do i remove characters in a string between two specific characters?

Body:
Given the expected output I'd use split instead of strip:

s = "adamannaogfrida_dfexosnfzg PeterMadsen_deinow_pk HjaltedDrejer_Weonfiweg"

out = [x.split("_")[0] for x in s.split()]
out
# ['adamannaogfrida', 'PeterMadsen', 'HjaltedDrejer']


问:
Fetch with post data to expressjs leads to 404 server not found
Having a react frontend with my own expressjs api backend.
Express v. 4.16.0

Using fetch on the react frontend to get data works just fine.

```<code> fetch('/desResData')
      .then(res => {....}
</code>```

As soon as I try to post some data with the request I get: "POST http://localhost:3000/desResData 404 (Not Found)"
Code:

```<code> fetch('/desResData',
      {
        method: 'POST',
        body: { product: "test" }, // tried JSON.stringify as well
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      }
    )
      .then(res => {....}
</code>```

Roughly spoken I can have static communication from front to backend but I cant parametrize my requests.

ExpressJS:

```<code>router.get('/', async function (req, res, next) {

  console.log(req.body) // tried with using req and without using it

  findByProduct("product") // some async db operation // this part is working fine while fetching without any post parameters
    .then(data => {
       res.json()
      })

</code>```

答:
add this in your server code : </p>

```<code>app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
    next();
});
</code>```

<p>inside package.json of your react code : </p>

```<code>"proxy": "http://localhost:serverport",  <-- server port will be port of your node-express server
</code>```

Body:
Having a react frontend with my own expressjs api backend.
Express v. 4.16.0

Using fetch on the react frontend to get data works just fine.

 fetch('/desResData')
      .then(res => {....}

As soon as I try to post some data with the request I get: "POST http://localhost:3000/desResData 404 (Not Found)"
Code:

 fetch('/desResData',
      {
        method: 'POST',
        body: { product: "test" }, // tried JSON.stringify as well
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      }
    )
      .then(res => {....}

Roughly spoken I can have static communication from front to backend but I cant parametrize my requests.

ExpressJS:

router.get('/', async function (req, res, next) {

  console.log(req.body) // tried with using req and without using it

  findByProduct("product") // some async db operation // this part is working fine while fetching without any post parameters
    .then(data => {
       res.json()
      })

Body:
add this in your server code :

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
    next();
});

inside package.json of your react code :

"proxy": "http://localhost:serverport",  <-- server port will be port of your node-express server


问:
URL rewrite by keeping $_GET parameters
How can I rewrite this type of URL:

```<code>https://example.com/assets/forms/vanilla/index.php?property=cus_F8fylX6aITpJOR
</code>```

to have something like this:

```<code>https://example.com/forms/cus_F8fylX6aITpJOR
</code>```

How can I access to the property and vanilla parameters after ?

Thanks.

答:
You can use RewriteCond %{QUERY_STRING} to mateh the query string

Something like that :

```<code>RewriteCond %{QUERY_STRING} property=(\w+) [NC]
RewriteRule ^assets/forms/([a-zA-Z]*)/index.php /forms/%1?$1 [L]
</code>```

Title: URL rewrite by keeping $_GET parameters

Body:
How can I rewrite this type of URL:

https://example.com/assets/forms/vanilla/index.php?property=cus_F8fylX6aITpJOR

to have something like this:

https://example.com/forms/cus_F8fylX6aITpJOR

How can I access to the property and vanilla parameters after ?

Thanks.

Body:
You can use RewriteCond %{QUERY_STRING} to mateh the query string

Something like that :

RewriteCond %{QUERY_STRING} property=(\w+) [NC]
RewriteRule ^assets/forms/([a-zA-Z]*)/index.php /forms/%1?$1 [L]


问:
eslint fails on  inside <Link> in React
I got Next.js React app. Here is my code:

```<code><Link href="/foo">
  <a>Bar</a>
</Link>
</code>```

eslint tells me this:
The href attribute is required for an anchor to be keyboard accessible.
But Next.js wants me to inculde an a tag inside my Link. Ho do I configure eslint properly or change my code so that it doesn't warn me about this? Aside from completely disabling this rule of course.

答:
eslint-disable-next-line jsx-a11y/anchor-is-valid

if you are using vscode just right click on the warning in PROBLEMS and you can check if disable only for that lino or the entire file

Title: eslint fails on <a> inside <Link> in React

Body:
I got Next.js React app. Here is my code:

<Link href="/foo">
  Bar
</Link>

eslint tells me this:
The href attribute is required for an anchor to be keyboard accessible.
But Next.js wants me to inculde an a tag inside my Link. Ho do I configure eslint properly or change my code so that it doesn't warn me about this? Aside from completely disabling this rule of course.


问:
undefined reference when including a local header file in android NDK
I construct a simple android application which uses ndk with JNI.
The application has onw .cpp(debugTest.cpp) file that is used to link java and c++ with jni and another .c(javaEssentials.c) file with it's header(javaEssentials.h).
When I include in the .cpp file the .c file(#include "javaEssentials.c") no error is reported when compiling.
When I include in the .cpp file the header the compiler reports error of undefined reference of the functions the .c file has.It is real strange problem and I can't understand why is this happening.
As usual I have an include declaration of the header file in the .c file.

My android.mk is:

```<code># build file written to describe the C and C++ source files to the Android NDK

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := debugTest
LOCAL_SRC_FILES := debugTest.cpp

include $(BUILD_SHARED_LIBRARY)
</code>```

Any ideas why this is happening ?

答:
Add to your Android.mk file:

```<code>LOCAL_C_INCLUDES := $(LOCAL_PATH)include_dir1 \
                    $(LOCAL_PATH)include_dir2 \
                    ...
</code>```

For every directory where there are .h files

Body:
I construct a simple android application which uses ndk with JNI.
The application has onw .cpp(debugTest.cpp) file that is used to link java and c++ with jni and another .c(javaEssentials.c) file with it's header(javaEssentials.h).
When I include in the .cpp file the .c file(#include "javaEssentials.c") no error is reported when compiling.
When I include in the .cpp file the header the compiler reports error of undefined reference of the functions the .c file has.It is real strange problem and I can't understand why is this happening.
As usual I have an include declaration of the header file in the .c file.

My android.mk is:

# build file written to describe the C and C++ source files to the Android NDK

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := debugTest
LOCAL_SRC_FILES := debugTest.cpp

include $(BUILD_SHARED_LIBRARY)

Any ideas why this is happening ?

Body:
Add to your Android.mk file:

LOCAL_C_INCLUDES := $(LOCAL_PATH)include_dir1 \
                    $(LOCAL_PATH)include_dir2 \
                    ...

For every directory where there are .h files


问:
Web-Service not working without reference update
I got a WPF project that is using ASMX web-service to connect to database. The problem is I can't connect to the web-service without updating web-service reference. Even if I've updated reference and then built the solution I can't connent to the web-service after closing visual-studio.

答: In this situation, it appears VS is hosting your web service via Cassini or IIS Express. That port number is a setting that can be changed in the project's configuration. When you close visual studio you are closing the web application host. If you are attempting to test your service locally, without VS hosting, then you will need to configure a new web application to run on a local instance of IIS pointing to the output directory of the service. You can still bind inside of your solution to the services' project reference, you just don't need VS running to access it locally.</p>


问:
JS and Firebase. Upload multiple images, Wait for URL and upload to database
[Sorry for duplicate question]

This is my working JS-function for uploading images. The problem is that the function for uploading the "tool"(data) to the database, don't wait for the imageURL from Firebase. I need some sort of async / await without using a timeout. I want to upload the data to firebase as soon as all of the imageURLs are uploaded.

Here is JS-code (vuex):

```<code>createTool ({ commit }, payload) {
  let toolData = {
    croppas: payload.croppas,
    title: payload.title
  }
  var imageURLS = []

                    // outputArray = imageURLS
  function forEachImage(images, outputArray) {
    return new Promise((resolve) => {
    images.forEach(file => {
        file.generateBlob(
            blob => {
              if (blob != null) {
              let rand = (Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16)).toUpperCase()
              let imageRef = firebase.storage().ref('toolImages/').child(rand)
              imageRef.put(blob)
                .then( data => {
                  imageRef.getDownloadURL()
                    .then( downloadURL => {
                      console.log('The Download Link is: ', downloadURL)
                      outputArray.push(downloadURL)
                      console.log('The imageArray after push is: ', outputArray)
                    })
                })
            }
            })
    })
    resolve()
    })
    }

    async function uploadEachImage () {
    await forEachImage(toolData.croppas, imageURLS)
    console.log(imageURLS)
    const mergedToolData = {
      title: payload.title,
      URLS: imageURLS
    }
    console.log('Uploading to database...')
    firebase.database().ref('tools').push(mergedToolData)
      .then((data) => {
        const key = data.key
        commit('createTool', {
          title: payload.title,
          URLS: imageURLS,
          id: key
        })
      })
    }
  uploadEachImage()
},
</code>```

My attempt here is to wait for the function "forEachImage" to complete.

The function will:

loop through all the images

generate a blob (image)

upload the blob to firebase

Recieve a URL and put it in a "global" variable (imageURLS)

My desired outcome is this:
after that function has completeted all the images, the async function continues and upload the data to the database (also containing the imageURLS[].
As I mentioned, I want to do this without using a timeout. (timer).

答:
I managed to find a solution with the desired outcome, though it is a rather primitive one. </p>

```<code>createTool ({ commit, getters }, payload) {
  commit('setLoading', true)
  const toolData = {
    title: payload.title,
    selectedCategory: payload.selectedCategory,
    description: payload.description,
    kontaktInfo: payload.kontaktInfo,
    creatorId: getters.user.id
  }
  const croppas = {
    croppas: payload.croppas
  }

  var imageURLS = []
  async function forEachImage(images, outputArray) {
    return new Promise((resolve) => {
      images.forEach(async (file) => {
        file.generateBlob(
            async (blob) => {
              if (blob != null) {
                let rand = (Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16)).toUpperCase()
                let imageRef = firebase.storage().ref('toolImages/').child(rand).put(blob)
                  .then( data => {
                    return data.ref.getDownloadURL()
                  })
                let url = await imageRef
                outputArray.push(url)
                console.log('The imageArray after push is: ', outputArray)
                console.log('Antall croppas er: ', croppas.croppas.length)
    console.log('Antall images in imageURLS: ', imageURLS.length + 1)
    if (croppas.croppas.length == imageURLS.length + 1) {
      resolve()
    }
            }
            })

    })
    })
    }

    async function uploadEachImage () {
    await forEachImage(croppas.croppas, imageURLS)
      .then(() => {
        console.log('Waiting is over')
      })
    console.log(imageURLS)
    const mergedToolData = {
      ...toolData,
      URLS: imageURLS
    }
    console.log('Uploading to database...')
    firebase.database().ref('tools').push(mergedToolData)
      .then((data) => {
        const key = data.key
        commit('createTool', {
          title: payload.title,
          URLS: imageURLS,
          id: key
        })
        console.log(croppas.croppas.length)
        console.log('Antall images in imageURLS: ', imageURLS.length)
      })
      .catch((error) => {
        console.log(error)
      })
      commit('setLoading', false)
    }
  uploadEachImage()
  commit('setLoading', false)
},
</code>```

Body:
[Sorry for duplicate question]

This is my working JS-function for uploading images. The problem is that the function for uploading the "tool"(data) to the database, don't wait for the imageURL from Firebase. I need some sort of async / await without using a timeout. I want to upload the data to firebase as soon as all of the imageURLs are uploaded.

Here is JS-code (vuex):

createTool ({ commit }, payload) {
  let toolData = {
    croppas: payload.croppas,
    title: payload.title
  }
  var imageURLS = []

                    // outputArray = imageURLS
  function forEachImage(images, outputArray) {
    return new Promise((resolve) => {
    images.forEach(file => {
        file.generateBlob(
            blob => {
              if (blob != null) {
              let rand = (Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16)).toUpperCase()
              let imageRef = firebase.storage().ref('toolImages/').child(rand)
              imageRef.put(blob)
                .then( data => {
                  imageRef.getDownloadURL()
                    .then( downloadURL => {
                      console.log('The Download Link is: ', downloadURL)
                      outputArray.push(downloadURL)
                      console.log('The imageArray after push is: ', outputArray)
                    })
                })
            }
            })
    })
    resolve()
    })
    }

    async function uploadEachImage () {
    await forEachImage(toolData.croppas, imageURLS)
    console.log(imageURLS)
    const mergedToolData = {
      title: payload.title,
      URLS: imageURLS
    }
    console.log('Uploading to database...')
    firebase.database().ref('tools').push(mergedToolData)
      .then((data) => {
        const key = data.key
        commit('createTool', {
          title: payload.title,
          URLS: imageURLS,
          id: key
        })
      })
    }
  uploadEachImage()
},

My attempt here is to wait for the function "forEachImage" to complete.

The function will:

loop through all the images

generate a blob (image)

upload the blob to firebase

Recieve a URL and put it in a "global" variable (imageURLS)

My desired outcome is this:
after that function has completeted all the images, the async function continues and upload the data to the database (also containing the imageURLS[].
As I mentioned, I want to do this without using a timeout. (timer).

Body:
I managed to find a solution with the desired outcome, though it is a rather primitive one.

createTool ({ commit, getters }, payload) {
  commit('setLoading', true)
  const toolData = {
    title: payload.title,
    selectedCategory: payload.selectedCategory,
    description: payload.description,
    kontaktInfo: payload.kontaktInfo,
    creatorId: getters.user.id
  }
  const croppas = {
    croppas: payload.croppas
  }

  var imageURLS = []
  async function forEachImage(images, outputArray) {
    return new Promise((resolve) => {
      images.forEach(async (file) => {
        file.generateBlob(
            async (blob) => {
              if (blob != null) {
                let rand = (Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16)).toUpperCase()
                let imageRef = firebase.storage().ref('toolImages/').child(rand).put(blob)
                  .then( data => {
                    return data.ref.getDownloadURL()
                  })
                let url = await imageRef
                outputArray.push(url)
                console.log('The imageArray after push is: ', outputArray)
                console.log('Antall croppas er: ', croppas.croppas.length)
    console.log('Antall images in imageURLS: ', imageURLS.length + 1)
    if (croppas.croppas.length == imageURLS.length + 1) {
      resolve()
    }
            }
            })

    })
    })
    }

    async function uploadEachImage () {
    await forEachImage(croppas.croppas, imageURLS)
      .then(() => {
        console.log('Waiting is over')
      })
    console.log(imageURLS)
    const mergedToolData = {
      ...toolData,
      URLS: imageURLS
    }
    console.log('Uploading to database...')
    firebase.database().ref('tools').push(mergedToolData)
      .then((data) => {
        const key = data.key
        commit('createTool', {
          title: payload.title,
          URLS: imageURLS,
          id: key
        })
        console.log(croppas.croppas.length)
        console.log('Antall images in imageURLS: ', imageURLS.length)
      })
      .catch((error) => {
        console.log(error)
      })
      commit('setLoading', false)
    }
  uploadEachImage()
  commit('setLoading', false)
},