问:
Android bluetooth printer app works fine in debug mode but doesn't work in release mode
I am writing an Android app to print text on a bluetooth thermal printer.
Here is the complete code

The app works fine in the debug mode but when I generate a signed APK and install it on the device, it does not respond at all.

I have tried different solution suggested on stackoverflow but non of them worked.

This is my main activity

```<code>import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.lvrenyang.io.IOCallBack;
import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private Handler mHandler; // Our main handler that will receive callback notifications
    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names

    private static String TAG = "MAIN_ACTIVITY";
    private Activity activity;
    private Button btnConnect;

    private String name = "MTP-II";
    private String mac_address = "02:15:44:31:49:05";

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

        //Get the activity
        this.activity = this;

        //Button from the XML view
        btnConnect = findViewById(R.id.btnConnect);

        //Start the Init Work Service Async task
        new InitWorkService().execute();

        //Set onClickListener for test print button
        btnConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    //Check if name and address are set
                    if (name != "null" && mac_address != "null" && mac_address.contains(":")) {

                        if (!WorkService.workThread.isConnected()) {
                            WorkService.workThread.connectBt(mac_address);
                            //Sleep for 3 seconds
                            try {
                                Thread.sleep(3000);
                            } catch (Exception e) {
                            }
                        }
                        //Check if connected
                        if (WorkService.workThread.isConnected()) {
                            //Collect data in background Thread
                            new PrintData().execute();
                        } else {
                            Toast.makeText(activity, Global.toast_notconnect, Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(activity, "Please setup printer first!", Toast.LENGTH_LONG).show();
                    }
                }
                catch(Exception e){
                    Log.e(TAG, e.getMessage(), e.fillInStackTrace());}
            }
        });
    }

    /**
     * Background Async Task
     * */
    private class InitWorkService extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                WorkService.cb = new IOCallBack() {
                    public void OnOpen() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONOPEN);
                            mHandler.sendMessage(msg);
                        }
                    }
                    public void OnClose() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONCLOSE);
                            mHandler.sendMessage(msg);
                        }
                    }
                };
            }
            catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){
            try {
                mHandler = new MHandler(MainActivity.this);
                WorkService.addHandler(mHandler);

                if (null == WorkService.workThread) {
                    Intent intent = new Intent(activity, WorkService.class);
                    startService(intent);
                }
            }
            catch (Exception e) {
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
                Toast.makeText(activity, "Unable to initiate the WorkService!", Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Background Async Task
     * */
    class PrintData extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                int nTextAlign=1;
                String text = "Test message!\r\n\r\n\r\n";
                String encoding = "UTF-8";
                byte[] hdrBytes = {0x1c, 0x26, 0x1b, 0x39, 0x01};

                Bundle dataAlign = new Bundle();
                Bundle dataTextOut = new Bundle();
                Bundle dataHdr = new Bundle();

                dataHdr.putByteArray(Global.BYTESPARA1, hdrBytes);
                dataHdr.putInt(Global.INTPARA1, 0);
                dataHdr.putInt(Global.INTPARA2, hdrBytes.length);

                dataAlign.putInt(Global.INTPARA1, nTextAlign);

                dataTextOut.putString(Global.STRPARA1, text);
                dataTextOut.putString(Global.STRPARA2, encoding);

                WorkService.workThread.handleCmd(Global.CMD_POS_WRITE,dataHdr);
                WorkService.workThread.handleCmd(Global.CMD_POS_SALIGN,dataAlign);
                WorkService.workThread.handleCmd(Global.CMD_POS_STEXTOUT,dataTextOut);
            }catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){}
    }

    @Override
    protected void onUserLeaveHint()
    {
        Log.d("onUserLeaveHint","Home button pressed");
        super.onUserLeaveHint();
        //Unregister bluetooth receiver
        try{unregisterReceiver(bluetoothReceiver);}catch(Exception e){}
        //Disconnect bt connection
        try{WorkService.workThread.disconnectBt();}catch(Exception e){}
        // remove the handler
        try{WorkService.delHandler(mHandler);}catch(Exception e){}
        mHandler = null;
    }

    /**
     * Broadcast receiver for bluetooth state changes
     */
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            final String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED))
            {
                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR);
                switch (state)
                {
                    case BluetoothAdapter.STATE_OFF:
//                        closeConnection();//Close on going connection and disable button
                        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
                        break;
                    case BluetoothAdapter.STATE_ON:
                        break;
                }
            }
        }
    };

    private static class MHandler extends Handler {
        WeakReference<MainActivity> mActivity;
        MHandler(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            MainActivity theActivity = mActivity.get();
            switch (msg.what) {

                case Global.CMD_POS_STEXTOUTRESULT:
                case Global.CMD_POS_WRITERESULT: {
                    int result = msg.arg1;
                    Toast.makeText(
                            theActivity,
                            (result == 1) ? Global.toast_success
                                    : Global.toast_fail, Toast.LENGTH_SHORT).show();
                    Log.v(TAG, "Result: " + result);
                    break;
                }

            }
        }
    }

}
</code>```

答: If it only happens when u sign the apk, it looks like u have to update ur proguard rules, to exclude the printer lib clases or similar</p>

Body:
I am writing an Android app to print text on a bluetooth thermal printer.
Here is the complete code

The app works fine in the debug mode but when I generate a signed APK and install it on the device, it does not respond at all.

I have tried different solution suggested on stackoverflow but non of them worked.

This is my main activity

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.lvrenyang.io.IOCallBack;
import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private Handler mHandler; // Our main handler that will receive callback notifications
    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names

    private static String TAG = "MAIN_ACTIVITY";
    private Activity activity;
    private Button btnConnect;

    private String name = "MTP-II";
    private String mac_address = "02:15:44:31:49:05";

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

        //Get the activity
        this.activity = this;

        //Button from the XML view
        btnConnect = findViewById(R.id.btnConnect);

        //Start the Init Work Service Async task
        new InitWorkService().execute();

        //Set onClickListener for test print button
        btnConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    //Check if name and address are set
                    if (name != "null" && mac_address != "null" && mac_address.contains(":")) {

                        if (!WorkService.workThread.isConnected()) {
                            WorkService.workThread.connectBt(mac_address);
                            //Sleep for 3 seconds
                            try {
                                Thread.sleep(3000);
                            } catch (Exception e) {
                            }
                        }
                        //Check if connected
                        if (WorkService.workThread.isConnected()) {
                            //Collect data in background Thread
                            new PrintData().execute();
                        } else {
                            Toast.makeText(activity, Global.toast_notconnect, Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(activity, "Please setup printer first!", Toast.LENGTH_LONG).show();
                    }
                }
                catch(Exception e){
                    Log.e(TAG, e.getMessage(), e.fillInStackTrace());}
            }
        });
    }

    /**
     * Background Async Task
     * */
    private class InitWorkService extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                WorkService.cb = new IOCallBack() {
                    public void OnOpen() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONOPEN);
                            mHandler.sendMessage(msg);
                        }
                    }
                    public void OnClose() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONCLOSE);
                            mHandler.sendMessage(msg);
                        }
                    }
                };
            }
            catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){
            try {
                mHandler = new MHandler(MainActivity.this);
                WorkService.addHandler(mHandler);

                if (null == WorkService.workThread) {
                    Intent intent = new Intent(activity, WorkService.class);
                    startService(intent);
                }
            }
            catch (Exception e) {
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
                Toast.makeText(activity, "Unable to initiate the WorkService!", Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Background Async Task
     * */
    class PrintData extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                int nTextAlign=1;
                String text = "Test message!\r\n\r\n\r\n";
                String encoding = "UTF-8";
                byte[] hdrBytes = {0x1c, 0x26, 0x1b, 0x39, 0x01};

                Bundle dataAlign = new Bundle();
                Bundle dataTextOut = new Bundle();
                Bundle dataHdr = new Bundle();

                dataHdr.putByteArray(Global.BYTESPARA1, hdrBytes);
                dataHdr.putInt(Global.INTPARA1, 0);
                dataHdr.putInt(Global.INTPARA2, hdrBytes.length);

                dataAlign.putInt(Global.INTPARA1, nTextAlign);

                dataTextOut.putString(Global.STRPARA1, text);
                dataTextOut.putString(Global.STRPARA2, encoding);

                WorkService.workThread.handleCmd(Global.CMD_POS_WRITE,dataHdr);
                WorkService.workThread.handleCmd(Global.CMD_POS_SALIGN,dataAlign);
                WorkService.workThread.handleCmd(Global.CMD_POS_STEXTOUT,dataTextOut);
            }catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){}
    }

    @Override
    protected void onUserLeaveHint()
    {
        Log.d("onUserLeaveHint","Home button pressed");
        super.onUserLeaveHint();
        //Unregister bluetooth receiver
        try{unregisterReceiver(bluetoothReceiver);}catch(Exception e){}
        //Disconnect bt connection
        try{WorkService.workThread.disconnectBt();}catch(Exception e){}
        // remove the handler
        try{WorkService.delHandler(mHandler);}catch(Exception e){}
        mHandler = null;
    }

    /**
     * Broadcast receiver for bluetooth state changes
     */
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            final String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED))
            {
                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR);
                switch (state)
                {
                    case BluetoothAdapter.STATE_OFF:
//                        closeConnection();//Close on going connection and disable button
                        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
                        break;
                    case BluetoothAdapter.STATE_ON:
                        break;
                }
            }
        }
    };

    private static class MHandler extends Handler {
        WeakReference<MainActivity> mActivity;
        MHandler(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            MainActivity theActivity = mActivity.get();
            switch (msg.what) {

                case Global.CMD_POS_STEXTOUTRESULT:
                case Global.CMD_POS_WRITERESULT: {
                    int result = msg.arg1;
                    Toast.makeText(
                            theActivity,
                            (result == 1) ? Global.toast_success
                                    : Global.toast_fail, Toast.LENGTH_SHORT).show();
                    Log.v(TAG, "Result: " + result);
                    break;
                }

            }
        }
    }

}


来源: stackexchange

问:
Get a dynamic range in google sheets
I have a function that takes a table's range and then emails it every day. Currently it is set up to get a fixed range (G2:H38). The process currently works, but every day I send the email, I have a handful of blank cells that are also sent out.  I am new to this and hoping someone can help me solve for this. </p>

```<code>var rowData = data[i];
    var emailAddress = "example@gmail.com";
    var recipient = rowData[0];
    var yesterdayDate = rowData[5];
    var message1 = rowData[2] + yesterdayDate;
    var message2 = rowData[3]
    var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var data = sh.getRange("G2:H38").getValues();
    //var htmltable =[];
    var TABLEFORMAT = 'cellspacing="2" cellpadding="2" dir="ltr" border="1" style="width:100%;display:table;max-width:400px;table-layout:fixed;font-size:10pt;font-family:arial,sans,sans-serif;border-collapse:collapse;border:1px solid #ccc;font-weight:normal;color:black;background-color:white;text-align:center;text-decoration:none;font-style:normal;margin-top:30px'
    var htmltable = '<table ' + TABLEFORMAT +' ">';
    var tablehead = 'style="background-color:#6aa84f;color:white;';

      for (row = 0; row<data.length; row++){
        htmltable += '<tr>';
      for (col = 0 ;col<data[row].length; col++){
        if (data[row][col] === "" || 0) {htmltable += '<td>' + '' + '</td>';}
          else
            if (row === 0)  {
              htmltable += '<th ' + tablehead +' ">' + data[row][col] + '</th>';
            }

          else {htmltable += '<td>' + data[row][col] + '</td>';}
      }
     htmltable += '</tr>';
      }
</code>```

答:
In your second for loop, first condition catches and appends empty table cells for cell values that have no data in them. Adding a 0 check does not help here as you should check for data[row][col]===0 if you want to match values that equal 0, not ||0.

Otherwise, your code works as intended and testing it on a sample Spreadsheet works - "if cell in Range is empty, append empty cell to table". Do you want to filter out all empty cells?

Update

I am still unsure why you would like to filter out empty cells from the HtmlTable, but if you want only the ones with data to be shown, change your if...else statement a little to account for that:

```<code>if (row===0&&data[0][col]!=='')  { //filter out empty header cells;
  htmltable += '<th>' + data[row][col] + '</th>';
}else if(data[row][col]!=='') { //filter out empty entries cells
  htmltable += '<td style="border:1px solid black;">' + data[row][col] + '</td>';
}
</code>```

ContentLicense: CC BY-SA 4.0

Title: Get a dynamic range in google sheets

Body:
I have a function that takes a table's range and then emails it every day. Currently it is set up to get a fixed range (G2:H38). The process currently works, but every day I send the email, I have a handful of blank cells that are also sent out.  I am new to this and hoping someone can help me solve for this.

var rowData = data[i];
    var emailAddress = "example@gmail.com";
    var recipient = rowData[0];
    var yesterdayDate = rowData[5];
    var message1 = rowData[2] + yesterdayDate;
    var message2 = rowData[3]
    var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var data = sh.getRange("G2:H38").getValues();
    //var htmltable =[];
    var TABLEFORMAT = 'cellspacing="2" cellpadding="2" dir="ltr" border="1" style="width:100%;display:table;max-width:400px;table-layout:fixed;font-size:10pt;font-family:arial,sans,sans-serif;border-collapse:collapse;border:1px solid #ccc;font-weight:normal;color:black;background-color:white;text-align:center;text-decoration:none;font-style:normal;margin-top:30px'
    var htmltable = '
';
    var tablehead = 'style="background-color:#6aa84f;color:white;';

      for (row = 0; row<data.length; row++){
        htmltable += '
';
      for (col = 0 ;col<data[row].length; col++){
        if (data[row][col] === "" || 0) {htmltable += '' + '' + '	';}
          else
            if (row === 0)  {
              htmltable += '' + data[row][col] + '	';
            }

          else {htmltable += '' + data[row][col] + '	';}
      }
     htmltable += '
';
      }

Body:
In your second for loop, first condition catches and appends empty table cells for cell values that have no data in them. Adding a 0 check does not help here as you should check for data[row][col]===0 if you want to match values that equal 0, not ||0.

Otherwise, your code works as intended and testing it on a sample Spreadsheet works - "if cell in Range is empty, append empty cell to table". Do you want to filter out all empty cells?

Update

I am still unsure why you would like to filter out empty cells from the HtmlTable, but if you want only the ones with data to be shown, change your if...else statement a little to account for that:

if (row===0&&data[0][col]!=='')  { //filter out empty header cells;
  htmltable += '<th>' + data[row][col] + '</th>';
}else if(data[row][col]!=='') { //filter out empty entries cells
  htmltable += '<td style="border:1px solid black;">' + data[row][col] + '</td>';
}


问:
The longest length of most consecutive number which is bigger than zero in a series
I wanna write a t-sql query which will return the longest length of  most consecutive number which is bigger than zero in a series
for example: I have the below dataset

```<code>create table samples(
  id int,
  num1 int, num2 int, num3 int, num4 int, num5 int,
  num6 int, num7 int, num8 int, num9 int, num10 int
);
insert into samples values
  (1, 1, 1 , 0, 0 , 0, 1, 1 , 1 , 0 , 0 ),
  (2, 1, 1 , 1, 1 , 0, 1, 1 , 1 , 0 , 0 ),
  (3, 0, 1 , 1, 0, 0, 1, 1 , 1 , 0 , 0 );
</code>```

The data represents activation based on months.(For 10 months). I'd like to get longest active time period through 10 months.

For id=1 there are two 1 at the beginning and three 1 following some zeros, for this id I'd like the get the three as result.
For id=2 there are four 1 at the beginning and three 1 after a zero, for this id I,'d like to get 4 as result.
And for id = 3 I'd like to get 3  as well.
And since max value is 1 in series, it occurs in two different consecutive places and first one has 2 as length and second is 3.

答:
One option is to concatenate a string of 1's an 0's, then use string_split() on the zero to get the max duration

This assumes ones an zeros.  If other values use can use sign(num1) or even left(num1,1)

Example

```<code>Select A.ID
      ,MaxLen = max(len(B.value))
 From samples A
 Cross Apply string_split(concat(num1,num2,num3,num4,num5,num6,num7,num8,num9,num10),'0') B
 Group By ID
</code>```

Returns

```<code>ID  MaxLen
1   3
2   4
3   3
</code>```

EDIT - Perhaps a more Performant version

```<code>Select A.ID
      ,B.MaxLen
 From samples A
 Cross Apply (Select MaxLen = max(len(value))
               From  string_split(concat(num1,num2,num3,num4,num5,num6,num7,num8,num9,num10),'0')
             ) B
</code>```

Body:
I wanna write a t-sql query which will return the longest length of  most consecutive number which is bigger than zero in a series
for example: I have the below dataset

create table samples(
  id int,
  num1 int, num2 int, num3 int, num4 int, num5 int,
  num6 int, num7 int, num8 int, num9 int, num10 int
);
insert into samples values
  (1, 1, 1 , 0, 0 , 0, 1, 1 , 1 , 0 , 0 ),
  (2, 1, 1 , 1, 1 , 0, 1, 1 , 1 , 0 , 0 ),
  (3, 0, 1 , 1, 0, 0, 1, 1 , 1 , 0 , 0 );

The data represents activation based on months.(For 10 months). I'd like to get longest active time period through 10 months.

For id=1 there are two 1 at the beginning and three 1 following some zeros, for this id I'd like the get the three as result.
For id=2 there are four 1 at the beginning and three 1 after a zero, for this id I,'d like to get 4 as result.
And for id = 3 I'd like to get 3  as well.
And since max value is 1 in series, it occurs in two different consecutive places and first one has 2 as length and second is 3.

Body:
One option is to concatenate a string of 1's an 0's, then use string_split() on the zero to get the max duration

This assumes ones an zeros.  If other values use can use sign(num1) or even left(num1,1)

Example

Select A.ID
      ,MaxLen = max(len(B.value))
 From samples A
 Cross Apply string_split(concat(num1,num2,num3,num4,num5,num6,num7,num8,num9,num10),'0') B
 Group By ID

Returns

ID  MaxLen
1   3
2   4
3   3

EDIT - Perhaps a more Performant version

Select A.ID
      ,B.MaxLen
 From samples A
 Cross Apply (Select MaxLen = max(len(value))
               From  string_split(concat(num1,num2,num3,num4,num5,num6,num7,num8,num9,num10),'0')
             ) B


问:
Why Larecipe can't load correctly?
I installed Larecipe in the project and he can't load correctly. When i see "/docs/1.0/overview", get errors in console and layout can't be load.

Uncaught ReferenceError: CreateLarecipe is not defined

Uncaught ReferenceError: LaRecipe is not defined

I made package updates and unfortunately it did not help.

```<code>Laravel Framework 5.7.28
"binarytorch/larecipe": "^2.1",
</code>```

答:
I experienced the same thing.

Try running both these Artisan commands:

php artisan larecipe:install
php artisan vendor:publish --tag=larecipe_assets --force
```

Title: Why Larecipe can't load correctly?

Body:
I installed Larecipe in the project and he can't load correctly. When i see "/docs/1.0/overview", get errors in console and layout can't be load.

Uncaught ReferenceError: CreateLarecipe is not defined

Uncaught ReferenceError: LaRecipe is not defined

I made package updates and unfortunately it did not help.

Laravel Framework 5.7.28
"binarytorch/larecipe": "^2.1",


问:
How to iterate all the children including those without tags in an DOM element with JavaScript
I am trying to parse a ruby tag like this:

  <ruby>
      <rb>気</rb>
      <rp>(</rp>
      <rt>き</rt>
      <rp>)</rp>
  </ruby>
  が
  <ruby>
      <rb>狂</rb>
      <rp>(</rp>
      <rt>くる</rt>
      <rp>)</rp>
  </ruby>
  ってしまう。

```

The problem is, that I am unable to iterate all the child elements including those without tags. All the functions like:
document.getElementById("foo").children and $("#foo").children()
return only the two ruby tags without the text in between.

I am trying to get a list like:

{ruby}

が

{ruby}

ってしまう

Is there a way I can get a list of all the tags and text?

答:
You can use Node.childNodes (See documentation)

```<code>document.getElementById("foo").childNodes
</code>```

But here is where it can get tricky:

In your HTML, between the
 tag and the <ruby> tag, there is whitespaces and a newline. This will be parsed as a TextNode here. So .childNodes will return 5 nodes:

A TextNode for what is between
 and the first <ruby> (including a newline and whitespaces).

The first <ruby> element.

A TextNode containing the text between the two <ruby> elements (including two newlines and whitespaces)

The second <ruby> element.

A TextNode containing the text between the second </ ruby> and
. (including a newline and whitespaces)

So, if you only need non-empty TextNode, when there is actually some text:

```<code>const nodes = [...document.getElementById('foo').childNodes].filter(node => !node.nodeValue || node.nodeValue.trim())
</code>```

Body:
I am trying to parse a ruby tag like this:

  <ruby>
      <rb>気</rb>
      <rp>(</rp>
      <rt>き</rt>
      <rp>)</rp>
  </ruby>
  が
  <ruby>
      <rb>狂</rb>
      <rp>(</rp>
      <rt>くる</rt>
      <rp>)</rp>
  </ruby>
  ってしまう。

The problem is, that I am unable to iterate all the child elements including those without tags. All the functions like:
document.getElementById("foo").children and $("#foo").children()
return only the two ruby tags without the text in between.

I am trying to get a list like:

{ruby}

が

{ruby}

ってしまう

Is there a way I can get a list of all the tags and text?

Body:
You can use Node.childNodes (See documentation)

document.getElementById("foo").childNodes

But here is where it can get tricky:

In your HTML, between the <div> tag and the <ruby> tag, there is whitespaces and a newline. This will be parsed as a TextNode here. So .childNodes will return 5 nodes:

A TextNode for what is between <div> and the first <ruby> (including a newline and whitespaces).

The first <ruby> element.

A TextNode containing the text between the two <ruby> elements (including two newlines and whitespaces)

The second <ruby> element.

A TextNode containing the text between the second </ ruby> and </ div>. (including a newline and whitespaces)

So, if you only need non-empty TextNode, when there is actually some text:

const nodes = [...document.getElementById('foo').childNodes].filter(node => !node.nodeValue || node.nodeValue.trim())


问:
Is using enums safe in all compilers?
In a discussion, a colleague told me that he never uses enum because he experienced that some C-compilers don't cope with the enum statement correctly.

He couldn't remember which compiler exactly had problems but among the problems, there were errors when doing something like

```<code>enum my_enum{
  my_enum_first  = 5;
  my_enum_second = 10;
};
</code>```

i.e. initializing enum values instead of letting the compiler do the automatic assignment. Another one was that the compiler decides for itself how big the enum is and therefore you could have unpredictable behavior for sizeof my_enum when compiling your code under various platforms.

To get around that, he told me to better use #defines to define the constant elements. But especially for using doxygen it's quite handy to have an enum (e.g. as function parameter) because in the generated documentation, you could simply click on my_enum and directly jump to the description of my_enum.

Another example would be code completion, where your IDE tells you what you could specify as valid parameters for functions. I know that – as long as you're compiling the code as C-code – that there's no type-safety (i.e. I could also specify 5 instead of my_enum_first), so the use of an enum seems to be a more cosmetic thing.

The question is: do you know any compilers that have limitations regarding the usage of enum?

Edit 1:

Regarding the environment: we are developing for various embedded platforms, so there could also be a compiler for some obscure micro-controller...

Edit 2:

He could tell me that the KEIL C51 compiler didn't play well with enums. Are there any experiences with current versions of the C51 compiler?

答:
I'm pretty sure that a compiler that doesn't play nice with enum is an invalid compiler - enum is specified in the standard, so a failure to implement it means the compiler shouldn't technically be used to compile C (For the record, the scope of enumeration types is discussed in 6.2.1 and defined as a type in 6.2.5 (of C99), so one would assume that it's a valid part of the standard from thereon in)!

So no, I don't know of any such compilers.

Title: Is using enums safe in all compilers?

Body:
In a discussion, a colleague told me that he never uses enum because he experienced that some C-compilers don't cope with the enum statement correctly.

He couldn't remember which compiler exactly had problems but among the problems, there were errors when doing something like

enum my_enum{
  my_enum_first  = 5;
  my_enum_second = 10;
};

i.e. initializing enum values instead of letting the compiler do the automatic assignment. Another one was that the compiler decides for itself how big the enum is and therefore you could have unpredictable behavior for sizeof my_enum when compiling your code under various platforms.

To get around that, he told me to better use #defines to define the constant elements. But especially for using doxygen it's quite handy to have an enum (e.g. as function parameter) because in the generated documentation, you could simply click on my_enum and directly jump to the description of my_enum.

Another example would be code completion, where your IDE tells you what you could specify as valid parameters for functions. I know that – as long as you're compiling the code as C-code – that there's no type-safety (i.e. I could also specify 5 instead of my_enum_first), so the use of an enum seems to be a more cosmetic thing.

The question is: do you know any compilers that have limitations regarding the usage of enum?

Edit 1:

Regarding the environment: we are developing for various embedded platforms, so there could also be a compiler for some obscure micro-controller...

Edit 2:

He could tell me that the KEIL C51 compiler didn't play well with enums. Are there any experiences with current versions of the C51 compiler?

ContentLicense: CC BY-SA 3.0


问:
show message using sharedWorker in all tabs
I'd like to show in all tabs a message.
So I'm using sharedWorker for this:

```<code>//sharedworker

var worker = new SharedWorker('/js/realtime.js');
worker.port.addEventListener("message", function(e) {
    alert(e.data);
}, false);

worker.port.start();

// post a message to the shared web worker
worker.port.postMessage("name");
</code>```

and the realtime.js:

```<code>var connections = 0; // count active connections

self.addEventListener("connect", function (e) {

    var port = e.ports[0];
    connections++;

    port.addEventListener("message", function (e) {
        port.postMessage("Hello " + e.data + " (port #" + connections + ")");
    }, true);

    port.start();

}, true);
</code>```

I'd like to see the alert in all tabs of my browser, but it is only in one... any ideas?

答:
Your port variable refers to a single tab. Each time the "connect" event fires, you get another port connected to another tab. So if you want to send a message to all tabs, you need to store all the ports and then send the message to all of them. Something like this:

```<code>const ports = [];

self.addEventListener("connect", function (e) {
    ports.push(e.ports[0]);

    port.addEventListener("message", function (e) {
        for (var i = 0; i < ports.length; i++) {
            ports[i].postMessage("Hello " + e.data + " (port #" + i + ")");
        }
    }, true);

    port.start();

}, true);
</code>```

Alternatively, I wrote a library which lets you easily send messages between a shared worker and tabs - either sending a message directly to one tab, or broadcasting to all connected tabs.

Body:
I'd like to show in all tabs a message.
So I'm using sharedWorker for this:

//sharedworker

var worker = new SharedWorker('/js/realtime.js');
worker.port.addEventListener("message", function(e) {
    alert(e.data);
}, false);

worker.port.start();

// post a message to the shared web worker
worker.port.postMessage("name");

and the realtime.js:

var connections = 0; // count active connections

self.addEventListener("connect", function (e) {

    var port = e.ports[0];
    connections++;

    port.addEventListener("message", function (e) {
        port.postMessage("Hello " + e.data + " (port #" + connections + ")");
    }, true);

    port.start();

}, true);

I'd like to see the alert in all tabs of my browser, but it is only in one... any ideas?

Body:
Your port variable refers to a single tab. Each time the "connect" event fires, you get another port connected to another tab. So if you want to send a message to all tabs, you need to store all the ports and then send the message to all of them. Something like this:

const ports = [];

self.addEventListener("connect", function (e) {
    ports.push(e.ports[0]);

    port.addEventListener("message", function (e) {
        for (var i = 0; i < ports.length; i++) {
            ports[i].postMessage("Hello " + e.data + " (port #" + i + ")");
        }
    }, true);

    port.start();

}, true);

Alternatively, I wrote a library which lets you easily send messages between a shared worker and tabs - either sending a message directly to one tab, or broadcasting to all connected tabs.


问:
You should not use Route outside a Router after use of withRouter
I have to use this.props.history.push('/...') in a nested component so I added withRouter() to navigate without history problems using react-router-dom.

But since I have added withRouter, I have You should not use Route outside a Router error.
I have read posts about this error but I can't understand what is wrong with my code.

Root.js:

```<code>import { BrowserRouter as Router, Route, Switch, Redirect, withRouter} from 'react-router-dom'
...
const Root = ({ store }) => (
          <Router>
            <Provider store={store}>
                <StripeProvider apiKey="pk_test_XXXXXXXXX">
                  <Switch>
                      <Route exact path="/" component={App} />
                      <Route path="/comp1" component={Comp1} />
                      <Route path="/comp2" component={Comp2} />
                      <Route path="/store" component={MyStoreCheckout} />
                      <Route component={Notfound} />
                  </Switch>
                </StripeProvider>
             </Provider>
          </Router>
)
Root.propTypes = {
  store: PropTypes.object.isRequired
}
export default withRouter(Root)
</code>```

and index.js:

```<code>import { createStore } from 'redux'
import myReducer from './redux/Reducers/myReducer'
import Root from './Root'
import Store from './redux/Store/store'

render(<Root store={Store} />, document.getElementById('root'))
</code>```

I use withRouter to be able to call this.props.history(...) in CheckoutForm
MyStoreCheckout.js:

```<code>class MyStoreCheckout extends React.Component {
  render() {
    return (
      <Elements>
        <InjectedCheckoutForm />
      </Elements>
    );
  }
}
export default MyStoreCheckout;
</code>```

CheckoutForm.js:

```<code>class CheckoutForm extends React.Component {
  handleSubmit = () => {
    fetch(getRequest)
        .then((response) => response.json())
        .then(...)
        .then(() => this.goToSuccessPage())
  }

  goToSuccessPage(){
    this.props.history.push('/') ; //----- error is here if I have no withRouter

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <DetailsSection/>
        <CardSection />
        <button>Confirm order</button>
      </form>
    );
  }
}

export default injectStripe(CheckoutForm);
</code>```

答:
As I mentioned in my comment... Just import withRouter at the top of your CheckoutForm file, then wrap the export with it, at the bottom. Like this:

CheckoutForm.js:

```<code>import { withRouter} from 'react-router-dom'

class CheckoutForm extends React.Component {
  // ... your class code ...
}

export default withRouter(injectStripe(CheckoutForm));
</code>```

If your injectStripe HOC doesn't pass all of the props from withRouter down to CheckoutForm, you can try doing export default injectStripe(withRouter(CheckoutForm)); instead, but order shouldn't matter (if set up correctly)

Body:
I have to use this.props.history.push('/...') in a nested component so I added withRouter() to navigate without history problems using react-router-dom.

But since I have added withRouter, I have You should not use Route outside a Router error.
I have read posts about this error but I can't understand what is wrong with my code.

Root.js:

import { BrowserRouter as Router, Route, Switch, Redirect, withRouter} from 'react-router-dom'
...
const Root = ({ store }) => (
          <Router>
            <Provider store={store}>
                <StripeProvider apiKey="pk_test_XXXXXXXXX">
                  <Switch>
                      <Route exact path="/" component={App} />
                      <Route path="/comp1" component={Comp1} />
                      <Route path="/comp2" component={Comp2} />
                      <Route path="/store" component={MyStoreCheckout} />
                      <Route component={Notfound} />
                  </Switch>
                </StripeProvider>
             </Provider>
          </Router>
)
Root.propTypes = {
  store: PropTypes.object.isRequired
}
export default withRouter(Root)

and index.js:

import { createStore } from 'redux'
import myReducer from './redux/Reducers/myReducer'
import Root from './Root'
import Store from './redux/Store/store'

render(<Root store={Store} />, document.getElementById('root'))

I use withRouter to be able to call this.props.history(...) in CheckoutForm
MyStoreCheckout.js:

class MyStoreCheckout extends React.Component {
  render() {
    return (
      <Elements>
        <InjectedCheckoutForm />
      </Elements>
    );
  }
}
export default MyStoreCheckout;

CheckoutForm.js:

class CheckoutForm extends React.Component {
  handleSubmit = () => {
    fetch(getRequest)
        .then((response) => response.json())
        .then(...)
        .then(() => this.goToSuccessPage())
  }

  goToSuccessPage(){
    this.props.history.push('/') ; //----- error is here if I have no withRouter

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <DetailsSection/>
        <CardSection />
        <button>Confirm order</button>
      </form>
    );
  }
}

export default injectStripe(CheckoutForm);

Body:
As I mentioned in my comment... Just import withRouter at the top of your CheckoutForm file, then wrap the export with it, at the bottom. Like this:

CheckoutForm.js:

import { withRouter} from 'react-router-dom'

class CheckoutForm extends React.Component {
  // ... your class code ...
}

export default withRouter(injectStripe(CheckoutForm));

If your injectStripe HOC doesn't pass all of the props from withRouter down to CheckoutForm, you can try doing export default injectStripe(withRouter(CheckoutForm)); instead, but order shouldn't matter (if set up correctly)


问:
AttributeError: 'NoneType' object has no attribute 'find_all' Beautifulsoup wrong class
I'm trying to scrape a house's price of this link : https://www.bienici.com/recherche/achat/france?page=2

And I need to know what's wrong with my program ?

My program :

```<code> from bs4 import BeautifulSoup
 import requests
 import csv

 with open("out.csv", "w", newline="") as f:
     writer = csv.writer(f)
     writer.writerow("Prix")

     for i in range(1, 20):
         url = "https://www.bienici.com/recherche/achat/france?page=%s" % i
         soup = BeautifulSoup(requests.get(url).text, "html.parser")
         data = soup.find(class_="resultsListContainer")

         for data in data.find_all(class_="sideListItemContainerInTableForListInResult"):
             prix = data.find("span", {"class": "thePrice"})
             prix = prix.text if prix else ""

             writer.writerow(prix)
</code>```

I get this error :

```<code>   Traceback (most recent call last):
     File "1.py", line 16, in <module>
        for data in data.find_all(class_="sideListItemContainerInTableForListInResult"):
   AttributeError: 'NoneType' object has no attribute 'find_all'
</code>```

I think my error is in the class_="sideListItemContainerInTableForListInResult" , but when I inspect the html code I think it's the right one !!

答:
It looks like you can access the data through the json response. You'll have to play around with the paramters and dig through the json structure to pull out what you want need, but look like quite a bit of data you are able to grab:

```<code>import requests

payload = {'filters': '{"size":24,"from":0,"filterType":"buy","propertyType":["house","flat"],"newProperty":false,"page":2,"resultsPerPage":24,"maxAuthorizedResults":2400,"sortBy":"relevance","sortOrder":"desc","onTheMarket":[true],"limit":"ih{eIzjhZ?q}qrAzaf}AlrD?rvfrA","showAllModels":false,"blurInfoType":["disk","exact"]}'}

url = 'https://www.bienici.com/realEstateAds.json'
response = requests.get(url, params = payload).json()

for prop in response['realEstateAds']:
    title = prop['title']
    city = prop['city']
    desc = prop['description']
    price = prop['price']

    print ('%s - %s\n%s\n%s' %(price, title, city, desc))
</code>```

Output:

```<code>print ('%s - %s\n%s\n%s' %(price, title, city, desc))
1190000 - BALMA - Bien d'exception 12 pièces 400 m2
Pin-Balma
- EXCLUSIVITÉ - Bien d'exception à BALMA (31130) . - 400 m2 - 12 pièces - 7 chambres - Sur 3000 m2 de terrain. . Luxe, calme et volupté dans cette magnifique et très rare maison divisée en deux lots d'habitation communicants (qui peuvent aussi être indépendants). L'un de 260 m2 et l'autre de 140 m2. Chacun avec son entrée, son séjour, sa cuisine, ses salles de bains et pièces d'eau, ses chambres, ses terrasses et ses équipements de qualité. Et ce, ouvrant le champ des possibles quant aux projets potentiels !. . Cette bâtisse de prestige du milieu du XVIIIème siècle a vu ses rénovations et prestations inhérentes réalisées avec des matériaux et des façons d'excellence.. . Sur les 3000 m2 de terrain, un jardin paysager orne les abords de la maison et de la piscine. Puis, vous trouverez un pré et un bois privé qui réveilleront vos aspirations bucoliques. Vous pourrez ainsi vous blottir dans un écrin précieux niché à proximité de TOULOUSE.. . Vos hôtes et vous serez à proximité des commodités, des transports (dont le métro), des cliniques, des établissements scolaires et des hypermarchés ; et tout aussi proches d'Airbus (BLAGNAC et Défense), du CEAT, des SSII, de Orange Business Services, etc.. . Recevez notre invitation au voyage, là où tout n'est qu'ordre et beauté, Luxe, calme et volupté.. . Visite virtuelle disponible en agence ou en LiveRoom avec un de nos conseillers.
</code>```

To get to a csv, you'll need to convert to a dataframe. Now the json structure is nested, so there are some columns that won't be entirelly flattened out. There are ways to handle that, but to get a basic dataframe:

```<code>from pandas.io.json import json_normalize

df = json_normalize(response['realEstateAds'])
</code>```

Output:

```<code>print (df.to_string())
   accountType  adCreatedByPro adType adTypeFR  addressKnown  agencyFeePercentage                                       agencyFeeUrl  annualCondominiumFees             availableDate  balconyQuantity  balconySurfaceArea  bathroomsQuantity  bedroomsQuantity                                      blurInfo.bbox  blurInfo.centroid.lat  blurInfo.centroid.lon blurInfo.origin  blurInfo.position.lat  blurInfo.position.lon  blurInfo.radius blurInfo.type                 city  condominiumPartsQuantity                                        description  descriptionTextLength district.code_insee district.cp  district.id  district.id_polygone  district.id_type district.insee_code                                   district.libelle                                      district.name district.postal_code  district.type_id  enclosedParkingQuantity  endOfPromotedAsExclusive energyClassification  energyValue      exposition feesChargedTo  floor  floorQuantity greenhouseGazClassification  greenhouseGazValue hasAirConditioning hasAlarm hasBalcony hasCaretaker hasCellar hasDoorCode hasElevator hasFirePlace hasGarden hasIntercom hasPool hasSeparateToilet hasTerrace                    heating  highlightMailContact                              id isCalm isCondominiumInProcedure isDisabledPeopleFriendly isExclusiveSaleMandate isInCondominium isRefurbished isStudio  landSurfaceArea          modificationDate needHomeStaging newOrOld  newProperty  nothingBehindForm  parkingPlacesQuantity                                             photos postalCode    price  priceHasDecreased  pricePerSquareMeter  priceWithoutFees propertyType           publicationDate          reference  roomsQuantity  showerRoomsQuantity  status.autoImported  status.closedByUser  status.highlighted  status.is3dHighlighted  status.isLeading  status.onTheMarket  surfaceArea  terracesQuantity             thresholdDate                                              title  toiletQuantity transactionType      userRelativeData.accountIds  userRelativeData.canChangeOnTheMarket  userRelativeData.canModifyAd  userRelativeData.canModifyAdBlur  userRelativeData.canSeeAddress  userRelativeData.canSeeContacts  userRelativeData.canSeeExactPosition  userRelativeData.canSeePublicationCertificateHtml  userRelativeData.canSeePublicationCertificatePdf  userRelativeData.canSeeRealDates  userRelativeData.canSeeStats userRelativeData.importAccountId  userRelativeData.isAdModifier  userRelativeData.isAdmin  userRelativeData.isFavorite  userRelativeData.isNetwork  userRelativeData.isOwner                  userRelativeData.searchAccountIds                                       virtualTours  with360  with3dModel workToDo  yearOfConstruction
0       agency            True    buy    vente          True                  NaN  https://www.immoceros.fr/mentions-legales-hono...                 2517.0                       NaN              NaN                 NaN                1.0                 3             [2.27006, 48.92827, 2.27006, 48.92827]              48.928270               2.270060          manual              48.928270               2.270060              NaN         exact             Colombes                      47.0  COLOMBES | Agent-Sarre - Champarons |\r\nSitué...                   1149               92025       92700       100331                100331                 1               92025                                Fossés Jean Bouvier                     Colombes - Fossés Jean Bouvier                92700                 1                      NaN                         0                    D       197.00             NaN        seller    5.0            6.0                           B                9.00                NaN      NaN      False          NaN     False         NaN        True          NaN     False         NaN     NaN               NaN       True     électricité individuel                 False              ag922079-195213238    NaN                      NaN                      NaN                   True            True           NaN      NaN              NaN  2019-05-11T08:53:15.943Z             NaN   ancien        False               True                    2.0  [{'url_photo': 'http://photos.ubiflow.net/9220...      92700   469000              False          5097.826087          469000.0         flat  2019-04-23T18:42:59.742Z  VA1952-IMMOCEROS2              4                  1.0                 True                False               False                   False              True                True        92.00               NaN                       NaN  COLOMBES  | APPARTEMENT A VENDRE | 4 PIECES - ...             1.0             buy  [ubiflow-easybusiness-ag922079]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         558bbfd06fbf04e50075bbce                          False                     False                        False                       False                     False  [ubiflow-easybusiness-ag922079, contract-type-...  [{'originalUrl': 'https://www.nodalview.com/bK...     True        False      NaN                 NaN
1       agency            True    buy    vente          True                  NaN                                                NaN                    NaN                       NaN              NaN                 NaN                NaN                 1  [7.251231, 43.700846999999996, 7.251231, 43.70...              43.700847               7.251231          custom              43.700847               7.251231              NaN         exact                 Nice                       NaN  A vendre à Nice dans le quartier Grosso / Tzar...                   1542               06088       06000       300102                300102                 1               06088                            Parc Impérial - Le Piol                     Nice - Parc Impérial - Le Piol                06000                 1                      NaN                         0                    E       270.00           Ouest           NaN    NaN            7.0                           C               14.00                NaN      NaN        NaN          NaN       NaN         NaN        True          NaN       NaN        True     NaN               NaN        NaN                Individuel                  False                   apimo-2871096    NaN                      NaN                      NaN                   True             NaN           NaN      NaN              NaN  2019-04-25T17:04:27.723Z             NaN      NaN        False               True                    NaN  [{'url_photo': 'https://d1qfj231ug7wdu.cloudfr...      06000   215000              False          4383.282365               NaN         flat  2019-04-04T18:04:38.323Z               1508              2                  NaN                 True                False               False                   False             False                True        49.05               NaN                       NaN  Nice François Grosso : F2 dernier étage, terra...             NaN             buy                     [apimo-3120]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         5913331e150de0009ce38406                          False                     False                        False                       False                     False  [apimo-3120, contract-type-basic, 5913331e150d...  [{'originalUrl': 'https://www.nodalview.com/PX...     True        False    False                 NaN
2       agency            True    buy    vente          True                  NaN                                                NaN                    NaN                       NaN              NaN                 NaN                NaN                 0  [7.2526839999999995, 43.69589099999998, 7.2526...              43.695891               7.252684          custom              43.695891               7.252684              NaN         exact                 Nice                       NaN  Joli studio entièrement meublé et équipé à ven...                   1205               06088       06000       300070                300070                 1               06088                                           Gambetta                                    Nice - Gambetta                06000                 1                      NaN                         0                    D       224.47             Est           NaN    2.0            6.0                           B                8.49               True      NaN        NaN          NaN       NaN         NaN        True          NaN       NaN        True     NaN               NaN        NaN                Individuel                  False                   apimo-1008273    NaN                      NaN                      NaN                   True             NaN           NaN     True              NaN  2019-04-24T17:02:19.834Z             NaN      NaN        False               True                    NaN  [{'url_photo': 'https://d1qfj231ug7wdu.cloudfr...      06000   145000              False          6722.299490               NaN         flat  1970-01-01T00:00:00.000Z               1496              1                  NaN                 True                False               False                   False             False                True        21.57               NaN  2019-03-29T09:52:38.387Z        Nice proche mer : studio meublé avec balcon             NaN             buy                     [apimo-3120]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         5913331e150de0009ce38406                          False                     False                        False                       False                     False  [apimo-3120, contract-type-basic, 5913331e150d...  [{'originalUrl': 'https://www.nodalview.com/xV...     True        False    False                 NaN
3       agency            True    buy    vente          True                  NaN  http://www.willman.fr/i/redac/honoraires?honof...                    NaN  2017-12-27T00:00:00.000Z              NaN                 NaN                3.0                 3  [7.165397, 43.666337999999996, 7.165397, 43.66...              43.666338               7.165397        accounts              43.666338               7.165397              NaN         exact       Cagnes-sur-Mer                       NaN  Située dans le quartier recherché des Bréguièr...                   1229               0
</code>```

Then to save it:

```<code>df.to_csv('file.csv', index=False)
</code>```

Body:
I'm trying to scrape a house's price of this link : https://www.bienici.com/recherche/achat/france?page=2

And I need to know what's wrong with my program ?

My program :

 from bs4 import BeautifulSoup
 import requests
 import csv

 with open("out.csv", "w", newline="") as f:
     writer = csv.writer(f)
     writer.writerow("Prix")

     for i in range(1, 20):
         url = "https://www.bienici.com/recherche/achat/france?page=%s" % i
         soup = BeautifulSoup(requests.get(url).text, "html.parser")
         data = soup.find(class_="resultsListContainer")

         for data in data.find_all(class_="sideListItemContainerInTableForListInResult"):
             prix = data.find("span", {"class": "thePrice"})
             prix = prix.text if prix else ""

             writer.writerow(prix)

I get this error :

   Traceback (most recent call last):
     File "1.py", line 16, in <module>
        for data in data.find_all(class_="sideListItemContainerInTableForListInResult"):
   AttributeError: 'NoneType' object has no attribute 'find_all'

I think my error is in the class_="sideListItemContainerInTableForListInResult" , but when I inspect the html code I think it's the right one !!

Body:
It looks like you can access the data through the json response. You'll have to play around with the paramters and dig through the json structure to pull out what you want need, but look like quite a bit of data you are able to grab:

import requests

payload = {'filters': '{"size":24,"from":0,"filterType":"buy","propertyType":["house","flat"],"newProperty":false,"page":2,"resultsPerPage":24,"maxAuthorizedResults":2400,"sortBy":"relevance","sortOrder":"desc","onTheMarket":[true],"limit":"ih{eIzjhZ?q}qrAzaf}AlrD?rvfrA","showAllModels":false,"blurInfoType":["disk","exact"]}'}

url = 'https://www.bienici.com/realEstateAds.json'
response = requests.get(url, params = payload).json()

for prop in response['realEstateAds']:
    title = prop['title']
    city = prop['city']
    desc = prop['description']
    price = prop['price']

    print ('%s - %s\n%s\n%s' %(price, title, city, desc))

Output:

print ('%s - %s\n%s\n%s' %(price, title, city, desc))
1190000 - BALMA - Bien d'exception 12 pièces 400 m2
Pin-Balma
- EXCLUSIVITÉ - Bien d'exception à BALMA (31130) . - 400 m2 - 12 pièces - 7 chambres - Sur 3000 m2 de terrain. . Luxe, calme et volupté dans cette magnifique et très rare maison divisée en deux lots d'habitation communicants (qui peuvent aussi être indépendants). L'un de 260 m2 et l'autre de 140 m2. Chacun avec son entrée, son séjour, sa cuisine, ses salles de bains et pièces d'eau, ses chambres, ses terrasses et ses équipements de qualité. Et ce, ouvrant le champ des possibles quant aux projets potentiels !. . Cette bâtisse de prestige du milieu du XVIIIème siècle a vu ses rénovations et prestations inhérentes réalisées avec des matériaux et des façons d'excellence.. . Sur les 3000 m2 de terrain, un jardin paysager orne les abords de la maison et de la piscine. Puis, vous trouverez un pré et un bois privé qui réveilleront vos aspirations bucoliques. Vous pourrez ainsi vous blottir dans un écrin précieux niché à proximité de TOULOUSE.. . Vos hôtes et vous serez à proximité des commodités, des transports (dont le métro), des cliniques, des établissements scolaires et des hypermarchés ; et tout aussi proches d'Airbus (BLAGNAC et Défense), du CEAT, des SSII, de Orange Business Services, etc.. . Recevez notre invitation au voyage, là où tout n'est qu'ordre et beauté, Luxe, calme et volupté.. . Visite virtuelle disponible en agence ou en LiveRoom avec un de nos conseillers.

To get to a csv, you'll need to convert to a dataframe. Now the json structure is nested, so there are some columns that won't be entirelly flattened out. There are ways to handle that, but to get a basic dataframe:

from pandas.io.json import json_normalize

df = json_normalize(response['realEstateAds'])

Output:

print (df.to_string())
   accountType  adCreatedByPro adType adTypeFR  addressKnown  agencyFeePercentage                                       agencyFeeUrl  annualCondominiumFees             availableDate  balconyQuantity  balconySurfaceArea  bathroomsQuantity  bedroomsQuantity                                      blurInfo.bbox  blurInfo.centroid.lat  blurInfo.centroid.lon blurInfo.origin  blurInfo.position.lat  blurInfo.position.lon  blurInfo.radius blurInfo.type                 city  condominiumPartsQuantity                                        description  descriptionTextLength district.code_insee district.cp  district.id  district.id_polygone  district.id_type district.insee_code                                   district.libelle                                      district.name district.postal_code  district.type_id  enclosedParkingQuantity  endOfPromotedAsExclusive energyClassification  energyValue      exposition feesChargedTo  floor  floorQuantity greenhouseGazClassification  greenhouseGazValue hasAirConditioning hasAlarm hasBalcony hasCaretaker hasCellar hasDoorCode hasElevator hasFirePlace hasGarden hasIntercom hasPool hasSeparateToilet hasTerrace                    heating  highlightMailContact                              id isCalm isCondominiumInProcedure isDisabledPeopleFriendly isExclusiveSaleMandate isInCondominium isRefurbished isStudio  landSurfaceArea          modificationDate needHomeStaging newOrOld  newProperty  nothingBehindForm  parkingPlacesQuantity                                             photos postalCode    price  priceHasDecreased  pricePerSquareMeter  priceWithoutFees propertyType           publicationDate          reference  roomsQuantity  showerRoomsQuantity  status.autoImported  status.closedByUser  status.highlighted  status.is3dHighlighted  status.isLeading  status.onTheMarket  surfaceArea  terracesQuantity             thresholdDate                                              title  toiletQuantity transactionType      userRelativeData.accountIds  userRelativeData.canChangeOnTheMarket  userRelativeData.canModifyAd  userRelativeData.canModifyAdBlur  userRelativeData.canSeeAddress  userRelativeData.canSeeContacts  userRelativeData.canSeeExactPosition  userRelativeData.canSeePublicationCertificateHtml  userRelativeData.canSeePublicationCertificatePdf  userRelativeData.canSeeRealDates  userRelativeData.canSeeStats userRelativeData.importAccountId  userRelativeData.isAdModifier  userRelativeData.isAdmin  userRelativeData.isFavorite  userRelativeData.isNetwork  userRelativeData.isOwner                  userRelativeData.searchAccountIds                                       virtualTours  with360  with3dModel workToDo  yearOfConstruction
0       agency            True    buy    vente          True                  NaN  https://www.immoceros.fr/mentions-legales-hono...                 2517.0                       NaN              NaN                 NaN                1.0                 3             [2.27006, 48.92827, 2.27006, 48.92827]              48.928270               2.270060          manual              48.928270               2.270060              NaN         exact             Colombes                      47.0  COLOMBES | Agent-Sarre - Champarons |\r\nSitué...                   1149               92025       92700       100331                100331                 1               92025                                Fossés Jean Bouvier                     Colombes - Fossés Jean Bouvier                92700                 1                      NaN                         0                    D       197.00             NaN        seller    5.0            6.0                           B                9.00                NaN      NaN      False          NaN     False         NaN        True          NaN     False         NaN     NaN               NaN       True     électricité individuel                 False              ag922079-195213238    NaN                      NaN                      NaN                   True            True           NaN      NaN              NaN  2019-05-11T08:53:15.943Z             NaN   ancien        False               True                    2.0  [{'url_photo': 'http://photos.ubiflow.net/9220...      92700   469000              False          5097.826087          469000.0         flat  2019-04-23T18:42:59.742Z  VA1952-IMMOCEROS2              4                  1.0                 True                False               False                   False              True                True        92.00               NaN                       NaN  COLOMBES  | APPARTEMENT A VENDRE | 4 PIECES - ...             1.0             buy  [ubiflow-easybusiness-ag922079]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         558bbfd06fbf04e50075bbce                          False                     False                        False                       False                     False  [ubiflow-easybusiness-ag922079, contract-type-...  [{'originalUrl': 'https://www.nodalview.com/bK...     True        False      NaN                 NaN
1       agency            True    buy    vente          True                  NaN                                                NaN                    NaN                       NaN              NaN                 NaN                NaN                 1  [7.251231, 43.700846999999996, 7.251231, 43.70...              43.700847               7.251231          custom              43.700847               7.251231              NaN         exact                 Nice                       NaN  A vendre à Nice dans le quartier Grosso / Tzar...                   1542               06088       06000       300102                300102                 1               06088                            Parc Impérial - Le Piol                     Nice - Parc Impérial - Le Piol                06000                 1                      NaN                         0                    E       270.00           Ouest           NaN    NaN            7.0                           C               14.00                NaN      NaN        NaN          NaN       NaN         NaN        True          NaN       NaN        True     NaN               NaN        NaN                Individuel                  False                   apimo-2871096    NaN                      NaN                      NaN                   True             NaN           NaN      NaN              NaN  2019-04-25T17:04:27.723Z             NaN      NaN        False               True                    NaN  [{'url_photo': 'https://d1qfj231ug7wdu.cloudfr...      06000   215000              False          4383.282365               NaN         flat  2019-04-04T18:04:38.323Z               1508              2                  NaN                 True                False               False                   False             False                True        49.05               NaN                       NaN  Nice François Grosso : F2 dernier étage, terra...             NaN             buy                     [apimo-3120]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         5913331e150de0009ce38406                          False                     False                        False                       False                     False  [apimo-3120, contract-type-basic, 5913331e150d...  [{'originalUrl': 'https://www.nodalview.com/PX...     True        False    False                 NaN
2       agency            True    buy    vente          True                  NaN                                                NaN                    NaN                       NaN              NaN                 NaN                NaN                 0  [7.2526839999999995, 43.69589099999998, 7.2526...              43.695891               7.252684          custom              43.695891               7.252684              NaN         exact                 Nice                       NaN  Joli studio entièrement meublé et équipé à ven...                   1205               06088       06000       300070                300070                 1               06088                                           Gambetta                                    Nice - Gambetta                06000                 1                      NaN                         0                    D       224.47             Est           NaN    2.0            6.0                           B                8.49               True      NaN        NaN          NaN       NaN         NaN        True          NaN       NaN        True     NaN               NaN        NaN                Individuel                  False                   apimo-1008273    NaN                      NaN                      NaN                   True             NaN           NaN     True              NaN  2019-04-24T17:02:19.834Z             NaN      NaN        False               True                    NaN  [{'url_photo': 'https://d1qfj231ug7wdu.cloudfr...      06000   145000              False          6722.299490               NaN         flat  1970-01-01T00:00:00.000Z               1496              1                  NaN                 True                False               False                   False             False                True        21.57               NaN  2019-03-29T09:52:38.387Z        Nice proche mer : studio meublé avec balcon             NaN             buy                     [apimo-3120]                                  False                         False                             False                           False                            False                                 False                                              False                                             False                             False                         False         5913331e150de0009ce38406                          False                     False                        False                       False                     False  [apimo-3120, contract-type-basic, 5913331e150d...  [{'originalUrl': 'https://www.nodalview.com/xV...     True        False    False                 NaN
3       agency            True    buy    vente          True                  NaN  http://www.willman.fr/i/redac/honoraires?honof...                    NaN  2017-12-27T00:00:00.000Z              NaN                 NaN                3.0                 3  [7.165397, 43.666337999999996, 7.165397, 43.66...              43.666338               7.165397        accounts              43.666338               7.165397              NaN         exact       Cagnes-sur-Mer                       NaN  Située dans le quartier recherché des Bréguièr...                   1229               0

Then to save it:

df.to_csv('file.csv', index=False)


问:
Is this program logically wrong or have a syntax that I can't seem to find?
I am helping an ex-teacher of mine and need help with this code. I am writing a python program that makes 30 unique cards. 10 are red, 10 are black and 10 are yellow. I have only used red in the code to make it easier to debug. I need to make them with the function which I believe works but then I need to then distribute them and display them at the end but the player's hands cannot be the same as each other and no duplicates in their own hand (as you would in an actual version of this). So I need to set a check system. I really can't find the problem and would appreciate a fresh set of eyes as this can easily fix it or it's out of my own league. Thanks for reading.

P.S
I know I have two player hands for each but that's to add to when a player wins a battle so I can compare who has the most cards and what ones for the end.

I have tried changing it up using different loops and writing it in pseudo code and comparing but don't know what's happening.

```<code>{import sys, random, time
this = sys.modules[__name__]

def redCardGen():
    for i in range(0,11, 1):
        setattr(this, 'R%s' % i, 'Red Card %s' % i)

def blackCardGen():
    for i in range(0,11, 1):
        setattr(this, 'B%s' % i, 'Black Card %s' % i)

def yellowCardGen():
    for i in range(0,11, 1):
        setattr(this, 'Y%s' % i, 'Yellow Card %s' % i)

redCardGen()

blackCardGen()
yellowCardGen()

breaker = 0

player1Hand = []
player2Hand = []
WinnnerDeck = []
WinnerDeck2 = []

Red = [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10]

play = input("Would you like to play the game?: ")
if(play == "yes"):
    print("Okay, then lets play!")
else:
    exit()
for i in range(0,6, 1):
    player1Hand.append(random.choice(Red))
    player2Hand.append(random.choice(Red))
breaker1 = 0
while(breaker1 == 0):
    if (player1Hand != 5):
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    elif ((len(set(player1Hand))==1) and (len(set(player2Hand))==1)):
        player1Hand.pop()
        player2Hand.pop()
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    elif ((len(set(player1Hand and player2Hand)) == 1)):
        player1Hand.pop()
        player2Hand.pop()
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    else:
        breaker1 = 1

print(player1Hand)
print(player2Hand)}
</code>```

There are no errors so I don't think that it is a syntax problem but rather a logical error.
My expected outcome is to have two player hands with random cards in but none are the same.

答:
An example of cards distribution using random.shuffle() :

```<code>import random

deck = ["R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10"]
random.shuffle(deck)

player1_hand = deck[:5]
player2_hand = deck[5:10]
print(player1_hand)
print(player2_hand)
</code>```

Returns :

```<code>['R4', 'R2', 'R10', 'R5', 'R1']
['R7', 'R8', 'R9', 'R3', 'R6']
</code>```

Body:
I am helping an ex-teacher of mine and need help with this code. I am writing a python program that makes 30 unique cards. 10 are red, 10 are black and 10 are yellow. I have only used red in the code to make it easier to debug. I need to make them with the function which I believe works but then I need to then distribute them and display them at the end but the player's hands cannot be the same as each other and no duplicates in their own hand (as you would in an actual version of this). So I need to set a check system. I really can't find the problem and would appreciate a fresh set of eyes as this can easily fix it or it's out of my own league. Thanks for reading.

P.S
I know I have two player hands for each but that's to add to when a player wins a battle so I can compare who has the most cards and what ones for the end.

I have tried changing it up using different loops and writing it in pseudo code and comparing but don't know what's happening.

{import sys, random, time
this = sys.modules[__name__]

def redCardGen():
    for i in range(0,11, 1):
        setattr(this, 'R%s' % i, 'Red Card %s' % i)

def blackCardGen():
    for i in range(0,11, 1):
        setattr(this, 'B%s' % i, 'Black Card %s' % i)

def yellowCardGen():
    for i in range(0,11, 1):
        setattr(this, 'Y%s' % i, 'Yellow Card %s' % i)

redCardGen()

blackCardGen()
yellowCardGen()

breaker = 0

player1Hand = []
player2Hand = []
WinnnerDeck = []
WinnerDeck2 = []

Red = [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10]

play = input("Would you like to play the game?: ")
if(play == "yes"):
    print("Okay, then lets play!")
else:
    exit()
for i in range(0,6, 1):
    player1Hand.append(random.choice(Red))
    player2Hand.append(random.choice(Red))
breaker1 = 0
while(breaker1 == 0):
    if (player1Hand != 5):
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    elif ((len(set(player1Hand))==1) and (len(set(player2Hand))==1)):
        player1Hand.pop()
        player2Hand.pop()
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    elif ((len(set(player1Hand and player2Hand)) == 1)):
        player1Hand.pop()
        player2Hand.pop()
        player1Hand.append(random.choice(Red))
        player2Hand.append(random.choice(Red))
    else:
        breaker1 = 1

print(player1Hand)
print(player2Hand)}

There are no errors so I don't think that it is a syntax problem but rather a logical error.
My expected outcome is to have two player hands with random cards in but none are the same.

Body:
An example of cards distribution using random.shuffle() :

import random

deck = ["R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10"]
random.shuffle(deck)

player1_hand = deck[:5]
player2_hand = deck[5:10]
print(player1_hand)
print(player2_hand)

Returns :

['R4', 'R2', 'R10', 'R5', 'R1']
['R7', 'R8', 'R9', 'R3', 'R6']


问:
Image compression java
I want to transfer Images via network socket(java.net).Where Can I find a sample Code for

compressing Buffered Images in java..Say for example If my Image file is around 200kb,I want

it to be converted to atleat 100kb..So that the transfer will be lil bit fast..

Thank you..

答:
The way to do that really depend of what you want to do.

If you want to transfer image as the expend of some loss of quality, you can save them to JPEG (in a memory stream), transfer theses byte data and read the image again on the other side. A typical 200KB image could be reduced to 20-50K with a good resulting quality.

Reading The Java Image I/O API could help for that.

If you absolutely want to preserve the original bytes, or want a more generic solution, just use some compression library like Gzip to compress/decompress your data. To get you started you can use Compressing and Decompressing Data Using Java APIs as a good start.

Title: Image compression java


问:
How do I use react-i18next with a connected component
I would like to use react-i18next with my react-redux connected component and am not sure how to go about it.

I've simplified my code to show an example of a connected component:

```<code>import React from 'react';
import {connect} from 'react-redux';
import {userSelectors} from "./userSelectors";

interface IConnectedProps {
    activeUserName: string | undefined;
}
export class LandingPageComponent extends React.Component<IConnectedProps> {
    public render(): JSX.Element {
        return (
            <React.Suspense fallback={<Spinner/>}>
                <React.Fragment>
                    <div>
                    ... a bunch of controls using translated text
                    </div>
                    <div>{activeUserName}</div>
                </React.Fragment>
            </React.Suspense>
        );
    }
}

const mapStateToProps = (state: ICoreRootState) : IConnectedProps => ({
    activeUserName: userSelectors.getDisplayName(state),
});

export const LandingPage = connect(mapStateToProps)(LandingPageComponent);
</code>```

Installed package versions:

```<code>react version: 16.8.4
react-redux version: 5.1.1
react-i18next version: 10.6.0
</code>```

What I've tried:

1) I get the error below when I use withTranslation, WithTranslation as follows:

```<code>export class LandingPageComponent extends React.Component<IConnectedProps & WithTranslation> {...}
export const LandingPage = connect(mapStateToProps)(withTranslation()(LandingPageComponent));
</code>```

Error:

```<code>The above error occurred in the <withI18nextTranslation(LandingPageComponent)> component:
    in withI18nextTranslation(LandingPageComponent) (created by Connect(withI18nextTranslation(LandingPageComponent)))
    in Connect(withI18nextTranslation(LandingPageComponent))
    in Route
    in t
    in Connect(t) (at App.tsx:49)
    in Switch (at App.tsx:45)
    in App (at src/index.tsx:14)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Connect(ConnectedRouter))
    in Connect(ConnectedRouter) (at src/index.tsx:13)
    in Provider (at src/index.tsx:12)
</code>```

2) I get the error below when I use withTranslation, WithTranslation as follows:

```<code>export class LandingPageComponent extends React.Component<IConnectedProps & WithTranslation> {...}
export const LandingPage = withTranslation()(connect(mapStateToProps)(LandingPageComponent));
</code>```

Error:

```<code>index.js:1446 The above error occurred in the <withI18nextTranslation(Connect(LandingPageComponent))> component:
    in withI18nextTranslation(Connect(LandingPageComponent))
    in Route
    in t
    in Connect(t) (at App.tsx:49)
    in Switch (at App.tsx:45)
    in App (at src/index.tsx:14)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Connect(ConnectedRouter))
    in Connect(ConnectedRouter) (at src/index.tsx:13)
    in Provider (at src/index.tsx:12)
</code>```

3) I cannot use useTranslation since hooks are not allowed to be used within a class.

I also tried the following:

```<code>... a bunch of imports
interface ILogoutButtonProps {
    userName?: string;
}
interface IConnectedHandlers {
    readonly logout: any;
    readonly push: any;
}
class InnerLogoutComponent extends React.Component<IButtonProps & IConnectedHandlers & ILogoutButtonProps & WithTranslation, {}> {

    public render() {
        const {userName, onClick, logout: Logout, push: Push, ...buttonProps} = this.props;
        const logoutText = this.props.i18n.t(StringNames.logout);
        const buttonText = userName ? logoutText + " " + userName : logoutText;
        return (
            <Button {...buttonProps} text={buttonText} onClick={this.handleClick}/>
        );
    }

    private handleClick = (event: React.MouseEvent<HTMLElement>) : void => {
        this.props.logout()
            .then(() => this.props.push(LoginPaths.verifyUser));
    }
}
const InnerLogoutTranslatedComponent = withTranslation()(InnerLogoutComponent);

class LogoutComponentInternal extends React.Component<IButtonProps & IConnectedHandlers & ILogoutButtonProps, {}> {
    public render () {
        return (
            <InnerLogoutTranslatedComponent {...this.props}/>
        );
    }
}
export const LogoutComponent = connect(null,{logout, push})(LogoutComponentInternal);
</code>```

but I get the following error:

```<code>Hooks can only be called inside the body of a function component.
</code>```

Thank you in advance...

答:
I'm actually having trouble to determine in which order you wrap your components in HOCs. In the project I'm currently working in we wrap like withNamespaces(connect(withStyles(component))), which works really well (withNamespaces is essentially the same as withTranslations). We had issues when trying to connect a translated component, you are possibly experiencing the same issues right now. So here's our way of doing it:

You have a "normal" component like

```<code>type InjectedProps = StateProps & ExternalProps & MyComponentsTranslations
export class MyComponent extends React.Component<InjectedProps> {
    ...
}
</code>```

(Note: the procedure works exactly the same with functional components)

you can const MyConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(MyComponent)

and finally, you do a

```<code>import {WithNamespaces, withNamespaces} from "react-i18next"
export const LocalizedMyComponent = withNamespaces()(
  ({t,...rest}): WithNamepsaces) => (
    <MyConnectedComponent translations={{ put translations here }} {...rest} />
  )
)
</code>```

Now, the trick is that we define an interface MyComponentsTranslations {} where we put all the required translations or translate functions (in case of plurals).
MyComponentsTranslations is added to the InjectedProps to make them available in the original component.

You can always simply inject the t-function of i18n into your components, but in my current project we decided that it is much cleaner to

explicitly name the translations required for the component

Since neither the original component nor the connected component are dependant on the t-function they are quiet easy to test

Let me know if this works for you.

Also, to make the whole thing a little bit more elegant, you can use these helpers:

```<code>export interface Translations<T> {
  translations: T
}

export const createTranslations = <T>(translations: T): Translations<T> => ({
  translations,
})
</code>```

This allows you to set

```<code>type InjectedProps = StateProps & Translations<MyComponentTranslations>
</code>```

and in the withNamespace hoc:

```<code><MyConnectedComponent {...createTranslations<MyComponentTranslations>({ put translations here })} {...rest} />
</code>```

Body:
I would like to use react-i18next with my react-redux connected component and am not sure how to go about it.

I've simplified my code to show an example of a connected component:

import React from 'react';
import {connect} from 'react-redux';
import {userSelectors} from "./userSelectors";

interface IConnectedProps {
    activeUserName: string | undefined;
}
export class LandingPageComponent extends React.Component<IConnectedProps> {
    public render(): JSX.Element {
        return (
            <React.Suspense fallback={<Spinner/>}>
                <React.Fragment>

                    ... a bunch of controls using translated text

{activeUserName}

                </React.Fragment>
            </React.Suspense>
        );
    }
}

const mapStateToProps = (state: ICoreRootState) : IConnectedProps => ({
    activeUserName: userSelectors.getDisplayName(state),
});

export const LandingPage = connect(mapStateToProps)(LandingPageComponent);

Installed package versions:

react version: 16.8.4
react-redux version: 5.1.1
react-i18next version: 10.6.0

What I've tried:

1) I get the error below when I use withTranslation, WithTranslation as follows:

export class LandingPageComponent extends React.Component<IConnectedProps & WithTranslation> {...}
export const LandingPage = connect(mapStateToProps)(withTranslation()(LandingPageComponent));

Error:

The above error occurred in the <withI18nextTranslation(LandingPageComponent)> component:
    in withI18nextTranslation(LandingPageComponent) (created by Connect(withI18nextTranslation(LandingPageComponent)))
    in Connect(withI18nextTranslation(LandingPageComponent))
    in Route
    in t
    in Connect(t) (at App.tsx:49)
    in Switch (at App.tsx:45)
    in App (at src/index.tsx:14)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Connect(ConnectedRouter))
    in Connect(ConnectedRouter) (at src/index.tsx:13)
    in Provider (at src/index.tsx:12)

2) I get the error below when I use withTranslation, WithTranslation as follows:

export class LandingPageComponent extends React.Component<IConnectedProps & WithTranslation> {...}
export const LandingPage = withTranslation()(connect(mapStateToProps)(LandingPageComponent));

Error:

index.js:1446 The above error occurred in the <withI18nextTranslation(Connect(LandingPageComponent))> component:
    in withI18nextTranslation(Connect(LandingPageComponent))
    in Route
    in t
    in Connect(t) (at App.tsx:49)
    in Switch (at App.tsx:45)
    in App (at src/index.tsx:14)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Connect(ConnectedRouter))
    in Connect(ConnectedRouter) (at src/index.tsx:13)
    in Provider (at src/index.tsx:12)

3) I cannot use useTranslation since hooks are not allowed to be used within a class.

I also tried the following:

... a bunch of imports
interface ILogoutButtonProps {
    userName?: string;
}
interface IConnectedHandlers {
    readonly logout: any;
    readonly push: any;
}
class InnerLogoutComponent extends React.Component<IButtonProps & IConnectedHandlers & ILogoutButtonProps & WithTranslation, {}> {

    public render() {
        const {userName, onClick, logout: Logout, push: Push, ...buttonProps} = this.props;
        const logoutText = this.props.i18n.t(StringNames.logout);
        const buttonText = userName ? logoutText + " " + userName : logoutText;
        return (
            <Button {...buttonProps} text={buttonText} onClick={this.handleClick}/>
        );
    }

    private handleClick = (event: React.MouseEvent<HTMLElement>) : void => {
        this.props.logout()
            .then(() => this.props.push(LoginPaths.verifyUser));
    }
}
const InnerLogoutTranslatedComponent = withTranslation()(InnerLogoutComponent);

class LogoutComponentInternal extends React.Component<IButtonProps & IConnectedHandlers & ILogoutButtonProps, {}> {
    public render () {
        return (
            <InnerLogoutTranslatedComponent {...this.props}/>
        );
    }
}
export const LogoutComponent = connect(null,{logout, push})(LogoutComponentInternal);

but I get the following error:

Hooks can only be called inside the body of a function component.

Thank you in advance...

Body:
I'm actually having trouble to determine in which order you wrap your components in HOCs. In the project I'm currently working in we wrap like withNamespaces(connect(withStyles(component))), which works really well (withNamespaces is essentially the same as withTranslations). We had issues when trying to connect a translated component, you are possibly experiencing the same issues right now. So here's our way of doing it:

You have a "normal" component like

type InjectedProps = StateProps & ExternalProps & MyComponentsTranslations
export class MyComponent extends React.Component<InjectedProps> {
    ...
}

(Note: the procedure works exactly the same with functional components)

you can const MyConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(MyComponent)

and finally, you do a

import {WithNamespaces, withNamespaces} from "react-i18next"
export const LocalizedMyComponent = withNamespaces()(
  ({t,...rest}): WithNamepsaces) => (
    <MyConnectedComponent translations={{ put translations here }} {...rest} />
  )
)

Now, the trick is that we define an interface MyComponentsTranslations {} where we put all the required translations or translate functions (in case of plurals).
MyComponentsTranslations is added to the InjectedProps to make them available in the original component.

You can always simply inject the t-function of i18n into your components, but in my current project we decided that it is much cleaner to

explicitly name the translations required for the component

Since neither the original component nor the connected component are dependant on the t-function they are quiet easy to test

Let me know if this works for you.

Also, to make the whole thing a little bit more elegant, you can use these helpers:

export interface Translations<T> {
  translations: T
}

export const createTranslations = <T>(translations: T): Translations<T> => ({
  translations,
})

This allows you to set

type InjectedProps = StateProps & Translations<MyComponentTranslations>

and in the withNamespace hoc:

<MyConnectedComponent {...createTranslations<MyComponentTranslations>({ put translations here })} {...rest} />


问:
how to change Android overflow menu icon
How do i change the Overflow Menu icon on the far right of the action bar as seen in the image below?  My Holo theme specifies this 3 row black stack icon by default and i want something else.  i can't seem to find a solution for this. I have looked at the documentation on http://developer.android.com/guide/topics/ui/menus.html but it doesn't seem to lend much help.

Thanks!

答:
```<code><style name="ToolBarTheme" parent="ThemeOverlay.AppCompat.ActionBar">
    <item name="android:tint">@color/colorAccent</item>
</code>```

create the above theme.set tint with your color and add this theme to the toolbar.

```<code><androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ToolBarTheme"/>
</code>```

Body:
<style name="ToolBarTheme" parent="ThemeOverlay.AppCompat.ActionBar">
    <item name="android:tint">@color/colorAccent</item>

create the above theme.set tint with your color and add this theme to the toolbar.

<androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ToolBarTheme"/>