I'm attempting to create a tool that compares the current year to the year that an event took place and then allows the user to guess how many years it has been since that event occurred. For example, the inaugural FRC Championship took place in 1992. The current year is 2015. The user guesses that it took place 23 years ago, which is correct.
So, in my mind the code would look like this...
public class Credits extends Activity {
int inaugural = 1992;
int guess;
int differenceInYears;
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int output;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_credits);
final EditText yearGuess=(EditText)findViewById(R.id.txtYearGuess);
Button go = (Button)findViewById(R.id.btnCalculate);
final TextView result = ((TextView)findViewById(R.id.txtResult));
go.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int userGuess= Integer.parseInt(yearGuess.getText().toString());
differenceInYears = year - inaugural;
output = userGuess - differenceInYears;
if (output < 1) {
result.setText("Guess again! You guessed too low!");
}
else if (output == 1) {
result.setText("You're REALLY close!");
}
else if (output == -1) {
result.setText("You're REALLY close!");
}
else if (output > 1) {
result.setText("Guess again! You guessed too high!");
}
else {
result.setText("Good job! You're an FRC Genious!");
}
}
});
}
}
...however, the values continue to come out wrong when tested. What am I missing here? Is there something wrong with my math? or code? or both?
It has to do with the logic of your if-statement. When the user guesses correctly, "output" should equal 0 which would get caught by your first condition.
Simple logic error.
if (output < 1) {
result.setText("Guess again! You guessed too low!");
}
should have been...
if (output < -1) {
result.setText("Guess again! You guessed too low!");
}
Just forgot to make the low comparison negative.
Related
I am struggling with one very strange bug in my app.
I have added TTS to it, and I am using the build one. The user can choose the language from the spinner which is filled in during AsyncTask started in onResume().
The AsyncTask looks like this:
private class AsyncTTSDownload extends AsyncTask<Void, Integer, String> {
#Override
protected String doInBackground(Void... params) {
try {
languagesTTS = tts.testLang();
} catch (Exception ex) {
if (D)
Log.e(TAG, ex.toString());
}
return null;
}
#Override
protected void onPostExecute(String result) {
ttsUpdate.dismiss();
TTSSpinnerAdapter adapterTTS = new TTSSpinnerAdapter(
MyTTS.this, android.R.layout.simple_spinner_item,
languagesTTS);
int savedLangTTS = ttsLang.getInt("savedTTS", -1);
langTTS.setAdapter(adapterTTS);
if (savedLangTTS == -1)
{
try {
int langObject = languagesTTS.indexOf(tts.getLanguage());
langTTS.setSelection(langObject);
} catch (IndexOutOfBoundsException ie) {
langTTS.setSelection(0);
}
} else {
langTTS.setSelection(savedLangTTS);
}
Locale langChoosen = (Locale) langTTS.getItemAtPosition(langTTS
.getSelectedItemPosition());
tts.setTTSLanguage(langChoosen);
}
#Override
protected void onPreExecute() {
ttsUpdate = ProgressDialog.show(MyTTS.this, "Wait",
"Loading TTS...");
ttsUpdate.setCancelable(false);
}
}
the thing is, that I am from time to time getting different number of languages supported. This is on this same device, during this same run. Just I open and close Activity with TTS. This bug is causing IndexOutOfBoundsException. This is my way of getting TTS languages:
public List<Locale> testLang() {
Locale[] AvalLoc = Locale.getAvailableLocales();
List<Locale> listaOK = new ArrayList<Locale>();
String tester = "";
for (Locale l : AvalLoc) {
if(tester.contains(l.getLanguage()))
{
continue;
}
int buf = tts.isLanguageAvailable(l);
if (buf == TextToSpeech.LANG_MISSING_DATA
|| buf == TextToSpeech.LANG_NOT_SUPPORTED) {
//TODO maybe
} else {
listaOK.add(l);
tester += l.getLanguage() + ";";
}
}
tts.setLanguage(Locale.ENGLISH);
return listaOK;
}
For now I've only find out a small hack for not showing this error, just save in shared preferences number of languages and compare it with what tts received, but it is not working well at all. Each time I am getting different number.
For me it seems, that something is not finished or started when I am starting again this same activity after return, because this is tts.isAvaliableLanguage(l) who is deciding whether language is supported or not and from time to time, one language is not supported and after reload it is.
EDIT:
As there appeared new comment about my question I need to add one important thing about TTS engine itself.
testLang() is a method inside my class Called TTSClass, that is implementing TextToSpeech.OnInitListener. tts object is created in onCreate of MyTTS activity and this constructor looks like this in TTSClass:
public TTSClass(Context context, Locale language) {
contextTTS = context;
languageTTS = language;
tts = new TextToSpeech(contextTTS, this);
}
and call in activity:
tts = new TTSClass(getApplicationContext(), Locale.ENGLISH);
Because TTSClass implements TextToSpeech.OnInitListener there is also onInit() method which looks like this:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = 0;
result = tts.setLanguage(languageTTS);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
if(D) Log.e(TAG, "This Language is not supported");
}
if(D) Log.d(TAG,"Initialized");
} else {
if(D) Log.e(TAG, "Initilization Failed!");
}
}
So, this is everything connecting to this class and problem I think. If anything is missing, let me now.
EDIT2:
Suggested by shoe rat comment I've run few more tests, and the outcome is just amazing, or extraordinary, I think it is better word.
So what I've done was adding 3 Log from different places in code informing me about list size on different stages.
First was added in onInit() in if status == TextToSpeech.SUCCESS. This one is just simple call of testLang().size(). The outcome is 5 languages - that is the correct number and it is always like this, no matter if there is or isn't an exception.
Second was added there:
protected String doInBackground(Void... params) {
try {
Log.w(TAG,"before: "+tts.testLang().size());
languagesTTS = tts.testLang();
}
and this one is starting to act quite weird. It is sometimes, or even quite often, showing number lower than 5. But this is not the strangest thing.
The third one is just at the beginning of onPostExecute checking the size of languagesTTS. And believe or not, the number is quite often totally different from the second log. However, it is never smaller. It can be equal or bigger.
Does anyone know, what is going one?
I've found solution. It came out that indeed it was initialization problem.
I'm not sure if documentation is saying anything about it, but it seem like the TTS engine initialization is done asynchronously, so it can finish at any time.
My solution was to change the doInBackground() method like this:
#Override
protected String doInBackground(Void... params) {
try {
while(!TTSClass.isInit){}
languagesTTS = tts.testLang();
} catch (Exception ex) {
if (D)
Log.e(TAG, ex.toString());
}
return null;
}
and in onInit() method I've added isInit public static boolean variable:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = 0;
result = tts.setLanguage(languageTTS);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
if(D) Log.e(TAG, "This Language is not supported");
}
if(D) Log.d(TAG,"initialized");
isInit = true;
} else {
if(D) Log.e(TAG, "Initilization Failed!");
}
}
Hope, that someone will find it helpful.
I'm generating a question and answers of that randomly. And I want to generate new random arrays and answer options according to those when users chose the correct answer. But it says "unreachable code" when I add a boolean while loop... What is theproblem?
Thanks...
final boolean basadon = false;
while(basadon)
{
Random soru = new Random();
final int[] rastgele = new int[1];
for (int i=0; i<1; i++)
{
rastgele[i]= soru.nextInt(8);
}
ArrayList<Integer> cevap = new ArrayList<Integer>();
for (int k = 0; k <= 7; ++k)
{
cevap.add(k);
}
final Integer[] rastgele2 = new Integer[4];
if (rastgele[0]!=cevap.get(0))
{
rastgele2[0]=cevap.get(0);
}
else
{
rastgele2[0]=cevap.get(3);
}
if (rastgele[0]!=cevap.get(1))
{
rastgele2[1]=cevap.get(1);
}
else
{
rastgele2[1]=cevap.get(3);
}
if (rastgele[0]!=cevap.get(2))
{
rastgele2[2]=cevap.get(2);
}
else
{
rastgele2[2]=cevap.get(3);
}
rastgele2[3]=rastgele[0];
Collections.shuffle(Arrays.asList(rastgele2));
view.setText(countries.get(rastgele[0]));
cevap1.setBackgroundResource(heads[rastgele2[0]]);
cevap1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (rastgele[0]==rastgele2[0])
{
cevap1.setBackgroundResource(heads[8]);
countries.remove(rastgele[0]);
basadon=true;
}
else {
cevap1.setBackgroundResource(heads[9]);
}
}
});
cevap2.setBackgroundResource(heads[rastgele2[1]]);
cevap2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (rastgele2[1]==rastgele[0])
{
cevap2.setBackgroundResource(heads[8]);
countries.remove(rastgele[0]);
basadon=true;
}
else {
cevap2.setBackgroundResource(heads[9]);
}
}
});
cevap3.setBackgroundResource(heads[rastgele2[2]]);
cevap3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (rastgele2[2]==rastgele[0])
{
cevap3.setBackgroundResource(heads[8]);
countries.remove(rastgele[0]);
basadon=true;
}
else {
cevap3.setBackgroundResource(heads[9]);
}
}
});
cevap4.setBackgroundResource(heads[rastgele2[3]]);
cevap4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (rastgele2[3]==rastgele[0])
{
cevap4.setBackgroundResource(heads[8]);
countries.remove(rastgele[0]);
basadon=true;
}
else {
cevap4.setBackgroundResource(heads[9]);
}
}
});
}
} }
Looks like you start with basedon value as false and later set it to true inside the loop.
So, Change
final boolean basedon = false
while (basedon) {
....
}
to
boolean basedon = false;
do {
....
} while (basedon);
while(basadon) is always false, so you never enter the loop. What you really mean is probably while(basadon==false). Also, don't declare basalon as final boolean because you want to modify its value later, and that will give error.
Why are you declaring all of those variables as final?
If bsadon for example needs to change from false to true, it can't be final. A final value is exactly that, a constant, it won't change.
Don't declare something as final unless you want it to keep the same value for the entire runtime of your program.
You are saying basadon is always "false", that's what final means, so the compiler is telling you you will never enter the while, since you need it to evaluate "true" to enter.
The expression between () in you while clause, needs to evaluate to true for the code to enter.
To your specific question which you have asked:
Why does the compiler give unreachable code warning
The answer is that since the condition in while loop is always false, there is no chance that the code in while loop will get executed. The warning is given to indicate that (given the current code situation) you have wasted your effort in typing that portion of code and it is guaranteed never to be executed. To rectify this, you can remove the final modifier from basedon and put a programming logic to set the value of basedon which will decide whether to enter the loop or not. If you want the loop to always run put while(true).
But I believe that what you wanted to ask was how to make the random question and answer generator. For that you'll have to post a bigger chunk of your code (It looks like you are trying to put a loop over a listener callback ?) and phrase your question to ask specific problems (possibly post a separate question).
It's probably complaining because basadon is known to be false and the body of the while loop cannot be reached. You can suppress the complaint by adding this annotation to the method:
#SuppressWarnings("unused")
You might also try removing the final modifier from the declaration of basadon. That might resolve the issue (but I'm not sure about that).
EDIT I finally noticed that you are trying to modify basadon directly from within your click listeners. That obviously won't work if basadon is final, yet you cannot access local variable unless it is final. I suggest you change basadon to be a (non-final) field of the enclosing class. Then all the warnings and errors should go away.
This question already has answers here:
How to change color of multiple choice to show correct answer
(2 answers)
Closed 9 years ago.
Im doing a multiple choice apps with 4 choices. I've downloaded a code. But how to prompt the user of the correct answer if his answer is incorrect answer (at the same time).Here is a sample of the code. Correct answer is green. Wrong answer is red.
optionOne.setOnClickListener(this); //On First Option selection
optionTwo.setOnClickListener(this); //On Second Option selection
optionThree.setOnClickListener(this); //On Third Option selection
optionFour.setOnClickListener(this); //On Forth Option selection
public void onClick(View v) {
if(v.getId() == optionOne.getId()){
onOptionSelected(optionOne.getText().toString(), v);
optionOne.setBackgroundColor(Color.RED);
}else if(v.getId() == optionTwo.getId()){
onOptionSelected(optionTwo.getText().toString(), v);
optionTwo.setBackgroundColor(Color.RED);
}else if(v.getId() == optionThree.getId()){
onOptionSelected(optionThree.getText().toString(), v);
optionThree.setBackgroundColor(Color.RED);
}else if(v.getId() == optionFour.getId()){
onOptionSelected(optionFour.getText().toString(), v);
optionFour.setBackgroundColor(Color.RED);
}else if(v.getId() == pause.getId()){ //True when Game is Paused
//When an option of a question is selected
private void onOptionSelected(String option, View v){
if(!isGamePaused && !isGameEnded) { //true when game is being played
ATriviaQuestion tTQuestion = myListOfTriviaQuestions.get(currentQuestionNumber);
if(option.equals(tTQuestion.GetOptions().get(tTQuestion.GetAnswer() - 1))) {
correct += 1;
v.setBackgroundColor(Color.GREEN);
}
else{
incorrect += 1;
totalPoints -= pointsPerWrongAnswer;
}
I need to insert a code on this portion to show the correct answer in green background if the user answer is incorrect but i don't know how.
else{
incorrect += 1;
totalPoints -= pointsPerWrongAnswer;
The database questions is in .plist
<question>
<key>Question</key>
<string>What is the ....</string>
<key>Options</key>
<array>
<string>option 1</string>
<string>option 2</string>
<string>option 3</string>
<string>option 4</string>
</array>
<key>Answer</key>
<integer>2</integer>
</question>
Here is my other code
public ATriviaQuestion(){
isThisQuestionAsked = false;
answer = -1;
answered = "";
}
public String GetQuestion()
{ return this.question; }
public void SetQuestion(String _question)
{ this.question=_question; }
public ArrayList<String> GetOptions()
{ return this.options; }
public void SetOptions(ArrayList<String> _options)
{ this.options = _options; }
public int GetAnswer()
{ return this.answer; }
public void SetAnswer(int _answer)
{ this.answer = _answer; }
I'm having trouble following exactly what is what here but you can loop through your options until the text equals tTQuestion.GetOptions().get(tTQuestion.GetAnswer() - 1) (which appears to be how you are getting the correct answer) then set that View's background color to green.
I am trying to learn java while building an android app. I have a points calculator without a button it uses a textchange listener to calculate the total. When backspace key is pressed and the box has null it crashes. I tried validating using the code below (only validated on field to begin with). But it does not work. Any help would be greatly appreciated.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wwcalc);
etFat = (EditText)findViewById(R.id.editTextFat);
etFiber = (EditText)findViewById(R.id.editTextFiber);
etProtein = (EditText)findViewById(R.id.editTextProtein);
etCarbs = (EditText)findViewById(R.id.editTextCarbs);
tvTotal = (TextView)findViewById(R.id.textViewPoints);
TextWatcher watcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if(isEmpty(etFat) == false){
intFat = Integer.parseInt(etFat.getText().toString());
}
else{
etFat.setText("0");
etFat.hasFocus();
return;
}
intProtein = Integer.parseInt(etProtein.getText().toString());
intFiber = Integer.parseInt(etFiber.getText().toString());
intCarbs = Integer.parseInt(etCarbs.getText().toString());
calculate();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
};
etFat.addTextChangedListener(watcher);
etProtein.addTextChangedListener(watcher);
etFiber.addTextChangedListener(watcher);
etCarbs.addTextChangedListener(watcher);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_wwcalc, menu);
return true;
}
public void calculate(){
//intTot = intFat + intCarbs + intFiber + intProtein;
intTot = (int) Math.ceil((intFat * (4/35)) + (intCarbs * (4/36.84)) - (intFiber* (4/50))+ (intProtein * (4/43.75)) ) ;
tvTotal.setText(Integer.toString(intTot));
}
private boolean isEmpty(EditText etText)
{
if(etText.getText().toString().trim().length() > 0 || etText.getText().toString().trim() != null)
return false;
else
return true;
}
}
Thanks for the help all. I got it working not sure if it is the best solution if anyone thinks there is a better way let me know. The try catch as suggested by conor catches the exception, then just insert a 0 set focus and select the 0
try {
intFat = Integer.parseInt(etFat.getText().toString());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
etFat.setText("0");
etFat.hasFocus();
etFat.selectAll();
}
Without seeing the stacktrace it is hard to know but i'm going to make a stab it anyway.
The following piece of your isEmpty() function is allowing false to be returned when the box could still be emtpy.
etText.getText().toString().trim() != null
This means that when you press backspace and clear the field it is empty but your function says it's not. Then the kicker, when your app thinks the field is not empty it tried to parse the contents for an integer value (which is not present). This attempt at parsing throws an exception and crashes your app.
I expect the stacktrace to show the app crashing at this line
intFat = Integer.parseInt(etFat.getText().toString());
It's worth noting that you should always surround calls like Integer.parseInt() with a try, catch block.
Hope that helps.
The exception should be caused by Integer.parseInt,
intFat = Integer.parseInt(etFat.getText().toString());
ntProtein = Integer.parseInt(etProtein.getText().toString());
intFiber = Integer.parseInt(etFiber.getText().toString());
intCarbs = Integer.parseInt(etCarbs.getText().toString());
If you pass string with spaces to parseInt, NumberFormatException will be thrown, you need to trim the text, and then set them, such as,
intFat = Integer.parseInt(etFat.getText().toString().trim());
try this
When backspace is pressed and a field is changed from say "0" to--> "" the operation that is supposed to convert the value to a double fails and crashed my application. "holder.mChoiceRNK"is the " EditView" reference " . If we look at what happens onAfterTextChanged we can set in a default value and then do a select all. The default value of "0" will not cause an error.
Cheers
And happy programming.
holder.mChoiceRNK.doAfterTextChanged {
Log.d(mTAG70, "130xxx 131 Pre Error")
if (holder.mChoiceRNK.text.toString() == "") {
holder.mChoiceRNK.setText("0") // new value if the backspace is pressed to create ""
holder.mChoiceRNK.selectAll()
} else{
Log.d(mTAG70, "130xxx 133 Past Error--> ${holder.mChoiceRNK.text}")
myRNKvotingArray[position].mRNK = holder.mChoiceRNK.text.toString().toDouble()
}}
Alternate solution:
holder.mChoiceRNK.doAfterTextChanged {
try {
myRNKvotingArray[position].mRNK =holder.mChoiceRNK.text.toString().toDouble()
} catch (err:Exception) {
holder.mChoiceRNK.setText("0")
holder.mChoiceRNK.selectAll()
}}
I have a view to create an account. If the save button is clicked and any of the fields are left open, it displays a toast. If all fields are filled in, the account is saved. I tried to accomplish this with an onClickListener that has an iteration through all the fields. It works perfectly if a field is not filled in and it works perfectly if alle fields are filled, but when a field isn't filled, I type something in there, try to save again and the button doesn't do anything.
I think it has something to do with the return, but I don't know what to do else. If the return wouldn't be there, I would get a toast for each field that isn't filled in.
Here's the relevant code:
private void registerButtonListeners() {
mCRUDAccountButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1;
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
}
thanks guys!
You're never resetting your flag back to 0!
so...
#Override
public void onClick(View v) {
mEmptyField = 0;//RIGHT HERE (give them the benefit of the doubt)
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1; //You were too optimistic, they failed.
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
Now, you're doing this test for the first time, every time. Otherwise, you go through and set that flag to 1, and next time, even though your loop never finds a match, when you get to the if mPentyField == 0 test, it fails cause you set that to 1 in the previous go around.