问:
Android database accessible for ALL activities to read from
UPDATE: I needed to override the onDestroy method to close the Database Helper class object.  Works fine now. Just add this in any activity where you create an object of your SQLiteOpenHelper class.

```<code>Database dbHelper; //in class
dbHelper = new Database(this, "pulling data",null,1); //in onCreate

@Override
protected void onDestroy()
{
    super.onDestroy();
    dbHelper.close();
}
</code>```

I create and update a database from a fragment with data that comes in about every 2 seconds from sensors that are connected over Bluetooth to my Android app.

I go to different activities in my app and those activities should be able to read from the database to display the data in a list/textview, but the issue is that the context in which the database was created and is getting updated is from a fragment.  Is there a way to make it so that all activities can read from the database?

I created a class that extends SQLiteOpenHelper, where you can access functions to do CRUD operations, but once I go into another activity and I query the database the cursor pulls nothing up although I inserted and am updating the database in the background from a fragment.

Heads up, I'm pretty new to Android dev and have looked at other questions/solutions but nothing works for me. Appreciate any tutorials or advice to get going, thanks!

Below is my SQLiteOpenHelper class:

```<code>import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class Database extends SQLiteOpenHelper
{

    public Context DBcontext = null;
    //DatabaseContract version
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "Sensors";

    public static final String SENSOR_DATA_TABLE_NAME ="SensorData";
    public static final String SENSOR_DATA_COLUMN_ID = "SensorDataID";
    public static final String NODE_COLUMN_NAME = "Nodes";
    public static final String TEMP_COLUMN_NAME = "TemperatureData";
    public static final String MOTION_COLUMN_NAME = "MotionData";
    public static final String GAS_COLUMN_NAME = "GasData";
    public static final String LIGHT_COLUMN_NAME = "LightData";

    //Constructor for the Database activity
    public DatabaseContract( Context context , String name, SQLiteDatabase.CursorFactory factory, int version) {
        super( context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL("CREATE TABLE "+SENSOR_DATA_TABLE_NAME+" ("+SENSOR_DATA_COLUMN_ID+" INTEGER PRIMARY KEY, "+NODE_COLUMN_NAME+ " STRING, "+TEMP_COLUMN_NAME+" STRING,     "+MOTION_COLUMN_NAME+" STRING, "+GAS_COLUMN_NAME+" STRING, "+ LIGHT_COLUMN_NAME+" STRING)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {

        db.execSQL("DROP TABLE IF EXISTS " + SENSOR_DATA_TABLE_NAME);
        onCreate(db);
    }

    public boolean checkExist()
    {

        SQLiteDatabase db = getReadableDatabase();

        String query = "SELECT * FROM "+ SENSOR_DATA_TABLE_NAME;

        Cursor res = db.rawQuery(query, null);

        if(res.getCount() > 0){
            res.close();
            return true;
        }else {
            res.close();
            return false;
        }

    }

    public void updateSensorData(String node_number, String temp_data, String motion_data, String light_data, String gas_data)
    {

        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM " + SENSOR_DATA_TABLE_NAME + " WHERE " + NODE_COLUMN_NAME + " ='" + node_number + "'";
        Cursor res = db.rawQuery(query, null);

       if (res.getCount() == 0){
           res.close();
           ContentValues content = new ContentValues();
           content.put(NODE_COLUMN_NAME, node_number);
           content.put(TEMP_COLUMN_NAME, temp_data);
           content.put(MOTION_COLUMN_NAME, motion_data);
           content.put(GAS_COLUMN_NAME, gas_data);
           content.put(LIGHT_COLUMN_NAME, light_data);
           db.insert(SENSOR_DATA_TABLE_NAME, null, content);

       }else{

           /**try to get ID from cursor, not working so hardcoded 1 for now to test**/
           //String ID = Long.toString(res.getLong(res.getColumnIndex(SENSOR_DATA_COLUMN_ID)));
           ContentValues contentValues = new ContentValues();
           contentValues.put(NODE_COLUMN_NAME, node_number);
           contentValues.put(TEMP_COLUMN_NAME, temp_data);
           contentValues.put(MOTION_COLUMN_NAME, motion_data);
           contentValues.put(GAS_COLUMN_NAME, gas_data);
           contentValues.put(LIGHT_COLUMN_NAME, light_data);

           //hardcoded ID = 1 just for testing
           db.update(SENSOR_DATA_TABLE_NAME, contentValues, SENSOR_DATA_COLUMN_ID + " = ? ", new String[] { "1" } );

       }

    }

}
</code>```

Below is the fragment that interacts with the class from above to insert/update data in the database.  I took the Google BluetoothChat app and modified it to work for my intended purpose. This fragment interacts with the Database class in the handler for MESSAGE_READ. I parse the data sent to me, then pass it as parameters to the Database function updateSensorData where it takes care of inserting then thereafter updating the data.

```<code>import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class Bluetooth extends Fragment
{
    private static final String TAG = "Bluetooth";

    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE_INSECURE = 1;
    private static final int REQUEST_ENABLE_BT = 2;

    // Layout Views
    private Button scan_button;
    private Button move;
    private DatabaseContract dbHelper;

    /**
     * Name of the connected device
     */
    private String mConnectedDeviceName = null;

    /**
     * Local Bluetooth adapter
     */
    private BluetoothAdapter BAdapter = null;

    /**
     * Member object for the chat services
     */
    private BluetoothChatService mChatService = null;

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

        setHasOptionsMenu(true);
        // Get local Bluetooth adapter
        BAdapter = BluetoothAdapter.getDefaultAdapter();

        if (BAdapter == null)
        {
            FragmentActivity activity = getActivity();
            new AlertDialog.Builder(activity)
                    .setTitle("Error: Not compatible")
                    .setMessage("Your phone does not support Bluetooth")
                    .setPositiveButton("Exit", new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which)
                        {
                            System.exit(0);
                        }
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();

        }
    }

    @Override
    public void onStart()
    {
        super.onStart();

        if (!BAdapter.isEnabled())
        {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        }
        else if (mChatService == null)
        {
            setupChat();
        }
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        if (mChatService != null)
        {
            mChatService.stop();
        }
    }

    @Override
    public void onResume()
    {
        super.onResume();

        // Performing this check in onResume() covers the case in which BT was
        // not enabled during onStart(), so we were paused to enable it...
        // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
        if (mChatService != null)
        {
            // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mChatService.getState() == BluetoothChatService.STATE_NONE)
            {
                // Start the Bluetooth chat services
                mChatService.start();
            }
        }
        scan_button.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {

                Intent serverIntent = new Intent(getActivity(), DeviceList.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);

            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.bluetooth, container, false);

        Button move = (Button)v.findViewById(R.id.move);
        move.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), Network.class);
                startActivity(intent);
            }
        });
        return v;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
    {
        scan_button = (Button) view.findViewById(R.id.scan_button);
        move = (Button) view.findViewById(R.id.move);
    }

    /**
     * Set up the UI and background operations for chat.
     */
    private void setupChat()
    {

        scan_button.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {

                Intent serverIntent = new Intent(getActivity(), DeviceList.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);

            }
        });

        // Initialize the BluetoothChatService to perform bluetooth connections
        mChatService = new BluetoothChatService(getActivity(), mHandler);

    }

    private final Handler mHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            FragmentActivity activity = getActivity();
            switch (msg.what)
            {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1)
                    {
                        case BluetoothChatService.STATE_CONNECTED:
                            Toast.makeText(getActivity(), "Connected to "+mConnectedDeviceName+" setting up network. . .", Toast.LENGTH_SHORT).show();
                            final Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    move.setVisibility(View.VISIBLE);
                                    scan_button.setVisibility(View.INVISIBLE);
                                }
                            }, 4000);

                            break;
                        case BluetoothChatService.STATE_CONNECTING:
                            Toast.makeText(getActivity(), "Connecting. . .", Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothChatService.STATE_LISTEN:

                        case BluetoothChatService.STATE_NONE:

                            scan_button.setVisibility(View.VISIBLE);
                            move.setVisibility(View.INVISIBLE);
                    }
                    break;

                /******************************** where this fragment interacts with SQLiteOpenHelper class for database******************************/

                case Constants.MESSAGE_READ:
                    byte[] readBuf = (byte[]) msg.obj;
                    // construct a string from the valid bytes in the buffer
                    String readMessage = new String(readBuf, 0, msg.arg1);

                    dbHelper = new DatabaseContract(getActivity(), "data transfer for sensors", null, 1);

                    int node = readMessage.indexOf("node");
                    int temp_number = readMessage.indexOf("t");
                    int motion_number = readMessage.indexOf("m");
                    int light_number = readMessage.indexOf("l");
                    int gas_number = readMessage.indexOf("g");

                    String node_number = readMessage.substring(node + 5, node + 6);
                    String temp_data = readMessage.substring(temp_number, motion_number);
                    String motion_data = readMessage.substring(motion_number, light_number);
                    String light_data = readMessage.substring(light_number, gas_number);
                    String gas_data = readMessage.substring(gas_number);

                    dbHelper.updateSensorData(node_number, temp_data, motion_data, light_data, gas_data);

                    break;
                case Constants.MESSAGE_DEVICE_NAME:
                    // save the connected device's name
                    mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);

                    break;
                case Constants.MESSAGE_TOAST:
                    if (null != activity) {
                        Toast.makeText(activity, msg.getData().getString(Constants.TOAST),
                                Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
        }
    };

    //automatically invoked when app starts up
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        switch (requestCode)
        {
            case REQUEST_CONNECT_DEVICE_INSECURE:
                // When DeviceList returns with a device to connect
                if (resultCode == Activity.RESULT_OK)
                {
                    connectDevice(data, false);
                }
                break;
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns
                if (resultCode == Activity.RESULT_OK)
                {
                    // Bluetooth is now enabled, so set up a chat session
                    setupChat();
                }
                else
                {
                    FragmentActivity activity = getActivity();
                    new AlertDialog.Builder(activity)
                            .setTitle("Error")
                            .setMessage("Bluetooth is disabled")
                            .setPositiveButton("ENABLE", new DialogInterface.OnClickListener()
                            {
                                public void onClick(DialogInterface dialog, int which)
                                {

                                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                    startActivityForResult(enableIntent, 8);
                                    onDestroy();
                                    onResume();
                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();
                }
        }
    }

    private void connectDevice(Intent data, boolean insecure)
    {
        // Get the device MAC address
        String address = data.getExtras()
                .getString(DeviceList.EXTRA_DEVICE_ADDRESS);
        // Get the BluetoothDevice object
        BluetoothDevice device = BAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device, insecure);
    }

}
</code>```

Below is an example of one of the different classes that needs to access the information in the database. I test it with the checkExist() function and it returns false although in the fragment I do successfully insert then update the sensor data. This is where my problem lies, not sure why it isn't pulling anything from the database

```<code>import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;

/**Here is an example of one of the activities that needs to pull readings from the database to display**/

public class NodeData extends AppCompatActivity
{

    private DatabaseContract dbHelper;
    private TextView tempDisplay;
    private TextView motionDisplay;
    private TextView gasDisplay;
    private TextView lightDisplay;
    private ListView dataDisplay;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.nodedata);
        String node_number = getIntent().getExtras().getString("node_number");
        String label = "Node "+node_number+" Data";
        TextView textViewToChange = (TextView) findViewById(R.id.node_data_label);
        textViewToChange.setText(label);

        dbHelper = new DatabaseContract(getApplicationContext(), "data transfer for sensors", null, 1);

        boolean test = dbHelper.checkExist();

        Toast.makeText(getApplicationContext(), "testing: "+test, Toast.LENGTH_SHORT).show();

    }

}
</code>```

答:
Extends LoaderManager.LoaderCallbacks in your activity to load the data from the data base.

For more information you can read that:
https://developer.android.com/guide/components/loaders.html

Body:
UPDATE: I needed to override the onDestroy method to close the Database Helper class object.  Works fine now. Just add this in any activity where you create an object of your SQLiteOpenHelper class.

Database dbHelper; //in class
dbHelper = new Database(this, "pulling data",null,1); //in onCreate

@Override
protected void onDestroy()
{
    super.onDestroy();
    dbHelper.close();
}

I create and update a database from a fragment with data that comes in about every 2 seconds from sensors that are connected over Bluetooth to my Android app.

I go to different activities in my app and those activities should be able to read from the database to display the data in a list/textview, but the issue is that the context in which the database was created and is getting updated is from a fragment.  Is there a way to make it so that all activities can read from the database?

I created a class that extends SQLiteOpenHelper, where you can access functions to do CRUD operations, but once I go into another activity and I query the database the cursor pulls nothing up although I inserted and am updating the database in the background from a fragment.

Heads up, I'm pretty new to Android dev and have looked at other questions/solutions but nothing works for me. Appreciate any tutorials or advice to get going, thanks!

Below is my SQLiteOpenHelper class:

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class Database extends SQLiteOpenHelper
{

    public Context DBcontext = null;
    //DatabaseContract version
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "Sensors";

    public static final String SENSOR_DATA_TABLE_NAME ="SensorData";
    public static final String SENSOR_DATA_COLUMN_ID = "SensorDataID";
    public static final String NODE_COLUMN_NAME = "Nodes";
    public static final String TEMP_COLUMN_NAME = "TemperatureData";
    public static final String MOTION_COLUMN_NAME = "MotionData";
    public static final String GAS_COLUMN_NAME = "GasData";
    public static final String LIGHT_COLUMN_NAME = "LightData";

    //Constructor for the Database activity
    public DatabaseContract( Context context , String name, SQLiteDatabase.CursorFactory factory, int version) {
        super( context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL("CREATE TABLE "+SENSOR_DATA_TABLE_NAME+" ("+SENSOR_DATA_COLUMN_ID+" INTEGER PRIMARY KEY, "+NODE_COLUMN_NAME+ " STRING, "+TEMP_COLUMN_NAME+" STRING,     "+MOTION_COLUMN_NAME+" STRING, "+GAS_COLUMN_NAME+" STRING, "+ LIGHT_COLUMN_NAME+" STRING)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {

        db.execSQL("DROP TABLE IF EXISTS " + SENSOR_DATA_TABLE_NAME);
        onCreate(db);
    }

    public boolean checkExist()
    {

        SQLiteDatabase db = getReadableDatabase();

        String query = "SELECT * FROM "+ SENSOR_DATA_TABLE_NAME;

        Cursor res = db.rawQuery(query, null);

        if(res.getCount() > 0){
            res.close();
            return true;
        }else {
            res.close();
            return false;
        }

    }

    public void updateSensorData(String node_number, String temp_data, String motion_data, String light_data, String gas_data)
    {

        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM " + SENSOR_DATA_TABLE_NAME + " WHERE " + NODE_COLUMN_NAME + " ='" + node_number + "'";
        Cursor res = db.rawQuery(query, null);

       if (res.getCount() == 0){
           res.close();
           ContentValues content = new ContentValues();
           content.put(NODE_COLUMN_NAME, node_number);
           content.put(TEMP_COLUMN_NAME, temp_data);
           content.put(MOTION_COLUMN_NAME, motion_data);
           content.put(GAS_COLUMN_NAME, gas_data);
           content.put(LIGHT_COLUMN_NAME, light_data);
           db.insert(SENSOR_DATA_TABLE_NAME, null, content);

       }else{

           /**try to get ID from cursor, not working so hardcoded 1 for now to test**/
           //String ID = Long.toString(res.getLong(res.getColumnIndex(SENSOR_DATA_COLUMN_ID)));
           ContentValues contentValues = new ContentValues();
           contentValues.put(NODE_COLUMN_NAME, node_number);
           contentValues.put(TEMP_COLUMN_NAME, temp_data);
           contentValues.put(MOTION_COLUMN_NAME, motion_data);
           contentValues.put(GAS_COLUMN_NAME, gas_data);
           contentValues.put(LIGHT_COLUMN_NAME, light_data);

           //hardcoded ID = 1 just for testing
           db.update(SENSOR_DATA_TABLE_NAME, contentValues, SENSOR_DATA_COLUMN_ID + " = ? ", new String[] { "1" } );

       }

    }

}

Below is the fragment that interacts with the class from above to insert/update data in the database.  I took the Google BluetoothChat app and modified it to work for my intended purpose. This fragment interacts with the Database class in the handler for MESSAGE_READ. I parse the data sent to me, then pass it as parameters to the Database function updateSensorData where it takes care of inserting then thereafter updating the data.

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class Bluetooth extends Fragment
{
    private static final String TAG = "Bluetooth";

    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE_INSECURE = 1;
    private static final int REQUEST_ENABLE_BT = 2;

    // Layout Views
    private Button scan_button;
    private Button move;
    private DatabaseContract dbHelper;

    /**
     * Name of the connected device
     */
    private String mConnectedDeviceName = null;

    /**
     * Local Bluetooth adapter
     */
    private BluetoothAdapter BAdapter = null;

    /**
     * Member object for the chat services
     */
    private BluetoothChatService mChatService = null;

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

        setHasOptionsMenu(true);
        // Get local Bluetooth adapter
        BAdapter = BluetoothAdapter.getDefaultAdapter();

        if (BAdapter == null)
        {
            FragmentActivity activity = getActivity();
            new AlertDialog.Builder(activity)
                    .setTitle("Error: Not compatible")
                    .setMessage("Your phone does not support Bluetooth")
                    .setPositiveButton("Exit", new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which)
                        {
                            System.exit(0);
                        }
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();

        }
    }

    @Override
    public void onStart()
    {
        super.onStart();

        if (!BAdapter.isEnabled())
        {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        }
        else if (mChatService == null)
        {
            setupChat();
        }
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        if (mChatService != null)
        {
            mChatService.stop();
        }
    }

    @Override
    public void onResume()
    {
        super.onResume();

        // Performing this check in onResume() covers the case in which BT was
        // not enabled during onStart(), so we were paused to enable it...
        // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
        if (mChatService != null)
        {
            // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mChatService.getState() == BluetoothChatService.STATE_NONE)
            {
                // Start the Bluetooth chat services
                mChatService.start();
            }
        }
        scan_button.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {

                Intent serverIntent = new Intent(getActivity(), DeviceList.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);

            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.bluetooth, container, false);

        Button move = (Button)v.findViewById(R.id.move);
        move.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), Network.class);
                startActivity(intent);
            }
        });
        return v;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
    {
        scan_button = (Button) view.findViewById(R.id.scan_button);
        move = (Button) view.findViewById(R.id.move);
    }

    /**
     * Set up the UI and background operations for chat.
     */
    private void setupChat()
    {

        scan_button.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {

                Intent serverIntent = new Intent(getActivity(), DeviceList.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);

            }
        });

        // Initialize the BluetoothChatService to perform bluetooth connections
        mChatService = new BluetoothChatService(getActivity(), mHandler);

    }

    private final Handler mHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            FragmentActivity activity = getActivity();
            switch (msg.what)
            {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1)
                    {
                        case BluetoothChatService.STATE_CONNECTED:
                            Toast.makeText(getActivity(), "Connected to "+mConnectedDeviceName+" setting up network. . .", Toast.LENGTH_SHORT).show();
                            final Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    move.setVisibility(View.VISIBLE);
                                    scan_button.setVisibility(View.INVISIBLE);
                                }
                            }, 4000);

                            break;
                        case BluetoothChatService.STATE_CONNECTING:
                            Toast.makeText(getActivity(), "Connecting. . .", Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothChatService.STATE_LISTEN:

                        case BluetoothChatService.STATE_NONE:

                            scan_button.setVisibility(View.VISIBLE);
                            move.setVisibility(View.INVISIBLE);
                    }
                    break;

                /******************************** where this fragment interacts with SQLiteOpenHelper class for database******************************/

                case Constants.MESSAGE_READ:
                    byte[] readBuf = (byte[]) msg.obj;
                    // construct a string from the valid bytes in the buffer
                    String readMessage = new String(readBuf, 0, msg.arg1);

                    dbHelper = new DatabaseContract(getActivity(), "data transfer for sensors", null, 1);

                    int node = readMessage.indexOf("node");
                    int temp_number = readMessage.indexOf("t");
                    int motion_number = readMessage.indexOf("m");
                    int light_number = readMessage.indexOf("l");
                    int gas_number = readMessage.indexOf("g");

                    String node_number = readMessage.substring(node + 5, node + 6);
                    String temp_data = readMessage.substring(temp_number, motion_number);
                    String motion_data = readMessage.substring(motion_number, light_number);
                    String light_data = readMessage.substring(light_number, gas_number);
                    String gas_data = readMessage.substring(gas_number);

                    dbHelper.updateSensorData(node_number, temp_data, motion_data, light_data, gas_data);

                    break;
                case Constants.MESSAGE_DEVICE_NAME:
                    // save the connected device's name
                    mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);

                    break;
                case Constants.MESSAGE_TOAST:
                    if (null != activity) {
                        Toast.makeText(activity, msg.getData().getString(Constants.TOAST),
                                Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
        }
    };

    //automatically invoked when app starts up
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        switch (requestCode)
        {
            case REQUEST_CONNECT_DEVICE_INSECURE:
                // When DeviceList returns with a device to connect
                if (resultCode == Activity.RESULT_OK)
                {
                    connectDevice(data, false);
                }
                break;
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns
                if (resultCode == Activity.RESULT_OK)
                {
                    // Bluetooth is now enabled, so set up a chat session
                    setupChat();
                }
                else
                {
                    FragmentActivity activity = getActivity();
                    new AlertDialog.Builder(activity)
                            .setTitle("Error")
                            .setMessage("Bluetooth is disabled")
                            .setPositiveButton("ENABLE", new DialogInterface.OnClickListener()
                            {
                                public void onClick(DialogInterface dialog, int which)
                                {

                                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                    startActivityForResult(enableIntent, 8);
                                    onDestroy();
                                    onResume();
                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();
                }
        }
    }

    private void connectDevice(Intent data, boolean insecure)
    {
        // Get the device MAC address
        String address = data.getExtras()
                .getString(DeviceList.EXTRA_DEVICE_ADDRESS);
        // Get the BluetoothDevice object
        BluetoothDevice device = BAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device, insecure);
    }

}

Below is an example of one of the different classes that needs to access the information in the database. I test it with the checkExist() function and it returns false although in the fragment I do successfully insert then update the sensor data. This is where my problem lies, not sure why it isn't pulling anything from the database

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;

/**Here is an example of one of the activities that needs to pull readings from the database to display**/

public class NodeData extends AppCompatActivity
{

    private DatabaseContract dbHelper;
    private TextView tempDisplay;
    private TextView motionDisplay;
    private TextView gasDisplay;
    private TextView lightDisplay;
    private ListView dataDisplay;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.nodedata);
        String node_number = getIntent().getExtras().getString("node_number");
        String label = "Node "+node_number+" Data";
        TextView textViewToChange = (TextView) findViewById(R.id.node_data_label);
        textViewToChange.setText(label);

        dbHelper = new DatabaseContract(getApplicationContext(), "data transfer for sensors", null, 1);

        boolean test = dbHelper.checkExist();

        Toast.makeText(getApplicationContext(), "testing: "+test, Toast.LENGTH_SHORT).show();

    }

}


来源: stackexchange

问:
How to programmatically hide header and tabs in landscape mode in Ionic 3?
I have one view in portrait mode and another in landscape mode where I want to show chart and I hide tabs and header (fullscreen mode, no scrolling). My view in landscape mode would look something like this:

```<code><div showWhen="landscape" class="chart-settings split-container">
<ion-toolbar showWhen="landscape">
  <ion-grid>
    <ion-row>
      <ion-col col-6>
        <ion-item>
          <ion-label>Period</ion-label>
          <ion-select [(ngModel)]="period">
            //options
          </ion-select>
        </ion-item>
      </ion-col>
      <ion-col col-6>
        <ion-item>
          <ion-label>Won/Lost</ion-label>
          <ion-select [(ngModel)]="gender">
             //options
          </ion-select>
        </ion-item>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-toolbar>
<div class="flexChart">
  <div id="chartdiv" [style.width.%]="100" [style.height.%]="100"></div>
</div>
</code>```

I use flex to fill out the page and create "fullscreen effect with no scrolling".

Thanks

答:
Well it seems there is this:
http://ionicframework.com/docs/api/platform/Platform/

It has:

```<code>isPortrait()
isLandscape()
</code>```

so you can do:
platform.isPortrait() or platform.isLandscape()
if you inject platform into constructor.

Combine this with *NgIf:

https://angular.io/guide/template-syntax#ngif

CSS overflow, overflow-x, overflow-y is what you'd look to for prevent scrolling provided it's a block level container:

https://developer.mozilla.org/en/docs/Web/CSS/overflow

UPDATE

Based on this comment:

That was my initial thought. The problem with this is that it leaves
  padding on top. I solved it by configuring styles, but it seemed
  pretty dirty solution to me

You can fix that padding issue by getting the instance of the Content and call the resize() method like this:

```<code>import { Component, ViewChild } from '@angular/core';
import { Content } from 'ionic-angular';

@Component({...})
export class MyPage{
  @ViewChild(Content) content: Content;

  public yourMethod(): void {
    this.content.resize();
  }
}
</code>```

https://ionicframework.com/docs/api/components/content/Content/#resize

Tell the content to recalculate its dimensions. This should be called
  after dynamically adding/removing headers, footers, or tabs.

ContentLicense: CC BY-SA 3.0

Body:
I have one view in portrait mode and another in landscape mode where I want to show chart and I hide tabs and header (fullscreen mode, no scrolling). My view in landscape mode would look something like this:

<ion-toolbar showWhen="landscape">
  <ion-grid>
    <ion-row>
      <ion-col col-6>
        <ion-item>
          <ion-label>Period</ion-label>
          <ion-select [(ngModel)]="period">
            //options
          </ion-select>
        </ion-item>
      </ion-col>
      <ion-col col-6>
        <ion-item>
          <ion-label>Won/Lost</ion-label>
          <ion-select [(ngModel)]="gender">
             //options
          </ion-select>
        </ion-item>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-toolbar>

I use flex to fill out the page and create "fullscreen effect with no scrolling".

Thanks

Body:
Well it seems there is this:
http://ionicframework.com/docs/api/platform/Platform/

It has:

isPortrait()
isLandscape()

so you can do:
platform.isPortrait() or platform.isLandscape()
if you inject platform into constructor.

Combine this with *NgIf:

https://angular.io/guide/template-syntax#ngif

CSS overflow, overflow-x, overflow-y is what you'd look to for prevent scrolling provided it's a block level container:

https://developer.mozilla.org/en/docs/Web/CSS/overflow

UPDATE

Based on this comment:

That was my initial thought. The problem with this is that it leaves
  padding on top. I solved it by configuring styles, but it seemed
  pretty dirty solution to me

You can fix that padding issue by getting the instance of the Content and call the resize() method like this:

import { Component, ViewChild } from '@angular/core';
import { Content } from 'ionic-angular';

@Component({...})
export class MyPage{
  @ViewChild(Content) content: Content;

  public yourMethod(): void {
    this.content.resize();
  }
}

https://ionicframework.com/docs/api/components/content/Content/#resize

Tell the content to recalculate its dimensions. This should be called
  after dynamically adding/removing headers, footers, or tabs.


问:
Replace the Variable Price range by the chosen variation price in WooCommerce 3
On WooCommerce, I would like to change the Variable single product page layout. Because when you have an variable product you get this wired price rage (below product title) in the Variable Product page and it shows in the shop page as well.

For me, the standard way is to show the lowest price of the product in the shop as well as product page and change that price according to user selection of variables. I can't believe why.

I can remove the price range and show the lowest price using this code snippet.

https://businessbloomer.com/disable-variable-product-price-range-woocommerce/

But then again, that lowest price doesn't change according to select variables. There are again two prices in the variable product layout. This is my current variable product page layout

http://www.preorders.lk/product/beats-solo3-wireless-on-ear-headphones/

So, can anyone please help to remove the price range from the variable product page and show only one lowest price ( under the product title) of the product as default. So that price should be change according to the variables which that product have. And that lowest price should be show in the shop page as well.

Here's a screenshot:

答:
2021 definitive update

Works for WooCommerce 4+ and 5+ available on:

Replace the Variable Price range by the chosen variation price in WooCommerce 4+

Update (December 2017): to avoid, Problems regarding non variable products in some themes and a repetition availability bug in some themes

Note: Some plugins like the German Market or some themes will not work with this code, as they make their own changes in the hooks or in the html structure.

This is completely possible.

First we remove the unwanted price.

We output instead the variable price without the price range and show the lowest price.

We make a copy of this variable price in a hidden container (to be used/read by our jQuery script)

Then we hide the containers of chosen variation price (and the stock availability)

With the help of our jQuery script, when we get the chosen variation price, we replace the variable price (and display the stock availability).

If the customer change of variation we update the price... If the variation price is not displayed during that change process, our variable price is displayed

Here is that code:

```<code>add_action( 'woocommerce_before_single_product', 'move_variations_single_price', 1 );
function move_variations_single_price(){
    global $product, $post;

    if ( $product->is_type( 'variable' ) ) {
        // removing the variations price for variable products
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );

        // Change location and inserting back the variations price
        add_action( 'woocommerce_single_product_summary', 'replace_variation_single_price', 10 );
    }
}

function replace_variation_single_price(){
    global $product;

    // Main Price
    $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
    $price = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    // Sale Price
    $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
    sort( $prices );
    $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    if ( $price !== $saleprice && $product->is_on_sale() ) {
        $price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
    }

    ?>
    <style>
        div.woocommerce-variation-price,
        div.woocommerce-variation-availability,
        div.hidden-variable-price {
            height: 0px !important;
            overflow:hidden;
            position:relative;
            line-height: 0px !important;
            font-size: 0% !important;
        }
    </style>
    <script>
    jQuery(document).ready(function($) {
        $('select').blur( function(){
            if( '' != $('input.variation_id').val() ){
                if($('p.availability'))
                    $('p.availability').remove();
                $('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
                console.log($('input.variation_id').val());
            } else {
                $('p.price').html($('div.hidden-variable-price').html());
                if($('p.availability'))
                    $('p.availability').remove();
                console.log('NULL');
            }
        });
    });
    </script>
    <?php

    echo '<p class="price">'.$price.'</p>
    <div class="hidden-variable-price" >'.$price.'</div>';
}
</code>```

Code goes in any php file of your active child theme (or theme) or also in any plugin php file.

This code is tested and works on WooCommerce 3.2.x (should work on WooCommerce 2.6.x too)

You can optionally move the CSS () to the styles.css file of your active child theme (or active theme) and then remove it from this function…

Related:

Move the variation price location in WooCommerce

ContentLicense: CC BY-SA 4.0

Body:
2021 definitive update

Works for WooCommerce 4+ and 5+ available on:

Replace the Variable Price range by the chosen variation price in WooCommerce 4+

Update (December 2017): to avoid, Problems regarding non variable products in some themes and a repetition availability bug in some themes

Note: Some plugins like the German Market or some themes will not work with this code, as they make their own changes in the hooks or in the html structure.

This is completely possible.

First we remove the unwanted price.

We output instead the variable price without the price range and show the lowest price.

We make a copy of this variable price in a hidden container (to be used/read by our jQuery script)

Then we hide the containers of chosen variation price (and the stock availability)

With the help of our jQuery script, when we get the chosen variation price, we replace the variable price (and display the stock availability).

If the customer change of variation we update the price... If the variation price is not displayed during that change process, our variable price is displayed

Here is that code:

add_action( 'woocommerce_before_single_product', 'move_variations_single_price', 1 );
function move_variations_single_price(){
    global $product, $post;

    if ( $product->is_type( 'variable' ) ) {
        // removing the variations price for variable products
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );

        // Change location and inserting back the variations price
        add_action( 'woocommerce_single_product_summary', 'replace_variation_single_price', 10 );
    }
}

function replace_variation_single_price(){
    global $product;

    // Main Price
    $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
    $price = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    // Sale Price
    $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
    sort( $prices );
    $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    if ( $price !== $saleprice && $product->is_on_sale() ) {
        $price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
    }

    ?>
    <style>
        div.woocommerce-variation-price,
        div.woocommerce-variation-availability,
        div.hidden-variable-price {
            height: 0px !important;
            overflow:hidden;
            position:relative;
            line-height: 0px !important;
            font-size: 0% !important;
        }
    </style>
    <script>
    jQuery(document).ready(function($) {
        $('select').blur( function(){
            if( '' != $('input.variation_id').val() ){
                if($('p.availability'))
                    $('p.availability').remove();
                $('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
                console.log($('input.variation_id').val());
            } else {
                $('p.price').html($('div.hidden-variable-price').html());
                if($('p.availability'))
                    $('p.availability').remove();
                console.log('NULL');
            }
        });
    });
    </script>
    <?php

    echo '<p class="price">'.$price.'</p>
    <div class="hidden-variable-price" >'.$price.'</div>';
}

Code goes in any php file of your active child theme (or theme) or also in any plugin php file.

This code is tested and works on WooCommerce 3.2.x (should work on WooCommerce 2.6.x too)

You can optionally move the CSS (<style></style>) to the styles.css file of your active child theme (or active theme) and then remove it from this function…

Related:

Move the variation price location in WooCommerce


问:
Split string to maximum length and append the rest to the last array item
Is there a way for me to split a string into an array and limit to x and if there are more parts than the limit append to the last array item?

So, for example I have

```<code>'Billy Bob Joe'.split(' ', 2) // Outputs ["Billy", "Bob"]
</code>```

I would like to output

```<code>["Billy", "Bob Joe"]
</code>```

Is there a way for this to be easily done in JavaScript?

答:
You can use splice and join like:

function customSplit(str, splitter, max) {
    let res = str.split(splitter);
    if(max < res.length)
        res.push(res.splice(max - 1).join(splitter));
    return res;
}

console.log(customSplit('Billy Bob Joe', ' ', 2));
console.log(customSplit('a b c d e f g h', ' ', 4));```

Body:
Is there a way for me to split a string into an array and limit to x and if there are more parts than the limit append to the last array item?

So, for example I have

'Billy Bob Joe'.split(' ', 2) // Outputs ["Billy", "Bob"]

I would like to output

["Billy", "Bob Joe"]

Is there a way for this to be easily done in JavaScript?


问:
How to set highlight on QPushButton hovering
How can I highlight a QPushButton when the user hovers it with the mouse?

I want something like the Toolbox from GIMP (flat buttons, checkable, highlighted on hovering)

答:
Double click on the .ui file of the project.

Right click on the button.

Left click on: 'Change styleSheet...'.

Add: 'QPushButton:hover { background-color: red; } (where QPushButton is the class of the button) or something else. It is css code.

Click on 'Apply'.

Click on 'OK'.


问:
Angular 2 - select binding
I want to select in <select> an option which I defined in component. But when I want to print this in console I get undefined. My code:

component.html:

```<code><div class="row">
    <div class="form-group col-md-6">
        <label>Select option:</label>
        <select class="form-control" [(ngModel)]="selectedOption">
            <option *ngFor="let item of options" [value]="item">{{ item.display }}</option>
        </select>
    </div>
</div>

<button type="button" (click)="showOption()">Show selected option</button>
</code>```

component.ts:

```<code>selectedOption: any;

sortOptions = [
    {
        value: 'option1',
        display: 'First option'
    },
    {
        value: 'option2',
        display: 'Second option'
    }
];

showOption(): void {
    console.log(this.selectedOption.value);
}
</code>```

When I try print console.log(this.selectedOption.value); I get "undefined" and when I try to print console.log(this.selectedOption) I get "[option Option]"

I don't know how to resole it.

答:
You can also use this :

```<code> <select [(ngModel)]="selectedOption">
   <option value=""></option>
   <option *ngFor="let item of sortOptions" [value]="item.id">
     {{item.display}}
   </option>
</select>
</code>```

[value] for string values and [ngValue] for all types

Title: Angular 2 - select binding

Body:
I want to select in <select> an option which I defined in component. But when I want to print this in console I get undefined. My code:

component.html:

        Select option:
        <select class="form-control" [(ngModel)]="selectedOption">
            <option *ngFor="let item of options" [value]="item">{{ item.display }}</option>
        </select>

<button type="button" (click)="showOption()">Show selected option</button>

component.ts:

selectedOption: any;

sortOptions = [
    {
        value: 'option1',
        display: 'First option'
    },
    {
        value: 'option2',
        display: 'Second option'
    }
];

showOption(): void {
    console.log(this.selectedOption.value);
}

When I try print console.log(this.selectedOption.value); I get "undefined" and when I try to print console.log(this.selectedOption) I get "[option Option]"

I don't know how to resole it.

Body:
You can also use this :

 <select [(ngModel)]="selectedOption">
   <option value=""></option>
   <option *ngFor="let item of sortOptions" [value]="item.id">
     {{item.display}}
   </option>
</select>

[value] for string values and [ngValue] for all types


问:
All preprocessing worsens accuracy
I am performing a grid search cross validation with a logistic regression model. I have my default model first, then one that should preprocess the data. The data are random text documents that fall into one of 4 categories. My preprocessor seems to worsen my accuracy and f1 score even when I just have it return the data, as below. The regularization parameter C the gridsearch picks after passing this preprocessing which shouldn't be doing anything.

```<code>Cs = {'C' : [0.0001, 0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 10.0]}
gs_clf_LR = GridSearchCV(LogisticRegression(penalty='l2'), Cs, refit=True)
gs_clf_LR.fit(transformed_train_data, train_labels)
preds = gs_clf_LR.predict(transformed_dev_data)
#print gs_clf_LR.score(transformed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds, average='weighted')
print metrics.classification_report(dev_labels, preds)
print

def better_preprocessor(string):
    #return re.sub(r'^[A-Z]', '^[a-z]', string)
    #return re.sub(r'(ing)$', '', string)
    #return re.sub(r'(es)$', '', string)
    #return re.sub(r's$', '', string)
    #return re.sub(r'(ed)$', '', string)
    return string

vec = CountVectorizer(preprocessor=better_preprocessor)
transformed_preprocessed_train_data = vec.fit_transform(train_data)
transformed_preprocessed_dev_data = vec.transform(dev_data)

gs_clf_LR.fit(transformed_preprocessed_train_data, train_labels)
preds_pp = gs_clf_LR.predict(transformed_preprocessed_dev_data)
#print gs_clf_LR.score(transformed_preprocessed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds_pp, average='weighted')
print metrics.classification_report(dev_labels, preds_pp)
</code>```

With some real preprocessing, such as the regex lines I have commented out, I also see a decrease in my accuracy and f1-score (plausible but I am getting rid of plurals and have been told this should improve my scores).

答:
The problem is that your preprocessing basically does nothing, because preprocessing is what happens in CountVectorizer before tokenization. This means that you get whole texts through your function, and no regex with $ at the end fires.

This is the result of fitting a vectorizer with your better_preprocessing:

```<code>In [16]: data = ['How are you guys doing? Fine! We are very satisfied']

In [17]: vec.fit(data)
Out[17]:
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1),
        preprocessor=<function better_preprocessor at 0x000002DB839FF048>,
        stop_words=None, strip_accents=None,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, vocabulary=None)

In [18]: vec.get_feature_names()
Out[18]: ['Fine', 'We', 'are', 'doing', 'guys', 'ow', 'satisfied', 'very', 'you']
</code>```

What this means is that you have to override the analyzer step with your function, not preprocessor. Compare:

analyzer : string, {‘word’, ‘char’, ‘char_wb’} or callable Whether the
  feature should be made of word or character n-grams. Option ‘char_wb’
  creates character n-grams only from text inside word boundaries. If a
  callable is passed it is used to extract the sequence of features out
  of the raw, unprocessed input.

preprocessor : callable or None
  (default) Override the preprocessing (string transformation) stage
  while preserving the tokenizing and n-grams generation steps.

However, you will have to deal with tokenization in you function, but you can use the default '(?u)\\b\\w\\w+\\b', so it is not that difficult. Anyway, I don't think you approach is really solid, and I would recommend using something like SnowballStemmer from NLTK instead of these regexes.

Title: All preprocessing worsens accuracy

Body:
I am performing a grid search cross validation with a logistic regression model. I have my default model first, then one that should preprocess the data. The data are random text documents that fall into one of 4 categories. My preprocessor seems to worsen my accuracy and f1 score even when I just have it return the data, as below. The regularization parameter C the gridsearch picks after passing this preprocessing which shouldn't be doing anything.

Cs = {'C' : [0.0001, 0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 10.0]}
gs_clf_LR = GridSearchCV(LogisticRegression(penalty='l2'), Cs, refit=True)
gs_clf_LR.fit(transformed_train_data, train_labels)
preds = gs_clf_LR.predict(transformed_dev_data)
#print gs_clf_LR.score(transformed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds, average='weighted')
print metrics.classification_report(dev_labels, preds)
print

def better_preprocessor(string):
    #return re.sub(r'^[A-Z]', '^[a-z]', string)
    #return re.sub(r'(ing)$', '', string)
    #return re.sub(r'(es)$', '', string)
    #return re.sub(r's$', '', string)
    #return re.sub(r'(ed)$', '', string)
    return string

vec = CountVectorizer(preprocessor=better_preprocessor)
transformed_preprocessed_train_data = vec.fit_transform(train_data)
transformed_preprocessed_dev_data = vec.transform(dev_data)

gs_clf_LR.fit(transformed_preprocessed_train_data, train_labels)
preds_pp = gs_clf_LR.predict(transformed_preprocessed_dev_data)
#print gs_clf_LR.score(transformed_preprocessed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds_pp, average='weighted')
print metrics.classification_report(dev_labels, preds_pp)

With some real preprocessing, such as the regex lines I have commented out, I also see a decrease in my accuracy and f1-score (plausible but I am getting rid of plurals and have been told this should improve my scores).

Body:
The problem is that your preprocessing basically does nothing, because preprocessing is what happens in CountVectorizer before tokenization. This means that you get whole texts through your function, and no regex with $ at the end fires.

This is the result of fitting a vectorizer with your better_preprocessing:

In [16]: data = ['How are you guys doing? Fine! We are very satisfied']

In [17]: vec.fit(data)
Out[17]:
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1),
        preprocessor=<function better_preprocessor at 0x000002DB839FF048>,
        stop_words=None, strip_accents=None,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, vocabulary=None)

In [18]: vec.get_feature_names()
Out[18]: ['Fine', 'We', 'are', 'doing', 'guys', 'ow', 'satisfied', 'very', 'you']

What this means is that you have to override the analyzer step with your function, not preprocessor. Compare:

analyzer : string, {‘word’, ‘char’, ‘char_wb’} or callable Whether the
  feature should be made of word or character n-grams. Option ‘char_wb’
  creates character n-grams only from text inside word boundaries. If a
  callable is passed it is used to extract the sequence of features out
  of the raw, unprocessed input.

preprocessor : callable or None
  (default) Override the preprocessing (string transformation) stage
  while preserving the tokenizing and n-grams generation steps.

However, you will have to deal with tokenization in you function, but you can use the default '(?u)\\b\\w\\w+\\b', so it is not that difficult. Anyway, I don't think you approach is really solid, and I would recommend using something like SnowballStemmer from NLTK instead of these regexes.


问:
The vehicle lifecycle application exits as we run it on a server which does not have a browser. Any solution?
I am using 16.04 ubuntu server from digital ocean.
I am trying to run vehicle example from composer-sample-appplication git project. So once we usee build.sh then excetue install.sh , it does everything like downloading docker images and deploy bna. Eveything run fines.

So once network is up,

It starts UI application as follows:

```<code># Start the VDA application.
docker run \
-d \
--network composer_default \
--name vda \
-e COMPOSER_BASE_URL=http://rest:3000 \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 6001:6001 \
hyperledger/vehicle-lifecycle-vda
2e0370a1d3694e6504d16fdf7b542f36bfb8c9a9e37f217ce35625968e772b52

# Start the manufacturing application.
docker run \
-d \
--network composer_default \
--name manufacturing \
-e COMPOSER_BASE_URL=http://rest:3000 \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 6002:6001 \
hyperledger/vehicle-lifecycle-manufacturing
09f641244ad91e410640450c55e8997fc0b60464c649180721465a63efbeb445

# Start the car-builder application.
docker run \
-d \
--network composer_default \
--name car-builder \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 8100:8100 \
hyperledger/vehicle-lifecycle-car-builder
4ef35265ee0f507ddfabcdc36ed6774fa8e0137808f7fd4b47c1a36ce74c4e10
</code>```

but after this

```<code># Open the playground in a web browser.
URLS="http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100"
case "$(uname)" in
"Darwin") open ${URLS}
          ;;
"Linux")  if [ -n "$BROWSER" ] ; then
                    $BROWSER http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100
            elif      which x-www-browser > /dev/null ; then
                  nohup x-www-browser ${URLS} < /dev/null > /dev/null 2>&1 &
          elif    which xdg-open > /dev/null ; then
                  for URL in ${URLS} ; do
                          xdg-open ${URL}
                    done
          elif      which gnome-open > /dev/null ; then
                    gnome-open http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100
          #elif other types blah blah
            else
                    echo "Could not detect web browser to use - please launch Composer Playground URL using your chosen browser ie: <browser executable name> http://localhost:8080 or set your BROWSER variable to the browser launcher in your PATH"
            fi
          ;;
*)        echo "Playground not launched - this OS is currently not supported "
          ;;
esac
uname
Could not detect web browser to use - please launch Composer Playground URL using your chosen browser ie: <browser executable name> http://localhost:8080 or set your BROWSER variable to the browser launcher in your PATH

# Exit; this is required as the payload immediately follows.
exit 0
</code>```

So the server does not have GUI and browser. I think scipt(install.sh) is not able to load all the payload that is required. Can this be fixed somehow?

答: All that section of the script does is try to open a web browser and open the various pages. It should not have any effect on the docker containers launched.</p>

Body:
I am using 16.04 ubuntu server from digital ocean.
I am trying to run vehicle example from composer-sample-appplication git project. So once we usee build.sh then excetue install.sh , it does everything like downloading docker images and deploy bna. Eveything run fines.

So once network is up,

It starts UI application as follows:

# Start the VDA application.
docker run \
-d \
--network composer_default \
--name vda \
-e COMPOSER_BASE_URL=http://rest:3000 \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 6001:6001 \
hyperledger/vehicle-lifecycle-vda
2e0370a1d3694e6504d16fdf7b542f36bfb8c9a9e37f217ce35625968e772b52

# Start the manufacturing application.
docker run \
-d \
--network composer_default \
--name manufacturing \
-e COMPOSER_BASE_URL=http://rest:3000 \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 6002:6001 \
hyperledger/vehicle-lifecycle-manufacturing
09f641244ad91e410640450c55e8997fc0b60464c649180721465a63efbeb445

# Start the car-builder application.
docker run \
-d \
--network composer_default \
--name car-builder \
-e NODE_RED_BASE_URL=ws://node-red:1880 \
-p 8100:8100 \
hyperledger/vehicle-lifecycle-car-builder
4ef35265ee0f507ddfabcdc36ed6774fa8e0137808f7fd4b47c1a36ce74c4e10

but after this

# Open the playground in a web browser.
URLS="http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100"
case "$(uname)" in
"Darwin") open ${URLS}
          ;;
"Linux")  if [ -n "$BROWSER" ] ; then
                    $BROWSER http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100
            elif      which x-www-browser > /dev/null ; then
                  nohup x-www-browser ${URLS} < /dev/null > /dev/null 2>&1 &
          elif    which xdg-open > /dev/null ; then
                  for URL in ${URLS} ; do
                          xdg-open ${URL}
                    done
          elif      which gnome-open > /dev/null ; then
                    gnome-open http://localhost:8080 http://localhost:3000/explorer/ http://localhost:1880 http://localhost:6001 http://localhost:6002 http://localhost:8100
          #elif other types blah blah
            else
                    echo "Could not detect web browser to use - please launch Composer Playground URL using your chosen browser ie: <browser executable name> http://localhost:8080 or set your BROWSER variable to the browser launcher in your PATH"
            fi
          ;;
*)        echo "Playground not launched - this OS is currently not supported "
          ;;
esac
uname
Could not detect web browser to use - please launch Composer Playground URL using your chosen browser ie: <browser executable name> http://localhost:8080 or set your BROWSER variable to the browser launcher in your PATH

# Exit; this is required as the payload immediately follows.
exit 0

So the server does not have GUI and browser. I think scipt(install.sh) is not able to load all the payload that is required. Can this be fixed somehow?


问:
The insert statement conflicted with the Foreign Key SQL
I have searched the internet but couldn't find a solution. I am using the following SQL Statement in order to update some cells or create a new row:

```<code>UPDATE [dbo].[PRCRDATALNS]

SET   FLD01 = :TIMX1
     ,FLD02 = :TIML1

WHERE DIM1= :vmtrl AND PRCRULE= '2' AND LINENUM = '1'

IF @@ROWCOUNT=0

INSERT INTO [dbo].[PRCRDATALNS] (

       COMPANY
      ,SODTYPE
      ,SOTYPE
      ,PRCRULE
      ,DIM1
      ,DIM2
      ,DIM3
      ,PRCRDATALNS
      ,LINENUM
      ,FROMDATE
      ,FLD01
      ,FLD02
      ,SCALEQTY
      )

VALUES
        ('1'
        ,'13'
        ,'1'
        ,2
        ,:vmtrl
        ,'0'
        ,'0'
        ,'1'
        ,'1'
        ,GETDATE ( )
        ,:TIMX1
        ,:TIML1
        ,'1'
        );
</code>```

When I execute it and a new row is to be inserted it says: The insert statement conflicted with the FOREIGN KEY constraint "XD_PRCRDATALNS_PRCRULE". The conflict occurred in database "KOMBOS", table "dbo.PRCRDATA". The statement has been terminated.

I am aware of what this means. First of all it isn't mentioned anything about issues in columns like others have. And secondly the table PRCRDATA has all the values that are needed like PRCRULE,SODTYPE,SOTYPE etc.

Where should I look at?

答:
I narrowed it down. The message from SQL Server was not right!
It was not PRCRULE the issue. The issue was the FROMDATE that was also a FK and I changed it from GETDATE () to CONVERT(DATE, GETDATE())  so I removed the time, and it worked.

Body:
I have searched the internet but couldn't find a solution. I am using the following SQL Statement in order to update some cells or create a new row:

UPDATE [dbo].[PRCRDATALNS]

SET   FLD01 = :TIMX1
     ,FLD02 = :TIML1

WHERE DIM1= :vmtrl AND PRCRULE= '2' AND LINENUM = '1'

IF @@ROWCOUNT=0

INSERT INTO [dbo].[PRCRDATALNS] (

       COMPANY
      ,SODTYPE
      ,SOTYPE
      ,PRCRULE
      ,DIM1
      ,DIM2
      ,DIM3
      ,PRCRDATALNS
      ,LINENUM
      ,FROMDATE
      ,FLD01
      ,FLD02
      ,SCALEQTY
      )

VALUES
        ('1'
        ,'13'
        ,'1'
        ,2
        ,:vmtrl
        ,'0'
        ,'0'
        ,'1'
        ,'1'
        ,GETDATE ( )
        ,:TIMX1
        ,:TIML1
        ,'1'
        );

When I execute it and a new row is to be inserted it says: The insert statement conflicted with the FOREIGN KEY constraint "XD_PRCRDATALNS_PRCRULE". The conflict occurred in database "KOMBOS", table "dbo.PRCRDATA". The statement has been terminated.

I am aware of what this means. First of all it isn't mentioned anything about issues in columns like others have. And secondly the table PRCRDATA has all the values that are needed like PRCRULE,SODTYPE,SOTYPE etc.

Where should I look at?


问:
How to save variables from any type into UserDefaults in Swift?
Here we have a variable named "Data". it is from the type "memorySTR" which is self defined. this variable must be saved to UserDefaults when the app is shutting down and load when app runs again . here is the code .

```<code>//Here loads the data when the app runs :
if UserDefaults.standard.object(forKey: "Data") != nil {Data = UserDefaults.standard.object(forKey: "Data") as! MemorySTR}
//Here saves the data when necessary :
UserDefaults.standard.set( Data ,forKey: "Data")
</code>```

but unfortunately the type "memorySTR" is not accepted to the UserDefaults , so it gives an error. Also, the type "memorySTR" is not a simple type, that means we can not save its properties one by one. so how can we save that variable to permanent storage ?
solve this problem in a code with the SIMPLES and the SHORTEST way please.

答:
You can use NSKeyArchiver and implement NSCoder protocol in your MemorySTR class and then doing this

Implementing NSCoder Protocol

```<code>required convenience init?(coder decoder: NSCoder)
    {
       //***decode your attributes here**//
    }

extension MemorySTR : NSCoding
{
    func encode(with aCoder: NSCoder) {
          //***encode your attributes here**//
    }
}
</code>```

Saving and Loading your custom object from UserDefaults

```<code>func saveData(object: MemorySTR){
    let myEncodedObject  =  NSKeyedArchiver.archivedData(withRootObject: object)
    UserDefaults.standard.set(myEncodedObject, forKey:"memoryStr")
}

func loadMemorySTRObject() -> MemorySTR?{
    let myEncodedObjet = UserDefaults.standard.object(forKey:"memoryStr")

    if myEncodedObjet != nil {
        return  NSKeyedUnarchiver.unarchiveObject(with: myEncodedObjet as! Data) as! MemorySTR
    }else{
        return  nil
    }
}
</code>```

Hope this helps

Body:
Here we have a variable named "Data". it is from the type "memorySTR" which is self defined. this variable must be saved to UserDefaults when the app is shutting down and load when app runs again . here is the code .

//Here loads the data when the app runs :
if UserDefaults.standard.object(forKey: "Data") != nil {Data = UserDefaults.standard.object(forKey: "Data") as! MemorySTR}
//Here saves the data when necessary :
UserDefaults.standard.set( Data ,forKey: "Data")

but unfortunately the type "memorySTR" is not accepted to the UserDefaults , so it gives an error. Also, the type "memorySTR" is not a simple type, that means we can not save its properties one by one. so how can we save that variable to permanent storage ?
solve this problem in a code with the SIMPLES and the SHORTEST way please.

Body:
You can use NSKeyArchiver and implement NSCoder protocol in your MemorySTR class and then doing this

Implementing NSCoder Protocol

required convenience init?(coder decoder: NSCoder)
    {
       //***decode your attributes here**//
    }

extension MemorySTR : NSCoding
{
    func encode(with aCoder: NSCoder) {
          //***encode your attributes here**//
    }
}

Saving and Loading your custom object from UserDefaults

func saveData(object: MemorySTR){
    let myEncodedObject  =  NSKeyedArchiver.archivedData(withRootObject: object)
    UserDefaults.standard.set(myEncodedObject, forKey:"memoryStr")
}

func loadMemorySTRObject() -> MemorySTR?{
    let myEncodedObjet = UserDefaults.standard.object(forKey:"memoryStr")

    if myEncodedObjet != nil {
        return  NSKeyedUnarchiver.unarchiveObject(with: myEncodedObjet as! Data) as! MemorySTR
    }else{
        return  nil
    }
}

Hope this helps


问:
Filling a plane with triangles (Triangulation)
I tried to create an image like the one below as a random background for a website, but after multiple attempts I couldn't find an algorithm that gets the job done.

What should the program do?

It should be able to fill a plane randomly with triangles. These triangles should all be independent, so I don't simply want to draw long lines on the canvas an color the triangles that are created.

Algorithms I've tried so far:

1.

Make random Points

Make random Connections with a length below a specific value (This could leed to holes in the triangle net)

Try to find out what connections make a triangle (I failed here)

2.

Start with a single triangle

Create a new Point close to an existing connection and add a triangle from there that doesn't cause any intersections. This lead to problems whenever it left a little hole like in this picture:

3.

Make random points

Make all possible connections (every point to every other)

Sort the connections by length

For every connection starting with the shortest draw if it isn't intersecting with any other drawn line. Otherwise delete the connection.

This was actually my best attemt even if it took the program far to long to get it done with only a few points. This is how the result looked:

I didn't find a way to find out what connections make a triangle and therefor I couldn't color them indipendently...

So hopefully you know a way to create a nice triangle-filled canvas like in the first picture and let me know...

答: A good solution is to start with random points (with your preferred distribution) and apply some triangulation algorithm. Among these, the Delaunay triangulation is a good candidate, for its low computational complexity and code availability.</p>


问:
JNI native methods not appearing in Javadoc
I am studying some code involving JNI. As part of this I can creating Javdoc libraries.  See CoreMidiClient.createClient and  CoreMidiClient.disposeClient in http://bradleyross.github.io/CoreMidi4J/apidocs for the Javadoc.  The actual Git repository is http://www.github.com/BradleyRoss/CoreMidi4J.  The methods are in the Java source files but don't appear in the Javadocs.  Is there some option that I am missing or something that I am interpreting wrong.  I am using maven-javadoc-plugin to create the Javadoc files.</p>

答: I found the problem.  I needed to have private in the configuration section of the maven-javadoc-plugin specifications.  This line had been lost in some cut-and-paste activity.</p>


问:
Unexpected coefficients from Spark multinomial Logistic Regression
I run Spark 2.1.1 on my Mac, OS Sierra (should this be helpful). I tried to fit a multinomial logistic regression on a test dataset I found online, I report here the first few lines (I don't know how to attach the file here):

```<code>1,0,24
1,0,26
1,0,26
1,1,27
1,1,27
3,1,27
</code>```

The first column is the label ('brand', values: 1, 2, 3), the second and third columns are the features ('sex' and 'age').

Since the label have 3 classes, the multinomial logistic regression should perform 3 binomial models and then choose the predictions from the one which maximizes the probability of being in that class. So I expect the model to return a 3x2 coefficientMatrix: 3 because the classes are 3, and 2 because the features are 2. This documentation seems to be coherent with this point of view.

But, surprise surprise...

```<code>>>> logit_model.coefficientMatrix
DenseMatrix(4, 2, [-1.2781, -2.8523, 0.0961, 0.5994, 0.6199, 0.9676, 0.5621, 1.2853], 1)
>>> logit_model.interceptVector
DenseVector([-4.5912, 13.0291, 1.2544, -9.6923])
</code>```

The coefficientMatrix is 4x2, and I have 4 intercepts rather than 3. Even stranger is this:

```<code>>>> logit_model.numClasses
4
</code>```

For some strange reason, the model "feel" 4 classes, even if I have just 3 (see code below for a check on this).

Any suggestion?
Thank you very much.

Here is the full code:

```<code>from pyspark.sql import functions as f
from pyspark.sql import types as t
from pyspark.ml import classification as cl
from pyspark.ml import feature as feat

customSchema = t.StructType(
    [t.StructField('brand', t.IntegerType(), True),
    t.StructField('sex', t.IntegerType(), True),
    t.StructField('age', t.IntegerType(), True)]
)

test_df01 = (
    spark
    .read
    .format('csv')
    .options(delimiter=',', header=False)
    .load('/Users/vanni/Downloads/mlogit_test.csv', schema=customSchema)
)

va = (
    feat.VectorAssembler()
    .setInputCols(['sex', 'age'])
    .setOutputCol('features')
)
test_df03 = (
    va
    .transform(test_df01)
    .drop('sex')
    .drop('age')
    .withColumnRenamed('brand', 'label')
)

logit_abst = (
    cl.LogisticRegression()
    .setFamily('multinomial')
    .setStandardization(False)
    .setThresholds([.5, .5, .5]) # to be adjusted after I know the actual values
    .setThreshold(None)
    .setMaxIter(100) # default
    .setRegParam(0.0) # default
    .setElasticNetParam(0.0) # default
    .setTol(1e-6) # default
)

logit_model = logit_abst.fit(test_df03)
</code>```

Here is the check that the classes are just 3:

```<code>>>> test_df03.select('label').distinct().orderBy('label').show()
+-----+
|label|
+-----+
|    1|
|    2|
|    3|
+-----+
</code>```

答:
There is nothing strange going on here. Spark assumes that labels are consecutive integer values, represented as DoubleType, and starting with 0.

Since the largest label you get is 3, Spark assumes that labels are actually 0, 1, 2, 3 - even if 0 never occurs in the dataset.

If this behavior is undesired you should re-encode labels to be zero-based, or apply StringIndexer on the raw labels.

Body:
I run Spark 2.1.1 on my Mac, OS Sierra (should this be helpful). I tried to fit a multinomial logistic regression on a test dataset I found online, I report here the first few lines (I don't know how to attach the file here):

1,0,24
1,0,26
1,0,26
1,1,27
1,1,27
3,1,27

The first column is the label ('brand', values: 1, 2, 3), the second and third columns are the features ('sex' and 'age').

Since the label have 3 classes, the multinomial logistic regression should perform 3 binomial models and then choose the predictions from the one which maximizes the probability of being in that class. So I expect the model to return a 3x2 coefficientMatrix: 3 because the classes are 3, and 2 because the features are 2. This documentation seems to be coherent with this point of view.

But, surprise surprise...

>>> logit_model.coefficientMatrix
DenseMatrix(4, 2, [-1.2781, -2.8523, 0.0961, 0.5994, 0.6199, 0.9676, 0.5621, 1.2853], 1)
>>> logit_model.interceptVector
DenseVector([-4.5912, 13.0291, 1.2544, -9.6923])

The coefficientMatrix is 4x2, and I have 4 intercepts rather than 3. Even stranger is this:

>>> logit_model.numClasses
4

For some strange reason, the model "feel" 4 classes, even if I have just 3 (see code below for a check on this).

Any suggestion?
Thank you very much.

Here is the full code:

from pyspark.sql import functions as f
from pyspark.sql import types as t
from pyspark.ml import classification as cl
from pyspark.ml import feature as feat

customSchema = t.StructType(
    [t.StructField('brand', t.IntegerType(), True),
    t.StructField('sex', t.IntegerType(), True),
    t.StructField('age', t.IntegerType(), True)]
)

test_df01 = (
    spark
    .read
    .format('csv')
    .options(delimiter=',', header=False)
    .load('/Users/vanni/Downloads/mlogit_test.csv', schema=customSchema)
)

va = (
    feat.VectorAssembler()
    .setInputCols(['sex', 'age'])
    .setOutputCol('features')
)
test_df03 = (
    va
    .transform(test_df01)
    .drop('sex')
    .drop('age')
    .withColumnRenamed('brand', 'label')
)

logit_abst = (
    cl.LogisticRegression()
    .setFamily('multinomial')
    .setStandardization(False)
    .setThresholds([.5, .5, .5]) # to be adjusted after I know the actual values
    .setThreshold(None)
    .setMaxIter(100) # default
    .setRegParam(0.0) # default
    .setElasticNetParam(0.0) # default
    .setTol(1e-6) # default
)

logit_model = logit_abst.fit(test_df03)

Here is the check that the classes are just 3:

>>> test_df03.select('label').distinct().orderBy('label').show()
+-----+
|label|
+-----+
|    1|
|    2|
|    3|
+-----+


问:
Codeigniter this->db->query unidentified index
I am trying to execute the following query using CodeIgniter, but I am getting

Unidentified index for ->row['code'];

```<code>public function getSExtension($id) {
  $temp = array();
  $query = $this->db->query("SELECT extension_id FROM " . DB_PREFIX . "zipcode_shipping WHERE `zip_code` = '" . $id . "'");
  if($query->num_rows) {
    foreach ($query->rows as $key => $value) {
      $code = $this->db->query("SELECT code FROM " . DB_PREFIX . "extension WHERE `extension_id` = '" . $value['extension_id'] . "'")->row['code'];
      $this->language->load("shipping/".$code);
      $temp[] = $this->language->get('text_title');
    }
  }
  return $temp;
}
</code>```

答:
The problem is you have not correctly retrieved a result set which requires a method call. As you have it you are trying to use db properties that don't exist i.e. $query->rows should probably be $query->row_array().

Documentation Here.

In the example below I use result() and row() instead of any "array" methods.

Try this.

```<code>$temp = array();
$query = $this->db->query("SELECT extension_id FROM ".DB_PREFIX."zipcode_shipping WHERE `zip_code` = '".$id."'");

if($query->num_rows() > 0)
{
    foreach($query->result() as $value)
    {
        $code = $this->db->query("SELECT code FROM ".DB_PREFIX."extension WHERE `extension_id` = '".$value->extension_id."'")->row()->code;
        $this->language->load("shipping/".$code);
        $temp[] = $this->language->get('text_title');
    }
}
</code>```

Body:
I am trying to execute the following query using CodeIgniter, but I am getting

Unidentified index for ->row['code'];

public function getSExtension($id) {
  $temp = array();
  $query = $this->db->query("SELECT extension_id FROM " . DB_PREFIX . "zipcode_shipping WHERE `zip_code` = '" . $id . "'");
  if($query->num_rows) {
    foreach ($query->rows as $key => $value) {
      $code = $this->db->query("SELECT code FROM " . DB_PREFIX . "extension WHERE `extension_id` = '" . $value['extension_id'] . "'")->row['code'];
      $this->language->load("shipping/".$code);
      $temp[] = $this->language->get('text_title');
    }
  }
  return $temp;
}

Body:
The problem is you have not correctly retrieved a result set which requires a method call. As you have it you are trying to use db properties that don't exist i.e. $query->rows should probably be $query->row_array().

Documentation Here.

In the example below I use result() and row() instead of any "array" methods.

Try this.

$temp = array();
$query = $this->db->query("SELECT extension_id FROM ".DB_PREFIX."zipcode_shipping WHERE `zip_code` = '".$id."'");

if($query->num_rows() > 0)
{
    foreach($query->result() as $value)
    {
        $code = $this->db->query("SELECT code FROM ".DB_PREFIX."extension WHERE `extension_id` = '".$value->extension_id."'")->row()->code;
        $this->language->load("shipping/".$code);
        $temp[] = $this->language->get('text_title');
    }
}


问:
Parse a log file and convert to case classes in Scala
I'm note sure how to approach the following problem.
Let's say I have a log file like this:

```<code>asdasdçkpoiwqe
askdjadlskjqw
<stuff>
    <a>some val</a>
    <b>some val</b>
</stuff>
kasdjllasdj
clkj
skdjalkd
<moreStuff>
    <c>some val</c>
    <d>some val</d>
</moreStuff>
iuoudnas
salkdj
sdmlaks
<moreStuff>
    <c>more val</c>
    <d>some val</d>
 </moreStuff>
...
</code>```

that is I have some crap text and in the middle, some xml structures well formed.
I want to parse this file and convert this xml to case classes, so I defined:

```<code>case class Stuff(a: String, b: String)

case class MoreStuff(c: String, d: String)
</code>```

and this code:

```<code>val filename = "logFile.log"
for (line <- Source.fromFile(filename).getLines) {
    line match {
              case "<stuff>" => parseStuff(line)
              case "<moreStuff>" => parseMoreStuff(line)
              case _ => println("Not Defined"+ line)
            }
}

def parseStuff(line: String) = {
  //Create a List[Stuff]
}

def parseMoreStuff(line: String) = {
  //Create a List[Stuff]
}
</code>```

but clearly this doesn't work because when the cycle for matches, the only line passing to the methods are <stuff> or <moreStuff>

than I thought I could pass the the iterator to the methods and inside make next. Something like this:

```<code>def parseMoreStuff(line: String, it: Iterator) = {
  var l = line
  while(!line.equals("</moreStuff>")){
    l += line
    it.next()
}
</code>```

and now I have a single String l only with xml content and I can treat as xml. I runned this code and I got a java.util.NoSuchElementException: next on empty iterator but anyway I think this approach is a big mess (even if I could solve this exception). I don't like it so my question is if there's a cleaner way to parse a log file with this caracteristics.

thanks in advance

答:
One approach is to first ignore the junk text:

```<code>val xmlAsString =
  Source.fromFile(filename)
        .getLines
        .map(_.trim)
        .filter(_.startsWith("<"))
        .mkString

// <stuff><a>some val</a><b>some val</b></stuff><moreStuff><c>some val</c><d>some val</d></moreStuff><moreStuff><c>more val</c><d>some val</d></moreStuff>
</code>```

Note that in the above code I convert the Iterator to a String, so this could be an issue if the XML content in your file is too large to fit in memory.

Next, using Scala's standard XML library (which, as of Scala 2.11, has been moved to its own library), aggregate the XML fragments into one XML document (to make this composite document well-formed, add a root element):

```<code>import scala.xml._

val xmlDoc = XML.loadString("<stuffRoot>" + xmlAsString + "</stuffRoot>")
</code>```

Then, to obtain a Seq of Stuffs and a Seq of MoreStuffs:

```<code>def parseStuff(node: Node): Stuff = {
  Stuff((node \ "a").toString, (node \ "b").toString)
}

def parseMoreStuff(node: Node): MoreStuff = {
  MoreStuff((node \ "c").toString, (node \ "d").toString)
}

val stuffs = (xmlDoc \ "stuff").map(parseStuff) // Seq[Stuff]
val moreStuffs = (xmlDoc \ "moreStuff").map(parseMoreStuff) // Seq[MoreStuff]
</code>```

Body:
I'm note sure how to approach the following problem.
Let's say I have a log file like this:

asdasdçkpoiwqe
askdjadlskjqw
<stuff>
    some val
    some val
</stuff>
kasdjllasdj
clkj
skdjalkd
<moreStuff>
    <c>some val</c>
    <d>some val</d>
</moreStuff>
iuoudnas
salkdj
sdmlaks
<moreStuff>
    <c>more val</c>
    <d>some val</d>
 </moreStuff>
...

that is I have some crap text and in the middle, some xml structures well formed.
I want to parse this file and convert this xml to case classes, so I defined:

case class Stuff(a: String, b: String)

case class MoreStuff(c: String, d: String)

and this code:

val filename = "logFile.log"
for (line <- Source.fromFile(filename).getLines) {
    line match {
              case "<stuff>" => parseStuff(line)
              case "<moreStuff>" => parseMoreStuff(line)
              case _ => println("Not Defined"+ line)
            }
}

def parseStuff(line: String) = {
  //Create a List[Stuff]
}

def parseMoreStuff(line: String) = {
  //Create a List[Stuff]
}

but clearly this doesn't work because when the cycle for matches, the only line passing to the methods are <stuff> or <moreStuff>

than I thought I could pass the the iterator to the methods and inside make next. Something like this:

def parseMoreStuff(line: String, it: Iterator) = {
  var l = line
  while(!line.equals("</moreStuff>")){
    l += line
    it.next()
}

and now I have a single String l only with xml content and I can treat as xml. I runned this code and I got a java.util.NoSuchElementException: next on empty iterator but anyway I think this approach is a big mess (even if I could solve this exception). I don't like it so my question is if there's a cleaner way to parse a log file with this caracteristics.

thanks in advance

Body:
One approach is to first ignore the junk text:

val xmlAsString =
  Source.fromFile(filename)
        .getLines
        .map(_.trim)
        .filter(_.startsWith("<"))
        .mkString

// <stuff><a>some val</a><b>some val</b></stuff><moreStuff><c>some val</c><d>some val</d></moreStuff><moreStuff><c>more val</c><d>some val</d></moreStuff>

Note that in the above code I convert the Iterator to a String, so this could be an issue if the XML content in your file is too large to fit in memory.

Next, using Scala's standard XML library (which, as of Scala 2.11, has been moved to its own library), aggregate the XML fragments into one XML document (to make this composite document well-formed, add a root element):

import scala.xml._

val xmlDoc = XML.loadString("<stuffRoot>" + xmlAsString + "</stuffRoot>")

Then, to obtain a Seq of Stuffs and a Seq of MoreStuffs:

def parseStuff(node: Node): Stuff = {
  Stuff((node \ "a").toString, (node \ "b").toString)
}

def parseMoreStuff(node: Node): MoreStuff = {
  MoreStuff((node \ "c").toString, (node \ "d").toString)
}

val stuffs = (xmlDoc \ "stuff").map(parseStuff) // Seq[Stuff]
val moreStuffs = (xmlDoc \ "moreStuff").map(parseMoreStuff) // Seq[MoreStuff]


问:
Powershell script doesn't pull certain fields from active directory?
I’m trying to write a PowerShell script to pull users information out of Active Directory and export it to a csv file. I have one partly working but for some reasons some fields in the tables come back blank even though there is data to be extracted? Anyone know why this happening ?

```<code>Import-Module ActiveDirectory

Get-ADUser -Filter * -Properties * | select domainname, domaincanonicalname,
samaccountname, displayname, dnid, isdeleted, distinguishedname, cn,
whencreated, whenchanged, lastlogontimestamp, accountexpires, department,
pwdlastsetdate, accountdisable, passwd_notreqd, passwd_cant_change,
dont_expire_password, password_expired | Format-Table -Auto
</code>```

Here are the fields that come out blank;

```<code>domainname = {}       domaincanonicalnam = {} dnid = {} isselected =
</code>```

Everything else has data in the tables.

答:
Try the following - a couple of the properties are missing as I have no idea what you are referring to e.g. "dnid"   </p>

```<code>Import-Module ActiveDirectory

Get-ADUser -Filter * -Properties * | select canonicalname,
samaccountname, displayname,  isdeleted, distinguishedname, cn,
created, Modified, lastlogontimestamp, accountexpires, department,
PasswordLastSet, Enabled, PasswordNotRequired,
PasswordNeverExpires, PasswordExpired | Format-Table
</code>```

Body:
I’m trying to write a PowerShell script to pull users information out of Active Directory and export it to a csv file. I have one partly working but for some reasons some fields in the tables come back blank even though there is data to be extracted? Anyone know why this happening ?

Import-Module ActiveDirectory

Get-ADUser -Filter * -Properties * | select domainname, domaincanonicalname,
samaccountname, displayname, dnid, isdeleted, distinguishedname, cn,
whencreated, whenchanged, lastlogontimestamp, accountexpires, department,
pwdlastsetdate, accountdisable, passwd_notreqd, passwd_cant_change,
dont_expire_password, password_expired | Format-Table -Auto

Here are the fields that come out blank;

domainname = {}       domaincanonicalnam = {} dnid = {} isselected =

Everything else has data in the tables.

Body:
Try the following - a couple of the properties are missing as I have no idea what you are referring to e.g. "dnid"

Import-Module ActiveDirectory

Get-ADUser -Filter * -Properties * | select canonicalname,
samaccountname, displayname,  isdeleted, distinguishedname, cn,
created, Modified, lastlogontimestamp, accountexpires, department,
PasswordLastSet, Enabled, PasswordNotRequired,
PasswordNeverExpires, PasswordExpired | Format-Table


问:
Why this setState is not a function in ComponenDidMount?
I am trying to fetch ordered data from Firebase and set it to state highscoreArray but it gives error "undefined is not a function (evaluating 'this.setState({ highscoreArray:sortedHighscores })')</p>

```<code>    componentDidMount() {
    const reference = database.ref("highscores");

    // Pushing sorted data to highscoreArray.
    reference.orderByChild("highscore").limitToLast(3).on("value", function (snapshot) {
        sortedHighscores = [];
        snapshot.forEach(function (child) {
            sortedHighscores.push({
                "username": child.val().username,
                "score": child.val().highscore
            });
        });
        sortedHighscores = sortedHighscores.reverse();
        console.log("sortedh", sortedHighscores); // fetch success
        this.setState({highscoreArray: sortedHighscores}); // gives error
    });
}
</code>```

答:
One of the major advantages of arrow functions is that it does not have it's own this value. It's this is lexically bound to the enclosing scope. </p>

```<code>class Logger {
  dumpData(data) {
    var _this = this;

    // this dumps data to a file and get the name of the file via a callback
    dump(data, function (outputFile) {
      _this.latestLog = outputFile;
    });
  }
}
</code>```

<p>// using arrow functions</p>

```<code>class Logger {
  dumpData(data) {
    dump(data, outputFile => this.latestLog = outputFile);
  }
}
</code>```

Body:
I am trying to fetch ordered data from Firebase and set it to state highscoreArray but it gives error "undefined is not a function (evaluating 'this.setState({ highscoreArray:sortedHighscores })')

    componentDidMount() {
    const reference = database.ref("highscores");

    // Pushing sorted data to highscoreArray.
    reference.orderByChild("highscore").limitToLast(3).on("value", function (snapshot) {
        sortedHighscores = [];
        snapshot.forEach(function (child) {
            sortedHighscores.push({
                "username": child.val().username,
                "score": child.val().highscore
            });
        });
        sortedHighscores = sortedHighscores.reverse();
        console.log("sortedh", sortedHighscores); // fetch success
        this.setState({highscoreArray: sortedHighscores}); // gives error
    });
}

Body:
One of the major advantages of arrow functions is that it does not have it's own this value. It's this is lexically bound to the enclosing scope.

class Logger {
  dumpData(data) {
    var _this = this;

    // this dumps data to a file and get the name of the file via a callback
    dump(data, function (outputFile) {
      _this.latestLog = outputFile;
    });
  }
}

// using arrow functions

class Logger {
  dumpData(data) {
    dump(data, outputFile => this.latestLog = outputFile);
  }
}