问:
Android Studio app loads previous session when loaded
I'm making a tictactoe app where corresponding messages reflect whose (Player X or Player Y) turn it is and who wins. This worked with no issues. Then I added a feature using Preferences and Fragments, where the user could add specific names to Player X and Player Y and the messages would implement their names. However, now everytime I open the app it remembers a previous session of the game. I think it loads the game as it was the previous time it was paused. How can I get it to load a new game everytime the emulator opens?

I'm sure it's something simple, I'm just new to AndroidStudio and I'm out of ideas. Thank you!

This is my Activity code

```<code>package com.asebastian.tictactoe;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class TictactoeActivity extends Activity implements OnClickListener {

private Button btn1;
private Button btn2;
private Button btn3;
private Button btn4;
private Button btn5;
private Button btn6;
private Button btn7;
private Button btn8;
private Button btn9;
private TextView txtmsg;
private int r = 0;
private String btn1txt = " ";
private String btn2txt = " ";
private String btn3txt = " ";
private String btn4txt = " ";
private String btn5txt = " ";
private String btn6txt = " ";
private String btn7txt = " ";
private String btn8txt = " ";
private String btn9txt = " ";
private String Xname = " ";
private String Yname = " ";
private SharedPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_tictactoe);
    btn1 = (Button)findViewById(R.id.btn1);
    btn2 = (Button)findViewById(R.id.btn2);
    btn3 = (Button)findViewById(R.id.btn3);
    btn4 = (Button)findViewById(R.id.btn4);
    btn5 = (Button)findViewById(R.id.btn5);
    btn6 = (Button)findViewById(R.id.btn6);
    btn7 = (Button)findViewById(R.id.btn7);
    btn8 = (Button)findViewById(R.id.btn8);
    btn9 = (Button)findViewById(R.id.btn9);
    txtmsg = (TextView)findViewById(R.id.txtMessage);
    txtmsg.setText("Player X's turn");
    btn1.setOnClickListener(this);
    btn2.setOnClickListener(this);
    btn3.setOnClickListener(this);
    btn4.setOnClickListener(this);
    btn5.setOnClickListener(this);
    btn6.setOnClickListener(this);
    btn7.setOnClickListener(this);
    btn8.setOnClickListener(this);
    btn9.setOnClickListener(this);
    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu){
    getMenuInflater().inflate(R.menu.tictactoe,menu);
    return true;
}

@Override
public void onPause(){
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("btn1txt",btn1.getText().toString());
    editor.putString("btn2txt",btn2.getText().toString());
    editor.putString("btn3txt",btn3.getText().toString());
    editor.putString("btn4txt",btn4.getText().toString());
    editor.putString("btn5txt",btn5.getText().toString());
    editor.putString("btn6txt",btn6.getText().toString());
    editor.putString("btn7txt",btn7.getText().toString());
    editor.putString("btn8txt",btn8.getText().toString());
    editor.putString("btn9txt",btn9.getText().toString());
    editor.putInt("r",r);
    editor.commit();
    super.onPause();
}

@Override
public void onResume(){
    super.onResume();
    btn1.setText(prefs.getString("btn1txt",""));
    btn2.setText(prefs.getString("btn2txt",""));
    btn3.setText(prefs.getString("btn3txt",""));
    btn4.setText(prefs.getString("btn4txt",""));
    btn5.setText(prefs.getString("btn5txt",""));
    btn6.setText(prefs.getString("btn6txt",""));
    btn7.setText(prefs.getString("btn7txt",""));
    btn8.setText(prefs.getString("btn8txt",""));
    btn9.setText(prefs.getString("btn9txt",""));
    Xname = prefs.getString("pref_edittextX","");
    Yname = prefs.getString("pref_edittextY","");
    txtmsg.setText(Xname + "'s turn");
    r = prefs.getInt("r",0);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.new_game){
        btn1.setEnabled(true);
        btn2.setEnabled(true);
        btn3.setEnabled(true);
        btn4.setEnabled(true);
        btn5.setEnabled(true);
        btn6.setEnabled(true);
        btn7.setEnabled(true);
        btn8.setEnabled(true);
        btn9.setEnabled(true);
        btn1.setText("");
        btn2.setText("");
        btn3.setText("");
        btn4.setText("");
        btn5.setText("");
        btn6.setText("");
        btn7.setText("");
        btn8.setText("");
        btn9.setText("");
        r = 0;
        txtmsg.setText("Player X's turn");
    }
    else if (item.getItemId() == R.id.action_settings) {
        startActivity(new Intent(getApplicationContext(),SettingsActivity.class));
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
    if (v.getId() == R.id.btn1) {
        r++;
        if ((r % 2) == 0) {
            btn1.setText("O");
        } else {
            btn1.setText("X");
        }
    }
    if (v.getId() == R.id.btn2) {
        r++;
        if ((r % 2) == 0) {
            btn2.setText("O");
        } else {
            btn2.setText("X");
        }
    }
    if (v.getId() == R.id.btn3) {
        r++;
        if ((r % 2) == 0) {
            btn3.setText("O");
        } else {
            btn3.setText("X");
        }
    }
    if (v.getId() == R.id.btn4) {
        r++;
        if ((r % 2) == 0) {
            btn4.setText("O");
        } else {
            btn4.setText("X");
        }
    }
    if (v.getId() == R.id.btn5) {
        r++;
        if ((r % 2) == 0) {
            btn5.setText("O");
        } else {
            btn5.setText("X");
        }
    }
    if (v.getId() == R.id.btn6) {
        r++;
        if ((r % 2) == 0) {
            btn6.setText("O");
        } else {
            btn6.setText("X");
        }
    }
    if (v.getId() == R.id.btn7) {
        r++;
        if ((r % 2) == 0) {
            btn7.setText("O");
        } else {
            btn7.setText("X");
        }
    }
    if (v.getId() == R.id.btn8) {
        r++;
        if ((r % 2) == 0) {
            btn8.setText("O");
        } else {
            btn8.setText("X");
        }
    }
    if (v.getId() == R.id.btn9) {
        r++;
        if ((r % 2) == 0) {
            btn9.setText("O");
        } else {
            btn9.setText("X");
        }
    }
    if (Xname.isEmpty() && Yname.isEmpty()) {
        if ((r % 2) == 0) {
            txtmsg.setText("Player X's turn");
        } else {
            txtmsg.setText("Player Y's turn");
        }
    } else {
        if ((r % 2) == 0) {
            txtmsg.setText(Xname + "'s turn");
        } else {
            txtmsg.setText(Yname + "'s turn");
        }
    }

    btn1txt = btn1.getText().toString();
    btn2txt = btn2.getText().toString();
    btn3txt = btn3.getText().toString();
    btn4txt = btn4.getText().toString();
    btn5txt = btn5.getText().toString();
    btn6txt = btn6.getText().toString();
    btn7txt = btn7.getText().toString();
    btn8txt = btn8.getText().toString();
    btn9txt = btn9.getText().toString();
    calcWinner();
}

public void calcWinner() {

    if (btn1txt == "X" && btn2txt == "X" && btn3txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn2txt == "O" && btn3txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn4txt == "X" && btn5txt == "X" && btn6txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn4txt == "O" && btn5txt == "O" && btn6txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn7txt == "X" && btn8txt == "X" && btn8txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn7txt == "O" && btn8txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn1txt == "X" && btn4txt == "X" && btn7txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn4txt == "O" && btn7txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn2txt == "X" && btn5txt == "X" && btn8txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn2txt == "O" && btn5txt == "O" && btn8txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn3txt == "X" && btn6txt == "X" && btn9txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn3txt == "O" && btn6txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn1txt == "X" && btn5txt == "X" && btn9txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn5txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn3txt == "X" && btn5txt == "X" && btn7txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn3txt == "O" && btn5txt == "O" && btn7txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (r == 9) {
        txtmsg.setText("Tie Game!");
        disableButtons();
    }
}
public void disableButtons(){
    btn1.setEnabled(false);
    btn2.setEnabled(false);
    btn3.setEnabled(false);
    btn4.setEnabled(false);
    btn5.setEnabled(false);
    btn6.setEnabled(false);
    btn7.setEnabled(false);
    btn8.setEnabled(false);
    btn9.setEnabled(false);
}
}
</code>```

This is my Fragment code:

```<code>package com.asebastian.tictactoe;
import android.os.Bundle;
import android.preference.PreferenceFragment;

/**
* A simple {@link Fragment} subclass.
*/
public class SettingsFragment extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
}

}
</code>```

This is the code to add the Fragment:

```<code>package com.asebastian.tictactoe;
import android.app.Activity;
import android.os.Bundle;

public class SettingsActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getFragmentManager().beginTransaction().replace(android.R.id.content,new
SettingsFragment()).commit();

}
}
</code>```

答:
So i guess by Storing/Restoring to/from SharedPreferences that you are trying to save the state of the activity!

And that is wrong (unless you deleted the SharedPreferences saved content in onDestroy()) becuase every time you open the app again the on onResume() will be called and hence state will be restored from SharedPreferences.

See The Activity Lifecycle

So, The solution is not to use SharedPreferences to save/restore activity state but instead override the methods onSaveInstanceState & onRestoreInstanceState like this:

```<code>@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putString("btn1txt",btn1.getText().toString());
    // and So on

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}
</code>```

and

```<code>public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    btn1.setText(savedInstanceState.getString("btn1txt"));
    // and so on
}
</code>```

Note:

The system calls onRestoreInstanceState() after the onStart()method.
Also The system calls onRestoreInstanceState() only if there is a saved state to restore.

See Saving and restoring activity state

Body:
I'm making a tictactoe app where corresponding messages reflect whose (Player X or Player Y) turn it is and who wins. This worked with no issues. Then I added a feature using Preferences and Fragments, where the user could add specific names to Player X and Player Y and the messages would implement their names. However, now everytime I open the app it remembers a previous session of the game. I think it loads the game as it was the previous time it was paused. How can I get it to load a new game everytime the emulator opens?

I'm sure it's something simple, I'm just new to AndroidStudio and I'm out of ideas. Thank you!

This is my Activity code

package com.asebastian.tictactoe;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class TictactoeActivity extends Activity implements OnClickListener {

private Button btn1;
private Button btn2;
private Button btn3;
private Button btn4;
private Button btn5;
private Button btn6;
private Button btn7;
private Button btn8;
private Button btn9;
private TextView txtmsg;
private int r = 0;
private String btn1txt = " ";
private String btn2txt = " ";
private String btn3txt = " ";
private String btn4txt = " ";
private String btn5txt = " ";
private String btn6txt = " ";
private String btn7txt = " ";
private String btn8txt = " ";
private String btn9txt = " ";
private String Xname = " ";
private String Yname = " ";
private SharedPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_tictactoe);
    btn1 = (Button)findViewById(R.id.btn1);
    btn2 = (Button)findViewById(R.id.btn2);
    btn3 = (Button)findViewById(R.id.btn3);
    btn4 = (Button)findViewById(R.id.btn4);
    btn5 = (Button)findViewById(R.id.btn5);
    btn6 = (Button)findViewById(R.id.btn6);
    btn7 = (Button)findViewById(R.id.btn7);
    btn8 = (Button)findViewById(R.id.btn8);
    btn9 = (Button)findViewById(R.id.btn9);
    txtmsg = (TextView)findViewById(R.id.txtMessage);
    txtmsg.setText("Player X's turn");
    btn1.setOnClickListener(this);
    btn2.setOnClickListener(this);
    btn3.setOnClickListener(this);
    btn4.setOnClickListener(this);
    btn5.setOnClickListener(this);
    btn6.setOnClickListener(this);
    btn7.setOnClickListener(this);
    btn8.setOnClickListener(this);
    btn9.setOnClickListener(this);
    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu){
    getMenuInflater().inflate(R.menu.tictactoe,menu);
    return true;
}

@Override
public void onPause(){
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("btn1txt",btn1.getText().toString());
    editor.putString("btn2txt",btn2.getText().toString());
    editor.putString("btn3txt",btn3.getText().toString());
    editor.putString("btn4txt",btn4.getText().toString());
    editor.putString("btn5txt",btn5.getText().toString());
    editor.putString("btn6txt",btn6.getText().toString());
    editor.putString("btn7txt",btn7.getText().toString());
    editor.putString("btn8txt",btn8.getText().toString());
    editor.putString("btn9txt",btn9.getText().toString());
    editor.putInt("r",r);
    editor.commit();
    super.onPause();
}

@Override
public void onResume(){
    super.onResume();
    btn1.setText(prefs.getString("btn1txt",""));
    btn2.setText(prefs.getString("btn2txt",""));
    btn3.setText(prefs.getString("btn3txt",""));
    btn4.setText(prefs.getString("btn4txt",""));
    btn5.setText(prefs.getString("btn5txt",""));
    btn6.setText(prefs.getString("btn6txt",""));
    btn7.setText(prefs.getString("btn7txt",""));
    btn8.setText(prefs.getString("btn8txt",""));
    btn9.setText(prefs.getString("btn9txt",""));
    Xname = prefs.getString("pref_edittextX","");
    Yname = prefs.getString("pref_edittextY","");
    txtmsg.setText(Xname + "'s turn");
    r = prefs.getInt("r",0);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.new_game){
        btn1.setEnabled(true);
        btn2.setEnabled(true);
        btn3.setEnabled(true);
        btn4.setEnabled(true);
        btn5.setEnabled(true);
        btn6.setEnabled(true);
        btn7.setEnabled(true);
        btn8.setEnabled(true);
        btn9.setEnabled(true);
        btn1.setText("");
        btn2.setText("");
        btn3.setText("");
        btn4.setText("");
        btn5.setText("");
        btn6.setText("");
        btn7.setText("");
        btn8.setText("");
        btn9.setText("");
        r = 0;
        txtmsg.setText("Player X's turn");
    }
    else if (item.getItemId() == R.id.action_settings) {
        startActivity(new Intent(getApplicationContext(),SettingsActivity.class));
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
    if (v.getId() == R.id.btn1) {
        r++;
        if ((r % 2) == 0) {
            btn1.setText("O");
        } else {
            btn1.setText("X");
        }
    }
    if (v.getId() == R.id.btn2) {
        r++;
        if ((r % 2) == 0) {
            btn2.setText("O");
        } else {
            btn2.setText("X");
        }
    }
    if (v.getId() == R.id.btn3) {
        r++;
        if ((r % 2) == 0) {
            btn3.setText("O");
        } else {
            btn3.setText("X");
        }
    }
    if (v.getId() == R.id.btn4) {
        r++;
        if ((r % 2) == 0) {
            btn4.setText("O");
        } else {
            btn4.setText("X");
        }
    }
    if (v.getId() == R.id.btn5) {
        r++;
        if ((r % 2) == 0) {
            btn5.setText("O");
        } else {
            btn5.setText("X");
        }
    }
    if (v.getId() == R.id.btn6) {
        r++;
        if ((r % 2) == 0) {
            btn6.setText("O");
        } else {
            btn6.setText("X");
        }
    }
    if (v.getId() == R.id.btn7) {
        r++;
        if ((r % 2) == 0) {
            btn7.setText("O");
        } else {
            btn7.setText("X");
        }
    }
    if (v.getId() == R.id.btn8) {
        r++;
        if ((r % 2) == 0) {
            btn8.setText("O");
        } else {
            btn8.setText("X");
        }
    }
    if (v.getId() == R.id.btn9) {
        r++;
        if ((r % 2) == 0) {
            btn9.setText("O");
        } else {
            btn9.setText("X");
        }
    }
    if (Xname.isEmpty() && Yname.isEmpty()) {
        if ((r % 2) == 0) {
            txtmsg.setText("Player X's turn");
        } else {
            txtmsg.setText("Player Y's turn");
        }
    } else {
        if ((r % 2) == 0) {
            txtmsg.setText(Xname + "'s turn");
        } else {
            txtmsg.setText(Yname + "'s turn");
        }
    }

    btn1txt = btn1.getText().toString();
    btn2txt = btn2.getText().toString();
    btn3txt = btn3.getText().toString();
    btn4txt = btn4.getText().toString();
    btn5txt = btn5.getText().toString();
    btn6txt = btn6.getText().toString();
    btn7txt = btn7.getText().toString();
    btn8txt = btn8.getText().toString();
    btn9txt = btn9.getText().toString();
    calcWinner();
}

public void calcWinner() {

    if (btn1txt == "X" && btn2txt == "X" && btn3txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn2txt == "O" && btn3txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn4txt == "X" && btn5txt == "X" && btn6txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn4txt == "O" && btn5txt == "O" && btn6txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn7txt == "X" && btn8txt == "X" && btn8txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn7txt == "O" && btn8txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn1txt == "X" && btn4txt == "X" && btn7txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn4txt == "O" && btn7txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn2txt == "X" && btn5txt == "X" && btn8txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn2txt == "O" && btn5txt == "O" && btn8txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn3txt == "X" && btn6txt == "X" && btn9txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn3txt == "O" && btn6txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn1txt == "X" && btn5txt == "X" && btn9txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn1txt == "O" && btn5txt == "O" && btn9txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (btn3txt == "X" && btn5txt == "X" && btn7txt == "X") {
        txtmsg.setText("Player X wins!");
        disableButtons();
    }
    if (btn3txt == "O" && btn5txt == "O" && btn7txt == "O") {
        txtmsg.setText("Player Y wins!");
        disableButtons();
    }
    if (r == 9) {
        txtmsg.setText("Tie Game!");
        disableButtons();
    }
}
public void disableButtons(){
    btn1.setEnabled(false);
    btn2.setEnabled(false);
    btn3.setEnabled(false);
    btn4.setEnabled(false);
    btn5.setEnabled(false);
    btn6.setEnabled(false);
    btn7.setEnabled(false);
    btn8.setEnabled(false);
    btn9.setEnabled(false);
}
}

This is my Fragment code:

package com.asebastian.tictactoe;
import android.os.Bundle;
import android.preference.PreferenceFragment;

/**
* A simple {@link Fragment} subclass.
*/
public class SettingsFragment extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
}

}

This is the code to add the Fragment:

package com.asebastian.tictactoe;
import android.app.Activity;
import android.os.Bundle;

public class SettingsActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getFragmentManager().beginTransaction().replace(android.R.id.content,new
SettingsFragment()).commit();

}
}

Body:
So i guess by Storing/Restoring to/from SharedPreferences that you are trying to save the state of the activity!

And that is wrong (unless you deleted the SharedPreferences saved content in onDestroy()) becuase every time you open the app again the on onResume() will be called and hence state will be restored from SharedPreferences.

See The Activity Lifecycle

So, The solution is not to use SharedPreferences to save/restore activity state but instead override the methods onSaveInstanceState & onRestoreInstanceState like this:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putString("btn1txt",btn1.getText().toString());
    // and So on

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

and

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    btn1.setText(savedInstanceState.getString("btn1txt"));
    // and so on
}

Note:

The system calls onRestoreInstanceState() after the onStart()method.
Also The system calls onRestoreInstanceState() only if there is a saved state to restore.

See Saving and restoring activity state


来源: stackexchange

问:
Replace slashes with dots in javascript regex
I have a date and I want to replace all the slashes with dots. This is what I have but it's not working:

```<code>var TheDate = "3 / 29 / 2017";
TheDate = TheDate.replace(/'/'/g,'.');
alert(TheDate);
</code>```

What's not right? There's a jsFiddle here to test.

答:
```<code>var TheDate = "3 / 29 / 2017";
TheDate = TheDate.replace(/\//g,'.');
alert(TheDate);
</code>```

You need to escape the / character. You do it by prepending it with a \.

ContentLicense: CC BY-SA 4.0

Body:
I have a date and I want to replace all the slashes with dots. This is what I have but it's not working:

var TheDate = "3 / 29 / 2017";
TheDate = TheDate.replace(/'/'/g,'.');
alert(TheDate);

What's not right? There's a jsFiddle here to test.

Body:
var TheDate = "3 / 29 / 2017";
TheDate = TheDate.replace(/\//g,'.');
alert(TheDate);

You need to escape the / character. You do it by prepending it with a \.

ContentLicense: CC BY-SA 3.0


问:
C variables overwriting values
Hi I implemented a linked list and I am having troubles updating the variables of the struc Process i created. Here is the sample code:

```<code>typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *create_node(){
    Node *temp = malloc(sizeof(Node));
    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void append(Node *head, Node *nodo){
    Node *current = head;
    while (current->next != NULL){
        current = current->next;
    }
    current->next = nodo;
}

void add_attr(char *string, Process *procc){
    char *pch;
    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++){
        if (i == 0){
            strcpy(procc->name,pch);
        }
        else if(i == 1){
            int aux = atoi(pch);
            procc->prior = aux;
        }
        else{
            int aux1 = atoi(pch);
            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }

int main(int argc, char * argv []) {
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    fp = fopen(argv[1],"r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));
    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1 ;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n",line);
        add_attr(line, proc);
        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n",proc->pid);
        printf("name = %s\n",proc->name);
        printf("pior = %d\n",proc->prior);
        printf("state = %d\n",proc->state);
        printf("start_time = %d\n",proc->start_time);
        printf("----------------------------------------------------------\n");
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));
        proc->pid = pid;
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo);
        pid = pid +1;
    }
    fclose(fp);
    return 0;
}
</code>```

There is the main()
as you can see i printed the state of the variables in the struct to see their values and all goes well except for the pid that is not changing. after the while loop finished i printed all the processes in my linked list and its attributes and they all changed. Here you can see a SS with the output.

I really don't know what is happening to my program any help would be great, i know its a very specific case, but i did not know how to make a working example that showed the same problem.
(*I updated the output now the pid's work, but the main issue is not fixed, i still can't figure out why the Process attr change).

```<code>Input sample:
p1 2 3 10 1 2 3 4 5 6 7 8 8 9
p2 1 4 8 6 2 6 4 3 2 2 1
p3 3 5 5 1 2 6 7 8
</code>```

答:
AFAIK, pid = pid++; is undefined behavior.

Use pid = pid + 1, pid++, or pid += 1 instead

UPDATE:

You were setting proc->pid after printing, so it would print as zero. Actually, what it printed was what malloc returned, so it could have been anything and just happened to be zero most of the time.

But, you also have another problem. You append a new node in the bottom of the loop in anticipation of reading the node's contents on the next loop iteration.

So, because you appended "one ahead", the resultant linked list will have one too many nodes, and the last node will have garbage data. You don't see this in the loop itself, but would during subsequent list traversal [and printing].

I've created two versions of your program. One with the bugs annotated. And a cleaned up version.

Here's the annotated version [which prints correctly]:

```<code>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);
        add_attr(line, proc);

// NOTE/FIX: this is the correct place to set the pid -- _before_ printing
#if 0
        proc->pid = pid;
#endif

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");

// NOTE/BUG: this is setting up the _next_ node before it is known if it will
// be filled
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));

// NOTE/BUG: this is set _after_ the printing is done
#if 1
        proc->pid = pid;
#endif

// NOTE/BUG: this is appending the node before it is filled in (i.e. the last
// node in the list will have garbage)
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo);

        pid = pid + 1;
    }

    fclose(fp);
    return 0;
}
</code>```

Here's the cleaned up and working version:

```<code>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);

        Process *proc = malloc(sizeof(Process));
        add_attr(line, proc);
        proc->state = 0;

        pid += 1;
        proc->pid = pid;

        Node *nodo = create_node();
        nodo->value = proc;
        append(process_list, nodo);

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");
    }

    fclose(fp);

    return 0;
}
</code>```

Title: C variables overwriting values

Body:
Hi I implemented a linked list and I am having troubles updating the variables of the struc Process i created. Here is the sample code:

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *create_node(){
    Node *temp = malloc(sizeof(Node));
    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void append(Node *head, Node *nodo){
    Node *current = head;
    while (current->next != NULL){
        current = current->next;
    }
    current->next = nodo;
}

void add_attr(char *string, Process *procc){
    char *pch;
    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++){
        if (i == 0){
            strcpy(procc->name,pch);
        }
        else if(i == 1){
            int aux = atoi(pch);
            procc->prior = aux;
        }
        else{
            int aux1 = atoi(pch);
            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }

int main(int argc, char * argv []) {
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    fp = fopen(argv[1],"r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));
    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1 ;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n",line);
        add_attr(line, proc);
        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n",proc->pid);
        printf("name = %s\n",proc->name);
        printf("pior = %d\n",proc->prior);
        printf("state = %d\n",proc->state);
        printf("start_time = %d\n",proc->start_time);
        printf("----------------------------------------------------------\n");
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));
        proc->pid = pid;
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo);
        pid = pid +1;
    }
    fclose(fp);
    return 0;
}

There is the main()
as you can see i printed the state of the variables in the struct to see their values and all goes well except for the pid that is not changing. after the while loop finished i printed all the processes in my linked list and its attributes and they all changed. Here you can see a SS with the output.

I really don't know what is happening to my program any help would be great, i know its a very specific case, but i did not know how to make a working example that showed the same problem.
(*I updated the output now the pid's work, but the main issue is not fixed, i still can't figure out why the Process attr change).

Input sample:
p1 2 3 10 1 2 3 4 5 6 7 8 8 9
p2 1 4 8 6 2 6 4 3 2 2 1
p3 3 5 5 1 2 6 7 8

Body:
AFAIK, pid = pid++; is undefined behavior.

Use pid = pid + 1, pid++, or pid += 1 instead

UPDATE:

You were setting proc->pid after printing, so it would print as zero. Actually, what it printed was what malloc returned, so it could have been anything and just happened to be zero most of the time.

But, you also have another problem. You append a new node in the bottom of the loop in anticipation of reading the node's contents on the next loop iteration.

So, because you appended "one ahead", the resultant linked list will have one too many nodes, and the last node will have garbage data. You don't see this in the loop itself, but would during subsequent list traversal [and printing].

I've created two versions of your program. One with the bugs annotated. And a cleaned up version.

Here's the annotated version [which prints correctly]:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;
    pid += 1;
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);
        add_attr(line, proc);

// NOTE/FIX: this is the correct place to set the pid -- _before_ printing
#if 0
        proc->pid = pid;
#endif

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");

// NOTE/BUG: this is setting up the _next_ node before it is known if it will
// be filled
        Node *nodo = create_node();
        Process *proc = malloc(sizeof(Process));

// NOTE/BUG: this is set _after_ the printing is done
#if 1
        proc->pid = pid;
#endif

// NOTE/BUG: this is appending the node before it is filled in (i.e. the last
// node in the list will have garbage)
        proc->state = 0;
        nodo->value = proc;
        append(process_list, nodo);

        pid = pid + 1;
    }

    fclose(fp);
    return 0;
}

Here's the cleaned up and working version:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Process {
    int pid;
    char name[256];
    int prior;
    int state;
    int start_time;
} Process;

typedef struct Node {
    Process *value;
    struct Node *next;
} Node;

Node *
create_node()
{
    Node *temp = malloc(sizeof(Node));

    temp->value = NULL;
    temp->next = NULL;
    return temp;
}

void
append(Node * head, Node * nodo)
{
    Node *current = head;

    while (current->next != NULL) {
        current = current->next;
    }
    current->next = nodo;
}

void
add_attr(char *string, Process * procc)
{
    char *pch;

    pch = strtok(string, " ");
    for (int i = 0; i < 3; i++) {
        if (i == 0) {
            strcpy(procc->name, pch);
        }
        else if (i == 1) {
            int aux = atoi(pch);

            procc->prior = aux;
        }
        else {
            int aux1 = atoi(pch);

            procc->start_time = aux1;
        }
        pch = strtok(NULL, " ");
    }
}

int
main(int argc, char *argv[])
{
    FILE *fp;
    int pid = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen(argv[1], "r");
    Node *process_list = create_node();
    Process *proc = malloc(sizeof(Process));

    proc->pid = pid;
    proc->state = 0;
    process_list->value = proc;

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("%s\n", line);

        Process *proc = malloc(sizeof(Process));
        add_attr(line, proc);
        proc->state = 0;

        pid += 1;
        proc->pid = pid;

        Node *nodo = create_node();
        nodo->value = proc;
        append(process_list, nodo);

        printf("---------------------------------------------------------\n");
        printf("pointer proc memory dir = %p\n", proc);
        printf("pid = %d\n", proc->pid);
        printf("name = %s\n", proc->name);
        printf("pior = %d\n", proc->prior);
        printf("state = %d\n", proc->state);
        printf("start_time = %d\n", proc->start_time);
        printf("----------------------------------------------------------\n");
    }

    fclose(fp);

    return 0;
}


问:
GitLab Runner cache for Gradle is not working
I'm using GitLab Runner as CI to build an Android project however the cache is not working.

Here's my .gitlab-ci.yml. It was modified from https://gist.github.com/daicham/5ac8461b8b49385244aa0977638c3420.

```<code>image: runmymind/docker-android-sdk:latest
variables:
  GRADLE_USER_HOME: $CI_PROJECT_DIR/.gradle
stages:
  - build
debug:
  stage: build
  script:
    - set +e
    - du -sh $CI_PROJECT_DIR/.gradle/wrapper
    - du -sh $CI_PROJECT_DIR/.gradle/caches
    - set -e
    - ./gradlew assembleDebug
    - mkdir artifacts
    - cp mobile/build/outputs/apk/*.apk artifacts/
    - cp wear/build/outputs/apk/*.apk artifacts/
  cache:
    paths:
      - .gradle/wrapper/
      - .gradle/caches/
      - build/
      - mobile/build/
      - wear/build/
  artifacts:
    name: "project_${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
    expire_in: 2 weeks
    paths:
      - artifacts/
</code>```

And the log:

```<code>Running with gitlab-ci-multi-runner 9.0.0 (08a9e6f)
Using Docker executor with image runmymind/docker-android-sdk:latest ...
Using docker image sha256:d696fa13188c8d2d121c86cf526201b363c1e34ee7b163d6ce1ab1718f91a5e6 ID=sha256:d696fa13188c8d2d121c86cf526201b363c1e34ee7b163d6ce1ab1718f91a5e6 for predefined container...
Pulling docker image runmymind/docker-android-sdk:latest ...
Using docker image runmymind/docker-android-sdk:latest ID=sha256:474ac98077a496f2f71aa22ce4eebcea966c2960a061d4a59babe81ff007009b for build container...
Running on runner-8ce5d03c-project-72-concurrent-0 via outrage...
Cloning repository...
Cloning into '/builds/User/android-project'...
Checking out 015d01d0 as master...
Skipping Git submodules setup
Checking cache for default...
Successfully extracted cache
$ set +e
$ du -sh $CI_PROJECT_DIR/.gradle/wrapper
du: cannot access '/builds/User/android-project/.gradle/wrapper': No such file or directory
$ du -sh $CI_PROJECT_DIR/.gradle/caches
du: cannot access '/builds/User/android-project/.gradle/caches': No such file or directory
$ set -e
$ ./gradlew assembleDebug
Downloading https://services.gradle.org/distributions/gradle-3.4.1-all.zip
Unzipping /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do/gradle-3.4.1-all.zip to /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do
Set executable permissions for: /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do/gradle-3.4.1/bin/gradle
Starting a Gradle Daemon (subsequent builds will be faster)
Download https://jcenter.bintray.com/com/android/tools/build/gradle/2.3.0/gradle-2.3.0.pom
(more downloads)
</code>```

I have also tried using gradle argument to set gradle user home, aggressively specifying .gradle/ for cache, etc, but none of them worked.

Any ideas?

答:
If you use Gitlab < 9.0,you add to specify the cache has to be shared among different pipelines.

Try to add key: $CI_PROJECT_NAME under cache:

```<code>image: runmymind/docker-android-sdk:latest
variables:
  GRADLE_USER_HOME: $CI_PROJECT_DIR/.gradle
stages:
  - build
debug:
  stage: build
  script:
    - set +e
    - du -sh $CI_PROJECT_DIR/.gradle/wrapper
    - du -sh $CI_PROJECT_DIR/.gradle/caches
    - set -e
    - ./gradlew assembleDebug
    - mkdir artifacts
    - cp mobile/build/outputs/apk/*.apk artifacts/
    - cp wear/build/outputs/apk/*.apk artifacts/
  cache:
    key: $CI_PROJECT_NAME
    paths:
      - .gradle/wrapper/
      - .gradle/caches/
      - build/
      - mobile/build/
      - wear/build/
  artifacts:
    name: "project_${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
    expire_in: 2 weeks
    paths:
      - artifacts/
</code>```

Body:
I'm using GitLab Runner as CI to build an Android project however the cache is not working.

Here's my .gitlab-ci.yml. It was modified from https://gist.github.com/daicham/5ac8461b8b49385244aa0977638c3420.

image: runmymind/docker-android-sdk:latest
variables:
  GRADLE_USER_HOME: $CI_PROJECT_DIR/.gradle
stages:
  - build
debug:
  stage: build
  script:
    - set +e
    - du -sh $CI_PROJECT_DIR/.gradle/wrapper
    - du -sh $CI_PROJECT_DIR/.gradle/caches
    - set -e
    - ./gradlew assembleDebug
    - mkdir artifacts
    - cp mobile/build/outputs/apk/*.apk artifacts/
    - cp wear/build/outputs/apk/*.apk artifacts/
  cache:
    paths:
      - .gradle/wrapper/
      - .gradle/caches/
      - build/
      - mobile/build/
      - wear/build/
  artifacts:
    name: "project_${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
    expire_in: 2 weeks
    paths:
      - artifacts/

And the log:

Running with gitlab-ci-multi-runner 9.0.0 (08a9e6f)
Using Docker executor with image runmymind/docker-android-sdk:latest ...
Using docker image sha256:d696fa13188c8d2d121c86cf526201b363c1e34ee7b163d6ce1ab1718f91a5e6 ID=sha256:d696fa13188c8d2d121c86cf526201b363c1e34ee7b163d6ce1ab1718f91a5e6 for predefined container...
Pulling docker image runmymind/docker-android-sdk:latest ...
Using docker image runmymind/docker-android-sdk:latest ID=sha256:474ac98077a496f2f71aa22ce4eebcea966c2960a061d4a59babe81ff007009b for build container...
Running on runner-8ce5d03c-project-72-concurrent-0 via outrage...
Cloning repository...
Cloning into '/builds/User/android-project'...
Checking out 015d01d0 as master...
Skipping Git submodules setup
Checking cache for default...
Successfully extracted cache
$ set +e
$ du -sh $CI_PROJECT_DIR/.gradle/wrapper
du: cannot access '/builds/User/android-project/.gradle/wrapper': No such file or directory
$ du -sh $CI_PROJECT_DIR/.gradle/caches
du: cannot access '/builds/User/android-project/.gradle/caches': No such file or directory
$ set -e
$ ./gradlew assembleDebug
Downloading https://services.gradle.org/distributions/gradle-3.4.1-all.zip
Unzipping /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do/gradle-3.4.1-all.zip to /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do
Set executable permissions for: /builds/User/android-project/.gradle/wrapper/dists/gradle-3.4.1-all/c3ib5obfnqr0no9szq6qc17do/gradle-3.4.1/bin/gradle
Starting a Gradle Daemon (subsequent builds will be faster)
Download https://jcenter.bintray.com/com/android/tools/build/gradle/2.3.0/gradle-2.3.0.pom
(more downloads)

I have also tried using gradle argument to set gradle user home, aggressively specifying .gradle/ for cache, etc, but none of them worked.

Any ideas?

Body:
If you use Gitlab < 9.0,you add to specify the cache has to be shared among different pipelines.

Try to add key: $CI_PROJECT_NAME under cache:

image: runmymind/docker-android-sdk:latest
variables:
  GRADLE_USER_HOME: $CI_PROJECT_DIR/.gradle
stages:
  - build
debug:
  stage: build
  script:
    - set +e
    - du -sh $CI_PROJECT_DIR/.gradle/wrapper
    - du -sh $CI_PROJECT_DIR/.gradle/caches
    - set -e
    - ./gradlew assembleDebug
    - mkdir artifacts
    - cp mobile/build/outputs/apk/*.apk artifacts/
    - cp wear/build/outputs/apk/*.apk artifacts/
  cache:
    key: $CI_PROJECT_NAME
    paths:
      - .gradle/wrapper/
      - .gradle/caches/
      - build/
      - mobile/build/
      - wear/build/
  artifacts:
    name: "project_${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
    expire_in: 2 weeks
    paths:
      - artifacts/


答:
Your expression should be /\//g

var d = "3 / 29 / 2017";
d = d.replace(/\//g,'.');
document.body.append(d);```

Title: Replace slashes with dots in javascript regex


问:
Floats breaking my code
I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).

All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.

```<code>#include <iostream>
using namespace std;

void sort(int * a,int n)
{
    for(int i=0;i<n;++i)
        for(int j=i+1;j<n;++j)
        {
            if(a[i]>a[j])
            {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }\
        }
    return;
}

int main()
{
    int n;
    int check;
    int x;
    cout<<"Enter length of array:";
    cin>>n;
    if (n < 0){
        while (n < 0){
        cout << "Please enter a length greater than 0" << endl;
        cin >> n;
        }
    } else if (n % 1 != 0){
        while (n % 1 != 0){
            cout << "Whole numbers only! Try again" << endl;
            cin >> n;
        }
    }
    if (n == 0){
        cout <<"You try to enter numbers, but there's no place to put them." << endl;
        cout << ":(";
        return 0;
    }
    int a[n];
    cout<<"Enter values one by one:\n";
    for(int i=0;i<n;++i){
        cin >> x;
        a[i] = int(x);
    }
    sort(a,n);
    if (n % 2 == 1){
    cout<<"Median is:"<<a[n/2]<<endl;
    }
    else{
    float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
    cout << "Median is:" << z << endl;
    }

    return 0;
}
</code>```

First thing I tried was catching the float like so

```<code>`if (n % 1 !=0){
    while(n % 1 !=0){
        cout << "Enter a whole number"
        cin >> n
    }
}`
</code>```

This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.

I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.

I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.

How can I check against float user-input and loop them until they give me an int?

答:
You're reading into an int:

```<code>int x;
...
cin >> x;
</code>```

So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).

Instead, you could read into a float:

```<code>float x;
...
cin >> x;
</code>```

And do the appropriate math.

Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.

And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.

Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

Title: Floats breaking my code

Body:
I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).

All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.

#include <iostream>
using namespace std;

void sort(int * a,int n)
{
    for(int i=0;i<n;++i)
        for(int j=i+1;j<n;++j)
        {
            if(a[i]>a[j])
            {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }\
        }
    return;
}

int main()
{
    int n;
    int check;
    int x;
    cout<<"Enter length of array:";
    cin>>n;
    if (n < 0){
        while (n < 0){
        cout << "Please enter a length greater than 0" << endl;
        cin >> n;
        }
    } else if (n % 1 != 0){
        while (n % 1 != 0){
            cout << "Whole numbers only! Try again" << endl;
            cin >> n;
        }
    }
    if (n == 0){
        cout <<"You try to enter numbers, but there's no place to put them." << endl;
        cout << ":(";
        return 0;
    }
    int a[n];
    cout<<"Enter values one by one:\n";
    for(int i=0;i<n;++i){
        cin >> x;
        a[i] = int(x);
    }
    sort(a,n);
    if (n % 2 == 1){
    cout<<"Median is:"<<a[n/2]<<endl;
    }
    else{
    float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
    cout << "Median is:" << z << endl;
    }

    return 0;
}

First thing I tried was catching the float like so

`if (n % 1 !=0){
    while(n % 1 !=0){
        cout << "Enter a whole number"
        cin >> n
    }
}`

This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.

I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.

I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.

How can I check against float user-input and loop them until they give me an int?

Body:
You're reading into an int:

int x;
...
cin >> x;

So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).

Instead, you could read into a float:

float x;
...
cin >> x;

And do the appropriate math.

Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.

And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.

Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).


问:
Should I test all enum values in a contract?
I have a doubt about about whether I should consider a certain type of test functional or contract.

Let's say I have an API like /getToolType, that accepts a {object" "myObject"} as input, and returns at type in the form {type: "[a-z]+"}

It was agreed between client and server that the types returned will match a set of strings, let's say [hammer|knife|screwdriver], so the consumer decided to parse them in an enum, with a fallback value when the returned type is unknown.

Should the consumer include a test case for each type(hammer, knife, screwdriver) to ensure the producer is still following the agreement that it will always return , for instance , the lowercase string "hammer" when /getToolType is called with an hammer object?
Or would you consider such a test case as functional? And why?

答:
Great question.  Short answer: there's no right or wrong way, just how you want to do it.

Longer answer:

The point of Pact (and contract testing) is to test specific scenarios and making sure that they match up.  You could simply, in your contract, create a regex that allows any string type for those enums, or maybe null, but only if your consumer simply doesn't care about that value.  For instance, if the tool type had a brand, I wouldn't care about the brand, just that it's returned back as a string since I just display the brand verbatim on the consumer (front-end).

However, if it was up to me, from what I understand of your scenario, it seems like the tool type is actually pretty important considering the endpoint it's hitting, hence I would probably have specific tests and contracts for each enum to make sure that those particular scenarios on my consumer are valid (I call X with something and I expect Y to have tool type Z).

Both of these solutions are valid, what it comes down to is this: Do you think the specific tool type is important to the consumer?  If it is, create contracts specific to it, if not, then just create a generic contract.

Hope that helps.


问:
The reference to the class in ES6 is lost
I have the following structure Javacript es5-es6 and the controller class loses the reference in the class Get, I was already investigating but I can not find how to avoid losing the reference.</p>

```<code>class Controller {
    constructor() {
        this.name = 'Test';
    }
    test() {
        console.log(1, this.name);
    }
}

referenceController = new Controller();
// working reference: console.log(1, 'Test');
referenceController.test();

class Get {
    method() {
        return {
            controller: referenceController.test
        }
    }
}

// Lost self reference: console.log(1, undefined)
new Get().method().controller()
</code>```

答:
In this section, you add the test function as a property of the returned object.

```<code>{
    controller: referenceController.test
}
</code>```

Then, when you call it as a method of that object (method().controller()) this refers to the object, and the name property is read from the object.

You could bind the context to preserve the reference:

```<code>referenceController.test.bind(referenceController)
</code>```

Body:
I have the following structure Javacript es5-es6 and the controller class loses the reference in the class Get, I was already investigating but I can not find how to avoid losing the reference.

class Controller {
    constructor() {
        this.name = 'Test';
    }
    test() {
        console.log(1, this.name);
    }
}

referenceController = new Controller();
// working reference: console.log(1, 'Test');
referenceController.test();

class Get {
    method() {
        return {
            controller: referenceController.test
        }
    }
}

// Lost self reference: console.log(1, undefined)
new Get().method().controller()

Body:
In this section, you add the test function as a property of the returned object.

{
    controller: referenceController.test
}

Then, when you call it as a method of that object (method().controller()) this refers to the object, and the name property is read from the object.

You could bind the context to preserve the reference:

referenceController.test.bind(referenceController)


问:
Augular 2 Router Animation - Cannot find module '@angular/platform-browser/animations'
I have been following the Angular 2 Routing and Navigation example that can be found at this link: https://plnkr.co/edit/I4ArEQTniO7MJtfzpBWl?p=info.

When I run the transpiler I get the error message: "client/app/app.module.ts(5,41): error TS2307: Cannot find module '@angular/platform-browser/animations'."

Based on my systemjs.config.js (shown below), I would expect the module '@angular/platform-browser/animations' to be the file, "platform-browser-animations.umd.js" located in node_modules/@angular/platform-browser/bundles, but it is not there.

```<code>//systemjs.config.js
(function (global) {
  System.config({
    paths: {
  // paths serve as alias
  'npm:': 'node_modules/'
   },
  // map tells the System loader where to look for things
  map: {
  // our app is within the app folder
  app: 'app',

  '@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
  '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
  '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
  '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
  '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
  '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
  '@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
  '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
  '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
  '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
  '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
  '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
  '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
  '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',

  // other libraries
  'rxjs':                      'npm:rxjs',
  'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
  //app: {
  //  main: './main.js',
  //  defaultExtension: 'js'
  //},
  client: {
    main: './main.js',
    defaultExtension: 'js'
  },
  rxjs: {
    defaultExtension: 'js'
  }
}
});
})(this);
</code>```

Using npm I tried to install the install the missing frameworks but receive an unmet dependency error message:

```<code>+-- UNMET PEER DEPENDENCY @angular/common@2.4.8
+-- UNMET PEER DEPENDENCY @angular/core@2.4.8
`-- UNMET PEER DEPENDENCY @angular/platform-browser@2.4.10
</code>```

I then tried to install the dependent versions but continued to receive the unmet dependency message.

```<code>>npm install @angular/common@2.4.8 @angular/core@2.4.8 @angular/platform-browser@2.4.10 --save
</code>```

I noticed one warning that indicates that I should install Angular 4.

```<code>npm WARN @angular/animations@4.0.0 requires a peer of @angular/core@4.0.0 but no
ne was installed.
</code>```

It looks like I have animations 4.0 installed and it requires core 4.0 which I do not want to install.   Do I need to uninstall animations 4.0 and install an earlier version of animations?   My package.json file is below.

```<code>//package.json
{
"name": "angular-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"build": "tsc -p client/",
"build:watch": "tsc -p client/ -w",
"build:e2e": "tsc -p e2e/",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "npm run build:watch",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./client/**/*.ts -t verbose"
  },
 "keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/common": "^2.4.8",
"@angular/compiler": "~2.4.0",
"@angular/core": "^2.4.8",
"@angular/forms": "~2.4.0",
"@angular/http": "~2.4.0",
"@angular/platform-browser": "^2.4.10",
"@angular/platform-browser-dynamic": "~2.4.0",
"@angular/router": "~3.4.0",
"angular-animate": "^1.6.3",
"angular-in-memory-web-api": "~0.2.4",
"body-parser": "^1.17.0",
"bootstrap": "^3.3.7",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"ejs": "^2.5.6",
"express": "^4.15.0",
"express-session": "^1.15.1",
"jade": "^1.11.0",
"jquery": "^3.1.1",
"mongoose": "^4.8.5",
"morgan": "^1.8.1",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"rxjs": "5.0.1",
"stylus": "^0.54.5",
"systemjs": "0.19.40",
"toastr": "^2.1.2",
"zone.js": "^0.7.4"
 },
"devDependencies": {
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"typescript": "~2.0.10",
"canonical-path": "0.0.2",
"tslint": "^3.15.1",
"lodash": "^4.16.4",
"jasmine-core": "~2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~4.0.14",
"rimraf": "^2.5.4",
"@types/node": "^6.0.46",
"@types/jasmine": "2.5.36"
 },
"repository": {}
}
</code>```

It looks like the problem could be related to my animations version ? If you agree, how to uninstall the existing version and what version should I install that is compatible with the version of @angular/core I have, 2.4.8.   If this is not the problem how do I install the missing file, @angular/platform-browser/bundles/platform-browser-animations.umd.js?

答:
After researching for hours I could find no version of @angular/animations that was compatible with my version(s) of @angular/core which ranged from 2.4.0-2.4.8.  I read the answer to this post, How to get list of versions for compatible Angular 2 modules?.  This post indicated that all modules of angular 2 except the router are at the same version so I plugged @angular/animations 2.4.8 into my package.json and changed all versions to 2.4.8 including the animations entry as I wanted to be sure I was not missing something.  I then ran npm install and this failed on the animations version.

I finally found this post; http://angularjs.blogspot.com/ on updating to Angular 4.0.  The post also had a specific mention to the animations module I have been missing but only available with the upgrade.   I followed the simple update instructions for windows and my application is now running fine. My app is very similar to the plunker example from the guide.  Per the post, if you are running Angular 2.x.x then this should backward compatible for most applications.  Below are the upgrade instructions.

Updating to 4.0.0

Updating to 4 is as easy as updating your Angular dependencies to the latest version, and double checking if you want animations. This will work for most use cases.

On Linux/Mac:

npm install @angular/{common,compiler,compiler-cli,core,forms,http,platform-browser,platform-browser-dynamic,platform-server,router,animations}@latest typescript@latest --save

On Windows:

npm install @angular/common@latest @angular/compiler@latest @angular/compiler-cli@latest @angular/core@latest @angular/forms@latest @angular/http@latest @angular/platform-browser@latest @angular/platform-browser-dynamic@latest @angular/platform-server@latest @angular/router@latest @angular/animations@latest typescript@latest --save

Body:
I have been following the Angular 2 Routing and Navigation example that can be found at this link: https://plnkr.co/edit/I4ArEQTniO7MJtfzpBWl?p=info.

When I run the transpiler I get the error message: "client/app/app.module.ts(5,41): error TS2307: Cannot find module '@angular/platform-browser/animations'."

Based on my systemjs.config.js (shown below), I would expect the module '@angular/platform-browser/animations' to be the file, "platform-browser-animations.umd.js" located in node_modules/@angular/platform-browser/bundles, but it is not there.

//systemjs.config.js
(function (global) {
  System.config({
    paths: {
  // paths serve as alias
  'npm:': 'node_modules/'
   },
  // map tells the System loader where to look for things
  map: {
  // our app is within the app folder
  app: 'app',

  '@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
  '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
  '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
  '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
  '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
  '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
  '@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
  '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
  '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
  '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
  '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
  '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
  '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
  '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',

  // other libraries
  'rxjs':                      'npm:rxjs',
  'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
  //app: {
  //  main: './main.js',
  //  defaultExtension: 'js'
  //},
  client: {
    main: './main.js',
    defaultExtension: 'js'
  },
  rxjs: {
    defaultExtension: 'js'
  }
}
});
})(this);

Using npm I tried to install the install the missing frameworks but receive an unmet dependency error message:

+-- UNMET PEER DEPENDENCY @angular/common@2.4.8
+-- UNMET PEER DEPENDENCY @angular/core@2.4.8
`-- UNMET PEER DEPENDENCY @angular/platform-browser@2.4.10

I then tried to install the dependent versions but continued to receive the unmet dependency message.

>npm install @angular/common@2.4.8 @angular/core@2.4.8 @angular/platform-browser@2.4.10 --save

I noticed one warning that indicates that I should install Angular 4.

npm WARN @angular/animations@4.0.0 requires a peer of @angular/core@4.0.0 but no
ne was installed.

It looks like I have animations 4.0 installed and it requires core 4.0 which I do not want to install.   Do I need to uninstall animations 4.0 and install an earlier version of animations?   My package.json file is below.

//package.json
{
"name": "angular-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"build": "tsc -p client/",
"build:watch": "tsc -p client/ -w",
"build:e2e": "tsc -p e2e/",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "npm run build:watch",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./client/**/*.ts -t verbose"
  },
 "keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/common": "^2.4.8",
"@angular/compiler": "~2.4.0",
"@angular/core": "^2.4.8",
"@angular/forms": "~2.4.0",
"@angular/http": "~2.4.0",
"@angular/platform-browser": "^2.4.10",
"@angular/platform-browser-dynamic": "~2.4.0",
"@angular/router": "~3.4.0",
"angular-animate": "^1.6.3",
"angular-in-memory-web-api": "~0.2.4",
"body-parser": "^1.17.0",
"bootstrap": "^3.3.7",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"ejs": "^2.5.6",
"express": "^4.15.0",
"express-session": "^1.15.1",
"jade": "^1.11.0",
"jquery": "^3.1.1",
"mongoose": "^4.8.5",
"morgan": "^1.8.1",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"rxjs": "5.0.1",
"stylus": "^0.54.5",
"systemjs": "0.19.40",
"toastr": "^2.1.2",
"zone.js": "^0.7.4"
 },
"devDependencies": {
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"typescript": "~2.0.10",
"canonical-path": "0.0.2",
"tslint": "^3.15.1",
"lodash": "^4.16.4",
"jasmine-core": "~2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~4.0.14",
"rimraf": "^2.5.4",
"@types/node": "^6.0.46",
"@types/jasmine": "2.5.36"
 },
"repository": {}
}

It looks like the problem could be related to my animations version ? If you agree, how to uninstall the existing version and what version should I install that is compatible with the version of @angular/core I have, 2.4.8.   If this is not the problem how do I install the missing file, @angular/platform-browser/bundles/platform-browser-animations.umd.js?


问:
Array does not connect with the tableView(numberOfRowsInSection) method
I have an array which I will store all data that I get from http request and display them on tableView but it seems that tableView(numberOfRowsInSection) does not recognize the change in the array because the count remains as 0.

```<code>class OrdersViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    var arr = [[String: AnyObject]]()
    var selectedIndex = -1

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        let baseUrl = "my url"
        let consumer_key = "consumer_key"
        let consumer_secret = "consumer_key"
        let url = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=processing"

        let headers2 = ["Accept": "application/json"]
        Alamofire.request(url, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                }
        }

        let url2 = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=pending"
        Alamofire.request(url2, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                    print("arr", self.arr)
                }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        print("after request", self.arr)
        return self.arr.count
    }
}
// and some other code...
</code>```

I do get data from the http request successfully and it gets updated in my Alamofire call but "after request" keeps printing empty array. What's going on here?

答:
You need to call tableView.reloadData() after changing your self.arr property. The corresponding documentation provides further details:

Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible.

If you plan on changing your self.arr property in many places, you could alternatively add a property observer to it:

```<code>var arr = [[String: AnyObject]]() {
    didSet { tableView?.reloadData() }
}
</code>```

...so you wouldn't need to copy-and-paste the same code all around ;-)

Body:
I have an array which I will store all data that I get from http request and display them on tableView but it seems that tableView(numberOfRowsInSection) does not recognize the change in the array because the count remains as 0.

class OrdersViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    var arr = [[String: AnyObject]]()
    var selectedIndex = -1

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        let baseUrl = "my url"
        let consumer_key = "consumer_key"
        let consumer_secret = "consumer_key"
        let url = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=processing"

        let headers2 = ["Accept": "application/json"]
        Alamofire.request(url, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                }
        }

        let url2 = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=pending"
        Alamofire.request(url2, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                    print("arr", self.arr)
                }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        print("after request", self.arr)
        return self.arr.count
    }
}
// and some other code...

I do get data from the http request successfully and it gets updated in my Alamofire call but "after request" keeps printing empty array. What's going on here?

Body:
You need to call tableView.reloadData() after changing your self.arr property. The corresponding documentation provides further details:

Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible.

If you plan on changing your self.arr property in many places, you could alternatively add a property observer to it:

var arr = [[String: AnyObject]]() {
    didSet { tableView?.reloadData() }
}

...so you wouldn't need to copy-and-paste the same code all around ;-)


答:
Replace /'/'/g with /[/]/g

/ - start of the regex

[/] match characters inside square brackets

/g end of the regex

Regex resources:

http://regexr.com/

https://regexone.com/


问:
Python Code from Programming Collective intelligence
Heres a code of recommendations.py Programming Collective Intelligence Book Chapter 2.

The code below is to returns the best matches for person from the preference dictionary and get recommendations for a person by using a weighted average of every other user's rankings

```<code>from math import sqrt
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,'The Night Listener': 3.0},'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,'You, Me and Dupree': 3.5},'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,'Superman Returns': 3.5, 'The Night Listener': 4.0},'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,'The Night Listener': 4.5, 'Superman Returns': 4.0,'You, Me and Dupree': 2.5},'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,'You, Me and Dupree': 2.0},'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}
def sim_distance(prefs,person1,person2):  # Get the list of shared_items
    si={}
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item]=1
# if they have no ratings in common, return 0
    if len(si)==0:
        return 0
# Add up the squares of all the differences
    sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
                    for item in prefs[person1] if item in prefs[person2]])
    return 1/(1+sum_of_squares)
</code>```

I have just started working with python, so I'm confused what is the difference between these two loops :

At the starting,

```<code>for item in prefs[person1]:
    if item in prefs[person2]:
</code>```

At the end,

```<code>for item in prefs[person1] if item in prefs[person2]])
</code>```

Also, they use the square root in implementation , which in this code, they   have not used. So, is this just an example or we dont use in codes?
Also, if these both for loops are same, they give different answers when I apply the second for loop like this.

```<code>for item in prefs[person1]:
    if item in prefs[person2]:
        sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)])
</code>```

答:
Also, they use the square root in implementation , which in this code, they have not used. So, is this just an example or we dont use in codes?

Please check this link The 'Unconfirmed' errata for this mistake by O'Reilly Media

The last method should be return 1/(1+*sqrt(sum_of_squares)) and off course you can use this in code.
Also, there is a mistake in the example too. The coordinates are wrong. please refer the link

As mentioned in the comment, 1st loop checks how many ratings they have in common.

>>> recommendations.sim_distance(recommendations.critics,'Lisa Rose','Toby')

[FOR] Lisa :  Lady in the Water
[FOR] Lisa :  Snakes on a Plane
[IF] Toby  :  Snakes on a Plane
[FOR] Lisa :  Just My Luck
[FOR] Lisa :  Superman Returns
[IF] Toby  :  Superman Returns
[FOR] Lisa :  You, Me and Dupree
[IF] Toby  :  You, Me and Dupree
[FOR] Lisa :  The Night Listener

0.3483314773547883
```

The 2nd loop iterates the item-values(ratings)for subtraction.

As per the above list, this loop has to make 3 iterations
(FOR == person1,    IF == person2).

Body:
Heres a code of recommendations.py Programming Collective Intelligence Book Chapter 2.

The code below is to returns the best matches for person from the preference dictionary and get recommendations for a person by using a weighted average of every other user's rankings

from math import sqrt
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,'The Night Listener': 3.0},'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,'You, Me and Dupree': 3.5},'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,'Superman Returns': 3.5, 'The Night Listener': 4.0},'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,'The Night Listener': 4.5, 'Superman Returns': 4.0,'You, Me and Dupree': 2.5},'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,'You, Me and Dupree': 2.0},'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}
def sim_distance(prefs,person1,person2):  # Get the list of shared_items
    si={}
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item]=1
# if they have no ratings in common, return 0
    if len(si)==0:
        return 0
# Add up the squares of all the differences
    sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
                    for item in prefs[person1] if item in prefs[person2]])
    return 1/(1+sum_of_squares)

I have just started working with python, so I'm confused what is the difference between these two loops :

At the starting,

for item in prefs[person1]:
    if item in prefs[person2]:

At the end,

for item in prefs[person1] if item in prefs[person2]])

Also, they use the square root in implementation , which in this code, they   have not used. So, is this just an example or we dont use in codes?
Also, if these both for loops are same, they give different answers when I apply the second for loop like this.

for item in prefs[person1]:
    if item in prefs[person2]:
        sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)])

Body:
Also, they use the square root in implementation , which in this code, they have not used. So, is this just an example or we dont use in codes?

Please check this link The 'Unconfirmed' errata for this mistake by O'Reilly Media

The last method should be return 1/(1+*sqrt(sum_of_squares)) and off course you can use this in code.
Also, there is a mistake in the example too. The coordinates are wrong. please refer the link

As mentioned in the comment, 1st loop checks how many ratings they have in common.

>>> recommendations.sim_distance(recommendations.critics,'Lisa Rose','Toby')

[FOR] Lisa :  Lady in the Water
[FOR] Lisa :  Snakes on a Plane
[IF] Toby  :  Snakes on a Plane
[FOR] Lisa :  Just My Luck
[FOR] Lisa :  Superman Returns
[IF] Toby  :  Superman Returns
[FOR] Lisa :  You, Me and Dupree
[IF] Toby  :  You, Me and Dupree
[FOR] Lisa :  The Night Listener

0.3483314773547883

The 2nd loop iterates the item-values(ratings)for subtraction.

As per the above list, this loop has to make 3 iterations
(FOR == person1,    IF == person2).


问:
Angular1 Scope not sending data to controller
Im doing an angular project to pass a form varible to different controllers. I'm a bit new to angular but after learning about rootscope i still havent solved this, the controler send data to the form but the for can send data to the controller, can someone please help. Below is my code;

```<code>form:
  <form ng-submit="start()">
    <div class="list card">
      <div class="item item-divider">Select Subjects</div>

    <label class="item item-input item-select">
    <div class="input-label icon icon-left ion-book">
      Subject 1
    </div>
    <select ng-model="sub1">
      <option selected>ENGLISH</option>
    </select>
  </label>

    <label class="item item-input item-select">
   <div class="input-label">
      Subject 2
    </div>
    <select ng-model="exam.sub2">
      <option>MATHEMATICS</option>
      <option selected>LITERATURE</option>
      <option>ECONOMICS</option>
        <option>GOVERNMENT</option>
        <option >PHYSICS</option>
        <option>COMMERCE</option>
        <option>ACCOUNT</option>
        <option>GEOGRAPHY</option>
        <option>BIOLOGY</option>
        <option>CRS</option>
        <option >CHEMISTRY</option>
    </select>
  </label>

Controller:
app.controller('setCtrl', ["$scope", function(c){
    c.start = function(){
       console.log = c.exam.sub2
    };

}]);
</code>```

Thanks in advanceenter code here

答:
You are missing is the exam object in your scope to begin with.

```<code>app.controller('setCtrl', ["$scope", function(c){
      c.exam = {};   // object to hold your form values
      c.start = function(){
        console.log( c.exam );
      };

}]);
</code>```

your HTML inputs should be

```<code><select ng-model="exam.sub1">

<select ng-model="exam.sub2">
</code>```

Body:
Im doing an angular project to pass a form varible to different controllers. I'm a bit new to angular but after learning about rootscope i still havent solved this, the controler send data to the form but the for can send data to the controller, can someone please help. Below is my code;

form:
  <form ng-submit="start()">

Select Subjects

      Subject 1

    <select ng-model="sub1">
      <option selected>ENGLISH</option>
    </select>

      Subject 2

    <select ng-model="exam.sub2">
      <option>MATHEMATICS</option>
      <option selected>LITERATURE</option>
      <option>ECONOMICS</option>
        <option>GOVERNMENT</option>
        <option >PHYSICS</option>
        <option>COMMERCE</option>
        <option>ACCOUNT</option>
        <option>GEOGRAPHY</option>
        <option>BIOLOGY</option>
        <option>CRS</option>
        <option >CHEMISTRY</option>
    </select>

Controller:
app.controller('setCtrl', ["$scope", function(c){
    c.start = function(){
       console.log = c.exam.sub2
    };

}]);

Thanks in advanceenter code here

Body:
You are missing is the exam object in your scope to begin with.

app.controller('setCtrl', ["$scope", function(c){
      c.exam = {};   // object to hold your form values
      c.start = function(){
        console.log( c.exam );
      };

}]);

your HTML inputs should be

<select ng-model="exam.sub1">

<select ng-model="exam.sub2">


问:
Returning string from C function
I haven't used C in over 3 years, I'm pretty rusty on a lot of things.

I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.

Here is my code:

```<code>#include <ncurses.h>

char * getStr(int length)
{
    char word[length];

    for (int i = 0; i < length; i++)
    {
        word[i] = getch();
    }

    word[i] = '\0';
    return word;
}

int main()
{
    char wordd[10];
    initscr();
    *wordd = getStr(10);
    printw("The string is:\n");
    printw("%s\n",*wordd);
    getch();
    endwin();
    return 0;
}
</code>```

I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).

Help is appreciated.

答:
Easier still: return a pointer to a string that's been malloc'd with strdup.</p>

```<code>#include <ncurses.h>

char * getStr(int length)
{
    char word[length];

    for (int i = 0; i < length; i++)
    {
        word[i] = getch();
    }

    word[i] = '\0';
    return strdup(&word[0]);
}

int main()
{
    char wordd[10];
    initscr();
    *wordd = getStr(10);
    printw("The string is:\n");
    printw("%s\n",*wordd);
    getch();
    endwin();
    return 0;
}
</code>```

Title: Returning string from C function

Body:
I haven't used C in over 3 years, I'm pretty rusty on a lot of things.

I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.

Here is my code:

#include <ncurses.h>

char * getStr(int length)
{
    char word[length];

    for (int i = 0; i < length; i++)
    {
        word[i] = getch();
    }

    word[i] = '\0';
    return word;
}

int main()
{
    char wordd[10];
    initscr();
    *wordd = getStr(10);
    printw("The string is:\n");
    printw("%s\n",*wordd);
    getch();
    endwin();
    return 0;
}

I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).

Help is appreciated.

Body:
Easier still: return a pointer to a string that's been malloc'd with strdup.

#include <ncurses.h>

char * getStr(int length)
{
    char word[length];

    for (int i = 0; i < length; i++)
    {
        word[i] = getch();
    }

    word[i] = '\0';
    return strdup(&word[0]);
}

int main()
{
    char wordd[10];
    initscr();
    *wordd = getStr(10);
    printw("The string is:\n");
    printw("%s\n",*wordd);
    getch();
    endwin();
    return 0;
}


问:
Show/Hide Div when link is clicked
Greeting first time poster longtime reader...
    I have looked high and low and yet to find what i am wanting to do.

with in my site there is going to be building layouts "Large" over 100 rooms.
I want to be able to click on the rooms and on the right side of the page pull up info about that room.
I want the info to be "hidden Div"
thank you all advance.

```<code><!DOCTYPE html>
<html>
<head>

<link rel="stylesheet" href="screen.css" type="text/css" media="all">

</head>
<body>
<div id="building">
<img src="http://upload.wikimedia.org/wikipedia/commons/9/9a/Sample_Floorplan.jpg"  alt="" usemap="#map">

<map id="map" name="map">
<area class="link" shape="rect" alt="" title="" coords="137,54,242,161" href="#one" target="" />
<area class="link" shape="rect" alt="" title="" coords="138,182,232,256" href="#two" target="" />
<area class="link" shape="rect" alt="" title="" coords="53,313,170,339" href="#three" target="" />
</map>
</div>
<div  id="menu">

<div class="tab" id="one">
This is One

</div>
<div class="tab" id="two">
This is two

</div>
<div class="tab" id="three">
This is three

</div>

</div>

</body>
</html>
</code>```

here is my css

```<code>  html {
 padding:0px;
 margin:0px;
}

body {
background-color: #e1ddd9;
font-size: 12px;
font-family: Verdana, Arial, SunSans-Regular, Sans-Serif;
color:#564b47;
padding:0px 20px;
margin:0px;
}

#building {
float: left;
width: 75%;
background-color: #fff;
margin:0px 0px 50px 0px;
overflow: auto;
}
 #menu {
float: left;
width: 25%;
background-color: #ff99CC;
overflow: auto;

}
</code>```

答:
It's simple:

```<code>div
{display: none;}
</code>```

When link is clicked, write .show() in jQuery.
When other links are clicked, write .hide() in jQuery.

Title: Show/Hide Div when link is clicked

Body:
Greeting first time poster longtime reader...
    I have looked high and low and yet to find what i am wanting to do.

with in my site there is going to be building layouts "Large" over 100 rooms.
I want to be able to click on the rooms and on the right side of the page pull up info about that room.
I want the info to be "hidden Div"
thank you all advance.

<!DOCTYPE html>

<link rel="stylesheet" href="screen.css" type="text/css" media="all">

<map id="map" name="map">
<area class="link" shape="rect" alt="" title="" coords="137,54,242,161" href="#one" target="" />
<area class="link" shape="rect" alt="" title="" coords="138,182,232,256" href="#two" target="" />
<area class="link" shape="rect" alt="" title="" coords="53,313,170,339" href="#three" target="" />
</map>

This is One

This is two

This is three

here is my css

  html {
 padding:0px;
 margin:0px;
}

body {
background-color: #e1ddd9;
font-size: 12px;
font-family: Verdana, Arial, SunSans-Regular, Sans-Serif;
color:#564b47;
padding:0px 20px;
margin:0px;
}

#building {
float: left;
width: 75%;
background-color: #fff;
margin:0px 0px 50px 0px;
overflow: auto;
}
 #menu {
float: left;
width: 25%;
background-color: #ff99CC;
overflow: auto;

}

Body:
It's simple:

div
{display: none;}

When link is clicked, write .show() in jQuery.
When other links are clicked, write .hide() in jQuery.


问:
list buttons responsive design
How can I put this button inline to be responsive?
had tried doing  but doesnt work.

```<code><div class="form-group btn-group"  >
    <ul class="btn-group list-inline social "  style="display: flex;">
      <li class="col-xs-12">
        <button type="submit" class="btn  btn-default" name="btn-login" id="btn-login">
          <span class="glyphicon glyphicon-log-in"></span>   Sign In
        </button>
      </li>
      <li class="col-xs-12">
        <a href="<?=$fbLoginUrl ?>" class="btn btn-social btn-facebook" style="float:left;margin-right:5px, color:#3B5998">Sign in with Facebook </a>
      </li>
      <li class="col-xs-12">
        <a href="register.php" class="btn btn-social btn-default" style="float:right;">Sign UP Here </a>
      </li>
    </ul>

  </div>
</code>```

答:
I would remove the style="display: flex;" from you ultag. Without it the two buttons will be full width (they have the col-xs-12 class).

To have them in one line in case the modal is displayed larger on larger screens you can add an additional class like col-sm-6 or col-md-6 to both.

Title: list buttons responsive design

Body:
How can I put this button inline to be responsive?
had tried doing  but doesnt work.

        <button type="submit" class="btn  btn-default" name="btn-login" id="btn-login">
             Sign In
        </button>

        <a href="<?=$fbLoginUrl ?>" class="btn btn-social btn-facebook" style="float:left;margin-right:5px, color:#3B5998">Sign in with Facebook

        Sign UP Here