Why do I have to use an extra method in this code? - java

I don't get why I have to use square() in this code? Why can't I just add n times n to the String s?
static int square(int n){
return n*n;
}
static void ausgabe(int n){
String s;
int i = n;
s = "SquareOf" + i + " = " + square(i);
Sysout(s);
}
my solution would be to miss out the square method and just add like this
s = "SquareOf" + i + " = " + i*i;
I tried and the result is always right. But our book suggests the first way and I would just like to know why they make it more complicated in my eyes.
Thanks in advance.

Well, you are partially right, BUT software is developed better when you split thing according of what they do...
The method Ausgabe have a job: display the result only
The method square have a job: do the math operation only
So the whole point behind soft development is not that the code works
we try to do something else:
it must work
it must be easy to maintain
it must be easy to improve
all those requirements are related to the project's complexity and can be reached based on a single responsibility principle

For something as trivial as i*i you wouldn't need a method. However if instead have to do a more complicated operation which would require quite a few lines of code, then it would be a good idea to put that in its own method in order to keep your code clean and easy to read, understand and maintain. Moreover if you need to do the same operation at multiple points in your program, then a method would be beneficial as you do not have to copy/paste the same code over and over again in different places.

Related

Unable to return a variable [duplicate]

I'm trying to understand the difference, and benefits of using System.out.println() vs. return blah in a method.
It seems like System.out.println() is used to display static information, and return is a value returned from the method. Yet I'm seeing examples like the one below, where a function is used within the System.out.println() statement
System.out.println(name.substring(1, 3));
When is it right to use System.out.println() and return. Is it that return can be used by another piece of code later, whereas System.out.println() cannot?
Your last sentence is effectively correct, but the distinction between these two operations is HUGE, so I'd like to provide a more in depth explanation of their differences.
The Difference:
return is an instruction that controls the flow of your program's execution. It is a fundamental part of the Java syntax. It tells the computer what part of your code to execute, and what values to use during that execution. When you return a value, you are saying "The result of calling this method is XXXX" (with 'XXXX' being the value you returned).
System.out.println is not used to control how your program executes. It is a merely way to inform the user of what is going on inside your program. System.out.println (syso for short) can print any information to the console; it doesn't matter if it's a variable, an expression, or the result of a method call. There is no limitation to "static" data.
Let's look at both of them in action:
int addInts(int arg0, int arg1)
{
return arg0 + arg1;
}
This means that wen we call addInts in our program, it will evaluate to the sum of its arguments. So when we write addInts(3, 7), it's the same as if had simply written 3 + 7 or 10 in our source code. Nothing is printed to the console; all we've done is give our program a way of calculating something.
However, any calculations we might make are ultimately useless if all they do is sit inside the computer, so we need a way to display this information to the user. Enter syso:
System.out.println(addInts(22, 16));
The addInts method is called and returns 38. This value is placed somewhere in the computer's memory such that our program can find it.
Next, syso takes that value (38) and prints it to the console, letting the user know what value was calculated. Nothing new is calculated from this procedure, and our program continues to the next statement.
So which do I use?
In simple programs, you have so few values to keep track of that it can be tempting to just print everything that you want to know where you calculate it. For instance, if you were writing a program to do your algebra homework (I've been there) and you wrote a method to solve the quadratic equation, it might be tempting to structure it like this:
class Algebra
{
static void quadSolve(double a, double b, double c)
{
double result = /* do math... we're ignoring the negative result here*/;
System.out.println("The solution to the quadratic equation is: " + result);
}
public static void main(String[] args)
{
quadSolve(1.0, -6.0, 9.0);
}
}
However, this approach quickly becomes a very bad idea if you want to make your program a little more complex. Let's say one problem requires you to solve the quadratic equation and then use the result of that calculation to calculate the volume of a cylinder. In the above example, we can't do that: after we dump the value of result to the console via syso, it disappears when the quadSolve method ends. It would make much more sense if we have quadSolve return result and let the "caller" (the place quadSolve was called from) deal with handling that value. This is a much more flexible design that allows us to make our programs much more complicated with relative ease. This increased flexibility and modularity is really what makes methods useful. Here is the implementation:
class Algebra
{
static double quadSolve(double a, double b, double c)
{
double result = /* do math... we're ignoring the negative result here*/;
return result;
}
public static void main(String[] args)
{
double x = quadSolve(1.0, -6.0, 9.0);
//now we can do whatever we want with result:
//print it, negate it, pass it to another method-- whatever.
System.out.println("The solution to the quadratic equation is: " + x);
System.out.println("And it's square is: " + (x * x));
}
}
I hope this clears things up. Feel free to ask if you need additional clarification.
A method often returns a value (which is done by using the return statement).
Information may be "printed" to an output stream by System.out.println() references.
They both have their uses ... which are usually orthogonal.
They have very little to do with each other.
System.out.println() is used to output strings to a console/terminal. So
System.out.println("Hello world");
should output the string "Hello world"
return is a statement in Java to go back to the code that invoked the method and pass back a value.
public static int add(int a, int b) {
return a + b; // go back to method that called this method (main)
}
public static void main(String[] args) {
int sum = add(3,4); // the return result (7) is stored in sum
}
From my understanding, and to give a simple answer which has a significant meaning, I would say:
It is like when you go to a coffee shop and order a cup of coffee, but the barista tells you if you want a picture of the coffee cup or the cup itself :).
System.out.println() is the picture, while..
return blah is the cup of coffee.
With "return" you can do what you like with the value of return, but with "print" you only see what the function is doing.

JAVA string how can i implement the length method

My roommate's teacher gave them a assignment to implement string length method in JAVA?
we have thought out two ways.
Check the element,and when get the out of bounds exception,it means the end of string,we catch this exception,then we can get the length.
Every time a string is pass to calculate the length,we add the special character to the end of it,it can be '\0',or "A",etc..
But we all think this two way may can finish the assignment,but they are bad(or bad habit to do with exception),it's not cool.
And we have googled it,but don't get what we want.
Something like this?
int i = 0;
for (char ch : string.toCharArray()) {
i++;
}
The pseudo-code you probably want is:
counter = 0
for(Character c in string) {
counter = counter + 1
}
This requires you to find a way to turn a Java String into an array of characters.
Likely the teacher is trying to make his or her students think, and will be satisfied with creative solutions that solve the problem.
None of these solutions would be used in the real world, because we have the String.length() method. But the creative, problem-solving process you're learning would be used in real development.
"1. Check the element,and when get the out of bounds exception,it means the end of string,we catch this exception,then we can get the length."
Here, you're causing an exception to be thrown in the normal case. A common style guideline is for exceptions to be thrown only in exceptional cases. Compared to normal flow of control, throwing an exception can be more expensive and more difficult to follow by humans.
That said, this one of your ideas has a potential advantage for very long strings. All of the posted answers so far run in linear time and space. The time and/or additional space they take to execute is proportional to the length of the string. With this approach, you could implement an O(log n) search for the length of the string.
Linear or not, it's possible that the teacher would find this approach acceptable for its creativity. Avoid if the teacher has communicated the idea that exceptions are only for exceptional cases.
"2. Every time a string is pass to calculate the length,we add the special character to the end of it,it can be '\0',or "A",etc.."
This idea has a flaw. What happens if the string contains your special character?
EDIT
A simple implementation would be to get a copy of the underlying char array with String.toCharArray(), then simply take its length. Unlike your ideas, this is not an in-place approach - making the copy requires additional space in memory.
String s = "foo";
int length = s.toCharArray().length;
Try this
public static int Length(String str) {
str = str + '\0';
int count = 0;
for (int i = 0; str.charAt(i) != '\0'; i++) {
count++;
}
return count;
}
What about:
"your string".toCharArray().length

fizzbuzz - can it be shorter?

WARNING:I'm not asking for a better code, I'm asking for a shorter code for HackerRank just to learn what can be done to shorten it.
I'm newbie to Java and was trying out this FizzBuzz problem:
Write a program that prints the numbers from 1 to 100. But for multiples of three print >“Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which >are multiples of both three and five print “FizzBuzz”.
I wrote my solution as short as possible.
class Solution{
public static void main(String[]b){
for(int i=1;i<101;i++){
String a=(i%3==0)?(i%5==0)?"FizzBuzz":"Fizz":(i%5==0)?"Buzz":i+"";
System.out.println(a);}}}
and I got a 3.6 score. But obviously there's room to improve because some people wrote it with 27 characters less. How is that possible ? Any suggestions? I don't really care about the ranks, I just wanna know what I'm missing.
EDIT: So with your help, I made it like this:
class Solution{public static void main(String[]b){for(int i=1;i<101;i++){System.out.println((i%3==0)?(i%5==0)?"FizzBuzz":"Fizz":(i%5==0)?"Buzz":i);}}}
and it seems I got rid of 14 characters. God knows what the other people did to lose 13 more characters. Anyway, thanks.
What about something like:
for(int i=0;i++<100;System.out.println((i%3>0?"":"Fizz")+(i%5>0?i%3>0?i:"":"Buzz")))
Warning: this code is just an exercise of trying to make the code shorter. It is neither good or readable as normal code should try to be!
Yes, it is possible to make it even shorter. Proof: According to the leaderboard, the highest score for java is 7.00.
How? Spoiler: identifier(s), parentheses, line breaks, pre/post increment. The conditions may be written as i%3>0 or the opposite like i%3<1.
class S{public static void main(String[]a){for(int i=0;++i<101;)System.out.println(i%3>0?i%5>0?i:"Buzz":"Fizz"+(i%5>0?"":"Buzz"));}}
It may not be getting significantly shorter yet, most likely due to the boilerplate code for main and print method. Based on everything suggested on this QA so far, it is possible to achieve at least 6.90 in Java if not the current max which is 7.00.
For example,
class S{public static void main(String[]a){for(int i=0;++i<101;)System.out.println(i%3>0?i%5>0?i:"Buzz":i%5>0?"Fizz":"FizzBuzz");}}
If we are open to try out other languages, we may wish to try JS with caution/advisory.
Many more approaches have been discussed here and here.
Java, C, C++, C#, Python, Ruby, R, none of the submissions in these languages reached the top score yet which is 16.0. It leads us to the question, which submission led to the top score? The answer is bash scripting. Proof: leaderboard for bash
How? The hint has been kindly provided by the author of the top submission, Byron Formwalt at here.
If we are new to bash scripting, we may wish to get started with few resources mentioned here, here, and here.
Disclaimer: Even though this may be suitable for the purpose of the getting higher score in hackerrank or just for exercise, it may not be a good practice for Best_coding_practices. There are many scopes for improvement in this post. Suggestions are welcome. Acknowledgements/Thanks.
It just becomes an argument to migrate to Kotlin!
fun fizzBuzz(number: Int) = when {
number.divisibleBy(3) and number.divisibleBy(5) -> "Fizz-Buzz"
number.divisibleBy(3) -> "Fizz"
number.divisibleBy(5) -> "Buzz"
else -> number.toString()
}
fun Int.divisibleBy(number: Int) = this % number == 0
fun main() {
(1..100).forEach {
println(fizzBuzz(it))
}
}
function fizzBuzz(n) {
for (i = 1; i <= n; i++) {
let result = "";
if (i % 3 === 0) result += "Fizz";
if (i % 5 === 0) result += "Buzz";
if (i % 7 === 0) result += "Foo";
console.log(result || i);
}
}
fizzBuzz(105);
It will check every condition, if all are true then all will be added together as well as it works with the single true condition as well as two true conditions.

Execution priority of expressions

In the following line of code:
x = x.times(x).plus(y);
in what order are these expressions going to be executed?
Will it be like:
x = (x + y)*x
or x = (x^2) + y,
or something else and why?
Links to documentation about the specific subject will be highly appreciated as I had no luck with my search. Apparently I don't know where to look at and what to look for.
Thank you.
These are methods; the fact that they are called "plus" and "times" doesn't mean that they'll necessarily follow the behaviour of the built-in + and * operators.
So x.times(x) will be executed first. This will return a reference to an object, on which plus(y) will then be executed. The return value of this will then be assigned to x. It's equivalent to:
tmp = x.times(x);
x = tmp.plus(y);
Here's a link to a documentation which most likely contains the required answer (probably at 15.7). It's highly technical and verbose but not inaccessible to most people (I believe).
However, it seems that you're just starting programming, so you'll be better off reading other answers here, and programming more to get an intuitive feel (not exactly a 'feel', as it's systematic and rigourous) of the order of operations etc...
Don't be afraid to write "throw-away" code (which you can incidentally save too) to find out things you don't know if you don't know where else to look for the answer. You can always google more intensively or dive through the language specs at a latter date. You'll learn faster this way. :)
One simple way to find out is to write something like this:
class Number{
private int number;
public Number(int x){
number = x;
}
public Number times(Number x){
System.Out.PrintLn("times");
return number * x;
}
public Number plus(Number x){
System.Out.PrintLn("plus");
return number + x;
}
}
Method chains get executed from left to right, with each method using the result from the previous method, so it will be x = (x^2) + y.
What you're referring to in the algebraic expressions is operator precedence - evaluating multiplications before addition, for example. The Java compiler knows about these rules for expressions, and will generate code to evaluate them as you expect.
For method calling, there are no "special rules". When given x = x.times(x).plus(y); the compiler only knows that to evaluate x.times(x).plus(y), it first needs to know what x is, so it can call times on it. Likewise, it then needs to know what x.times(x) is so it can call the plus method on that result. Hence, this type of statement is parsed left to right : (x * x) + y.
Some languages allow the creation of functions that are "infix" with user supplied precedence. (such as Haskell : See http://www.haskell.org/tutorial/functions.html, section "Fixity declarations"). Java is, alas, not one of them.
It's going to be executed in left-to-right order, as
x = (x.times(x)).plus(y)
The other way:
x = x.(times(x).plus(y))
doesn't even make sense to me. You would have to rewrite it as
x = x.times(x.plus(y))
to make sense of it, but the fact that the second x is contained within times() while the y is outside it rules out that interpretation.
The reason the documentation doesn't say anything about this is probably that such expressions follow the normal rules for how a statement like a.b().c().d() is evaluated: from left to right. We start with a and call the function b() on it. Then, we call c() on the result of that call, and we call d() on the result of c(). Hence, x.times(x).plus(y) will first perform the multiplication, then the addition.

Java Binary search

Trying to perform a binary search on a sorted array of Book objects.
Its not working well, it returns the correct results for some of the objects, but not all.
I went through the loop on paper and it seems that a number can get missed out due to rounding #.5 upwards.
Any ideas how to make this work?
Book found = null;
/*
* Search at the center of the collection. If the reference is less than that,
* search in the upper half of the collection, else, search in the lower half.
* Loop until found else return null.
*/
int top = numberOfBooks()-1;
int bottom = 0;
int middle;
while (bottom <= top && found == null){
middle = (bottom + top)/2;
if (givenRef.compareTo(bookCollection.get(middle).getReference()) == 0) {
found = bookCollection.get(middle);
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) < 0){
bottom = middle + 1;
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) > 0){
top = middle - 1;
}
}
return found;
A couple suggestions for you:
there's no need to keep a Book variable. In your loop, just return the book when it's found, and at the end return null. And you can also remove the boolean check for the variable in the while condition.
the middle variable can be scoped inside the loop, no need to have it live longer.
you're doing bookCollection.get(middle).getReference() three times. Consider creating a variable and then using it.
the middle = (bottom + top)/2 is a classic mistake in binary search implementation algorithms. Even Joshua Bloch, who wrote the Java Collection classes, made that error (see this interesting blog post about it). Instead, use (bottom+top) >>> 1, to avoid integer overflow for very large values (you probably wouldn't encounter this error, but it's for the principle).
As for your actual problem statement, rounding would be downwards (integer division), not upwards. To troubleshoot the problem:
are you sure the numberOfBooks() method corresponds to the length of your collection?
are you sure the compareTo() method works as expected for the types you are using (in your code example we do not know what the getReference() return type is)
are you sure your collection is properly sorted according to getReference()?
and finally, are you sure that using givenRef.compareTo(bookCollection.get(middle).getReference()) < 0 is correct? In standard binary search implementations it would be reversed, e.g. bookCollection.get(middle).getReference().compareTo(givenRef) < 0. This might be what donroby mentions, not sure.
In any case, the way to find the error would be to try out different values and see for which the output is correct and for which it isn't, and thus infer what the problem is. You can also use your debugger to help you step through the algorithm, rather than using pencil and paper if you have to run many tests. Even better, as donroby said, write a unit test.
What about Collections.binarySearch()?
All of JRL's suggestions are right, but the actual fail is that your compares are reversed.
I didn't see this immediately myself, but replicating your code into a function (using strings instead of Books), writing a some simple Junit tests and then running them in the debugger made it really obvious.
Write unit tests!
I found the problem.
It turns out i was binary searching my bookCollection arrayList, and NOT the new sroted array i had created - sortedLib.
Silly mistake at my end, but thanks for the input and suggestions!

Categories