问:
Making a bluetooth service that sends a signal to arduino bluetooth module
So I have been working with arduino for a while and now I've been trying to connect to the blue-tooth module with android studio. I was able to get the blue-tooth to connect but I'm having issues making the blue-tooth connection a service so that it can run even if the app is closed. Whenever I try to get the service to run on my phone, the app crashes as soon as i try to connect to blue-tooth module where as before when it was an activity, it worked perfectly. I've looked at a lot of links and guides on using services and blue-tooth but none of them do exactly what I want.

Below are some code snippets, but here is a link to the entire GitHub project

Blue-tooth activity that I got to work:

```<code>package edu.memphis.teamhack.smart_nightlight;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

public class BluetoothActivity extends AppCompatActivity {

    // GUI Components
    private TextView mBluetoothStatus;
    private TextView mReadBuffer;
    private Button mScanBtn;
    private Button mOffBtn;
    private Button mListPairedDevicesBtn;
    private Button mDiscoverBtn;
    private BluetoothAdapter mBTAdapter;
    private Set<BluetoothDevice> mPairedDevices;
    private ArrayAdapter<String> mBTArrayAdapter;
    private ListView mDevicesListView;
    private CheckBox mLED1;

    private final String TAG = MainActivity.class.getSimpleName();
    private Handler mHandler; // Our main handler that will receive callback notifications
    private ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
    private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path

    private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // "random" unique identifier

    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
    private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
    private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);

        mBluetoothStatus = (TextView)findViewById(R.id.bluetoothStatus);
        mReadBuffer = (TextView) findViewById(R.id.readBuffer);
        mScanBtn = (Button)findViewById(R.id.scan);
        mOffBtn = (Button)findViewById(R.id.off);
        mDiscoverBtn = (Button)findViewById(R.id.discover);
        mListPairedDevicesBtn = (Button)findViewById(R.id.PairedBtn);
        mLED1 = (CheckBox)findViewById(R.id.checkboxLED1);

        mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
        mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio

        mDevicesListView = (ListView)findViewById(R.id.devicesListView);
        mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
        mDevicesListView.setOnItemClickListener(mDeviceClickListener);

        // Ask for location permission if not already allowed
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);

        mHandler = new Handler(){
            public void handleMessage(android.os.Message msg){
                if(msg.what == MESSAGE_READ){
                    String readMessage = null;
                    try {
                        readMessage = new String((byte[]) msg.obj, "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    mReadBuffer.setText(readMessage);
                }

                if(msg.what == CONNECTING_STATUS){
                    if(msg.arg1 == 1)
                        mBluetoothStatus.setText("Connected to Device: " + (String)(msg.obj));
                    else
                        mBluetoothStatus.setText("Connection Failed");
                }
            }
        };

        if (mBTArrayAdapter == null) {
            // Device does not support Bluetooth
            mBluetoothStatus.setText("Status: Bluetooth not found");
            Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
        }
        else {
            mLED1.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    SharedPreferences settings = getSharedPreferences("MyPref",
                            Context.MODE_PRIVATE);
                    Integer myInt = settings.getInt("colorHex", 0);
                    if(mConnectedThread != null){ //First check to make sure thread created
                        mConnectedThread.write(myInt.toString());}
                }
            });

            mScanBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bluetoothOn(v);
                }
            });

            mOffBtn.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    bluetoothOff(v);
                }
            });

            mListPairedDevicesBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v){
                    listPairedDevices(v);
                }
            });

            mDiscoverBtn.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    discover(v);
                }
            });
        }
    }

    private void bluetoothOn(View view){
        if (!mBTAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            mBluetoothStatus.setText("Bluetooth enabled");
            Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();

        }
        else{
            Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

    // Enter here after user selects "yes" or "no" to enabling radio
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent Data){
        // Check which request we're responding to
        if (requestCode == REQUEST_ENABLE_BT) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // The user picked a contact.
                // The Intent's data Uri identifies which contact was selected.
                mBluetoothStatus.setText("Enabled");
            }
            else
                mBluetoothStatus.setText("Disabled");
        }
    }

    private void bluetoothOff(View view){
        mBTAdapter.disable(); // turn off
        mBluetoothStatus.setText("Bluetooth disabled");
        Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
    }

    private void discover(View view){
        // Check if the device is already discovering
        if(mBTAdapter.isDiscovering()){
            mBTAdapter.cancelDiscovery();
            Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
        }
        else{
            if(mBTAdapter.isEnabled()) {
                mBTArrayAdapter.clear(); // clear items
                mBTAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
                registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
            }
            else{
                Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
            }
        }
    }

    final BroadcastReceiver blReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // add the name to the list
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mBTArrayAdapter.notifyDataSetChanged();
            }
        }
    };

    private void listPairedDevices(View view){
        mPairedDevices = mBTAdapter.getBondedDevices();
        if(mBTAdapter.isEnabled()) {
            // put it's one to the adapter
            for (BluetoothDevice device : mPairedDevices)
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());

            Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
        }
        else
            Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
    }

    private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {

            if(!mBTAdapter.isEnabled()) {
                Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
                return;
            }

            mBluetoothStatus.setText("Connecting...");
            // Get the device MAC address, which is the last 17 chars in the View
            String info = ((TextView) v).getText().toString();
            final String address = info.substring(info.length() - 17);
            final String name = info.substring(0,info.length() - 17);

            // Spawn a new thread to avoid blocking the GUI one
            new Thread()
            {
                public void run() {
                    boolean fail = false;

                    BluetoothDevice device = mBTAdapter.getRemoteDevice(address);

                    try {
                        mBTSocket = createBluetoothSocket(device);
                    } catch (IOException e) {
                        fail = true;
                        Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                    }
                    // Establish the Bluetooth socket connection.
                    try {
                        mBTSocket.connect();
                    } catch (IOException e) {
                        try {
                            fail = true;
                            mBTSocket.close();
                            mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
                                    .sendToTarget();
                        } catch (IOException e2) {
                            //insert code to deal with this
                            Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                    if(fail == false) {

                        mConnectedThread = new ConnectedThread(mBTSocket);
                        mConnectedThread.start();

                        mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
                                .sendToTarget();
                    }
                }
            }.start();
        }
    };

    private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
        try {
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
            return (BluetoothSocket) m.invoke(device, BTMODULEUUID);
        } catch (Exception e) {
            Log.e(TAG, "Could not create Insecure RFComm Connection",e);
        }
        return  device.createRfcommSocketToServiceRecord(BTMODULEUUID);
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()
            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.available();
                    if(bytes != 0) {
                        buffer = new byte[1024];
                        SystemClock.sleep(100); //pause and wait for rest of data. Adjust this depending on your sending speed.
                        bytes = mmInStream.available(); // how many bytes are ready to be read?
                        bytes = mmInStream.read(buffer, 0, bytes); // record how many bytes we actually read
                        mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget(); // Send the obtained bytes to the UI activity
                    }
                } catch (IOException e) {
                    e.printStackTrace();

                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(String input) {
            byte[] bytes = input.getBytes();           //converts entered String into bytes
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }
</code>```

Here is the Bluetooth Service I'm working on:

```<code>package edu.memphis.teamhack.smart_nightlight;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;

public class BluetoothCommService extends Service {

    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
    private BluetoothAdapter mBTAdapter;
    private ArrayAdapter<String> mBTArrayAdapter;

    public BluetoothCommService() {
    }

    public void onCreate(Bundle savedInstanceState){
        //super.onCreate(savedInstanceState);
        mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
        mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);

    }
   @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    void bluetoothOn(View view){
        if (!mBTAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            //startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

            //GUI
            //mBluetoothStatus.setText("Bluetooth enabled");
            // Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();

        }
        else{
            //Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

    private void bluetoothOff(View view){
        mBTAdapter.disable(); // turn off

        //GUI
        //mBluetoothStatus.setText("Bluetooth disabled");
        //Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
    }
    private void discover(View view){
        // Check if the device is already discovering
        if(mBTAdapter.isDiscovering()){
            mBTAdapter.cancelDiscovery();
            Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
        }
        else{
            if(mBTAdapter.isEnabled()) {
                mBTArrayAdapter.clear(); // clear items
                mBTAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
                registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
            }
            else{
                Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
            }
        }
    }
    final BroadcastReceiver blReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // add the name to the list
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mBTArrayAdapter.notifyDataSetChanged();
            }
        }
    };
}
</code>```

Feel free to ask any questions.

答:
Try this instructables, i did it by reffering to this tutorial

http://www.instructables.com/id/Android-Bluetooth-Control-LED-Part-2/

for more idea, also refer to

https://www.intorobotics.com/how-to-develop-simple-bluetooth-android-application-to-control-a-robot-remote/

Body:
So I have been working with arduino for a while and now I've been trying to connect to the blue-tooth module with android studio. I was able to get the blue-tooth to connect but I'm having issues making the blue-tooth connection a service so that it can run even if the app is closed. Whenever I try to get the service to run on my phone, the app crashes as soon as i try to connect to blue-tooth module where as before when it was an activity, it worked perfectly. I've looked at a lot of links and guides on using services and blue-tooth but none of them do exactly what I want.

Below are some code snippets, but here is a link to the entire GitHub project

Blue-tooth activity that I got to work:

package edu.memphis.teamhack.smart_nightlight;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

public class BluetoothActivity extends AppCompatActivity {

    // GUI Components
    private TextView mBluetoothStatus;
    private TextView mReadBuffer;
    private Button mScanBtn;
    private Button mOffBtn;
    private Button mListPairedDevicesBtn;
    private Button mDiscoverBtn;
    private BluetoothAdapter mBTAdapter;
    private Set<BluetoothDevice> mPairedDevices;
    private ArrayAdapter<String> mBTArrayAdapter;
    private ListView mDevicesListView;
    private CheckBox mLED1;

    private final String TAG = MainActivity.class.getSimpleName();
    private Handler mHandler; // Our main handler that will receive callback notifications
    private ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
    private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path

    private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // "random" unique identifier

    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
    private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
    private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);

        mBluetoothStatus = (TextView)findViewById(R.id.bluetoothStatus);
        mReadBuffer = (TextView) findViewById(R.id.readBuffer);
        mScanBtn = (Button)findViewById(R.id.scan);
        mOffBtn = (Button)findViewById(R.id.off);
        mDiscoverBtn = (Button)findViewById(R.id.discover);
        mListPairedDevicesBtn = (Button)findViewById(R.id.PairedBtn);
        mLED1 = (CheckBox)findViewById(R.id.checkboxLED1);

        mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
        mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio

        mDevicesListView = (ListView)findViewById(R.id.devicesListView);
        mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
        mDevicesListView.setOnItemClickListener(mDeviceClickListener);

        // Ask for location permission if not already allowed
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);

        mHandler = new Handler(){
            public void handleMessage(android.os.Message msg){
                if(msg.what == MESSAGE_READ){
                    String readMessage = null;
                    try {
                        readMessage = new String((byte[]) msg.obj, "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    mReadBuffer.setText(readMessage);
                }

                if(msg.what == CONNECTING_STATUS){
                    if(msg.arg1 == 1)
                        mBluetoothStatus.setText("Connected to Device: " + (String)(msg.obj));
                    else
                        mBluetoothStatus.setText("Connection Failed");
                }
            }
        };

        if (mBTArrayAdapter == null) {
            // Device does not support Bluetooth
            mBluetoothStatus.setText("Status: Bluetooth not found");
            Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
        }
        else {
            mLED1.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    SharedPreferences settings = getSharedPreferences("MyPref",
                            Context.MODE_PRIVATE);
                    Integer myInt = settings.getInt("colorHex", 0);
                    if(mConnectedThread != null){ //First check to make sure thread created
                        mConnectedThread.write(myInt.toString());}
                }
            });

            mScanBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bluetoothOn(v);
                }
            });

            mOffBtn.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    bluetoothOff(v);
                }
            });

            mListPairedDevicesBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v){
                    listPairedDevices(v);
                }
            });

            mDiscoverBtn.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    discover(v);
                }
            });
        }
    }

    private void bluetoothOn(View view){
        if (!mBTAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            mBluetoothStatus.setText("Bluetooth enabled");
            Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();

        }
        else{
            Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

    // Enter here after user selects "yes" or "no" to enabling radio
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent Data){
        // Check which request we're responding to
        if (requestCode == REQUEST_ENABLE_BT) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // The user picked a contact.
                // The Intent's data Uri identifies which contact was selected.
                mBluetoothStatus.setText("Enabled");
            }
            else
                mBluetoothStatus.setText("Disabled");
        }
    }

    private void bluetoothOff(View view){
        mBTAdapter.disable(); // turn off
        mBluetoothStatus.setText("Bluetooth disabled");
        Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
    }

    private void discover(View view){
        // Check if the device is already discovering
        if(mBTAdapter.isDiscovering()){
            mBTAdapter.cancelDiscovery();
            Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
        }
        else{
            if(mBTAdapter.isEnabled()) {
                mBTArrayAdapter.clear(); // clear items
                mBTAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
                registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
            }
            else{
                Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
            }
        }
    }

    final BroadcastReceiver blReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // add the name to the list
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mBTArrayAdapter.notifyDataSetChanged();
            }
        }
    };

    private void listPairedDevices(View view){
        mPairedDevices = mBTAdapter.getBondedDevices();
        if(mBTAdapter.isEnabled()) {
            // put it's one to the adapter
            for (BluetoothDevice device : mPairedDevices)
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());

            Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
        }
        else
            Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
    }

    private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {

            if(!mBTAdapter.isEnabled()) {
                Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
                return;
            }

            mBluetoothStatus.setText("Connecting...");
            // Get the device MAC address, which is the last 17 chars in the View
            String info = ((TextView) v).getText().toString();
            final String address = info.substring(info.length() - 17);
            final String name = info.substring(0,info.length() - 17);

            // Spawn a new thread to avoid blocking the GUI one
            new Thread()
            {
                public void run() {
                    boolean fail = false;

                    BluetoothDevice device = mBTAdapter.getRemoteDevice(address);

                    try {
                        mBTSocket = createBluetoothSocket(device);
                    } catch (IOException e) {
                        fail = true;
                        Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                    }
                    // Establish the Bluetooth socket connection.
                    try {
                        mBTSocket.connect();
                    } catch (IOException e) {
                        try {
                            fail = true;
                            mBTSocket.close();
                            mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
                                    .sendToTarget();
                        } catch (IOException e2) {
                            //insert code to deal with this
                            Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                    if(fail == false) {

                        mConnectedThread = new ConnectedThread(mBTSocket);
                        mConnectedThread.start();

                        mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
                                .sendToTarget();
                    }
                }
            }.start();
        }
    };

    private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
        try {
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
            return (BluetoothSocket) m.invoke(device, BTMODULEUUID);
        } catch (Exception e) {
            Log.e(TAG, "Could not create Insecure RFComm Connection",e);
        }
        return  device.createRfcommSocketToServiceRecord(BTMODULEUUID);
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()
            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.available();
                    if(bytes != 0) {
                        buffer = new byte[1024];
                        SystemClock.sleep(100); //pause and wait for rest of data. Adjust this depending on your sending speed.
                        bytes = mmInStream.available(); // how many bytes are ready to be read?
                        bytes = mmInStream.read(buffer, 0, bytes); // record how many bytes we actually read
                        mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget(); // Send the obtained bytes to the UI activity
                    }
                } catch (IOException e) {
                    e.printStackTrace();

                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(String input) {
            byte[] bytes = input.getBytes();           //converts entered String into bytes
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

Here is the Bluetooth Service I'm working on:

package edu.memphis.teamhack.smart_nightlight;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;

public class BluetoothCommService extends Service {

    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
    private BluetoothAdapter mBTAdapter;
    private ArrayAdapter<String> mBTArrayAdapter;

    public BluetoothCommService() {
    }

    public void onCreate(Bundle savedInstanceState){
        //super.onCreate(savedInstanceState);
        mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
        mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);

    }
   @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    void bluetoothOn(View view){
        if (!mBTAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            //startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

            //GUI
            //mBluetoothStatus.setText("Bluetooth enabled");
            // Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();

        }
        else{
            //Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

    private void bluetoothOff(View view){
        mBTAdapter.disable(); // turn off

        //GUI
        //mBluetoothStatus.setText("Bluetooth disabled");
        //Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
    }
    private void discover(View view){
        // Check if the device is already discovering
        if(mBTAdapter.isDiscovering()){
            mBTAdapter.cancelDiscovery();
            Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
        }
        else{
            if(mBTAdapter.isEnabled()) {
                mBTArrayAdapter.clear(); // clear items
                mBTAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
                registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
            }
            else{
                Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
            }
        }
    }
    final BroadcastReceiver blReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // add the name to the list
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mBTArrayAdapter.notifyDataSetChanged();
            }
        }
    };
}

Feel free to ask any questions.


来源: stackexchange

问:
Using OpenFeint to get current Achievement progression
So I'm setting my achievement like so:

```<code>int currentPercentage = ... // Work out current percentage of progression to update too
[[OFAchievement achievement: ACHIEVEMENT_ID] updateProgressionComplete: currentPercentage andShowNotification: YES];
</code>```

But is there anyway to get the currentProgression from the OF servers?

This would be useful to know so I can update the progression by a percentage rather than storing values locally to do this.

Thanks

答:
you can do this by calling :</p>

```<code>[OFAchievementService getPercentComplete:achievementId forUser:[OpenFeint lastLoggedInUserId]];
</code>```

ContentLicense: CC BY-SA 2.5

Body:
So I'm setting my achievement like so:

int currentPercentage = ... // Work out current percentage of progression to update too
[[OFAchievement achievement: ACHIEVEMENT_ID] updateProgressionComplete: currentPercentage andShowNotification: YES];

But is there anyway to get the currentProgression from the OF servers?

This would be useful to know so I can update the progression by a percentage rather than storing values locally to do this.

Thanks

Body:
you can do this by calling :

[OFAchievementService getPercentComplete:achievementId forUser:[OpenFeint lastLoggedInUserId]];


问:
Azure Machine Learning Write output to Azure SQL Database
I am using Azure Machine Learning to clustering data.

The input data is from an Azure SQL Database, and it works fine.
At the end of everything I want to write the output to a table in the same Azure SQL Database, but I get this error:

```<code>Error: Error 1000: AFx Library library exception:
Sql encountered an error: Login failed for user
</code>```

Anyone any idea?
Thank you very much!

答:
Please follow the instructions and examine the examples provided here to properly use the Export Data module to save the data of ML to Azure SQL Database.

How to Export Data to an Azure SQL Database

Add the Export Data module to your experiment. You can find this module in the Data Input and Output group in the experiment items list in Azure Machine Learning Studio.

Connect it to the module that produces the data that you want to export to Azure SQL DB.

For Data destination, select Azure SQL Database. This option supports Azure SQL Data Warehouse as well.

Set the following options specific to Azure SQL Database or Azure SQL Data Warehouse.

Database server name

Type the server name that is generated by Azure. Typically it has the form    <generated_identifier>.database.windows.net.

Database name

Type the name of a database on the server you just specified.The database must already exist; the Export Data cannot create it.

Server user account name

Type the user name of an account that has access permissions for the database.

Server user account password

Provide the password for the specified user account.

Comma-separated list of columns to be saved

Type the names of the columns in the experiment that you want to write to the database.

Data table name

Type the name of the table where data will be stored.

For Azure SQL Database, if the table does not exist, it will be created. For Azure SQL Data Warehouse, the table must already exist and have the correct schema, so be sure to create it in advance.

Comma-separated list of datatable columns

Type the names of the columns as you wish them to appear in the destination table. The columns should correspond in order with the column names that you list in Comma-separated list of columns to be saved.

if you are writing to Azure SQL Data Warehouse, the columns names must match those already in the destination table schema.

Number of rows written per SQL Azure operation

Indicate how many rows should be written to the destination table in each batch. By default, the value is set to 50, which is the default batch size for Azure SQL Database. However, you should increase this value if you have a large number of rows to write.

TIP:

For Azure SQL Data Warehouse, we recommend that you set this value to 1. If you use a larger batch size, the size of the command string that is sent to Azure SQL Data Warehouse can exceed the allowed string length, causing an error.

If you don't want to write new results each time you run the experiment, select the Use cached results option. If there are no other changes to module parameters, the experiment will write the data the first time the module is run, and thereafter not perform writes.

However, a write will always be performed if any parameters have been changed in Export Data that would change the results.

Run the experiment.

ContentLicense: CC BY-SA 3.0

Body:
I am using Azure Machine Learning to clustering data.

The input data is from an Azure SQL Database, and it works fine.
At the end of everything I want to write the output to a table in the same Azure SQL Database, but I get this error:

Error: Error 1000: AFx Library library exception:
Sql encountered an error: Login failed for user

Anyone any idea?
Thank you very much!


问:
Spaces in directory path python
I'm a noob at coding Python and I've run into something that no amount of Googling is helping me with.
I'm trying to write a simple Directory listing tool and I cannot seem to deal with Spaces in the directory name in OSX.
My code is as follows:

```<code>def listdir_nohidden(path):
    import os
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

def MACListDirNoExt():
import os
MACu = PCu = os.environ['USER']
MACDIR = '/Users/'+MACu+'/Desktop//'
while True:
    PATH = raw_input("What is the PATH you would like to list?")
    if os.path.exists(PATH):
        break
    else:
        print "That PATH cannot be found or does not exist."
NAME = raw_input ("What would you like to name your file?")
DIR = listdir_nohidden(PATH)
DIR = [os.path.splitext(x)[0] for x in DIR]
f = open(''+MACDIR+NAME+'.txt', "w")
for file in DIR:
    f.write(str(file) + "\n")
f.close()
print "The file %s.txt has been written to your Desktop" % (NAME)
raw_input ("Press Enter to exit")
</code>```

For ease of trouble shooting though I think this could essentially be boiled down to:

```<code>import os
PATH = raw_input("What is the PATH you would like to list")
os.listdir(PATH)
</code>```

When supplying a directory path that contains spaces /Volumes/Disk/this is a folder it returns

"No such file or Directory: '/Volumes/Disk/this\\ is\\ a\\ folder/'

It looks like its escaping the escape...?

答:
I just ran into this, and I'm guessing that what I was hastily doing is also what you were trying. In a way, both @zwol and @trans1st0r are right.

Your boiled down program has nothing wrong with it. I believe that if you put in the input /Volumes/Disk/this is a folder, everything would work fine.

However, what you may have been doing (or at least, what I was doing) is dragging a folder from the Finder to the Terminal. When you drag to the Terminal, the OS automatically escapes spaces for you, so what ends up getting typed into the Terminal is /Volumes/Disk/this\ is\ a\ folder.

So either you can make sure that what you "type in" doesn't have those backslashes, or you can use @trans1st0r's suggestion as a way to support the dragging functionality, though the latter will cause issues in the edge case that your desired path actually has backslashes in it.

Title: Spaces in directory path python

Body:
I'm a noob at coding Python and I've run into something that no amount of Googling is helping me with.
I'm trying to write a simple Directory listing tool and I cannot seem to deal with Spaces in the directory name in OSX.
My code is as follows:

def listdir_nohidden(path):
    import os
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

def MACListDirNoExt():
import os
MACu = PCu = os.environ['USER']
MACDIR = '/Users/'+MACu+'/Desktop//'
while True:
    PATH = raw_input("What is the PATH you would like to list?")
    if os.path.exists(PATH):
        break
    else:
        print "That PATH cannot be found or does not exist."
NAME = raw_input ("What would you like to name your file?")
DIR = listdir_nohidden(PATH)
DIR = [os.path.splitext(x)[0] for x in DIR]
f = open(''+MACDIR+NAME+'.txt', "w")
for file in DIR:
    f.write(str(file) + "\n")
f.close()
print "The file %s.txt has been written to your Desktop" % (NAME)
raw_input ("Press Enter to exit")

For ease of trouble shooting though I think this could essentially be boiled down to:

import os
PATH = raw_input("What is the PATH you would like to list")
os.listdir(PATH)

When supplying a directory path that contains spaces /Volumes/Disk/this is a folder it returns

"No such file or Directory: '/Volumes/Disk/this\\ is\\ a\\ folder/'

It looks like its escaping the escape...?


问:
Browser Resize and Chrome Inspect shows different Layouts , how to fix this issue using media query?
I have add css and media queries for width of screens thats ranging from 320 to a max width above 1440 , When i take the webpage using chromes inspect everything shows fine , but when i resize the browser the page layouts breaks apart for the same size , for example if i resize the browser to 992 x 442 as browser resize , the layout breaks , but if i use the same resolution while inspecting in chrome the page layout is prefect.

What is happening over here ? and can i fix this issue?

```<code>@media only screen
and (min-device-width: 769px)
and (max-device-width: 991px) {
    .fix-feedback{height: 80px;}
    .col-f-lt {
        width: 14% !important;
        height: 80px;
    }
    .col-f-lt p{line-height: 53px;}
    .col-f-rt {
        width: 83% !important;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}

@media only screen
and (min-device-width: 768px)
and (max-device-width: 1199px) {

    .navbar-nav>li {
        display: inline-block;
        float: inherit;
    }
    .navbar-nav {
        text-align: center;
        float: none;
        margin: 6px auto;
    }
}

@media (width: 768px){
    .col-f-lt{  width: 16%;  float: left;  background: #13929e;  padding: 33px 20px;  margin-right: 10px; }
    .col-f-rt {  margin: 2px 0 0;  width: 80%;  float: left;  padding: 10px 0 15px;    }
    .sav-btnn{ display: inline-block; width: 100%;}
    .sav-btnn a{ display: table; margin: 0 auto; float: inherit !important;   margin-bottom: 10px;}
    .table-responsive {
        width: 100%;
        margin-bottom: 15px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        -ms-overflow-style: -ms-autohiding-scrollbar;
        border: 1px solid #ddd;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}
</code>```

答:
First off, min-device-width and max-device-width is deprecated, use min-width and max-width.

The problem here is that your first query start at 769px and ends at 991px, then your second start at 768px, even before the first one started, so when the screen is between 769px and 991px both will be applied.

If they are to be applied one after the other, change the seconds min-width to 992px

Based on a comment, change the 3rd to @media only screen and (min-width: 480px) and (max-width: 768px){.

Note, when both min-width/max-width are used like this, it won't matter their position in the CSS, though it is recommended to order them from low to high, to make it easier to follow what happens to who and when.

```<code>@media only screen
and (min-width: 769px)
and (max-width: 991px) {
    .fix-feedback{height: 80px;}
    .col-f-lt {
        width: 14% !important;
        height: 80px;
    }
    .col-f-lt p{line-height: 53px;}
    .col-f-rt {
        width: 83% !important;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}

@media only screen
and (min-width: 992px)
and (max-width: 1199px) {

    .navbar-nav>li {
        display: inline-block;
        float: inherit;
    }
    .navbar-nav {
        text-align: center;
        float: none;
        margin: 6px auto;
    }
}

@media only screen
and (min-width: 480px)
and (max-width: 768px){
    .col-f-lt{  width: 16%;  float: left;  background: #13929e;  padding: 33px 20px;  margin-right: 10px; }
    .col-f-rt {  margin: 2px 0 0;  width: 80%;  float: left;  padding: 10px 0 15px;    }
    .sav-btnn{ display: inline-block; width: 100%;}
    .sav-btnn a{ display: table; margin: 0 auto; float: inherit !important;   margin-bottom: 10px;}
    .table-responsive {
        width: 100%;
        margin-bottom: 15px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        -ms-overflow-style: -ms-autohiding-scrollbar;
        border: 1px solid #ddd;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}
</code>```

Body:
I have add css and media queries for width of screens thats ranging from 320 to a max width above 1440 , When i take the webpage using chromes inspect everything shows fine , but when i resize the browser the page layouts breaks apart for the same size , for example if i resize the browser to 992 x 442 as browser resize , the layout breaks , but if i use the same resolution while inspecting in chrome the page layout is prefect.

What is happening over here ? and can i fix this issue?

@media only screen
and (min-device-width: 769px)
and (max-device-width: 991px) {
    .fix-feedback{height: 80px;}
    .col-f-lt {
        width: 14% !important;
        height: 80px;
    }
    .col-f-lt p{line-height: 53px;}
    .col-f-rt {
        width: 83% !important;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}

@media only screen
and (min-device-width: 768px)
and (max-device-width: 1199px) {

    .navbar-nav>li {
        display: inline-block;
        float: inherit;
    }
    .navbar-nav {
        text-align: center;
        float: none;
        margin: 6px auto;
    }
}

@media (width: 768px){
    .col-f-lt{  width: 16%;  float: left;  background: #13929e;  padding: 33px 20px;  margin-right: 10px; }
    .col-f-rt {  margin: 2px 0 0;  width: 80%;  float: left;  padding: 10px 0 15px;    }
    .sav-btnn{ display: inline-block; width: 100%;}
    .sav-btnn a{ display: table; margin: 0 auto; float: inherit !important;   margin-bottom: 10px;}
    .table-responsive {
        width: 100%;
        margin-bottom: 15px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        -ms-overflow-style: -ms-autohiding-scrollbar;
        border: 1px solid #ddd;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}

Body:
First off, min-device-width and max-device-width is deprecated, use min-width and max-width.

The problem here is that your first query start at 769px and ends at 991px, then your second start at 768px, even before the first one started, so when the screen is between 769px and 991px both will be applied.

If they are to be applied one after the other, change the seconds min-width to 992px

Based on a comment, change the 3rd to @media only screen and (min-width: 480px) and (max-width: 768px){.

Note, when both min-width/max-width are used like this, it won't matter their position in the CSS, though it is recommended to order them from low to high, to make it easier to follow what happens to who and when.

@media only screen
and (min-width: 769px)
and (max-width: 991px) {
    .fix-feedback{height: 80px;}
    .col-f-lt {
        width: 14% !important;
        height: 80px;
    }
    .col-f-lt p{line-height: 53px;}
    .col-f-rt {
        width: 83% !important;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}

@media only screen
and (min-width: 992px)
and (max-width: 1199px) {

    .navbar-nav>li {
        display: inline-block;
        float: inherit;
    }
    .navbar-nav {
        text-align: center;
        float: none;
        margin: 6px auto;
    }
}

@media only screen
and (min-width: 480px)
and (max-width: 768px){
    .col-f-lt{  width: 16%;  float: left;  background: #13929e;  padding: 33px 20px;  margin-right: 10px; }
    .col-f-rt {  margin: 2px 0 0;  width: 80%;  float: left;  padding: 10px 0 15px;    }
    .sav-btnn{ display: inline-block; width: 100%;}
    .sav-btnn a{ display: table; margin: 0 auto; float: inherit !important;   margin-bottom: 10px;}
    .table-responsive {
        width: 100%;
        margin-bottom: 15px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        -ms-overflow-style: -ms-autohiding-scrollbar;
        border: 1px solid #ddd;
    }
    .btn-send-fb {
        margin-top: 1px;
        display: inline-block;
    }
}


问:
Cytoscape.js – Unable to display a graph fitting to a collection
I've got a problem with displaying graph using Cytoscape.js. I want to display graph which fits to the viewport, let's look at fiddle. As you can see, I'm using also React. The fiddle version of the graph works well, however in my personal project, when I'll display node's labels, it breaks. Nodes are moved to the bottom of viewport. Also when I'll set

```<code>'text-valign': 'center'
</code>```

to the node's labels, they are displayed below nodes. If I remove node's labels, it works ... but with labels no. What should I do? Where should I look for an error?

答:
css definiton

```<code>body > div { height: 100%; }
</code>```

is responsible for this bug

Body:
I've got a problem with displaying graph using Cytoscape.js. I want to display graph which fits to the viewport, let's look at fiddle. As you can see, I'm using also React. The fiddle version of the graph works well, however in my personal project, when I'll display node's labels, it breaks. Nodes are moved to the bottom of viewport. Also when I'll set

'text-valign': 'center'

to the node's labels, they are displayed below nodes. If I remove node's labels, it works ... but with labels no. What should I do? Where should I look for an error?

Body:
css definiton

body > div { height: 100%; }

is responsible for this bug


问:
Refactoring out default Asp.Net MVC helpers to their own file
I am trying to re-factor the helpers that come in the controllers of a default Asp.Net Core web application, into their own ControllerHelper class. These methods are in each controller and that doesn't meet the DRY principles. Here are the methods.

```<code>  #region Helpers

    private void AddErrors(IdentityResult result)
    {
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

   public static IActionResult RedirectToLocal(string returnUrl,
        IUrlHelper url, RedirectResult redirect)
    {
        if (url.IsLocalUrl(returnUrl))
        {
            //this expects a method name off redirect?
            return redirect(returnUrl);
        }
        else
        {
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }
    }
</code>```

ModelState is in the Microsoft.AspNetCore.Mvc.ModelBinding namespace

I would have to pass the ModelStateDictionary from the controller to the method, but am not sure how to do that. I can seem to find the ModelStateDictionary in the controller to pass to the method.

How do I pass that ModelStateDictionary?

答:
ModelStateDictionary is a public property of ControllerBase abstract class, from which the Controller abstract class inherit and all your controllers inherit from this Controller class. So you can access it like this.ModelSate inside a controller to pass it to your custom helper method call.

Add a parameter to your method of type ModelStateDictionary

```<code>public void AddErrors(ModelStateDictionary modelState,IdentityResult result)
{
    foreach (var error in result.Errors)
    {
        modelState.AddModelError(string.Empty, error.Description);
    }
}
</code>```

and call it from controller class like, pass this.ModelState as the value for your first parameter

```<code>yourHelperClassObject.AddErrors(this.ModelState,identityResultObject);
</code>```

Body:
I am trying to re-factor the helpers that come in the controllers of a default Asp.Net Core web application, into their own ControllerHelper class. These methods are in each controller and that doesn't meet the DRY principles. Here are the methods.

  #region Helpers

    private void AddErrors(IdentityResult result)
    {
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

   public static IActionResult RedirectToLocal(string returnUrl,
        IUrlHelper url, RedirectResult redirect)
    {
        if (url.IsLocalUrl(returnUrl))
        {
            //this expects a method name off redirect?
            return redirect(returnUrl);
        }
        else
        {
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }
    }

ModelState is in the Microsoft.AspNetCore.Mvc.ModelBinding namespace

I would have to pass the ModelStateDictionary from the controller to the method, but am not sure how to do that. I can seem to find the ModelStateDictionary in the controller to pass to the method.

How do I pass that ModelStateDictionary?

Body:
ModelStateDictionary is a public property of ControllerBase abstract class, from which the Controller abstract class inherit and all your controllers inherit from this Controller class. So you can access it like this.ModelSate inside a controller to pass it to your custom helper method call.

Add a parameter to your method of type ModelStateDictionary

public void AddErrors(ModelStateDictionary modelState,IdentityResult result)
{
    foreach (var error in result.Errors)
    {
        modelState.AddModelError(string.Empty, error.Description);
    }
}

and call it from controller class like, pass this.ModelState as the value for your first parameter

yourHelperClassObject.AddErrors(this.ModelState,identityResultObject);


问:
App works on emulator but crashes on S8
I am using 2 images for my app's splash screen. The logo in my ImageView (src) and the background in the layout(:background) and although my app works fine on the emulator it crashes on my phone(S8). Below you can see my xml file responsible for my splashScreen and the exception. From what I understand one of those images(or both?) are considered too large for my phone's memory? Their dimension however, are :
logo(1305x641)
background(1688x1125).

Any ideas on how to fix this? I thought of providing different resolution versions of the images but I get lost in the process.

```<code><?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:gravity="center_horizontal|center_vertical"
    tools:context="com.spdesigns.funfacts.SplashScreen">

<ImageView
    android:id="@+id/logoImageView"
    android:layout_width="377dp"
    android:layout_height="293dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:src="@drawable/logo"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</code>```

Exception:

```<code>11-16 00:11:01.529 3688-3688/com.spdesigns.funfacts E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: com.spdesigns.funfacts, PID: 3688
                                                                  java.lang.RuntimeException: Canvas: trying to draw too large(120362760bytes) bitmap.
                                                                      at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
                                                                      at android.graphics.Canvas.drawBitmap(Canvas.java:1420)
                                                                      at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
                                                                      at android.widget.ImageView.onDraw(ImageView.java:1286)
                                                                      at android.view.View.draw(View.java:18394)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.draw(View.java:18397)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.draw(View.java:18397)
                                                                      at com.android.internal.policy.DecorView.draw(DecorView.java:967)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:722)
                                                                      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:728)
                                                                      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:836)
                                                                      at android.view.ViewRootImpl.draw(ViewRootImpl.java:3181)
                                                                      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2977)
                                                                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2565)
                                                                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1550)
                                                                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7189)
                                                                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
                                                                      at android.view.Choreographer.doCallbacks(Choreographer.java:734)
                                                                      at android.view.Choreographer.doFrame(Choreographer.java:670)
                                                                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
                                                                      at android.os.Handler.handleCallback(Handler.java:751)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                      at android.os.Looper.loop(Looper.java:154)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:6776)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
</code>```

答:
I fixed the issue.

For anyone facing the same problem, just move your bitmap inside the mipmap-xxxhdpi folder. Since the image is too large and since I placed it inside the drawables dir, android considers this as an mdpi image. This causes android to scale it even more thus crashing the app and throwing the OutOfMemory Exception. By putting it inside the mipmap-xxxhdpi folder, android just scales it down to the target res.

Title: App works on emulator but crashes on S8

Body:
I am using 2 images for my app's splash screen. The logo in my ImageView (src) and the background in the layout(:background) and although my app works fine on the emulator it crashes on my phone(S8). Below you can see my xml file responsible for my splashScreen and the exception. From what I understand one of those images(or both?) are considered too large for my phone's memory? Their dimension however, are :
logo(1305x641)
background(1688x1125).

Any ideas on how to fix this? I thought of providing different resolution versions of the images but I get lost in the process.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:gravity="center_horizontal|center_vertical"
    tools:context="com.spdesigns.funfacts.SplashScreen">

<ImageView
    android:id="@+id/logoImageView"
    android:layout_width="377dp"
    android:layout_height="293dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:src="@drawable/logo"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Exception:

11-16 00:11:01.529 3688-3688/com.spdesigns.funfacts E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: com.spdesigns.funfacts, PID: 3688
                                                                  java.lang.RuntimeException: Canvas: trying to draw too large(120362760bytes) bitmap.
                                                                      at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
                                                                      at android.graphics.Canvas.drawBitmap(Canvas.java:1420)
                                                                      at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
                                                                      at android.widget.ImageView.onDraw(ImageView.java:1286)
                                                                      at android.view.View.draw(View.java:18394)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.draw(View.java:18397)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17367)
                                                                      at android.view.View.draw(View.java:18156)
                                                                      at android.view.ViewGroup.drawChild(ViewGroup.java:3969)
                                                                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3755)
                                                                      at android.view.View.draw(View.java:18397)
                                                                      at com.android.internal.policy.DecorView.draw(DecorView.java:967)
                                                                      at android.view.View.updateDisplayListIfDirty(View.java:17372)
                                                                      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:722)
                                                                      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:728)
                                                                      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:836)
                                                                      at android.view.ViewRootImpl.draw(ViewRootImpl.java:3181)
                                                                      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2977)
                                                                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2565)
                                                                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1550)
                                                                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7189)
                                                                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
                                                                      at android.view.Choreographer.doCallbacks(Choreographer.java:734)
                                                                      at android.view.Choreographer.doFrame(Choreographer.java:670)
                                                                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
                                                                      at android.os.Handler.handleCallback(Handler.java:751)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                      at android.os.Looper.loop(Looper.java:154)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:6776)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)


问:
Why Either value is not discarded?
Have the following in ghci:

```<code>:m + Control.Monad.Error
let f x = Right x

Left 1.0 >> Right 1 >>= f
</code>```

gives

```<code>Left 1.0
</code>```

As I understand >> operator discards monadic result of the first argument,
but I see that here it is preserved. Could you please explain?

http://hackage.haskell.org/package/base-4.10.0.0/docs/src/Data.Either.html#Either

strangely, that link doesn't show how Either is implementing methods of Monad typeclass.

答:
As I understand[, the] >> operator discards monadic result of the first argument,

No, it does not. It more or less sees Left like a Maybe monad sees Nothing (the main difference is that Left also carries a value). Therefore it is sometimes used as an "advanced Maybe" that can for instance carry error messages.

(>>) :: Monad m => m a -> m b -> m b is a function such that f >> g is equivalent to f >>= \_ -> g and f >>= const g. This is the default implementation in the Monad typeclass.

It depends thus on how (>>=) :: Monad m => m a -> (a -> m b) -> m b is implemented.

Now for an Either it is implemented as:

```<code>instance Monad (Either e) where
    Left  l >>= _ = Left l
    Right r >>= k = k r
</code>```

So that means in case of a Left l on the left hand side, then the right hand side is ignored, in case the left hand side is a Right r, then k is applied to the value the Right constructor is wrapping.

So we can replace your query with (added brackets for clarity):

```<code>   Left 1.0 >> Right 1 >>= f
=  (>>) (Left 1.0) (Right 1 >>= f)
-> Left 1.0
</code>```

Semantically you can see an Either as a "more advanced" version of Maybe where Left takes the place of the Nothing. So from the moment someting is Left x, then it stays Left x. Regardless how we bind it.

Title: Why Either value is not discarded?

Body:
Have the following in ghci:

:m + Control.Monad.Error
let f x = Right x

Left 1.0 >> Right 1 >>= f

gives

Left 1.0

As I understand >> operator discards monadic result of the first argument,
but I see that here it is preserved. Could you please explain?

http://hackage.haskell.org/package/base-4.10.0.0/docs/src/Data.Either.html#Either

strangely, that link doesn't show how Either is implementing methods of Monad typeclass.

Body:
As I understand[, the] >> operator discards monadic result of the first argument,

No, it does not. It more or less sees Left like a Maybe monad sees Nothing (the main difference is that Left also carries a value). Therefore it is sometimes used as an "advanced Maybe" that can for instance carry error messages.

(>>) :: Monad m => m a -> m b -> m b is a function such that f >> g is equivalent to f >>= \_ -> g and f >>= const g. This is the default implementation in the Monad typeclass.

It depends thus on how (>>=) :: Monad m => m a -> (a -> m b) -> m b is implemented.

Now for an Either it is implemented as:

instance Monad (Either e) where
    Left  l >>= _ = Left l
    Right r >>= k = k r

So that means in case of a Left l on the left hand side, then the right hand side is ignored, in case the left hand side is a Right r, then k is applied to the value the Right constructor is wrapping.

So we can replace your query with (added brackets for clarity):

   Left 1.0 >> Right 1 >>= f
=  (>>) (Left 1.0) (Right 1 >>= f)
-> Left 1.0

Semantically you can see an Either as a "more advanced" version of Maybe where Left takes the place of the Nothing. So from the moment someting is Left x, then it stays Left x. Regardless how we bind it.


问:
Repeat rows in a pandas DataFrame based on column value
I have the following df:

```<code>code . role    . persons
123 .  Janitor . 3
123 .  Analyst . 2
321 .  Vallet  . 2
321 .  Auditor . 5
</code>```

The first line means that I have 3 persons with the role Janitors.
My problem is that I would need to have one line for each person. My df should look like this:

```<code>df:

code . role    . persons
123 .  Janitor . 3
123 .  Janitor . 3
123 .  Janitor . 3
123 .  Analyst . 2
123 .  Analyst . 2
321 .  Vallet  . 2
321 .  Vallet  . 2
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5
</code>```

How could I do that using pandas?

答:
Wen's solution is really nice and intuitive, however it will fail for duplicate rows by throwing ValueError: cannot reindex from a duplicate axis.

Here's an alternative which avoids this by calling repeat on df.values.

```<code>df

   code     role  persons
0   123  Janitor        3
1   123  Analyst        2
2   321   Vallet        2
3   321  Auditor        5

pd.DataFrame(df.values.repeat(df.persons, axis=0), columns=df.columns)

   code     role persons
0   123  Janitor       3
1   123  Janitor       3
2   123  Janitor       3
3   123  Analyst       2
4   123  Analyst       2
5   321   Vallet       2
6   321   Vallet       2
7   321  Auditor       5
8   321  Auditor       5
9   321  Auditor       5
10  321  Auditor       5
11  321  Auditor       5
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have the following df:

code . role    . persons
123 .  Janitor . 3
123 .  Analyst . 2
321 .  Vallet  . 2
321 .  Auditor . 5

The first line means that I have 3 persons with the role Janitors.
My problem is that I would need to have one line for each person. My df should look like this:

df:

code . role    . persons
123 .  Janitor . 3
123 .  Janitor . 3
123 .  Janitor . 3
123 .  Analyst . 2
123 .  Analyst . 2
321 .  Vallet  . 2
321 .  Vallet  . 2
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5
321 .  Auditor . 5

How could I do that using pandas?

Body:
Wen's solution is really nice and intuitive, however it will fail for duplicate rows by throwing ValueError: cannot reindex from a duplicate axis.

Here's an alternative which avoids this by calling repeat on df.values.

df

   code     role  persons
0   123  Janitor        3
1   123  Analyst        2
2   321   Vallet        2
3   321  Auditor        5

pd.DataFrame(df.values.repeat(df.persons, axis=0), columns=df.columns)

   code     role persons
0   123  Janitor       3
1   123  Janitor       3
2   123  Janitor       3
3   123  Analyst       2
4   123  Analyst       2
5   321   Vallet       2
6   321   Vallet       2
7   321  Auditor       5
8   321  Auditor       5
9   321  Auditor       5
10  321  Auditor       5
11  321  Auditor       5


问:
Need to create a Binary Search Tree with a custom comparator, can't seem to get it to work
I'm trying to create a Binary Search Tree using a TreeSet. I'm aware that by definition, a set does not contain any duplicate entries. However, I am sure that if I create my own comparator, I can allow the TreeSet to take in duplicate entries. I've done so:

```<code>public class A3BSTree <E> implements Tree <E> {

    private TreeSet<E> tree;
    private LinkedList<E> arr1;
    private MyComparator comp;

    public A3BSTree(){
        tree = new TreeSet<>(comp);
    }

    ...
    ...
    ...

    private class MyComparator implements Comparator<E> {
        @SuppressWarnings("unchecked")
        @Override
        public int compare(E e1, E e2) {
            if (((A3BSTree<E>.MyComparator) e1).compareTo(e2) < 0) {
                return -1;
            }
            else if (e1.equals(e2)) {
                return 0;
            }
            else {
                return 1;
            }
        }

        public int compareTo(E e) {
            return this.compareTo(e);
        }
    }

}
</code>```

I don't want the answer, I just need an explanation on why the TreeSet still won't take in duplicates. I just need to be steered in the right direction. Could the problem be that I cannot create a Comparator with generics?

答:
java.util.TreeSet add() method

java.util.TreeSet class uses the add method to add elements into the Set. This method does not allow duplicates. It detects duplicates using the equals() method as mentioned in Javadoc.

public boolean add(E e)
  Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

Current comparator implementation

As per your Comparator implementation, you expect the equals method to identify duplicates (probably you have overridden it?).

```<code>} else if (e1.equals(e2)) {
    return 0;
}
</code>```

If that is the case, I believe the behavior of TreeSet is correct in rejecting the duplicates based on the equals() method.

On the other hand, may be it is better to use Comparable approach rather than Comparator here as that allows objects to be comparable with its own instances (difference is explained here).

Body:
I'm trying to create a Binary Search Tree using a TreeSet. I'm aware that by definition, a set does not contain any duplicate entries. However, I am sure that if I create my own comparator, I can allow the TreeSet to take in duplicate entries. I've done so:

public class A3BSTree <E> implements Tree <E> {

    private TreeSet<E> tree;
    private LinkedList<E> arr1;
    private MyComparator comp;

    public A3BSTree(){
        tree = new TreeSet<>(comp);
    }

    ...
    ...
    ...

    private class MyComparator implements Comparator<E> {
        @SuppressWarnings("unchecked")
        @Override
        public int compare(E e1, E e2) {
            if (((A3BSTree<E>.MyComparator) e1).compareTo(e2) < 0) {
                return -1;
            }
            else if (e1.equals(e2)) {
                return 0;
            }
            else {
                return 1;
            }
        }

        public int compareTo(E e) {
            return this.compareTo(e);
        }
    }

}

I don't want the answer, I just need an explanation on why the TreeSet still won't take in duplicates. I just need to be steered in the right direction. Could the problem be that I cannot create a Comparator with generics?

Body:
java.util.TreeSet add() method

java.util.TreeSet class uses the add method to add elements into the Set. This method does not allow duplicates. It detects duplicates using the equals() method as mentioned in Javadoc.

public boolean add(E e)
  Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

Current comparator implementation

As per your Comparator implementation, you expect the equals method to identify duplicates (probably you have overridden it?).

} else if (e1.equals(e2)) {
    return 0;
}

If that is the case, I believe the behavior of TreeSet is correct in rejecting the duplicates based on the equals() method.

On the other hand, may be it is better to use Comparable approach rather than Comparator here as that allows objects to be comparable with its own instances (difference is explained here).


问:
Python Column Generation with AVERAGEIF equivalent to Excel
I've poured over StackOverflow and just cant figure this one out. I a data tables with unique letter# combinations, and im trying to get the "averageif" of those values into the second table. Basically, I am trying to generate the "AVG" column below.

```<code>Letter  Value      Unique   Avg
A1  7.97           A1       5.76
A1  3.56           A2       5.34
A2  3.16           A3       1.53
A2  9.09           B1       4.55
A2  0.64           B2       5.43
A2  8.48           B3       6.76
A3  1.53
B1  4.55
B2  7.36
B2  3.81
B2  7.30
B2  4.39
B2  4.30
B3  4.61
B3  8.91
</code>```

I've used pd.DataFrame to isolate the unique values in the first data set as a DataFrame of unique values, but I'm really having trouble. I have all the code to pull this data in from a csv, generate the unique values, etc but it doesnt seem relevant. Thanks for any advice, I just cant get passed this step.

Best

答:
Well, you can do that using groupby as follows:

```<code>df.groupby('Letter').mean()
</code>```

Body:
I've poured over StackOverflow and just cant figure this one out. I a data tables with unique letter# combinations, and im trying to get the "averageif" of those values into the second table. Basically, I am trying to generate the "AVG" column below.

Letter  Value      Unique   Avg
A1  7.97           A1       5.76
A1  3.56           A2       5.34
A2  3.16           A3       1.53
A2  9.09           B1       4.55
A2  0.64           B2       5.43
A2  8.48           B3       6.76
A3  1.53
B1  4.55
B2  7.36
B2  3.81
B2  7.30
B2  4.39
B2  4.30
B3  4.61
B3  8.91

I've used pd.DataFrame to isolate the unique values in the first data set as a DataFrame of unique values, but I'm really having trouble. I have all the code to pull this data in from a csv, generate the unique values, etc but it doesnt seem relevant. Thanks for any advice, I just cant get passed this step.

Best

Body:
Well, you can do that using groupby as follows:

df.groupby('Letter').mean()