问:
Android - How to detect slow network connection?
I have a problem with how to detect an internet connection, I want if the internet connection has slowly there is show alert dialog or notice about the connection internet slowly.

Here is my code:

```<code>private void detectIfLostConnection() {

        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                runOnUiThread(() -> linearNetworkProblem.setVisibility(View.GONE));
            }

            @Override
            public void onLost(@NonNull Network network) {
                super.onLost(network);
                runOnUiThread(() -> linearNetworkProblem.setVisibility(View.VISIBLE));
            }
        };

        connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        connectivityManager.registerDefaultNetworkCallback(networkCallback);
    }
</code>```

I'm using network callback, but here isn't available to check the slow internet.

Any suggestion or answer will be appreciated.

Thank you.

答:
you can use the below mentioned Connectivity utility class to check if internet connected or speed of the internet connection,

```<code>import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;

import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_DISABLED;
import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_WHITELISTED;

public class Connectivity {

    /**
     * Get the network info
     *
     * @param context
     * @return
     */
    public static NetworkInfo getNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * Check if there is any connectivity
     *
     * @param context
     * @return
     */
    public static boolean isConnected(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected());
    }

    public static boolean isConnectedWifi(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
    }

    public static boolean isConnectedMobile(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
    }

    /**
     * Check if there is fast connectivity
     *
     * @param context
     * @return
     */
    public static boolean isConnectedFast(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(), info.getSubtype()));
    }

    /**
     * Check if the connection is fast
     *
     * @param type
     * @param subType
     * @return
     */
    public static boolean isConnectionFast(int type, int subType) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                    return true; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return true; // ~ 14-64 kbps
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    return true; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    return true; // ~ 400-1000 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    return true; // ~ 600-1400 kbps
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return true; // ~ 100 kbps
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                    return true; // ~ 2-14 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPA:
                    return true; // ~ 700-1700 kbps
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                    return true; // ~ 1-23 Mbps
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    return true; // ~ 400-7000 kbps
            /*
             * Above API level 7, make sure to set android:targetSdkVersion
             * to appropriate level to use these
             */
                case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                    return true; // ~ 1-2 Mbps
                case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                    return true; // ~ 5 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                    return true; // ~ 10-20 Mbps
                case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                    return false; // ~25 kbps
                case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                    return true; // ~ 10+ Mbps
                // Unknown
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    public static String getConnectionStrength(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        if (info != null && info.isConnected()) {
            return Connectivity.getInternetStrength(info.getType(), info.getSubtype(), context);
        } else {
            return "Not Connected";
        }
    }

    public static String getInternetStrength(int type, int subType, Context context) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            int numberOfLevels = 5;
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
            return "" + level/* + " out of 5"*/;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return "" + 1; //Poor
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return "" + 3; //Fair
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                case TelephonyManager.NETWORK_TYPE_LTE:
                    return "" + 5; //Good
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    return "" + 0; //No Connection
                default:
                    return "" + 0;
            }
        } else {
            return "Not Connected";
        }
    }

    /***
     * Get Device Connection Status
     * @param context Calling Context.
     * @return Connectivity signal status value which is based on Network Info
     */
    public static String getConnectionStatus(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        if (info == null || !info.isConnected()) {
            return Constants.ConnectionSignalStatus.NO_CONNECTIVITY;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) == 3
                && Utils.getBatteryPercentageDouble(context) > 20) {
            return Constants.ConnectionSignalStatus.GOOD_STRENGTH;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) >= 2
                && Utils.getBatteryPercentageDouble(context) > 20) {
            return Constants.ConnectionSignalStatus.FAIR_STRENGTH;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) >= 2
                && Utils.getBatteryPercentageDouble(context) <= 20) {
            return Constants.ConnectionSignalStatus.BATTERY_LOW;
        } else {
            return Constants.ConnectionSignalStatus.POOR_STRENGTH;
        }
    }

    public static int getInternetStatus(int type, int subType, Context context) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            int numberOfLevels = 5;
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
            if (level < 2) {
                return 2; //Fair
            } else {
                return 3; //Good
            }
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return 1; //Poor
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return 1; //Fair
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                case TelephonyManager.NETWORK_TYPE_LTE:
                    return 3; //Good
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    return 0; //No Connection
                default:
                    return 0;
            }
        } else {
            return 0;
        }
    }

    /**
     * Return the availability of cellular data access in background.
     *
     * @param context Application or Activity context.
     *
     * @return Availability of cellular data access in background.
     */
    public static boolean isBackgroundDataAccessAvailable(Context context) {

        boolean isBackgroundDataAccessAvailable = true;

        ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connMgr != null) {
            // Checks if the device is on a metered network
            if (connMgr.isActiveNetworkMetered()) {

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                    // Checks user’s Data Saver settings.
                    switch (connMgr.getRestrictBackgroundStatus()) {

                        case RESTRICT_BACKGROUND_STATUS_DISABLED:
                            // Data Saver is disabled. Since the device is connected to a
                            // metered network, the app should use less data wherever possible.
                            isBackgroundDataAccessAvailable = true;
                            break;

                        case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
                            // The app is whitelisted. Wherever possible,
                            // the app should use less data in the foreground and background.
                            isBackgroundDataAccessAvailable = true;
                            break;

                        case RESTRICT_BACKGROUND_STATUS_ENABLED:
                            // Background data usage is blocked for this app. Wherever possible,
                            // the app should also use less data in the foreground.
                            isBackgroundDataAccessAvailable = false;
                            break;
                    }
                } else {
                    NetworkInfo.State state = connMgr.getActiveNetworkInfo().getState();
                    isBackgroundDataAccessAvailable = state != NetworkInfo.State.DISCONNECTED;
                }

            } else {
                // The device is not on a metered network.
                // Use data as required to perform syncs, downloads, and updates.
                isBackgroundDataAccessAvailable = true;
            }
        } else {
            isBackgroundDataAccessAvailable = true;
        }

        return isBackgroundDataAccessAvailable;
    }

}
</code>```

USAGE

```<code>boolean isFastConnection = Connectivity.isConnectedFast(ctx);
</code>```

Body:
I have a problem with how to detect an internet connection, I want if the internet connection has slowly there is show alert dialog or notice about the connection internet slowly.

Here is my code:

private void detectIfLostConnection() {

        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                runOnUiThread(() -> linearNetworkProblem.setVisibility(View.GONE));
            }

            @Override
            public void onLost(@NonNull Network network) {
                super.onLost(network);
                runOnUiThread(() -> linearNetworkProblem.setVisibility(View.VISIBLE));
            }
        };

        connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        connectivityManager.registerDefaultNetworkCallback(networkCallback);
    }

I'm using network callback, but here isn't available to check the slow internet.

Any suggestion or answer will be appreciated.

Thank you.

Body:
you can use the below mentioned Connectivity utility class to check if internet connected or speed of the internet connection,

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;

import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_DISABLED;
import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_WHITELISTED;

public class Connectivity {

    /**
     * Get the network info
     *
     * @param context
     * @return
     */
    public static NetworkInfo getNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * Check if there is any connectivity
     *
     * @param context
     * @return
     */
    public static boolean isConnected(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected());
    }

    public static boolean isConnectedWifi(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
    }

    public static boolean isConnectedMobile(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
    }

    /**
     * Check if there is fast connectivity
     *
     * @param context
     * @return
     */
    public static boolean isConnectedFast(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(), info.getSubtype()));
    }

    /**
     * Check if the connection is fast
     *
     * @param type
     * @param subType
     * @return
     */
    public static boolean isConnectionFast(int type, int subType) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                    return true; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return true; // ~ 14-64 kbps
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    return true; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    return true; // ~ 400-1000 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    return true; // ~ 600-1400 kbps
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return true; // ~ 100 kbps
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                    return true; // ~ 2-14 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPA:
                    return true; // ~ 700-1700 kbps
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                    return true; // ~ 1-23 Mbps
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    return true; // ~ 400-7000 kbps
            /*
             * Above API level 7, make sure to set android:targetSdkVersion
             * to appropriate level to use these
             */
                case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                    return true; // ~ 1-2 Mbps
                case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                    return true; // ~ 5 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                    return true; // ~ 10-20 Mbps
                case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                    return false; // ~25 kbps
                case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                    return true; // ~ 10+ Mbps
                // Unknown
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    public static String getConnectionStrength(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        if (info != null && info.isConnected()) {
            return Connectivity.getInternetStrength(info.getType(), info.getSubtype(), context);
        } else {
            return "Not Connected";
        }
    }

    public static String getInternetStrength(int type, int subType, Context context) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            int numberOfLevels = 5;
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
            return "" + level/* + " out of 5"*/;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return "" + 1; //Poor
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return "" + 3; //Fair
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                case TelephonyManager.NETWORK_TYPE_LTE:
                    return "" + 5; //Good
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    return "" + 0; //No Connection
                default:
                    return "" + 0;
            }
        } else {
            return "Not Connected";
        }
    }

    /***
     * Get Device Connection Status
     * @param context Calling Context.
     * @return Connectivity signal status value which is based on Network Info
     */
    public static String getConnectionStatus(Context context) {
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        if (info == null || !info.isConnected()) {
            return Constants.ConnectionSignalStatus.NO_CONNECTIVITY;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) == 3
                && Utils.getBatteryPercentageDouble(context) > 20) {
            return Constants.ConnectionSignalStatus.GOOD_STRENGTH;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) >= 2
                && Utils.getBatteryPercentageDouble(context) > 20) {
            return Constants.ConnectionSignalStatus.FAIR_STRENGTH;
        } else if (Connectivity.getInternetStatus(info.getType(), info.getSubtype(), context) >= 2
                && Utils.getBatteryPercentageDouble(context) <= 20) {
            return Constants.ConnectionSignalStatus.BATTERY_LOW;
        } else {
            return Constants.ConnectionSignalStatus.POOR_STRENGTH;
        }
    }

    public static int getInternetStatus(int type, int subType, Context context) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            int numberOfLevels = 5;
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
            if (level < 2) {
                return 2; //Fair
            } else {
                return 3; //Good
            }
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return 1; //Poor
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return 1; //Fair
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                case TelephonyManager.NETWORK_TYPE_LTE:
                    return 3; //Good
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    return 0; //No Connection
                default:
                    return 0;
            }
        } else {
            return 0;
        }
    }

    /**
     * Return the availability of cellular data access in background.
     *
     * @param context Application or Activity context.
     *
     * @return Availability of cellular data access in background.
     */
    public static boolean isBackgroundDataAccessAvailable(Context context) {

        boolean isBackgroundDataAccessAvailable = true;

        ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connMgr != null) {
            // Checks if the device is on a metered network
            if (connMgr.isActiveNetworkMetered()) {

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                    // Checks user’s Data Saver settings.
                    switch (connMgr.getRestrictBackgroundStatus()) {

                        case RESTRICT_BACKGROUND_STATUS_DISABLED:
                            // Data Saver is disabled. Since the device is connected to a
                            // metered network, the app should use less data wherever possible.
                            isBackgroundDataAccessAvailable = true;
                            break;

                        case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
                            // The app is whitelisted. Wherever possible,
                            // the app should use less data in the foreground and background.
                            isBackgroundDataAccessAvailable = true;
                            break;

                        case RESTRICT_BACKGROUND_STATUS_ENABLED:
                            // Background data usage is blocked for this app. Wherever possible,
                            // the app should also use less data in the foreground.
                            isBackgroundDataAccessAvailable = false;
                            break;
                    }
                } else {
                    NetworkInfo.State state = connMgr.getActiveNetworkInfo().getState();
                    isBackgroundDataAccessAvailable = state != NetworkInfo.State.DISCONNECTED;
                }

            } else {
                // The device is not on a metered network.
                // Use data as required to perform syncs, downloads, and updates.
                isBackgroundDataAccessAvailable = true;
            }
        } else {
            isBackgroundDataAccessAvailable = true;
        }

        return isBackgroundDataAccessAvailable;
    }

}

USAGE

boolean isFastConnection = Connectivity.isConnectedFast(ctx);


来源: stackexchange

问:
php openssl library not loaded error in terminal
I run php7.2 on mac os mojave. I recently noticed when I run php -v in terminal I get this error

I am not sure what caused it because I noticed it today. uninstalling openssl using homebrew & installing again didn't work.

答: I installed new php version, php7.72 , it fixed the issue for me.</p>

ContentLicense: CC BY-SA 4.0


问:
how to increase nodejs default memory?
On Server startup exporting 2GB(Approximately) data from mongodb to redis,then getting error as FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory.

Then started server with this command node --max-old-space-size=4076 server.js and works fine. But needs to configure in nodejs applicaton so that node server always starts with 4gb memory. Please help me how to fix this?
Thanks.

答:
There are two ways to resolve this, First way is to set memory size explicitly for your application, already answered above. And the other way is to set memory size globally for node - This is done by creating an Environment variable, with

```<code>variable name=NODE_OPTIONS
</code>```

and

```<code>variable value=--max-old-space-size=4096
</code>```

ContentLicense: CC BY-SA 3.0

Title: how to increase nodejs default memory?

Body:
There are two ways to resolve this, First way is to set memory size explicitly for your application, already answered above. And the other way is to set memory size globally for node - This is done by creating an Environment variable, with

variable name=NODE_OPTIONS

and

variable value=--max-old-space-size=4096


问:
Why does Ecto have a maintenance_database option?
I was recently looking through the docs of Ecto Postgres Adapter and noticed it had an option for maintenance_database. It says it's the database used when dropping or creating the db. But why would it need this because at the time of dropping or creating the database you would be using a mix task most of the time and it would be a controller at that point so it wouldn't be a using a persisted connection to connected to the db anyway?

I was just baffled by this option because it just seems odd and I was wondering if someone could shed some light on how to use it in a practical way and maybe why it would exist.

If this is the wrong medium for asking these sort of discussion questions then let me know and I'll move it to another location.

答:
mix is not included in releases, in the first place. Imagine the case when you maintain the mission-critical software that cannot be shut down for a nanosecond. Now there is a need to clean up the database for, say, performance reasons.

The simplest (and fastest) way would be to drop and create the DB. So you instruct your supervision tree to understand this option via GenServer.code_change/3 callbacks and deploy the code that performs an action.

Also, I doubt I follow what controller do you mention in the question, ecto applications do not require phoenix-framework at all to run.


问:
I am using lookup in mongodb aggregation, but it doesnt return data i am looking for
Here is a sample building collection.

```<code>{
    _id: 5e4aa096a6b7db2270c65815,
    previous_audit: false,
    no_of_people: 3,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'Nemi',
    building_type: 'Hospital',
    climate_zone: 'Hot & Dry',
    no_of_stories: '3',
    year_of_occupation: 3,
    gross_area: 3333,
    gross_area_units: 'Square Meters',
    lease_type: 'Annual Rental',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-17T14:17:58.892Z,
    updatedAt: 2020-02-17T14:17:58.892Z,
    __v: 0,
}
</code>```

And in first pipeline stage i am using $match function.

```<code>Building.aggregate([
    {
        $match: {
            campus_id: {
                $in: campus_ids
            }
        }
    },
    {
        $lookup: {
            from: 'manual_meters',
            localField: '_id',
            foreignField: 'building_name',
            as: 'manual_meter'
        }
    }
])
</code>```

But when looking lookup , it always return empty arryay in manual_meter.
This is the respnse i am getting. ALthough the collection manual meter contains the id of building, but still it doesnt return the manual meter collection.

```<code> {
    _id: 5e4857816560b92a58129e72,
    previous_audit: false,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'U.N.House',
    building_type: 'Office',
    climate_zone: 'Hot & Dry',
    no_of_stories: '4',
    year_of_occupation: 1970,
    gross_area: 6500,
    gross_area_units: 'Square Meters',
    lease_type: 'Owned',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-15T20:41:37.171Z,
    updatedAt: 2020-02-15T20:41:37.171Z,
    __v: 0,
    manual_meter: []
  },
  {
    _id: 5e4aa096a6b7db2270c65815,
    previous_audit: false,
    no_of_people: 3,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'Nemi',
    building_type: 'Hospital',
    climate_zone: 'Hot & Dry',
    no_of_stories: '3',
    year_of_occupation: 3,
    gross_area: 3333,
    gross_area_units: 'Square Meters',
    lease_type: 'Annual Rental',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-17T14:17:58.892Z,
    updatedAt: 2020-02-17T14:17:58.892Z,
    __v: 0,
    manual_meter: []
  }
]
</code>```

Below is a sample manual_meter collection.

```<code>    {"_id":"5e4ad8e1a3833e2bb44b4dcb",
"meter_data : [],
"meter_name":"undp_unh",
"meter_id":"1001",
"meter_type":"energy",
"campus_name":"UNDP",
"building_name":"5e4857816560b92a58129e72",
"floor_name":"common",
"zone_name":"common",
"createdAt":"2020-02-17T18:18:09.192Z",
"updatedAt":"2020-02-17T18:18:09.192Z",
"__v":0}
</code>```

答:
It looks like you're trying to match string against ObjectId which won't work, even if the values are the same. You can run $toString on your _id field as part of $lookup:

```<code>{
    $lookup: {
        from: "manual_meters",
        let: { building_id: { $toString: "$_id" } },
        pipeline: [
            {
                $match:{
                    $expr: {
                        $eq: [ "$$building_id", "$building_name" ]
                    }
                }
            }
        ],
        as: "manual_meter"
    }
}
</code>```

Body:
Here is a sample building collection.

{
    _id: 5e4aa096a6b7db2270c65815,
    previous_audit: false,
    no_of_people: 3,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'Nemi',
    building_type: 'Hospital',
    climate_zone: 'Hot & Dry',
    no_of_stories: '3',
    year_of_occupation: 3,
    gross_area: 3333,
    gross_area_units: 'Square Meters',
    lease_type: 'Annual Rental',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-17T14:17:58.892Z,
    updatedAt: 2020-02-17T14:17:58.892Z,
    __v: 0,
}

And in first pipeline stage i am using $match function.

Building.aggregate([
    {
        $match: {
            campus_id: {
                $in: campus_ids
            }
        }
    },
    {
        $lookup: {
            from: 'manual_meters',
            localField: '_id',
            foreignField: 'building_name',
            as: 'manual_meter'
        }
    }
])

But when looking lookup , it always return empty arryay in manual_meter.
This is the respnse i am getting. ALthough the collection manual meter contains the id of building, but still it doesnt return the manual meter collection.

 {
    _id: 5e4857816560b92a58129e72,
    previous_audit: false,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'U.N.House',
    building_type: 'Office',
    climate_zone: 'Hot & Dry',
    no_of_stories: '4',
    year_of_occupation: 1970,
    gross_area: 6500,
    gross_area_units: 'Square Meters',
    lease_type: 'Owned',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-15T20:41:37.171Z,
    updatedAt: 2020-02-15T20:41:37.171Z,
    __v: 0,
    manual_meter: []
  },
  {
    _id: 5e4aa096a6b7db2270c65815,
    previous_audit: false,
    no_of_people: 3,
    project_name: 'UNDP',
    premise_contact: 'Kanagaraj',
    premise_address: 'Delhi',
    premise_city: 'Delhi',
    premise_state: 'Delhi',
    premise_country: 'IN',
    latitude: '28.593716',
    longitude: '77.222391',
    building_name: 'Nemi',
    building_type: 'Hospital',
    climate_zone: 'Hot & Dry',
    no_of_stories: '3',
    year_of_occupation: 3,
    gross_area: 3333,
    gross_area_units: 'Square Meters',
    lease_type: 'Annual Rental',
    campus_id: 5e4857816560b92a58129e68,
    project_name_lower: 'undp',
    createdAt: 2020-02-17T14:17:58.892Z,
    updatedAt: 2020-02-17T14:17:58.892Z,
    __v: 0,
    manual_meter: []
  }
]

Below is a sample manual_meter collection.

    {"_id":"5e4ad8e1a3833e2bb44b4dcb",
"meter_data : [],
"meter_name":"undp_unh",
"meter_id":"1001",
"meter_type":"energy",
"campus_name":"UNDP",
"building_name":"5e4857816560b92a58129e72",
"floor_name":"common",
"zone_name":"common",
"createdAt":"2020-02-17T18:18:09.192Z",
"updatedAt":"2020-02-17T18:18:09.192Z",
"__v":0}

Body:
It looks like you're trying to match string against ObjectId which won't work, even if the values are the same. You can run $toString on your _id field as part of $lookup:

{
    $lookup: {
        from: "manual_meters",
        let: { building_id: { $toString: "$_id" } },
        pipeline: [
            {
                $match:{
                    $expr: {
                        $eq: [ "$$building_id", "$building_name" ]
                    }
                }
            }
        ],
        as: "manual_meter"
    }
}


问:
How can I get additional data from one promise to another?
I have one promise that relies on the return value of another promise. I'm successfully passing that value to the second promise, but there's additional data that's created in the first promise that I'd like to get into the second promise somehow.

Here's my code:

```<code>const getAlbumInfo = async (album, artist) => {
        let hostname = 'http://www.musicbrainz.org';
        let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
        let res = await fetch(hostname + path);
        return res.json();
};

const getAlbumArt = async (albumInfo) => {
    let res = await fetch(`${albumInfo.url}`);
    return res.json();
};

let artist = '', album = '';

getAlbumInfo(album, artist)
    .then((res) => {
        const metadata = {
            album: res['album'],
            artist: res['artist'],
            url: res['url']
        };

        return getAlbumArt(metadata);
    })
    .then((res) => {
        console.log(res);  // prints result from getAlbumArt

        // I also need the contents of metadata here
    })
    .catch(e => { console.error(e); });
</code>```

So I'm getting album metadata in the first promise, which includes a URL, and then I'm running a fetch on that URL, which returns a second promise. The problem is that I need access to the album metadata in the second promise.

Since I'm returning/passing the metadata into the second promise, I tried using Object.assign() inside getAlbumArt() to combine the metadata and the fetch result, but that didn't seem to work.

答:
There are multiple ways of doing this, you could use await:

```<code>const getAlbumInfo = async(album, artist) => {
  let hostname = 'http://www.musicbrainz.org';
  let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
  let res = await fetch(hostname + path);
  return res.json();
};

const getAlbumArt = async(albumInfo) => {
  let res = await fetch(`${albumInfo.url}`);
  return res.json();
};

let artist = '',
  album = '';

const getAll = async() => {
  const res1 = await getAlbumInfo(album, artist);
  const metadata = {
    album: res['album'],
    artist: res['artist'],
    url: res['url']
  };
  const res2 = await getAlbumArt(metadata);

  // here you have access to both responses (res1 and res2) and the created metadata object.
}
</code>```

If you use this, you should wrap the calls in try..catch...

Another option will be to pass the metadata from the second promise along with the response:

```<code>const getAlbumInfo = async(album, artist) => {
  let hostname = 'http://www.musicbrainz.org';
  let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
  let res = await fetch(hostname + path);
  return res.json();
};

const getAlbumArt = async(albumInfo) => {
  let res = await fetch(`${albumInfo.url}`);
  res = await res.json();
  return {
    res,
    albumInfo
  };
};

let artist = '',
  album = '';

getAlbumInfo(album, artist)
  .then((res) => {
    const metadata = {
      album: res['album'],
      artist: res['artist'],
      url: res['url']
    };

    return getAlbumArt(metadata);
  })
  .then((o) => {
    console.log(o.res, o.albumInfo);
  })
  .catch(e => {
    console.error(e);
  });
</code>```

And a third option will be to resolve the second promise inside the first promise's callback function:

```<code>getAlbumInfo(album, artist)
  .then((res) => {
    const metadata = {
      album: res['album'],
      artist: res['artist'],
      url: res['url']
    };

    getAlbumArt(metadata)
      .then(res2 => {
        // here you can access res, res2 and metadata
      })
      .catch(..);
  })
  .catch(..);
</code>```

Body:
I have one promise that relies on the return value of another promise. I'm successfully passing that value to the second promise, but there's additional data that's created in the first promise that I'd like to get into the second promise somehow.

Here's my code:

const getAlbumInfo = async (album, artist) => {
        let hostname = 'http://www.musicbrainz.org';
        let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
        let res = await fetch(hostname + path);
        return res.json();
};

const getAlbumArt = async (albumInfo) => {
    let res = await fetch(`${albumInfo.url}`);
    return res.json();
};

let artist = '', album = '';

getAlbumInfo(album, artist)
    .then((res) => {
        const metadata = {
            album: res['album'],
            artist: res['artist'],
            url: res['url']
        };

        return getAlbumArt(metadata);
    })
    .then((res) => {
        console.log(res);  // prints result from getAlbumArt

        // I also need the contents of metadata here
    })
    .catch(e => { console.error(e); });

So I'm getting album metadata in the first promise, which includes a URL, and then I'm running a fetch on that URL, which returns a second promise. The problem is that I need access to the album metadata in the second promise.

Since I'm returning/passing the metadata into the second promise, I tried using Object.assign() inside getAlbumArt() to combine the metadata and the fetch result, but that didn't seem to work.

Body:
There are multiple ways of doing this, you could use await:

const getAlbumInfo = async(album, artist) => {
  let hostname = 'http://www.musicbrainz.org';
  let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
  let res = await fetch(hostname + path);
  return res.json();
};

const getAlbumArt = async(albumInfo) => {
  let res = await fetch(`${albumInfo.url}`);
  return res.json();
};

let artist = '',
  album = '';

const getAll = async() => {
  const res1 = await getAlbumInfo(album, artist);
  const metadata = {
    album: res['album'],
    artist: res['artist'],
    url: res['url']
  };
  const res2 = await getAlbumArt(metadata);

  // here you have access to both responses (res1 and res2) and the created metadata object.
}

If you use this, you should wrap the calls in try..catch...

Another option will be to pass the metadata from the second promise along with the response:

const getAlbumInfo = async(album, artist) => {
  let hostname = 'http://www.musicbrainz.org';
  let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
  let res = await fetch(hostname + path);
  return res.json();
};

const getAlbumArt = async(albumInfo) => {
  let res = await fetch(`${albumInfo.url}`);
  res = await res.json();
  return {
    res,
    albumInfo
  };
};

let artist = '',
  album = '';

getAlbumInfo(album, artist)
  .then((res) => {
    const metadata = {
      album: res['album'],
      artist: res['artist'],
      url: res['url']
    };

    return getAlbumArt(metadata);
  })
  .then((o) => {
    console.log(o.res, o.albumInfo);
  })
  .catch(e => {
    console.error(e);
  });

And a third option will be to resolve the second promise inside the first promise's callback function:

getAlbumInfo(album, artist)
  .then((res) => {
    const metadata = {
      album: res['album'],
      artist: res['artist'],
      url: res['url']
    };

    getAlbumArt(metadata)
      .then(res2 => {
        // here you can access res, res2 and metadata
      })
      .catch(..);
  })
  .catch(..);


问:
Load data from SQL Server to datagridview using a thread
I'm trying to load data from a SQL Server database into a DataGridView using threading with delegates and later will try to add a loading or waiting form. But I can't make it work.

Dim t1 As Thread

Private Delegate Sub delegate_updatedgv()

Private Sub mainform_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    t1 = New Thread(AddressOf load_dgv)
    t1.Start()
End Sub

Private Function load_dgv()
    Try
        If DBCon.State = ConnectionState.Closed Then
            DBCon.Open()
        End If

        DBCmd = New SqlCommand("SELECT * FROM Jobs ", DBCon)
        DBCmd.ExecuteNonQuery()
        Dim DBDT = New DataTable
        Dim DBDA = New SqlDataAdapter(DBCmd)
        Dim RecordCount = DBDA.Fill(DBDT)
        assignit(DBDT)
        DBCon.Close()

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        If DBCon.State = ConnectionState.Open Then DBCon.Close()
    End Try
End Function

Sub assignit(ByVal x As DataTable)
    If Me.InvokeRequired Then
        Me.Invoke(New delegate_updatedgv(AddressOf assignit))
    End If
    GridControl1.DataSource = x
End Sub
```

and its not working at all

答:
While we are at, let's fix up the database code a bit. There is no need to check connection state when database objects are keep local to the method where they are used. This way you can ensure that they are closed and disposed with a Using...End Using block.

I have no idea why you are calling .ExecuteNonQuery on this command. You never use RecordCount so I don't see the point of that either. I just used one line to load the DataTable. The adapter seemed extraneous.

```<code>Private Sub load_dgv()
    Dim dt As New DataTable
    Using DBCon As New SqlConnection("Your connection string"),
        DBCmd As New SqlCommand("SELECT * FROM Jobs ", DBCon)
        DBCon.Open()
        dt.Load(DBCmd.ExecuteReader)
    End Using
    assignit(dt)
End Sub
</code>```

I know this didn't answer your threading question but I hope it helped for data access.

Where is the bottleneck in this code? Is it just the retrieval of data or is it updating the UI? Maybe only the data access needs to run on a separate thread.

Body:
I'm trying to load data from a SQL Server database into a DataGridView using threading with delegates and later will try to add a loading or waiting form. But I can't make it work.

Dim t1 As Thread

Private Delegate Sub delegate_updatedgv()

Private Sub mainform_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    t1 = New Thread(AddressOf load_dgv)
    t1.Start()
End Sub

Private Function load_dgv()
    Try
        If DBCon.State = ConnectionState.Closed Then
            DBCon.Open()
        End If

        DBCmd = New SqlCommand("SELECT * FROM Jobs ", DBCon)
        DBCmd.ExecuteNonQuery()
        Dim DBDT = New DataTable
        Dim DBDA = New SqlDataAdapter(DBCmd)
        Dim RecordCount = DBDA.Fill(DBDT)
        assignit(DBDT)
        DBCon.Close()

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        If DBCon.State = ConnectionState.Open Then DBCon.Close()
    End Try
End Function

Sub assignit(ByVal x As DataTable)
    If Me.InvokeRequired Then
        Me.Invoke(New delegate_updatedgv(AddressOf assignit))
    End If
    GridControl1.DataSource = x
End Sub

and its not working at all

Body:
While we are at, let's fix up the database code a bit. There is no need to check connection state when database objects are keep local to the method where they are used. This way you can ensure that they are closed and disposed with a Using...End Using block.

I have no idea why you are calling .ExecuteNonQuery on this command. You never use RecordCount so I don't see the point of that either. I just used one line to load the DataTable. The adapter seemed extraneous.

Private Sub load_dgv()
    Dim dt As New DataTable
    Using DBCon As New SqlConnection("Your connection string"),
        DBCmd As New SqlCommand("SELECT * FROM Jobs ", DBCon)
        DBCon.Open()
        dt.Load(DBCmd.ExecuteReader)
    End Using
    assignit(dt)
End Sub

I know this didn't answer your threading question but I hope it helped for data access.

Where is the bottleneck in this code? Is it just the retrieval of data or is it updating the UI? Maybe only the data access needs to run on a separate thread.


问:
Ruby on Rails: Error `require': cannot load such file -- bundler/setup (LoadError)
I'm trying to set up redmine on an managed server. Redmine installation works, I can start the rails server and visit the redmine page localy with lynx.
Integration in the Apache is done via FCGI and when I enter the redmine start page in my browser I get an Server error 500. In the server logs I see this:

```<code>Feb 18 01:17:12 dedi444 apache: /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/config/boot.rb:4:in `<top (required)>'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/startup.rb:1:in `<main>'
Feb 18 01:17:12 dedi444 apache: /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/config/boot.rb:4:in `<top (required)>'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/startup.rb:1:in `<main>'
Feb 18 01:17:18 dedi444 apache: [Tue Feb 18 01:17:18.386071 2020] [fcgid:info] [pid 31847:tid 140048663593024] mod_fcgid: process /usr/www/users/admin/test/dispatch.fcgi(3096) exit(communication error), terminated by calling exit(), return code: 1
</code>```

I searched for the errormessage other answers recommended an bundle install - output is

```<code>...
Bundle complete! 27 Gemfile dependencies, 58 gems now installed.
Gems in the groups development, test and rmagick were not installed.
Bundled gems are installed into `/usr/home/admin/.gem`
</code>```

EDIT
additional info: I continued searching for answers, maybe the GEM_PATH is the problem and ruby can't find the bundle/setup.
My fcgi script looks like this:

```<code>#!/bin/dash
export GEM_HOME="$HOME/.gem/ruby/2.3.0/"
export GEM_PATH="$GEM_HOME:/var/lib/ruby/gems/1.8"
exec /usr/bin/ruby /usr/www/users/admin/redmine/startup.rb
</code>```

How can I find the location of the 'bundle/setup' on my system?

Any idea what I can do?

Thanks a lot
Klaus

答:
Looks that you have ambiguity with your ruby & gem paths.
They are installed  in /usr/home/admin/.gem and fcgi is trying to find them in /usr/lib/ruby/2.3.0/rubygems/ that's because Apache doesn't know where to look.

You should try passing env config variables via .htaccess file if your shared hosting system allows it or via apache config

```<code>SetEnv GEM_HOME /usr/home/admin/.gem
</code>```

However, Redmine is preferably used via some application server (puma, thin, webrick...), and reverse-proxied or run via Passenger as Apache module, and preferably it uses Ruby installed via rvm or rbenv...

Thus, depending upon version, it might also require you to add

gem "fcgi"  in Gemfile and run bundle install again, and also to add these lines in dispatch.fcgi

```<code>require 'rubygems'
require 'fcgi'
</code>```

Body:
I'm trying to set up redmine on an managed server. Redmine installation works, I can start the rails server and visit the redmine page localy with lynx.
Integration in the Apache is done via FCGI and when I enter the redmine start page in my browser I get an Server error 500. In the server logs I see this:

Feb 18 01:17:12 dedi444 apache: /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/config/boot.rb:4:in `<top (required)>'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/startup.rb:1:in `'
Feb 18 01:17:12 dedi444 apache: /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/config/boot.rb:4:in `<top (required)>'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Feb 18 01:17:12 dedi444 apache:         from /usr/www/users/admin/redmine/startup.rb:1:in `'
Feb 18 01:17:18 dedi444 apache: [Tue Feb 18 01:17:18.386071 2020] [fcgid:info] [pid 31847:tid 140048663593024] mod_fcgid: process /usr/www/users/admin/test/dispatch.fcgi(3096) exit(communication error), terminated by calling exit(), return code: 1

I searched for the errormessage other answers recommended an bundle install - output is

...
Bundle complete! 27 Gemfile dependencies, 58 gems now installed.
Gems in the groups development, test and rmagick were not installed.
Bundled gems are installed into `/usr/home/admin/.gem`

EDIT
additional info: I continued searching for answers, maybe the GEM_PATH is the problem and ruby can't find the bundle/setup.
My fcgi script looks like this:

#!/bin/dash
export GEM_HOME="$HOME/.gem/ruby/2.3.0/"
export GEM_PATH="$GEM_HOME:/var/lib/ruby/gems/1.8"
exec /usr/bin/ruby /usr/www/users/admin/redmine/startup.rb

How can I find the location of the 'bundle/setup' on my system?

Any idea what I can do?

Thanks a lot
Klaus

Body:
Looks that you have ambiguity with your ruby & gem paths.
They are installed  in /usr/home/admin/.gem and fcgi is trying to find them in /usr/lib/ruby/2.3.0/rubygems/ that's because Apache doesn't know where to look.

You should try passing env config variables via .htaccess file if your shared hosting system allows it or via apache config

SetEnv GEM_HOME /usr/home/admin/.gem

However, Redmine is preferably used via some application server (puma, thin, webrick...), and reverse-proxied or run via Passenger as Apache module, and preferably it uses Ruby installed via rvm or rbenv...

Thus, depending upon version, it might also require you to add

gem "fcgi"  in Gemfile and run bundle install again, and also to add these lines in dispatch.fcgi

require 'rubygems'
require 'fcgi'


问:
Why is std::vector slower than an array?
When I run the following program (with optimization on), the for loop with the std::vector takes about 0.04 seconds while the for loop with the array takes 0.0001 seconds.

```<code>#include <iostream>
#include <vector>
#include <chrono>

int main()
{
    int len = 800000;
    int* Data = new int[len];

    int arr[3] = { 255, 0, 0 };
    std::vector<int> vec = { 255, 0, 0 };

    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < len; i++) {
        Data[i] = vec[0];
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
    std::cout << "The vector took " << elapsed.count() << "seconds\n";

    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < len; i++) {
        Data[i] = arr[0];
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
    std::cout << "The array took " << elapsed.count() << "seconds \n";

    char s;
    std::cin >> s;
    delete[] Data;
}
</code>```

The code is a simplified version of a performance issue I was having while writing a raycaster.  The len variable corresponds to how many times the loop in the original program needs to run (400 pixels * 400 pixels * 50 maximum render distance).  For complicated reasons (perhaps that I don't fully understand how to use arrays) I have to use a vector rather than an array in the actual raycaster.  However, as this program demonstrates, that would only give me 20 frames per second as opposed to the envied 10,000 frames per second that using an array would supposedly give me (obviously, this is just a simplified performance test).  But regardless of how accurate those numbers are, I still want to boost my frame rate as much as possible.  So, why is the vector performing so much slower than the array?  Is there a way to speed it up?  Thanks for your help.  And if there's anything else I'm doing weirdly that might be affecting performance, please let me know.  I didn't even know about optimization until researching an answer for this question, so if there are any more things like that which might boost the performance, please let me know (and I'd prefer if you explained where those settings are in the properties manager rather than command line since I don't yet know how to use the command line)

答:
It is about caches. I dont know how it works detailed but Data[] is getting known better by cpu while it is used. If you reverse the order of calculation you can see 'vector is faster'.

But actually, you are testing neither vector nor array. Let's assume that vec[0] resides at 0x01 memory location, arr[0] resides at 0xf1. Only difference is reading a word from different single memory adresses. So you are testing how fast can I assign a value to elements of dynamically allocated array.

Note: std::chrono::high_resolution_clock might not be sufficient to measure ticks. It is  better to use steady_clock as cppreference says.

Body:
When I run the following program (with optimization on), the for loop with the std::vector takes about 0.04 seconds while the for loop with the array takes 0.0001 seconds.

#include <iostream>
#include <vector>
#include <chrono>

int main()
{
    int len = 800000;
    int* Data = new int[len];

    int arr[3] = { 255, 0, 0 };
    std::vector<int> vec = { 255, 0, 0 };

    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < len; i++) {
        Data[i] = vec[0];
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
    std::cout << "The vector took " << elapsed.count() << "seconds\n";

    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < len; i++) {
        Data[i] = arr[0];
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
    std::cout << "The array took " << elapsed.count() << "seconds \n";

    char s;
    std::cin >> s;
    delete[] Data;
}

The code is a simplified version of a performance issue I was having while writing a raycaster.  The len variable corresponds to how many times the loop in the original program needs to run (400 pixels * 400 pixels * 50 maximum render distance).  For complicated reasons (perhaps that I don't fully understand how to use arrays) I have to use a vector rather than an array in the actual raycaster.  However, as this program demonstrates, that would only give me 20 frames per second as opposed to the envied 10,000 frames per second that using an array would supposedly give me (obviously, this is just a simplified performance test).  But regardless of how accurate those numbers are, I still want to boost my frame rate as much as possible.  So, why is the vector performing so much slower than the array?  Is there a way to speed it up?  Thanks for your help.  And if there's anything else I'm doing weirdly that might be affecting performance, please let me know.  I didn't even know about optimization until researching an answer for this question, so if there are any more things like that which might boost the performance, please let me know (and I'd prefer if you explained where those settings are in the properties manager rather than command line since I don't yet know how to use the command line)


问:
Get remote address/IP - C Berkeley Sockets
If I have a socket file descriptor connected (either by connect or by bind), type SOCK_STREAM, is it possible to get the remote address / IP address?

I need to do this within a function where I don't have any other data than the socket file descriptor.

答: See the getpeername() system call.

Body: See the getpeername() system call.


问:
Simple jQuery toggle with bulma card not working
I have a little bulma card. I tried to display it, when I click on the icon:

```<code>  <div class="card">
    <header class="card-header">
      <p class="card-header-title">
        Component
      </p>
      <a href="#" class="card-header-icon" aria-label="more options" id="server">
        <span class="icon">
          <i class="fas fa-angle-down" aria-hidden="true"></i>
        </span>
      </a>
    </header>
    <div class="card-content is-hidden" id="server-content">
      <div class="content">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.
        <a href="#">@bulmaio</a>. <a href="#">#css</a> <a href="#">#responsive</a>
        <br>
        <time datetime="2016-1-1">11:09 PM - 1 Jan 2016</time>
      </div>
    </div>
  </div>
</code>```

This I tried:

```<code>$(document).ready(function() {

  $("#server").click(function() {
    $("#server-content").toggle();
  });
});
</code>```

But it didn't work. In my HTML Head I do this:

```<code>  <script src="js/jquery.js" type="text/javascript"></script>
  <script src="js/main.js" type="text/javascript"></script>
</code>```

In the main.js file is the snippet from above.
When I put an alert inside the jquery function it will be pop up, but the content is still hidden.

答:
You just need to use jQuery's toggleClass function instead of toggle. is-hidden class in bulma will hide the div it is applied to. Please check at https://jsfiddle.net/rutsxz91/3/</p>

```<code>$(document).ready(function() {

  $("#server").click(function() {
    $("#server-content").toggleClass('is-hidden');
  });
});
</code>```

Body:
I have a little bulma card. I tried to display it, when I click on the icon:

        Component

        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.
        @bulmaio. #css #responsive

        <time datetime="2016-1-1">11:09 PM - 1 Jan 2016</time>

This I tried:

$(document).ready(function() {

  $("#server").click(function() {
    $("#server-content").toggle();
  });
});

But it didn't work. In my HTML Head I do this:

In the main.js file is the snippet from above.
When I put an alert inside the jquery function it will be pop up, but the content is still hidden.

Body:
You just need to use jQuery's toggleClass function instead of toggle. is-hidden class in bulma will hide the div it is applied to. Please check at https://jsfiddle.net/rutsxz91/3/

$(document).ready(function() {

  $("#server").click(function() {
    $("#server-content").toggleClass('is-hidden');
  });
});


问:
GLTF loaded object drag and drop using three js
I tried to load the gltf (object) which is made up of multiple elements when I try to select and drag the object, I am able to drag only one element. Please help me to fix this issue.

var loader = new THREE.GLTFLoader();
loader.load(‘W3030 / W3030.gltf’, (gltf) => {
  this.scene.add(gltf.scene);
  gltf.scene.scale.set(1, 1, 1);
  gltf.scene.traverse(function(object) {
    if (object.isMesh) objects.push(object);
    if (object.isMesh) objects.castShadow = true;
  });
});
```

Screenshot for GLTF Demo:

Before Drag: https://prnt.sc/pu940g

After Drag: https://prnt.sc/pu93g3

答:
```<code>use following code to drag multi mesh GLTF. It is Work for me.

 var dragobjects =[];
 //add following code in init function
 var gltfobject = addGLTFObjectIntoScene();
 scene.add(gltfobject);

dragControls = new THREE.DragControls(dragobjects, camera, renderer.domElement);
dragControls.addEventListener('dragstart', onDragStart, false);
dragControls.addEventListener('drag', onDrag , false);
dragControls.addEventListener('dragend', onDragEnd, false);
</code>```

<p>//end init function code
//add following function after or before init function</p>

```<code> function drawBox(objectwidth,objectheight,objectdepth){
 var geometry, material, box;
 geometry = new THREE.BoxGeometry(objectwidth,objectheight,objectdepth);
 material = new THREE.MeshBasicMaterial({color: 0xffff00, transparent: true, opacity: 0,depthTest:false});
 box = new THREE.Mesh(geometry, material);
 dragobjects.push(box);
 box.position.set(0, 0, 0);
 return box;
};
function addGLTFObjectIntoScene(){
 group = new THREE.Group();
 var loader = new THREE.GLTFLoader();
 loader.load( 'W1230/W1230.gltf', ( gltf ) => {
    mesh = gltf.scene;
    mesh.scale.set( 30, 30, 30);
    var gltfbox = new THREE.Box3().setFromObject( mesh );
    var objectwidth = Math.floor(gltfbox.getSize().x);
    var objectheight = Math.floor(gltfbox.getSize().y);
    var objectdepth = Math.floor(gltfbox.getSize().z);
    objectwidth = objectwidth + parseInt(2);
    objectheight = objectheight + parseInt(2);
    objectdepth  = objectdepth + parseInt(1);
    mesh.position.set(0, -objectheight/2, 0);
    box  = drawBox(objectwidth,objectheight,objectdepth);
    group.add(box);
    group.name = "quadrant";
    console.log(mesh);
    box.add( mesh);
 });
 return group;
};
</code>```

Body:
I tried to load the gltf (object) which is made up of multiple elements when I try to select and drag the object, I am able to drag only one element. Please help me to fix this issue.

var loader = new THREE.GLTFLoader();
loader.load(‘W3030 / W3030.gltf’, (gltf) => {
  this.scene.add(gltf.scene);
  gltf.scene.scale.set(1, 1, 1);
  gltf.scene.traverse(function(object) {
    if (object.isMesh) objects.push(object);
    if (object.isMesh) objects.castShadow = true;
  });
});

Screenshot for GLTF Demo:

Before Drag: https://prnt.sc/pu940g

After Drag: https://prnt.sc/pu93g3

Body:
use following code to drag multi mesh GLTF. It is Work for me.

 var dragobjects =[];
 //add following code in init function
 var gltfobject = addGLTFObjectIntoScene();
 scene.add(gltfobject);

dragControls = new THREE.DragControls(dragobjects, camera, renderer.domElement);
dragControls.addEventListener('dragstart', onDragStart, false);
dragControls.addEventListener('drag', onDrag , false);
dragControls.addEventListener('dragend', onDragEnd, false);

//end init function code
//add following function after or before init function

 function drawBox(objectwidth,objectheight,objectdepth){
 var geometry, material, box;
 geometry = new THREE.BoxGeometry(objectwidth,objectheight,objectdepth);
 material = new THREE.MeshBasicMaterial({color: 0xffff00, transparent: true, opacity: 0,depthTest:false});
 box = new THREE.Mesh(geometry, material);
 dragobjects.push(box);
 box.position.set(0, 0, 0);
 return box;
};
function addGLTFObjectIntoScene(){
 group = new THREE.Group();
 var loader = new THREE.GLTFLoader();
 loader.load( 'W1230/W1230.gltf', ( gltf ) => {
    mesh = gltf.scene;
    mesh.scale.set( 30, 30, 30);
    var gltfbox = new THREE.Box3().setFromObject( mesh );
    var objectwidth = Math.floor(gltfbox.getSize().x);
    var objectheight = Math.floor(gltfbox.getSize().y);
    var objectdepth = Math.floor(gltfbox.getSize().z);
    objectwidth = objectwidth + parseInt(2);
    objectheight = objectheight + parseInt(2);
    objectdepth  = objectdepth + parseInt(1);
    mesh.position.set(0, -objectheight/2, 0);
    box  = drawBox(objectwidth,objectheight,objectdepth);
    group.add(box);
    group.name = "quadrant";
    console.log(mesh);
    box.add( mesh);
 });
 return group;
};


问:
How to sum float numbers in the format hours and minutes?
How to sum float numbers in the format hours and minutes?

Those. if  calculate two such numbers 0.35+3.45 then it should be = 4.20, not 3.80

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

var sum = 0.0;

arr.forEach(function(item) {
  console.log(sum);
  sum += parseFloat(item);
});```
</div>
</div>
</p>

<p>The result should be like this:</p>

```0
0.15
0.35
4.20
5.0
7.0
7.30
12.50
13.50
15.30
16.40
19.20
20.20
```

答:
const arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

const reducer = (acc, curr) => {
  acc = `${acc}`.split('.').length > 1 ? acc : `${acc}.0`;
  curr = `${curr}`.split('.').length > 1 ? curr : `${curr}.0`;
  let hours = parseStrAndSum(true, `${acc}`.split('.')[0], `${curr}`.split('.')[0]);
  let minute = parseStrAndSum(false, `${acc}`.split('.')[1], `${curr}`.split('.')[1]);
  hours = parseInt(hours / 1) + parseInt(minute / 60);
  minute = minute % 60;
  console.log(`${acc} + ${curr} = ${hours}.${minute}`);
  return `${hours}.${minute}`;
}

const parseStrAndSum = (is_hours, ...strs) => {
  let result = 0;
  strs.forEach(function(number) {
    if (!is_hours) {
      number = number.length == 1 ? `${number}0` : number;
    }
    result += parseInt(number);
  });
  return result;
};

arr.reduce(reducer);```

Body:
How to sum float numbers in the format hours and minutes?

Those. if  calculate two such numbers 0.35+3.45 then it should be = 4.20, not 3.80

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

var sum = 0.0;

arr.forEach(function(item) {
  console.log(sum);
  sum += parseFloat(item);
});

The result should be like this:

0
0.15
0.35
4.20
5.0
7.0
7.30
12.50
13.50
15.30
16.40
19.20
20.20


问:
how to fix this error Array to string conversion in laravel and chartjs?
i want to get sum men learning and women learning from learnings table and display to chart with group by province name.

Error:

```<code> Array to string conversion (View: C:\xampp\htdocs\project\resources\views\chart\index.blade.php)
</code>```

my controller

```<code> $learnings =DB::table('provinces')
            ->join('learning_province','provinces.id','learning_province.province_id')
            ->join('learnings','learnings.id','learning_province.learning_id')
            ->select('title',\DB::raw('sum(men_learned + women_learned) as sum'))
            ->groupby('title')->whereYear('provinces.created_at', $year)->get();

        $title = [];
        $learning= [];
        foreach ($learnings as $key => $value) {
            $title[$key]=$value->title;
            $learning[$key]=$value->sum;
        }
        return view('home.home', compact('learning', 'title'));
</code>```

how to display sum men and women with group by province name in this script
my script

```<code><script>
        var ctx = document.getElementById('lineChart').getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels:  [{!!$title!!}],
                datasets: [{
                    label: '# ',
                    data: [{!!$learning!!}],
                    backgroundColor: ["#3e95cd"],
                    borderWidth: 1
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        });
    </script>
</code>```

答:
However, instead of manually calling json_encode, you may use the @json Blade directive. The @json directive accepts the same arguments as PHP's json_encode function.

Please like this json_encode in laravel blade

```<code><script>
        var ctx = document.getElementById('lineChart').getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: @json($title),
                datasets: [{
                    label: '# ',
                    data: @json($learning),
                    backgroundColor: ["#3e95cd"],
                    borderWidth: 1
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        });
    </script>
</code>```

Body:
i want to get sum men learning and women learning from learnings table and display to chart with group by province name.

Error:

 Array to string conversion (View: C:\xampp\htdocs\project\resources\views\chart\index.blade.php)

my controller

 $learnings =DB::table('provinces')
            ->join('learning_province','provinces.id','learning_province.province_id')
            ->join('learnings','learnings.id','learning_province.learning_id')
            ->select('title',\DB::raw('sum(men_learned + women_learned) as sum'))
            ->groupby('title')->whereYear('provinces.created_at', $year)->get();

        $title = [];
        $learning= [];
        foreach ($learnings as $key => $value) {
            $title[$key]=$value->title;
            $learning[$key]=$value->sum;
        }
        return view('home.home', compact('learning', 'title'));

how to display sum men and women with group by province name in this script
my script

Body:
However, instead of manually calling json_encode, you may use the @json Blade directive. The @json directive accepts the same arguments as PHP's json_encode function.

Please like this json_encode in laravel blade

<script>
        var ctx = document.getElementById('lineChart').getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: @json($title),
                datasets: [{
                    label: '# ',
                    data: @json($learning),
                    backgroundColor: ["#3e95cd"],
                    borderWidth: 1
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        });
    </script>


问:
String replacement from another dataframe
I need to replace my column depending upon data from another dataframe.
Have to search for respective "name" from the other dataframe and include the "change_name" in the df1

df1:

```<code>ID  name
1   cat
2   jack
3   snake
4   monkey
</code>```

df2:

```<code>name    change_name
cat     meow
jack    oooo
snake   ssss
monkey
</code>```

output:

```<code>ID  name
1   cat      meow
2   jack     oooo
3   snake    ssss
4   monkey   nan
</code>```

Sorry, I had to edit my question.

I had to do like below:

```<code>def map_name(name):
    elif name == 'cat':
        return 'meow'
    elif name == 'jack':
        return 'oooo'
    elif name == 'snake':
        return 'ssss'
    elif name == 'monkey ':
        return None
    else
        return name
</code>```

df1['name'] = df1['name'].apply(map_name)

As the list is small, I have hardcoded here but the list might grow. Can someone tell how to do teh same functionality using dataframes?

答:
I think you need:

```<code>d = {k:v for k,v in zip(df1["name"], df1["change_name"])}

df["new_name"] = df["name"].map(d)

df.dropna(subset=["new_name"], inplace=True)

print(df)
</code>```

output:

```<code>    ID  name    new_name
0   1   cat     meow
1   2   jack    oooo
2   3   snake   ssss
</code>```

Body:
I need to replace my column depending upon data from another dataframe.
Have to search for respective "name" from the other dataframe and include the "change_name" in the df1

df1:

ID  name
1   cat
2   jack
3   snake
4   monkey

df2:

name    change_name
cat     meow
jack    oooo
snake   ssss
monkey

output:

ID  name
1   cat      meow
2   jack     oooo
3   snake    ssss
4   monkey   nan

Sorry, I had to edit my question.

I had to do like below:

def map_name(name):
    elif name == 'cat':
        return 'meow'
    elif name == 'jack':
        return 'oooo'
    elif name == 'snake':
        return 'ssss'
    elif name == 'monkey ':
        return None
    else
        return name

df1['name'] = df1['name'].apply(map_name)

As the list is small, I have hardcoded here but the list might grow. Can someone tell how to do teh same functionality using dataframes?

Body:
I think you need:

d = {k:v for k,v in zip(df1["name"], df1["change_name"])}

df["new_name"] = df["name"].map(d)

df.dropna(subset=["new_name"], inplace=True)

print(df)

output:

    ID  name    new_name
0   1   cat     meow
1   2   jack    oooo
2   3   snake   ssss


问:
Can't read swagger's doc in UI (Rails project, localhost)
When I coming to http://localhost:3000/api/swagger, I see in doc's address field http://api.webcrm.dev:3000/doc, and, as result, message Can't read from server. It may not have the appropriate access-control-origin settings. instead of my api's endpoints etc.

I trying to find proper address to use it in localhost.

in console:

```<code>Settings.api
=> {"url_options"=>{"host"=>"api.webcrm.dev", "port"=>3000, "version"=>"/v1/"},
 "swagger"=>{"discovery_url"=>{"host"=>"api.webcrm.dev", "port"=>3000, "path"=>"/doc"}}}
</code>```

in application.yml:

```<code>api:
  url_options:
    host: api.webcrm.dev
    port: 3000
    version: /v1/
  swagger:
    discovery_url:
      host: api.webcrm.dev
      port: 3000
      path: /doc
</code>```

in config/initializers.010_swagger.rb:

```<code>GrapeSwaggerRails.options.url     = Settings.api.swagger.discovery_url.path
GrapeSwaggerRails.options.app_url = "http://#{Settings.api.swagger.discovery_url.host}#{ ':' + Settings.api.swagger.discovery_url.port.to_s if Settings.api.swagger.discovery_url.port.present? }"
</code>```

in routes.rb:

```<code>mount API => '/api' if ENV['ASSETS_PRECOMPILE'].blank?
  mount GrapeSwaggerRails::Engine => '/api/swagger'
  get '/api', to: redirect('/api/swagger')
</code>```

But in logs output I see:

```<code>2020-02-19 12:11:07 +0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
2020-02-19 12:11:07 +0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.7.0 Snowy Sagebrush", "GATEWAY_INTERFACE"=>"CGI/1.2"}
---
</code>```

How can I find proper docs address and why it is not inputs automatically? Thank you so much for help!

P.S.:

Rails 4.2.11.1
ruby 2.3.8p459

答:
Found proper address:
http://localhost:3000/api/swagger_doc
it looks like we should to make something with configs</p>

Body:
When I coming to http://localhost:3000/api/swagger, I see in doc's address field http://api.webcrm.dev:3000/doc, and, as result, message Can't read from server. It may not have the appropriate access-control-origin settings. instead of my api's endpoints etc.

I trying to find proper address to use it in localhost.

in console:

Settings.api
=> {"url_options"=>{"host"=>"api.webcrm.dev", "port"=>3000, "version"=>"/v1/"},
 "swagger"=>{"discovery_url"=>{"host"=>"api.webcrm.dev", "port"=>3000, "path"=>"/doc"}}}

in application.yml:

api:
  url_options:
    host: api.webcrm.dev
    port: 3000
    version: /v1/
  swagger:
    discovery_url:
      host: api.webcrm.dev
      port: 3000
      path: /doc

in config/initializers.010_swagger.rb:

GrapeSwaggerRails.options.url     = Settings.api.swagger.discovery_url.path
GrapeSwaggerRails.options.app_url = "http://#{Settings.api.swagger.discovery_url.host}#{ ':' + Settings.api.swagger.discovery_url.port.to_s if Settings.api.swagger.discovery_url.port.present? }"

in routes.rb:

mount API => '/api' if ENV['ASSETS_PRECOMPILE'].blank?
  mount GrapeSwaggerRails::Engine => '/api/swagger'
  get '/api', to: redirect('/api/swagger')

But in logs output I see:

2020-02-19 12:11:07 +0700: HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
2020-02-19 12:11:07 +0700: ENV: {"rack.version"=>[1, 3], "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma 3.7.0 Snowy Sagebrush", "GATEWAY_INTERFACE"=>"CGI/1.2"}
---

How can I find proper docs address and why it is not inputs automatically? Thank you so much for help!

P.S.:

Rails 4.2.11.1
ruby 2.3.8p459


问:
get monthly and weekly average working hours in postgresql
I have a table that has following columns:-  local_id | time_in  | time_out |    date    | employee_id
I have to calculate average working hours(which will be calculated by time_out and time_in) on a monthly basis in PSQL. I have no clue how to do that, was thinking about using date_part function...
here are the table details:</p>

```<code> local_id | time_in  | time_out |    date    | employee_id
 ---------+----------+----------+------------+-------------
        7 | 08:00:00 | 17:00:00 | 2020-02-12 |           2
        6 | 08:00:00 | 17:00:00 | 2020-02-12 |           4
        8 | 09:00:00 | 17:00:00 | 2020-02-12 |           3
       13 | 08:05:00 | 17:00:00 | 2020-02-17 |           3
       12 | 08:00:00 | 18:09:00 | 2020-02-13 |           2
</code>```

答:
Click: demo:db<>fiddle; extended example covering two months

```<code>SELECT
    employee_id,
    date_trunc('month', the_date) AS month,  -- 1
    AVG(time_out - time_in)                  -- 2, 3
FROM
    mytable
GROUP BY employee_id, month                  -- 3
</code>```

date_trunc() "shortens" the date to a certain date part. In that case, all dates are truncated to the month. This gives the opportunity to group by month. (for your "monthly basis")

Calculate the working time by calculating the difference of both times

Grouping by employee_id and calculated month, calculating the average of the time differences.

Body:
I have a table that has following columns:-  local_id | time_in  | time_out |    date    | employee_id
I have to calculate average working hours(which will be calculated by time_out and time_in) on a monthly basis in PSQL. I have no clue how to do that, was thinking about using date_part function...
here are the table details:

 local_id | time_in  | time_out |    date    | employee_id
 ---------+----------+----------+------------+-------------
        7 | 08:00:00 | 17:00:00 | 2020-02-12 |           2
        6 | 08:00:00 | 17:00:00 | 2020-02-12 |           4
        8 | 09:00:00 | 17:00:00 | 2020-02-12 |           3
       13 | 08:05:00 | 17:00:00 | 2020-02-17 |           3
       12 | 08:00:00 | 18:09:00 | 2020-02-13 |           2

Body:
Click: demo:db<>fiddle; extended example covering two months

SELECT
    employee_id,
    date_trunc('month', the_date) AS month,  -- 1
    AVG(time_out - time_in)                  -- 2, 3
FROM
    mytable
GROUP BY employee_id, month                  -- 3

date_trunc() "shortens" the date to a certain date part. In that case, all dates are truncated to the month. This gives the opportunity to group by month. (for your "monthly basis")

Calculate the working time by calculating the difference of both times

Grouping by employee_id and calculated month, calculating the average of the time differences.


问:
Is it possible to capture all current Uncaught Exceptions handlers in Node.js?
I am making a Node.js exception reporter (NPM package) and I need it to work with other exception reporters (such as Raven). The problem with Raven and a few other Exceptions handlers is that it exits the process after receiving an Uncaught Exception. This makes it impossible for my exception reporter to send the exception report via http.

I want to know if it is possible to:

get all current running Uncaught Exceptions handlers.

get all upcoming Uncaught Exceptions handlers.

So basically what I want to do is to wrap around these bad boys and make sure my exception reporter runs first. Such as:

Uncaught Exception => my exception reporter => Raven => process.exit(1);

OR

Uncaught Exception => my exception reporter => the project's own exception reporter => whatever it sees fit;

AND I also need to make sure if there is no other exception reporters, we should exit the process:

Uncaught Exception => my exception reporter => nothing => process.exit(1);

答:
You can use process 'uncaughtException' and 'unhandledRejection' events.

Also remember that it is not safe to resume normal operation after 'uncaughtException', because the system becomes corrupted:

Example:

```<code>process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });
</code>```

Body:
You can use process 'uncaughtException' and 'unhandledRejection' events.

Also remember that it is not safe to resume normal operation after 'uncaughtException', because the system becomes corrupted:

Example:

process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });


问:
How to use radio on change event?
I have two radio button
on change event i want change button How it is possible?
My Code

```<code><input type="radio" name="bedStatus" id="allot" checked="checked" value="allot">Allot
<input type="radio" name="bedStatus" id="transfer" value="transfer">Transfer
</code>```

Script

```<code><script>
    $(document).ready(function () {
        $('input:radio[name=bedStatus]:checked').change(function () {
            if ($("input[name='bedStatus']:checked").val() == 'allot') {
                alert("Allot Thai Gayo Bhai");
            }
            if ($("input[name='bedStatus']:checked").val() == 'transfer') {
                alert("Transfer Thai Gayo");
            }
        });
    });
</script>
</code>```

答:
```<code>$(document).ready(function () {
    $('input:radio[name=bedStatus]:checked').change(function () {
        if ($("input:radio[name='bedStatus']:checked").val() == 'allot') {
            alert("Allot Thai Gayo Bhai");
        }
        if ($("input:radio[name='bedStatus']:checked").val() == 'transfer') {
            alert("Transfer Thai Gayo");
        }
    });
});
</code>```

Title: How to use radio on change event?

Body:
I have two radio button
on change event i want change button How it is possible?
My Code

<input type="radio" name="bedStatus" id="allot" checked="checked" value="allot">Allot
<input type="radio" name="bedStatus" id="transfer" value="transfer">Transfer

Script


问:
check box not displayed inside the popup in android
I am trying to add a popup with a checkbox and if the checkbox is not ticked, it shouldn't be able to press yes on the popup and better some kind of a error message get appeared inside the popup. My attempt is as follows.

```<code>    AlertDialog.Builder builder = new AlertDialog.Builder(EmptyActivity.this);
    builder.setTitle(R.string.app_name);
    builder.setMessage("Confirm for go?");
    final CharSequence[] items = {"Something to check before going "};
    final ArrayList selectedItems=new ArrayList();
    builder.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            //Here you add or remove the items from the list selectedItems. That list will be the result of the user selection.
            if(isChecked) {
                selectedItems.add(which);
            }
        }
    });

    builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
            if(selectedItems.size() == 1) {
                //call going api
            }
            else{
                //show an error msg inside pop up to tick the checkbox and unable to click yes
            }
        }
    });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
</code>```

popup displayed as in the below image.

I couldn't see the checkbox inside the popup when I run it. So any one knows where I got wrong? And how should I show an error msg inside the pop up to inform the user to tick the checkbox before clicking yes?

答:
```<code>    private void showDialogue() {

            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
            LayoutInflater inflater = this.getLayoutInflater();
            View dialogView = inflater.inflate(R.layout.custom_dashboard, null);
            dialogBuilder.setView(dialogView);
            final AlertDialog alertDialog = dialogBuilder.create();
            final CheckBox one = dialogView.findViewById(R.id.chk01);

            Button done = dialogView.findViewById(R.id.done);
            done.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (one.isChecked()) {
                  //do something
                }else{
 //do something
}
            });
            alertDialog.show();

        }
</code>```

Body:
I am trying to add a popup with a checkbox and if the checkbox is not ticked, it shouldn't be able to press yes on the popup and better some kind of a error message get appeared inside the popup. My attempt is as follows.

    AlertDialog.Builder builder = new AlertDialog.Builder(EmptyActivity.this);
    builder.setTitle(R.string.app_name);
    builder.setMessage("Confirm for go?");
    final CharSequence[] items = {"Something to check before going "};
    final ArrayList selectedItems=new ArrayList();
    builder.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            //Here you add or remove the items from the list selectedItems. That list will be the result of the user selection.
            if(isChecked) {
                selectedItems.add(which);
            }
        }
    });

    builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
            if(selectedItems.size() == 1) {
                //call going api
            }
            else{
                //show an error msg inside pop up to tick the checkbox and unable to click yes
            }
        }
    });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

popup displayed as in the below image.

I couldn't see the checkbox inside the popup when I run it. So any one knows where I got wrong? And how should I show an error msg inside the pop up to inform the user to tick the checkbox before clicking yes?


问:
What unix command can we use to append some text to a specific line in a file?
Does anyone know of a series of unix commands that allows someone to append some text to the end of a specific line in a file?

eg

Line 1

Line 2

Line 3

Line 4

I wish to append the text ", extra information" to Line 3 so that the File will now look like this:

Line 1

Line 2

Line 3, extra information

Line 4

答:
```<code>sed -e "s/^Line 3/\0, extra info/" -i text.txt
</code>```

OwnerDisplayName: Alex Wong

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: saua


答:
You can use then in the inner promise and return any format of data u want frm there.</p>

```<code>getAlbumInfo(album, artist)
.then((res) => {
    const metadata = {
        album: res['album'],
        artist: res['artist'],
        url: res['url']
    };

    return getAlbumArt(metadata).then(responseArt => {
       return {
           innerPromise: responseArt,
           outerPromise: metadata
       };
    });
})
.then((res) => {
    console.log(res);  // Now u have both here

    // I also need the contents of metadata here
})
.catch(e => { console.error(e); });
</code>```

Title: How can I get additional data from one promise to another?

Body:
I have one promise that relies on the return value of another promise. I'm successfully passing that value to the second promise, but there's additional data that's created in the first promise that I'd like to get into the second promise somehow.

Here's my code:

const getAlbumInfo = async (album, artist) => {
        let hostname = 'http://www.musicbrainz.org';
        let path = `/ws/2/release-group/?query=release:${album}%20AND%20artist:${artist}&fmt=json`;
        let res = await fetch(hostname + path);
        return res.json();
};

const getAlbumArt = async (albumInfo) => {
    let res = await fetch(`${albumInfo.url}`);
    return res.json();
};

let artist = '', album = '';

getAlbumInfo(album, artist)
    .then((res) => {
        const metadata = {
            album: res['album'],
            artist: res['artist'],
            url: res['url']
        };

        return getAlbumArt(metadata);
    })
    .then((res) => {
        console.log(res);  // prints result from getAlbumArt

        // I also need the contents of metadata here
    })
    .catch(e => { console.error(e); });

So I'm getting album metadata in the first promise, which includes a URL, and then I'm running a fetch on that URL, which returns a second promise. The problem is that I need access to the album metadata in the second promise.

Since I'm returning/passing the metadata into the second promise, I tried using Object.assign() inside getAlbumArt() to combine the metadata and the fetch result, but that didn't seem to work.

Body:
You can use then in the inner promise and return any format of data u want frm there.

getAlbumInfo(album, artist)
.then((res) => {
    const metadata = {
        album: res['album'],
        artist: res['artist'],
        url: res['url']
    };

    return getAlbumArt(metadata).then(responseArt => {
       return {
           innerPromise: responseArt,
           outerPromise: metadata
       };
    });
})
.then((res) => {
    console.log(res);  // Now u have both here

    // I also need the contents of metadata here
})
.catch(e => { console.error(e); });


问:
Class access methods
How can I access a class which is in another project in C#. Please keep in mind that I cannot add any reference due to creating circular referencing.

Is there any way?

答:
Not without some refactoring. Reflection could help but you still wouldn't be able to extend from that class or use it in any non runtime way.

I have found that this can happen with minimum refactoring

Identify the shared code

Extract it to a new shared project

Add the new project as a reference to all projects that need it

Title: Class access methods