Multiple Methods - java

I'm trying to create my own methods to use in my main method. I have asked the user for input in my main method and have captured it using next line. However, I am unable to use it in my other methods.
static Scanner keyboard = new Scanner(System.in);
public static void main (String[] args) {
System.out.println("Input string of any length");
String s = keyboard.nextLine();
System.out.println("If you want to the program to check if palindrome, type 1."+
" If you want the program to compute rounded sum, type 2. If you want " +
"the program to count unique characters, type 3");
String o = keyboard.nextLine();
if (o.equals("1"))
System.out.println(isPalindrome());
}
public static boolean isPalindrome () {
boolean palindrome = true;
String s = keyboard.nextLine();
It is asking me to redefine string s, in my other method, even though it has already been defined in the main.

This is because of variable scope. Each variable only exists in a certain part of the program and other parts can have different variables with the same name that only exist in that part.
There are plenty of tutorials around on the subject. For example:
http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html
http://www.java-made-easy.com/variable-scope.html
http://www.cs.berkeley.edu/~jrs/4/lec/08

Adding on to Tim B's answer, it is always good to make a function full and sound.
i.e. instead of
public static boolean isPalindrome ()
Use
public static boolean isPalindrome (String text)
and pass in the text you want to check for palindrome. This makes the function more complete. Treat a function like asking someone a question. "Is this text a Palindrome?" instead of "Is Palindrome?".

Related

What's a better or more standard way to perform this function?

I am a java beginner, and in this particular problem I practiced making a program that converts any given string to lowercase string. Is there a a better way to achieve this goal in java (in terms of design)?
Also, how does the "else" (after "else if") catches or waits for me to make an input. Somehow that part does not make sense to me, even though I achieved what I wanted. How is the value of "ans" from input transferred to the entire loop and used until the loop is closed?
After many attempts and failures, I used a separate method for the conversion part. My second question is a bit too complicated to be researched.
import static java.lang.System.out;
import java.util.Scanner;
public class MyClass {
public static Scanner s = new Scanner(System.in);
public static String ans;
public static void main(String args[]) {
Conversion();
do {
ans = new String(s.nextLine());
if (ans.equalsIgnoreCase("Y")) {
Conversion();
} else if (ans.equalsIgnoreCase("N")) {
out.println("Thank you for using this program!");
break;
} else {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
} while (ans != "N");
}//END MAIN
public static void Conversion() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
out.println("Your new string is: " + str.toLowerCase());
out.println("Would you like to convert another string? (Y/N)");
}
}
I notice a few issues; Conversion looks like a class-name (Java naming convention would be conversion) and ans != "N" is using == instead of .equals - and wouldn't ignore case (!ans.equalsIgnoreCase("N")). Globals (e.g. static) are bad (pass the Scanner to the methods that need it), and the static import just makes the code more difficult to reason about (in my opinion). Your current loop doesn't really follow a conventional form, I would extract the prompt and loop for "another" conversion to a new method and if you must print a thank you I'd do so after the "main loop". Something like,
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
do {
conversion(sc);
} while (another(sc));
System.out.println("Thank you for using this program!");
}
public static void conversion(Scanner s) {
System.out.println("Please enter string to be converted to lowercase: ");
System.out.printf("Your new string is: %s%n", s.nextLine().toLowerCase());
}
public static boolean another(Scanner s) {
while (true) {
System.out.println("Would you like to convert another string? (Y/N)");
String ans = s.nextLine();
if (ans.equalsIgnoreCase("Y")) {
return true;
} else if (ans.equalsIgnoreCase("N")) {
return false;
}
System.out.println("Invalid entry!");
System.out.println("(Please type 'Y' for yes, or 'N' for no.)");
}
}
Answering your first question:
There are many design patterns and practices so many people can argue what I would recommend you to do. It's basically the same for all programming languages. Let's take your function "Conversion". The name itself says that you use it to convert stuff. Not to display, not to prompt - to convert. In this case, the only actual thing it should do is to convert upperCase to lowercase. In fact, you might want to specify what type of conversion it has in the name of the function (convertToLowerCase?). In fact, in Java, we use lowerCamelCase for all function names and UpperCamelCase for classes.
If you accept my previous suggestion, you could break the Conversion function into multiple ones like promptUserForInput, WrongInputHandler and so forth.
If I understood your second question correctly, you wonder about the way the code executed and how the variable ans is transferred further into the loop. Let's take a look at your code and what variables do:
You initialize your variable in the class MyClass by making it accessible to all methods in the class;
You prompt the user for the input to assign to this variable inside the do..while loop with this line ans = new String(s.nextLine()); which saves the value of the variable and, again, which can be accessed inside the whole class so its value is changed.
It goes into the if..else if...else statement. The way it works, it goes line by line - if the first if-statement fails, it goes on until it finds a truthy statement and it doesn't go any further. In your case, if the ans is not equal to either y/Y/ it will go to else if statement and if it's not n/N, it will go to else (so basically whatever except y/Y/n/N) and will be executed. After that, it jumps into the while (ans!= "N"); line where it compares your class-member variable ans and if it's not equal to "N" it starts over the loop right after the do{ part until you type in the "N".
I hope that makes sense. Whenever the program is asking you for input, it does not execute code further but is stuck until you provide any input. The value from input itself isn't passed throughout the loop and the program. The reason why you can use it because you created a higher-scope variable ans where you saved the result of your input.
IMPORTANT: if you've declared the ans inside the do..while loop, you would've not been able to have accessed it in the while (ans...) because it will 'die' right before the curly brace between do { ...here} while(). If you want to learn more about the scope and variables in general, you can read this article.
Here is my code example:
public static void main(String args[]) {
//declare before entering the loop to have higher scope
String ans = "y";
do {
//we get the given string to convert from the user
String str = promptForString();
//we convert the string
str = converseStringToLowerCase(str);
//display the string (could use another function for that: easier to debug and locate problems and in bigger projects)
out.println("Your new string is: " + str);
//prompt user for respond to continue or not
ans = promptForContinue();
handleResponse(ans);
} while (!ans.equals("n"));
}//END MAIN
//prompts user for an input string
public static String promptForString() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
return str;
}
//converts any given string to lower case
public static String converseStringToLowerCase(String str) {
return str.toLowerCase();
}
//is used to prompt user for reply
public static String promptForContinue() {
out.println("Would you like to convert another string? (Y/N)");
String str = new String(s.nextLine());
//is good to make if...else statements easier - it will always be lower case (or upper if you prefer)
return str.toLowerCase();
}
//easier to locate other response scenarios
public static void handleResponse(String response) {
if (response.equals("n")) {
out.println("Thank you for using this program!");
//it's not a very good practice to innaturally break loops. Use input for that in while(..) statement
// break;
} else if (!response.equals("y")) {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
}

Java Is okay to put input/output only in main method?

I'm new to Java Programing.
Lately I am doing the Java assignment.
I sew this method in user-defined class
public void intputRank( Scanner s) {
salary = s.nextInt();
}
I was confused because I always want put I/O in main method (like in C++ I only write cin cout in main function). I have 2 reasons for doing this:
It's easy for me to see where my program accept input. When there is something wrong about I/O, I just need to debug the main method.
Scanner is a more complicated Class, use it as parameter would make unknown wrong.
So, kind Stack Overflowers, is it just a bad example or I understand something wrongly?
If it is the latter? Why not
public void inputRank( int asalary) {
salary = asalary;
}
//in main method
Scanner reader = new Scanner(System.in);
int asalary = reader.nextInt();
//then pass the asalary as parameter
If your program needs to be robust, e.g. when prompting for an integer it'll validate the input and re-prompt if bad, then having reusable helper methods is a good thing.
This means that you'll need multiple methods that use Scanner. Now, you can pass the Scanner object in as a parameter, or you can put it in a field, that's entirely up to you.
But the main point is that having code in a method that uses a Scanner is perfectly fine, and it really is a must for robust code, otherwise you'll ruin the DRY (Don't Repeat Yourself) principle.
Example:
public static int promptNonNegativeInt(Scanner sc, String prompt) {
for (;;) {
System.out.print(prompt + ": ");
if (! sc.hasNextInt()) {
System.out.println("** Not a valid number, please try again");
sc.nextLine(); // discard bad input
continue;
}
int value = sc.nextInt();
sc.nextLine(); // discard any extra text on the line
if (value < 0) {
System.out.println("** Number cannot be negative, please try again");
continue;
}
return value;
}
}
Example use
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int value = promptNonNegativeInt(sc, "Enter number");
System.out.println("You entered: " + value);
}
Even more complex is if you need to prompt for an object with multiple fields. Isolating the code that does this is good programming (separation of concern), so writing a promptMyObject(Scanner sc) method is a good thing.
Especially if you need to prompt for various objects. If you leave all prompting code in the main() method, it'll be huge and unreadable. It would be a God method, a variation of the God object:
A God object is an object that knows too much or does too much. The God object is an example of an anti-pattern.
In general, I prefer to write methods that take simpler types over more complicated types. This makes them easier to compose and reuse later on.
In your example, the method that takes an int could be considered better than taking a Scanner, because int is simpler and more common than a Scanner. That being said, the name inputRank kind of implies it's doing to read / receive input, so I would be tempted to rename it to something like applyRank in this case.

Need help writing a dynamic method that gives user a different prompt when the method is called with a different parameter every time

Im trying to write a method that works around user choices (ex. queryChoicesMethod). There are 4 choices that the user can pick, and at the end of it all, all 4 choices have to be in a String[] in some order. Say you have choices a, b, c, and d. You ask the user to pick the first choice, and the static method will return the first choice as a string. The answer will then get put into the array at [0] in the main method. When I call the queryChoicesMethod again, this time it should say something like, "please select a second choice ..." and it will list the other choices the user hasn't already picked yet (ex. Say the user picked "a" the first time around, at the call during the second time, it should print something like "please pick options b, c, or d"). The answer will then go into the String[] at [1]. During the third call, it should ask the user the to pick any one of the two remaining options (ex. if user picked "b" the second time, method should print "please pick options c or d" during the third call). Answer will go into String[] at [2]. The last remaining option would get put into the array without calling the method again, because you dont have to ask the user to put in the last option (its already decided that the last option goes into the array at [3] during this stage because its the only option left).
I've tried to do everything I can, but have failed. This is an assignment that I cant figure out
The method that I must use is as follows:
public static String queryChoices(String[] choices) {}
Thanks for any help
Take a static variable and increment in your method. Map the variable values with words like first, second in order to use in your print statement.
Use a boolean array for your choices to help you know whether it is taken or not.
import java.util.Scanner;
public class HelloWorld{
public static int i=0;
public static String num[]={"first","second","third","fourth"};
public static boolean taken[]={false,false,false,false};
static String[] choicelist={"","","",""};
public static String queryChoices(String[] choices){
HelloWorld h=new HelloWorld();
int l;
String ch;
Scanner s=new Scanner(System.in);
if(i<3){
System.out.println("enter your "+num[i]+" choice:\n The choices are");
for(int j=0;j<4;j++){
if(!taken[j])
System.out.println(j+". "+choices[j]);
}
int n=s.nextInt();
taken[n]=true;
h.choicelist[i]=choices[n];
ch=choices[n];
i++;
}else{
for(l=0;l<4;l++){
if(!taken[l])
break;
}
h.choicelist[3]=choices[l];
ch=choices[l];
}
return ch;
}
public static void main(String []args){
String[] choices={"a","b","c","d"};
String choice=queryChoices(choices);
System.out.println("your choice is: "+ choice);
System.out.println("your choice is: "+ choicelist[0]);
}
}

How to create parameters in this code

I am a first year c.s student, but I am having trouble making this program fit my teacher's requirement. The program will receive a string and an integer that will create this:
Please enter a string: ThisIsAnExample
Please enter an integer: 3
Thi
sIs
AnE
xam
ple
He wants the for loop to be inside a method called splitter. The splitter method should have two parameters, a string and an int, for inputStr and inputInt.
Here is what I have so far:
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Please enter a string: ");
String inputStr;
inputStr = keyboard.nextLine();
System.out.println("Please enter an integer: ");
int inputInt;
inputInt=keyboard.nextInt();
for(int i =0;i<inputStr.length();i+=inputInt){
if(i+inputInt < inputStr.length())
System.out.println(inputStr.substring(i,i+inputInt));
else
System.out.println(inputStr.substring(i,inputStr.length()));
}
}
If the splitter method is to actually just print the stuff to standard output, start with:
static void splitter (String inputStr, int inputInt) {
}
and call it with:
splitter (inputStr, inputInt);
once you have those values in your main method.
Then it's a simple matter of moving some of your code from main() into splitter().
If you wanted to return the string array and print it from main(), you could use:
static String[] splitter (String inputStr, int inputInt) {
}
and call it with:
String[] bits = splitter (inputStr, inputInt);
// print the array here.
This would be a more flexible case if you ever wanted to do something other than just print it. For an assignment at this level though, it's probably okay to just print within the method itself.
You need to create a function, apparently.
To use a method/function, a few things need to be done:
You need to write the body of your function :
public void splitter(String myStringArg,int myIntArg){
// Your code ....///}
Finally, you need to call your function. In your main :
splitter(myString,myInt);
In the splitter body, you'll be able to use myStringArg; you will supply its value by calling.
So, in splitter :
myStringArg = myString (in value).
Good luck!

Why is this code keep being "terminated"?

I have this code in Eclipse:
package test;
import java.util.Scanner;
class test{
public static void main(String args[]){
Scanner Input = new Scanner(System.in);
if (Input.equals("payday2")){
System.out.println(Input);
}
}
}
Now when I try to start the code/aplication, it terminates itself.
Any ideas why that happens?
You instantiate the Scanner as a variable named Input but never try to read.
Your condition
if (Input.equals("payday2")){
will only check if the Scanner object is equals to the string "payday2" which will always be false, hence the program terminate.
If you want to read, you need to do Input.nextLine().
I dont know about eclipse, but Netbeans would give a warning "equals on incompatible type" with this line.
Also, you should not name your variable with a capital letter as by convention, only class name should start with a capital.
So your fixed program would be
Scanner input = new Scanner(System.in);
String value = input.nextLine();
if ("payday2".equals(value)) {
System.out.println(value);
}
Notice that I kept the string in a variable to display it as displaying input would call toString of the Scanner object which is probably not what you expected.
Notice that I also compared the string in reverse order which is a good practice to avoid NPE even if not really needed here.
You never read input from the Scanner instance so the application doesnt block
String text = input.nextLine();
if ("payday2".equals(text)) {
...
I think you mean to do:
String in = Input.nextLine();
if(in.equals("payday2"))
{
System.out.println(in);
}
Note: in Java 7 you can do the following:
String in = Input.nextLine();
switch(in)
{
case "payday2":
System.out.println(in)
break;
case "payday the heist":
//...
break;
}
Which makes it much easier to manage different input cases.

Categories

Resources