d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Java & Android Questions > Continuous Over Semester
Prev123Next
Add Reply New Topic New Poll
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Jan 26 2015 07:17pm
Quote (carteblanche @ Jan 25 2015 10:26pm)
Yes.
some other utilities i enjoy: .......


Awsome, thanks! I don't think I'll be using those utilities for a while, but good to know they are out there! And maybe later this semester they will come in handy!

So I've worked on my main method for my TipCalculator, and GRRRR!!!
Things I did:
-I switched to using the Scanner object
-I created a very basic try { catch exception

Things I will do once I get code fixed more:
-A while loop I think?
-Catches for each input?
-Created detailed comments / rework comments


The problem: The compiler HATES my
Code
if (customTipAnswer.toLowerCase() == "yes") {
&&
Code
} else (customTipAnswer.toLowerCase() == "no") {


Not sure whats I'm doing wrong, it looks right, But this seems to be the source because without the if / else statement the problem is no more.


Code
package com.bciancio;
import java.util.*;

public class TipCalculation {

public static void main(String[] args) {
// Creates an instance of the Tip class
Tip tipTestA; //Creates controller / reference
Scanner input = new Scanner(System.in); //create a way for user to addInput

try {

System.out.println("Enter the bill amount: ");
double billAmountInput = input.nextDouble();

System.out.println("Would you like to add a custom tip? Type either 'yes' or 'no'");
String customTipAnswer = input.next();

if (customTipAnswer == "yes") {

System.out.println("Enter the optional custom tip: ");
int customTipAmountInput = input.nextInt();

tipTestA = new Tip(billAmountInput,customTipAmountInput);

System.out.println(tipTestA); //Println tipTestA, the Objects.toString is override in the Tip class

} else if (customTipAnswer == "no"){

tipTestA = new Tip(billAmountInput); // Calls constructor

System.out.println(tipTestA); //Println tipTestA, the Objects.toString is override in the Tip class
}

} catch (Exception e) {
System.out.println("Please enter valid criteria!");
}
}
}


Did I approach exception handling correctly / Any input on what I'm doing wrong?!

Thanks again, you guys definitely have accelerated my understanding of certain things // providing me with a resource i can look back at!

This post was edited by Noobtard on Jan 26 2015 07:18pm
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Jan 26 2015 08:57pm
you gave me two different else blocks. which one are you using?

this is incorrect:
Code
} else (customTipAnswer.toLowerCase() == "no") {


this is correct:
Code
} else if (customTipAnswer == "no"){


i suggest using .equals() or .equalsIgnoreCase() instead of == since string equality is iffy in java depending on where they're coming from. to avoid any null pointers, i suggest reversing it to call methods on string literals instead of variables. eg instead of:
Code
if (variable.equalsIgnoreCase("no"))

i use:
Code
if ("no".equalsIgnoreCase(variable))


in your scenario it's not a problem, but i find it helpful as a habit. the difference is the first one can throw a null pointer exception if variable is null, whereas the second example will never throw a null pointer exception. alternatively, use apache's StringUtils.equals(..)

as for error handling, no that is not the correct way to use it.
1) if you want to handle bad output, that logic belongs in the else block
2) you generally want to be as specific as possible with your exception, specifically catching whatever you're expecting to go wrong. using a blanket Exception is used for safety when you dont know what to expect can go wrong. is that what you're trying to do?

This post was edited by carteblanche on Jan 26 2015 09:00pm
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Jan 26 2015 09:49pm
Quote
you gave me two different else blocks. which one are you using?

The correct one, sorry for the confusion.

Quote
I suggest using .equals() or .equalsIgnoreCase() instead of == since string equality is iffy in java depending on where they're coming from. to avoid any null pointers, i suggest reversing it to call methods on string literals instead of variables. eg instead of:

This must of been it, although it wasn't throwing an error, rather main was just ending right after I typed 'anything' into the second input (when it asks yes / no). Both of the solutions now allow my code to run and produce output!! Not sure which 'style' (the two solutions you posted) I like better. So i'll use both of them, to help me remember them.

Quote
1) if you want to handle bad output, that logic belongs in the else block

I don't follow, the else block of my if statement!?

Quote
2) you generally want to be as specific as possible with your exception, specifically catching whatever you're expecting to go wrong. using a blanket Exception is used for safety when you dont know what to expect can go wrong. is that what you're trying to do?

I used the blanket Exception because I wasn't sure how to do exception handling, so I decided to get more of a 'psudeo' down / the logic I want before I got more specific.

I think I want: InputMismatchException for all three inputs, not sure I need any other exception?
I'll modify my exceptions, once I understand what you mean by 1)

Current modified:
Code
package com.bciancio;
import java.util.*;

public class TipCalculation {

public static void main(String[] args) {
// Creates an instance of the Tip class
Tip tipTestA; //Creates controller / reference
Scanner input = new Scanner(System.in); //create a way for user to addInput
boolean notValidated = true;

try {
System.out.println("Enter the bill amount: ");
double billAmountInput = input.nextDouble();

while (notValidated) {
System.out.println("Would you like to add a custom tip? Type either 'yes' or 'no'");
String customTipAnswer = input.next();

if ((customTipAnswer.equalsIgnoreCase("yes"))) {

System.out.println("Enter your custom tip: ");
int customTipAmountInput = input.nextInt();

tipTestA = new Tip(billAmountInput, customTipAmountInput);

System.out.println(tipTestA); //Println tipTestA, the Objects.toString is override in the Tip class
notValidated = false;

} else if ("no".equalsIgnoreCase(customTipAnswer)) {

tipTestA = new Tip(billAmountInput); // Calls constructor
System.out.println(tipTestA); //Println tipTestA, the Objects.toString is override in the Tip class
notValidated = false;
} else {
System.out.println("Please enter yes or no!");
}
}

} catch (Exception e) {
System.out.println("Please enter valid criteria!" + e);
}
}
}


Quote
alternatively, use apache's StringUtils.equals(..)

Ohhhhh, maybe I'll be trying those resources you posted sooner than expected! After I get this to work, I'll make a copy and play with it. Still very new to the imports, and especially these "packages"

As always thank you.

This post was edited by Noobtard on Jan 26 2015 09:50pm
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Jan 28 2015 02:47pm
for I/O
What would you guys say is used more: Serialization or String --> Text file

Personally I understand the books way of explaining Serialization than how to actually String --> text

I understand that Serialization is when you want to save an instance that will be run by the same JVM. And that Text file could be read by a non java application.

My actual question is in the real world which do you tend to use more? (in your experience)
just curious!
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Jan 28 2015 05:13pm
Quote
I understand that Serialization is when you want to save an instance that will be run by the same JVM. And that Text file could be read by a non java application.

ehhh.

I've only used binary serialization in a few specific instance, mostly revolved around (web) frameworks. in ASP.NET our pagestate was serialized, which caused some problems. we would serialize the data and stick it into our database, then pull it out later and deserialize it via reflection. unfortunately, we started versioning some of our controls, and the version number that went into the DB with an older control no longer matched the version number of our controls after a deployment, so we couldn't create the controls dynamically and we dropped the data. binary serialization can be used a lot internally by frameworks, but it's rarely a good idea for you to manually do it. you'll see frameworks/APIs mention that certain classes need to be serializable to work.

Keep in mind "text" also includes xml and json, which is my preference for anything manual. then you can pass data to anything. they're also human readable. my android app, ios app, desktop app, and web app can all call the exact same web service or oracle API and pass the xml/json and everything works beautifully. it's very easy to read, write, and edit. i mentioned before the libraries XStream and GSON which handle all of that for you.

This post was edited by carteblanche on Jan 28 2015 05:15pm
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Feb 3 2015 11:29pm
AHHH!!
It's been a while since I've posted. So here's an update.
Completed the tipCalculator, apparently we weren't needing to put exception handling, so I reversed back to using command line arguments, and than called the correct constructor based on args.length. Now in class we are migrating that java into android. I've created a layout and started to wire the widgets..

As for using utilities, I'm a tad scared to lol!! OH-MUH-GURD SOMETHING NEW MUCH SCARE

The class I would first like to play with these utilities are my android class, since my Adv. Java class is seems to be VERY picky, while the android class seems more pick your route, follow good standards but create your own... type feel to it.

With that said the Android Studio project folder is ridiculous or more so overwhelming for a beginner like myself.(So many files!) In android studio when we select the SDK for a new project, its fairly simple just select it in its location. (usually java in the C:/ -- But with a utility like Apache Commons, is this the same? Where do I put the "Apache Commons Lang 3.3.2 (Java 6.0+)" thing I would download? How do I reference it?

Since it's unlike java, and probably not installed on other machines, I'm going to guess it'd be somewhere in my projects folder??

^Am I thinking of how to use utilities right? By the end I started to question it.

Quote (carteblanche @ Jan 28 2015 06:13pm)


Keep in mind "text" also includes xml and json, which is my preference for anything manual. then you can pass data to anything. they're also human readable. my android app, ios app, desktop app, and web app can all call the exact same web service or oracle API and pass the xml/json and everything works beautifully. it's very easy to read, write, and edit. i mentioned before the libraries XStream and GSON which handle all of that for you.




Thanks for the input on text / serialization. Always good to have peoples 'real world' experience give you a better idea of something.
I'm barley familiar with XML, but started to use it for android layouts and BARELY remember taking the class last year. json I have not touched, but can only assume its similar to xml.

This part lost me, not sure what you mean. "my android app, ios app, desktop app, and web app can all call the exact same web service or oracle API and pass the xml/json"
^ Very limited on xml knowledge and the 'flow / process' of using it.

As for this thread, I will continue to try and post my 'finished' code and kinda see where you guys think I could improve. Also will post any snags I come across / questions that I'm curious about (like the text/seralization.
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Feb 5 2015 04:42pm
Managed to make that tipCalculation code and put it into an android application.

I would like, if possible, to know what I could have done differently. What should I refactored, what other ways could I have made it easier to read etc...Anything to help improve my style.

For instance this:
Code
mTenPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getTenPercentTipAmount())));

kinda is an eye-sore?

Only "important" XML part
Code
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_calculate"
android:id="@+id/btn_calculate"
android:layout_gravity="center_horizontal"
android:onClick="tipCalculations"/>


MainActivity.Java
Code
package bciancio.com.mytipcalcapp;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.text.NumberFormat;

/**
* The type Main activity.
*/
public class MainActivity extends ActionBarActivity {

//Creates a myDebug Tag constant for easy LogCat referencing
private static final String TAG = "myDebug";


//Member userInput variable declarations
EditText mBillAmount;
EditText mCustomTipPercent;

//Member variable declarations of the PercentTipAmount
TextView mTenPercentTipAmount;
TextView mFifteenPercentTipAmount;
TextView mEighteenPercentTipAmount;
TextView mCustomPercentTipAmount;

//Member variable declarations of the totalWithTipAdded
TextView mTotalWithTenTipAdded;
TextView mTotalWithFifteenTipAdded;
TextView mTotalWithEighteenTipAdded;
TextView mTotalWithCustomTipAdded;

//Declaring member variable for the calculate button
Button mCalculate;

//Referencing the NumberFormat class
NumberFormat df;


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

//Add resource links for widgets in the xml layout
//Wiring up widgets
//Wire userInput widgets
mBillAmount = (EditText) findViewById(R.id.userInput_billAmount);
mCustomTipPercent = (EditText) findViewById(R.id.userInput_customTip);
mCalculate = (Button) findViewById(R.id.btn_calculate);

//Wiring of the tipAmount variables
mTenPercentTipAmount = (TextView) findViewById(R.id.tenPercentTipAmount);
mFifteenPercentTipAmount = (TextView) findViewById(R.id.fifteenPercentTipAmount);
mEighteenPercentTipAmount =(TextView) findViewById(R.id.eighteenPercentTipAmount);
mCustomPercentTipAmount = (TextView) findViewById(R.id.customPercentTipAmount);

//Wiring of the totalAmount variables
mTotalWithTenTipAdded = (TextView) findViewById(R.id.totalWithTenTipAdded);
mTotalWithFifteenTipAdded = (TextView) findViewById(R.id.totalWithFifteenTipAdded);
mTotalWithEighteenTipAdded = (TextView) findViewById(R.id.totalWithEighteenTipAdded);
mTotalWithCustomTipAdded = (TextView) findViewById(R.id.totalWithCustomTipAdded);

df = NumberFormat.getCurrencyInstance();
}

/**
* Tip calculations.
*
* @param view the view
*/
public void tipCalculations(View view){

tipCalc tipTestA = null;
Log.println(Log.DEBUG,TAG,"Calculate button has been clicked!");

if(mBillAmount.getText().toString().length() == 0) { //validates if user entered billAmount
//if not set a toast else run other checks for constructor calling
//The toast method requires to know context,charSequence, and the toast duration
Toast.makeText(getApplicationContext(), "BAD!! Enter at least a bill amount",
Toast.LENGTH_SHORT).show();

Log.println(Log.DEBUG,TAG,"User did not enter a Bill Amount! TOAST EM!!!");

} else {
//Did the user input a customTip?
if(mCustomTipPercent.getText().toString().length() == 0) {

Integer customTipPercent = 0;
Double billAmount = Double.parseDouble(mBillAmount.getText().toString());
tipTestA = new tipCalc(billAmount, customTipPercent);

Log.println(Log.DEBUG,TAG,"Bill Amount was entered, but no Custom Tip. Assign a default custom tip of 0");

} else { //If no customTip than...

Integer customTipPercent = Integer.parseInt(mCustomTipPercent.getText().toString());
Double billAmount = Double.parseDouble(mBillAmount.getText().toString());
tipTestA = new tipCalc(billAmount, customTipPercent);

Log.println(Log.DEBUG,TAG,"Bill Amount & Custom Tip Percent were entered");
}
}
//Did the user enter atleast a billAmount (making tipTestA != null)
if(tipTestA != null){

mTenPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getTenPercentTipAmount())));
mFifteenPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getFifteenPercentTipAmount())));
mEighteenPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getEighteenPercentTipAmount())));
mCustomPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getCustomPercentTipAmount())));

mTotalWithTenTipAdded.setText(String.valueOf(df.format(tipTestA.getTotalWithTenTipAdded())));
mTotalWithFifteenTipAdded.setText(String.valueOf(df.format(tipTestA.getTotalWithFifteenTipAdded())));
mTotalWithEighteenTipAdded.setText(String.valueOf(df.format(tipTestA.getTotalWithEighteenTipAdded())));
mTotalWithCustomTipAdded.setText(String.valueOf(df.format(tipTestA.getTotalWithCustomTipAdded())));

Log.println(Log.DEBUG,TAG,"Since they entered ATLEAST a bill amount tipTestA != null, time to get the values!!!!");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}

tipCalc.java
Code
package bciancio.com.mytipcalcapp;
/**
* Created by student on 2/4/2015.
* @author Brandon Ciancio Lab2_1
*/
public class tipCalc {

//Argument Variables
private double mBillAmount;
private int mCustomTipPercent;

//Private variable declarations of the PercentTipAmount
private double mTenPercentTipAmount;
private double mFifteenPercentTipAmount;
private double mEighteenPercentTipAmount;
private double mCustomPercentTipAmount;

//Private variable declarations of the totalWithTipAdded
private double mTotalWithTenTipAdded;
private double mTotalWithFifteenTipAdded;
private double mTotalWithEighteenTipAdded;
private double mTotalWithCustomTipAdded;

/**
* Instantiates a new Tip calc.
*
* @param mBillAmount the m bill amount
* @param mCustomTipPercent the m custom tip percent
*/
public tipCalc(Double mBillAmount, Integer mCustomTipPercent) {

this.mBillAmount = mBillAmount;
this.mCustomTipPercent = mCustomTipPercent;

mTenPercentTipAmount = (mBillAmount * .1);
mFifteenPercentTipAmount = (mBillAmount * .15);
mEighteenPercentTipAmount = (mBillAmount * .18);
mCustomPercentTipAmount = (mBillAmount * mCustomTipPercent * .01);

mTotalWithTenTipAdded = (mBillAmount + mTenPercentTipAmount);
mTotalWithFifteenTipAdded = (mBillAmount + mFifteenPercentTipAmount);
mTotalWithEighteenTipAdded = (mBillAmount + mEighteenPercentTipAmount);
mTotalWithCustomTipAdded = (mBillAmount + mCustomPercentTipAmount);

}

/**
* Gets ten percent tip amount.
*
* @return the ten percent tip amount
*/
public double getTenPercentTipAmount() {
return mTenPercentTipAmount;
}

/**
* Gets fifteen percent tip amount.
*
* @return the fifteen percent tip amount
*/
public double getFifteenPercentTipAmount() {
return mFifteenPercentTipAmount;
}

/**
* Gets eighteen percent tip amount.
*
* @return the eighteen percent tip amount
*/
public double getEighteenPercentTipAmount() {
return mEighteenPercentTipAmount;
}

/**
* Gets custom percent tip amount.
*
* @return the custom percent tip amount
*/
public double getCustomPercentTipAmount() {
return mCustomPercentTipAmount;
}

/**
* Gets total with ten tip added.
*
* @return the total with ten tip added
*/
public double getTotalWithTenTipAdded() {
return mTotalWithTenTipAdded;
}

/**
* Gets total with fifteen tip added.
*
* @return the total with fifteen tip added
*/
public double getTotalWithFifteenTipAdded() {
return mTotalWithFifteenTipAdded;
}

/**
* Gets total with eighteen tip added.
*
* @return the total with eighteen tip added
*/
public double getTotalWithEighteenTipAdded() {
return mTotalWithEighteenTipAdded;
}

/**
* Gets total with custom tip added.
*
* @return the total with custom tip added
*/
public double getTotalWithCustomTipAdded() {
return mTotalWithCustomTipAdded;
}

}


We just learned listeners within the java there's another way to get userInput, but in this I use an onClick within the xml. My teacher mentioned another way to get input, that we will be learning next week -- but the onClick provides me with the functionality I require so npnpnp
Also I use the LogCat in xml while building and to DEBUG, was finding it very nice to use, not needed anymore but I think ill keep? Do you guys normally keep your debug logs within your working code or?
Thanks for looking!

This post was edited by Noobtard on Feb 5 2015 04:43pm
Member
Posts: 2,757
Joined: Nov 26 2007
Gold: 1,214.81
Feb 6 2015 12:10pm
the other way to set the listener is to call setOnClickListener(OnClickListener onClickListener)


for example...
Code
mCalculate .setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
tipCalculations();
}
});


i've always done it this way because i hate going back and forth from xml and java to see what the function names are. also easier to read for other people not as familiar with android
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Feb 6 2015 02:35pm
Quote
For instance this:
Code
mTenPercentTipAmount.setText(String.valueOf(df.format(tipTestA.getTenPercentTipAmount())));
kinda is an eye-sore?


use a wrapper. start building your own Utility class and add these kinds of things.

why are you using String.valueOf anyway? pretty sure that's already a string.
http://docs.oracle.com/javase/7/docs/api/java/text/NumberFormat.html#format(double)

Quote
Also I use the LogCat in xml while building and to DEBUG, was finding it very nice to use, not needed anymore but I think ill keep? Do you guys normally keep your debug logs within your working code or?
Thanks for looking!


1) use a wrapper around LogCat. do not use it directly. 6 months from now you'll say "I wish i added XYZ feature to my log. now i have to change it in thousands of places to use the feature."
2) always keep log statements inside and set the log level to error/fatal in production apps, but trace/debug in dev. you dont want to go back and edit hundreds of files to remove log statements right before you put your app in production. you'll break something. then when you want to debug it, you'll say "oh shit, i wish i still had my log statements everywhere so i can see where the problem is..."

i have a debug or trace with params at the beginning of almost every method i have so i can look at the logs and determine the app flow.

Quote
This part lost me, not sure what you mean. "my android app, ios app, desktop app, and web app can all call the exact same web service or oracle API and pass the xml/json"
^ Very limited on xml knowledge and the 'flow / process' of using it.

suppose we have an API that takes in a person's information and imports them into the system as a new customer. the API consumes xml like this:

Code
<customer>
<name>lelouch lamperouge</name>
<phone>5555555555</phone>
<email>lelouch.lamperouge@gmail.com</email>
</customer>


pretty much any language on any platform can build this xml. i can use java, i can use javascript, or i can tell my grandmother to write it in notepad. right?

suppose instead, you require the user use a proprietary java class written by some company in india and your object needs to be serialized. how do you think you're gonna do that on a system that doesnt support java? and uh oh, the company just went out of business. looks like we can't use their class anymore, so our API is useless. you'll be thinking "if only we used a simple cross platform markup to describe our data..."

This post was edited by carteblanche on Feb 6 2015 02:39pm
Member
Posts: 1,849
Joined: May 31 2008
Gold: 2,571.50
Feb 10 2015 04:53pm
Quote (labatymo @ Feb 6 2015 01:10pm)

the other way to set the listener is to call setOnClickListener(OnClickListener onClickListener)


Just learned about this in class today, anonymous inner class. I will definitely be using this for my next lab!

Quote (carteblanche @ Feb 6 2015 03:35pm)

why are you using String.valueOf anyway? pretty sure that's already a string.
http://docs.oracle.com/javase/7/docs/api/java/text/NumberFormat.html#format(double)

You are right, some reason I thought that NumberFormat output a double, I didn't check the API -- I have to start getting into
the habit of always checking it for each method I use.

Quote

1) use a wrapper around LogCat. do not use it directly. 6 months from now you'll say "I wish i added XYZ feature to my log. now i have to change it in thousands of places to use the feature."
2) always keep log statements inside and set the log level to error/fatal in production apps, but trace/debug in dev. you dont want to go back and edit hundreds of files to remove log statements right before you put your app in production. you'll break something. then when you want to debug it, you'll say "oh shit, i wish i still had my log statements everywhere so i can see where the problem is..."

So something like this:
Code

private static final String TAG = "myDebug";
public void logCatGen(String debugMessage) {
Log.println(Log.DEBUG,TAG,debugMessage);
}

logCatGen("HelloWorld");



^ So like if I wanted to change the log level for all my logCats that call this log method I could just do it there? Is this what a wrapper is, we havn't learned about them yet. But this is what it sounds like to me? I'll look more into it after my projects, they've been keeping me busy.
And my understanding is, when you are creating the app have your log level set to DEBUG, but when your ready to put it on the app store set the log level to error / fatal? -- We havn't worked with any other log levels yet -- but this is my understanding of what you said?


Thanks for clarifying on the XML, I understand it MUCH better!!


Go Back To Programming & Development Topic List
Prev123Next
Add Reply New Topic New Poll