How to use the value of a return statement in a different method? - variables

I recently started codeing java, so this question might be a little, well, stupid, but i created a small program that averages 5 numbers. I know the program is very over complicated, i have just been trying out some of the new things i've learned.My problem is i would like to get the variable "Answer" up in my main program. I dont want to change around the program if i dont have to.I have returned the value in the average method, and set this answer to the variable Answer, but how can i use System.out.print(Answer) or print the return. Heres the code! Sorry if its not in a code block, i indented 4 spaces, but it doesnt say anything.
package Tests;
import java.util.*;
public class average_Test {
static double Total=0;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int temp;
int count[]={5,1,2,3,4};
for(int x:count){
System.out.print("Please enter 5 numbers: ");
temp=scan.nextInt();
average(temp);
}
}
public static double average(int n){
for(int c=0;c<1;c++){
Total+=n;
}
double average=Total/5;
System.out.println(average);
double Answer = Total/5;
return Total/5;
}
}

You can use variable binding, or print result of function:
double a = average(temp);
System.out.println(a);
or:
System.out.println(average(temp));
At the end it will look like this:
double result = 0;
System.out.print("Please enter 5 numbers: ");
for (int x : count) {
temp = scan.nextInt();
result = average(temp);
}
System.out.println(result);
P.S. code looks weird, consider implementing double average(int[] numbers)

Related

Are there any changes I should make to the formatting of my code?

My teacher is telling me that I need to work on my formatting by using code blocks properly. I've edited the code and would like to know if anyone has any ideas for improvement, or if my code looks ok. I'm just not sure if I am formatting it correctly. I didn't lose many points on the assignment for it, but if there is room for improvement I would greatly appreciate it.
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
int n1 = 0;
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 0;
int i = 1;
System.out.println("Enter a number between 1 and 30 ");
n1 = input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n2= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n3= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n4= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n5= input.nextInt();
for(i = 1; i <= n1; i++){
System.out.print("*");
}
System.out.println();//new line
for(i = 1; i <= n2; i++){
System.out.print("*");
}
System.out.println();//new line
for(i = 1; i <= n3; i++){
System.out.print("*");
}
System.out.println();
for(i = 1; i <= n4; i++){
System.out.print("*");
}
System.out.println();
for(i = 1; i <= n5; i++){
System.out.print("*");}
}
System.out.println();
input.close();
}
}
This is what the program looked like before I edited it.
import java.util.Scanner;
public class BarChart
{
public static void main(String[] args)
{
/* Instructor Comments: You need to work on the formatting. Make sure your
code lines up properly. You have most of your code indented too far.
Within the Main method it should be indented one tab stop and
all the code lined up. It should only be indented again if
it is inside another code structure such as an if statement
or for loop. */
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
//initializing variables
int n1 = 0;
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 0;
int i = 1;//index
System.out.println("Enter a number between 1 and 30 ");//prompt user input
/* Instructor Comments: This next line should line up with the rest
of the code and not be indented. */
n1 = input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n2= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n3= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n4= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n5= input.nextInt();//store user input
/* Instructor Comments: Format your for loops properly. The code blocks
should be on there own line. Not on the same line as the code inside it.
I am fixing the first one to show you. */
for(i = 1; i <= n1; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{
System.out.print("*");
}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n2; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n3; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n4; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n5; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
input.close();//closes scanner
}
}
One thing to note about formatting code is that most of the time, the format of code does not impact how it runs. (In some cases you could write most of your code on one line and it would still work).
Formatting is one of those things that is designed to make it easier on the developer to debug and change or add code. With this in mind, everyone can format their code in whatever way they find it suits them. You shouldn't have lost marks for a piece of code that does work.
Here are some well-known practices of formatting code:
Hierarchical
Think of this as a hierarchy. If you place an object within a class, or a function within a function, you format it to represent that.
For example:
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
Would become:
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
See how this represents that public static void main(String[] args){ is within public class BarChart{? It makes it a lot easier to see it visually. Use your parentheses to represent a closure of a function, and indent it at the same level as the declaration. Of course, this brings up the never-ending debate about whether you use tab or space to indent your code, but really - it doesn't matter. It's your choice.
Spacing
I once read somewhere that if you believe a comment would be most suitable in between two lines of code, leave a gap. This especially applies between two different functions or the like (which it appears you've already done).
Commenting
Ah, commenting. It's saved me from hours of trying to remember why I wrote something like that, or why something wasn't working. Always try to comment your code. It's the one time you can convert all the computer language into human-readable language and it will help you better understand your code. If you need to pass the code on, the new developer will be able to understand it better. If you need to fix something a year later, you will be able to recall how it worked and possibly what needs to be changed. Comment, comment, comment.
These are just some of my favourite practices and some you should adapt too. These are by no means professional practices and they're just the basics of coding. To answer your original question, your code is very well structured but try to focus on indenting and commenting.
(Note: if you were talking about the structure of your code and not the format, you should look into not repeating functions. This makes your code look bulky).
They probably meant for you to use loops when you need to repeat certain patterns. Your main function can be rewritten like this:
public static void main(String[] args) {
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
int[] n = new int[5];
int i, j;
for (i = 0; i < 5; i++) {
System.out.println("Enter a number between 1 and 30 ");
n[i] = input.nextInt();
}
for (i = 0; i < 5; i++) {
for (j = 0; j < n[i]; j++) {
System.out.print("*");
}
System.out.println();
}
input.close();
}
As you can see, I used loop variables starting from zero index and ending before the array size is reached. This is generally considered good practice, because arrays, for example, start with index 0. If you really want to impress your teacher, you can use methods as well:
private static int[] readNumbers(int amount) {
Scanner input = new Scanner(System.in);
int[] n = new int[amount];
int i;
for (i = 0; i < 5; i++) {
System.out.println("Enter a number between 1 and 30 ");
n[i] = input.nextInt();
}
input.close();
return n;
}
private static void printStars(int[] amounts) {
int i, j;
for (i = 0; i < amounts.length; i++) {
for (j = 0; j < amounts[i]; j++) {
System.out.print("*");
}
System.out.println();
}
}
public static void main(String[] args) {
System.out.println("Riley Hall - Assignment 3\n");
int[] n = readNumbers(5);
printStars(n);
}
They make code reusable and are infinitely useful.
As per formatting, you can always get IntelliJ IDEA community edition and use its auto format feature to see how a generally good formatting looks. You shouldn't rely on this though to do the job for you until you're comfortable with keeping the format yourself.

how to count the number of integers input by the user

i have to make a program that reads an arbitrarily long integer input from the user and finds the sum of the digits. i was thinking about making the program do a loop until the integer count is zero and adding up the sum of the numbers the user typed in. but im not sure how to write that since im a beginner at java. this is what i got from my try at it
import java.util.Scanner;
public class sumofnumberstest {
public static void main(String[] args) {
int data;
int sum = 0;
Scanner input = new Scanner(System.in);
System.out.print( "Enter an integer ): ");
data = input.nextInt();
int length = data.length
do {
data %10;
sum += data;
} while (data.length >=0 & = 100000000000000000000000000000 );
System.out.println("The sum is " + sum);
}
}
your question is similar to a previously asked question. Take a look here -> How to read each individual digit of a number in Java
Here's a simple implementation of what you're trying to do:
https://stackoverflow.com/a/39861955/6913557

Multiple thenApply in a completableFuture

I have a situation where I want to execute some methods in different threads but want to pass the result of one thread to another. I have following methods in my class.
public static int addition(int a, int b){
System.out.println((a+b));
return (a+b);
}
public static int subtract(int a, int b){
System.out.println((a-b));
return (a-b);
}
public static int multiply(int a, int b){
System.out.println((a*b));
return (a*b);
}
public static String convert(Integer a){
System.out.println((a));
return a.toString();
}
here is main method:
public static void main(String[] args) {
int a = 10;
int b = 5;
CompletableFuture<String> cf = new CompletableFuture<>();
cf.supplyAsync(() -> addition(a, b))
.thenApply(r ->subtract(20,r)
.thenApply(r1 ->multiply(r1, 10))
.thenApply(r2 ->convert(r2))
.thenApply(finalResult ->{
System.out.println(cf.complete(finalResult));
}));
System.out.println(cf.complete("Done"));
}
I am trying to pass result of addition to subtraction to multiplication to printing result. But I am getting compilation error. Looks like we can't do nested thenApply(). Is there any way we can do this? Searched it over google and found one helpful link- http://kennethjorgensen.com/blog/2016/introduction-to-completablefutures But didn't find much help.
A couple of things are wrong with your snippet:
Parenthesis: you have to start the next thenApply after the end of the one before, not after the substract method.
supplyAsync() is a static method. Use it as such.
If you just want to print out the result in the last operation, use thenAccept instead of thenApply
You do not need to complete the CF in thenAccept (neither you would have to do it in thenApply before.
This piece of code compiles, and it may be close to what you want to achieve:
CompletableFuture<Void> cf = CompletableFuture
.supplyAsync(() -> addition(a, b))
.thenApply(r -> subtract(20, r))
.thenApply(r1 -> multiply(r1, 10))
.thenApply(r2 -> convert(r2))
.thenAccept(finalResult -> {
System.out.println("this is the final result: " + finalResult);
});
//just to wait until the cf is completed - do not use it on your program
cf.join();

Sage: Iterate over increasing sequences

I have a problem that I am unwilling to believe hasn't been solved before in Sage.
Given a pair of integers (d,n) as input, I'd like to receive a list (or set, or whatever) of all nondecreasing sequences of length d all of whose entries are no greater than n.
Similarly, I'd like another function which returns all strictly increasing sequences of length d whose entries are no greater than n.
For example, for d = 2 n=3, I'd receive the output:
[[1,2], [1,3], [2,3]]
or
[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
depending on whether I'm using increasing or nondecreasing.
Does anyone know of such a function?
Edit Of course, if there is such a method for nonincreasing or decreasing sequences, I can modify that to fit my purposes. Just something to iterate over sequences
I needed this algorithm too and I finally managed to write one today. I will share the code here, but I only started to learn coding last week, so it is not pretty.
Idea Input=(r,d). Step 1) Create a class "ListAndPosition" that has a list L of arrays Integer[r+1]'s, and an integer q between 0 and r. Step 2) Create a method that receives a ListAndPosition (L,q) and screens sequentially the arrays in L checking if the integer at position q is less than the one at position q+1, if so, it adds a new array at the bottom of the list with that entry ++. When done, the Method calls itself again with the new list and q-1 as input.
The code for Step 1)
import java.util.ArrayList;
public class ListAndPosition {
public static Integer r=5;
public final ArrayList<Integer[]> L;
public int q;
public ListAndPosition(ArrayList<Integer[]> L, int q) {
this.L = L;
this.q = q;
}
public ArrayList<Integer[]> getList(){
return L;
}
public int getPosition() {
return q;
}
public void decreasePosition() {
q--;
}
public void showList() {
for(int i=0;i<L.size();i++){
for(int j=0; j<r+1 ; j++){
System.out.print(""+L.get(i)[j]);
}
System.out.println("");
}
}
}
The code for Step 2)
import java.util.ArrayList;
public class NonDecreasingSeqs {
public static Integer r=5;
public static Integer d=3;
public static void main(String[] args) {
//Creating the first array
Integer[] firstArray;
firstArray = new Integer[r+1];
for(int i=0;i<r;i++){
firstArray[i] = 0;
}
firstArray[r] = d;
//Creating the starting listAndDim
ArrayList<Integer[]> L = new ArrayList<Integer[]>();
L.add(firstArray);
ListAndPosition Lq = new ListAndPosition(L,r-1);
System.out.println(""+nonDecSeqs(Lq).size());
}
public static ArrayList<Integer[]> nonDecSeqs(ListAndPosition Lq){
int iterations = r-1-Lq.getPosition();
System.out.println("How many arrays in the list after "+iterations+" iterations? "+Lq.getList().size());
System.out.print("Should we stop the iteration?");
if(0<Lq.getPosition()){
System.out.println(" No, position = "+Lq.getPosition());
for(int i=0;i<Lq.getList().size();i++){
//Showing particular array
System.out.println("Array of L #"+i+":");
for(int j=0;j<r+1;j++){
System.out.print(""+Lq.getList().get(i)[j]);
}
System.out.print("\nCan it be modified at position "+Lq.getPosition()+"?");
if(Lq.getList().get(i)[Lq.getPosition()]<Lq.getList().get(i)[Lq.getPosition()+1]){
System.out.println(" Yes, "+Lq.getList().get(i)[Lq.getPosition()]+"<"+Lq.getList().get(i)[Lq.getPosition()+1]);
{
Integer[] tempArray = new Integer[r+1];
for(int j=0;j<r+1;j++){
if(j==Lq.getPosition()){
tempArray[j] = new Integer(Lq.getList().get(i)[j])+1;
}
else{
tempArray[j] = new Integer(Lq.getList().get(i)[j]);
}
}
Lq.getList().add(tempArray);
}
System.out.println("New list");Lq.showList();
}
else{
System.out.println(" No, "+Lq.getList().get(i)[Lq.getPosition()]+"="+Lq.getList().get(i)[Lq.getPosition()+1]);
}
}
System.out.print("Old position = "+Lq.getPosition());
Lq.decreasePosition();
System.out.println(", new position = "+Lq.getPosition());
nonDecSeqs(Lq);
}
else{
System.out.println(" Yes, position = "+Lq.getPosition());
}
return Lq.getList();
}
}
Remark: I needed my sequences to start at 0 and end at d.
This is probably not a very good answer to your question. But you could, in principle, use Partitions and the max_slope=-1 argument. Messing around with filtering lists of IntegerVectors sounds equally inefficient and depressing for other reasons.
If this has a canonical name, it might be in the list of sage-combinat functionality, and there is even a base class you could perhaps use for integer lists, which is basically what you are asking about. Maybe you could actually get what you want using IntegerListsLex? Hope this proves helpful.
This question can be solved by using the class "UnorderedTuples" described here:
http://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tuple.html
To return all all nondecreasing sequences with entries between 0 and n-1 of length d, you may type:
UnorderedTuples(range(n),d)
This returns the nondecreasing sequence as a list. I needed an immutable object (because the sequences would become keys of a dictionary). So I used the "tuple" method to turn the lists into tuples:
immutables = []
for s in UnorderedTuples(range(n),d):
immutables.append(tuple(s))
return immutables
And I also wrote a method which picks out only the increasing sequences:
def isIncreasing(list):
for i in range(len(list) - 1):
if list[i] >= list[i+1]:
return false
return true
The method that returns only strictly increasing sequences would look like
immutables = []
for s in UnorderedTuples(range(n),d):
if isIncreasing(s):
immutables.append(tuple(s))
return immutables

What is the fastest way to compare two byte arrays?

I am trying to compare two long bytearrays in VB.NET and have run into a snag. Comparing two 50 megabyte files takes almost two minutes, so I'm clearly doing something wrong. I'm on an x64 machine with tons of memory so there are no issues there. Here is the code that I'm using at the moment and would like to change.
_Bytes and item.Bytes are the two different arrays to compare and are already the same length.
For Each B In item.Bytes
If B <> _Bytes(I) Then
Mismatch = True
Exit For
End If
I += 1
Next
I need to be able to compare as fast as possible files that are potentially hundreds of megabytes and even possibly a gigabyte or two. Any suggests or algorithms that would be able to do this faster?
Item.bytes is an object taken from the database/filesystem that is returned to compare, because its byte length matches the item that the user wants to add. By comparing the two arrays I can then determine if the user has added something new to the DB and if not then I can just map them to the other file and not waste hard disk drive space.
[Update]
I converted the arrays to local variables of Byte() and then did the same comparison, same code and it ran in like one second (I have to benchmark it still and compare it to others), but if you do the same thing with local variables and use a generic array it becomes massively slower. I’m not sure why, but it raises a lot more questions for me about the use of arrays.
What is the _Bytes(I) call doing? It's not loading the file each time, is it? Even with buffering, that would be bad news!
There will be plenty of ways to micro-optimise this in terms of looking at longs at a time, potentially using unsafe code etc - but I'd just concentrate on getting reasonable performance first. Clearly there's something very odd going on.
I suggest you extract the comparison code into a separate function which takes two byte arrays. That way you know you won't be doing anything odd. I'd also use a simple For loop rather than For Each in this case - it'll be simpler. Oh, and check whether the lengths are correct first :)
EDIT: Here's the code (untested, but simple enough) that I'd use. It's in C# for the minute - I'll convert it in a sec:
public static bool Equals(byte[] first, byte[] second)
{
if (first == second)
{
return true;
}
if (first == null || second == null)
{
return false;
}
if (first.Length != second.Length)
{
return false;
}
for (int i=0; i < first.Length; i++)
{
if (first[i] != second[i])
{
return false;
}
}
return true;
}
EDIT: And here's the VB:
Public Shared Function ArraysEqual(ByVal first As Byte(), _
ByVal second As Byte()) As Boolean
If (first Is second) Then
Return True
End If
If (first Is Nothing OrElse second Is Nothing) Then
Return False
End If
If (first.Length <> second.Length) Then
Return False
End If
For i as Integer = 0 To first.Length - 1
If (first(i) <> second(i)) Then
Return False
End If
Next i
Return True
End Function
The fastest way to compare two byte arrays of equal size is to use interop. Run the following code on a console application:
using System;
using System.Runtime.InteropServices;
using System.Security;
namespace CompareByteArray
{
class Program
{
static void Main(string[] args)
{
const int SIZE = 100000;
const int TEST_COUNT = 100;
byte[] arrayA = new byte[SIZE];
byte[] arrayB = new byte[SIZE];
for (int i = 0; i < SIZE; i++)
{
arrayA[i] = 0x22;
arrayB[i] = 0x22;
}
{
DateTime before = DateTime.Now;
for (int i = 0; i < TEST_COUNT; i++)
{
int result = MemCmp_Safe(arrayA, arrayB, (UIntPtr)SIZE);
if (result != 0) throw new Exception();
}
DateTime after = DateTime.Now;
Console.WriteLine("MemCmp_Safe: {0}", after - before);
}
{
DateTime before = DateTime.Now;
for (int i = 0; i < TEST_COUNT; i++)
{
int result = MemCmp_Unsafe(arrayA, arrayB, (UIntPtr)SIZE);
if (result != 0) throw new Exception();
}
DateTime after = DateTime.Now;
Console.WriteLine("MemCmp_Unsafe: {0}", after - before);
}
{
DateTime before = DateTime.Now;
for (int i = 0; i < TEST_COUNT; i++)
{
int result = MemCmp_Pure(arrayA, arrayB, SIZE);
if (result != 0) throw new Exception();
}
DateTime after = DateTime.Now;
Console.WriteLine("MemCmp_Pure: {0}", after - before);
}
return;
}
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint="memcmp", ExactSpelling=true)]
[SuppressUnmanagedCodeSecurity]
static extern int memcmp_1(byte[] b1, byte[] b2, UIntPtr count);
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "memcmp", ExactSpelling = true)]
[SuppressUnmanagedCodeSecurity]
static extern unsafe int memcmp_2(byte* b1, byte* b2, UIntPtr count);
public static int MemCmp_Safe(byte[] a, byte[] b, UIntPtr count)
{
return memcmp_1(a, b, count);
}
public unsafe static int MemCmp_Unsafe(byte[] a, byte[] b, UIntPtr count)
{
fixed(byte* p_a = a)
{
fixed (byte* p_b = b)
{
return memcmp_2(p_a, p_b, count);
}
}
}
public static int MemCmp_Pure(byte[] a, byte[] b, int count)
{
int result = 0;
for (int i = 0; i < count && result == 0; i += 1)
{
result = a[0] - b[0];
}
return result;
}
}
}
If you don't need to know the byte, use 64-bit ints that gives you 8 at once. Actually, you can figure out the wrong byte, once you've isolated it to a set of 8.
Use BinaryReader:
saveTime = binReader.ReadInt32()
Or for arrays of ints:
Dim count As Integer = binReader.Read(testArray, 0, 3)
Better approach... If you are just trying to see if the two are different then save some time by not having to go through the entire byte array and generate a hash of each byte array as strings and compare the strings. MD5 should work fine and is pretty efficient.
I see two things that might help:
First, rather than always accessing the second array as item.Bytes, use a local variable to point directly at the array. That is, before starting the loop, do something like this:
array2 = item.Bytes
That will save the overhead of dereferencing from the object each time you want a byte. That could be expensive in Visual Basic, especially if there's a Getter method on that property.
Also, use a "definite loop" instead of "for each". You already know the length of the arrays, so just code the loop using that value. This will avoid the overhead of treating the array as a collection. The loop would look something like this:
For i = 1 to max Step 1
If (array1(i) <> array2(i))
Exit For
EndIf
Next
Not strictly related to the comparison algorithm:
Are you sure your bottleneck is not related to the memory available and the time used to load the byte arrays? Loading two 2 GB byte arrays just to compare them could bring most machines to their knees. If the program design allows, try using streams to read smaller chunks instead.