I am trying to build a Java program based on this UML:
UML of Polygon Class
But I ran into a few hiccups along the way. This is my basic code:
import java.util.Scanner;
public class Polygon {
private int[] side;
private double perimeter;
public double addSide(double length[]) {
int i = 0;
double perimeter = 0;
while(length[i] > 0){
perimeter += (double)length[i];
i++;
}
return perimeter;
}
public int[] getSides() {return side;}
public double getPerimeter() {return perimeter;}
public static void main(String[] args) {
Polygon polygon=new Polygon();
polygon.side = new int[99];
int i=0;
do{
System.out.print("Side length(0 when done): ");
Scanner in = new Scanner(System.in);
polygon.side[i] = in.nextInt();
i++;
}while(polygon.side[i]>0);
//polygon.perimeter = addSide((double)polygon.side);
System.out.println("Perimeter of " + i + "-sided polygon: " + polygon.getPerimeter());
}
}
There's a couple of issues.
I got it to compile but when it accepts the first side[0], it immediately stops and gives me the perimeter. Exiting the loop eventhough the conditions haven't been met for it to so. So there's an issue with my while-loop. I want it to keep accepting values into the side[] array until a non-positive value is entered.
Also the UML requires I use double parameter-type for the addSide method. I tried to cast it in the argument and tried a couple of other different things with no success. How would one transition an int-array into a double-array for the perimeter calucalation which has to be double as per the requirements.
I wouldn't surprised if I made other issues since I'm new to Java so feel free to point them out to me or if you have a better way to go about this, I would love to learn your thinking.
Any advice is appreciated!
There are a number of issues with your code.
First, differences from the UML specification:
You haven't used the given signature for addSide. The UML says that it takes a single double parameter, and returns nothing, i.e. void in Java. You are passing an array of double and returning a double.
You are directly accessing sides in your main method. Java allows you to do this, because your main method is part of the Polygon class, but the UML shows that the field is private. What does direct manipulation of sides do to the validity of the value in perimeter?
The UML shows the class having a field sides of type int. Your field sides is of type int[].
Similarly you haven't used the given signature for getSides, which should probably have been named getNumberOfSides.
Your code has quite a few other issues, but I think you should fix the issues above first.
A futher hint: The only things that the Polygon class can do is to tell you how many sides it has and what its total perimeter is. It does not care about the details of individual sides.
(Off topic, it is strange to include main in the UML description of Polygon)
Related
I'm trying to learning Java from zero. I have an exercise that after reading it all over again I can't find why doesn't work. Researching on Google and StackOverflow returned to zero results...
Main objective is to translate dollars to pesetas by just multiplying by a number. I have to use two functions and call them on "main".
My problem is that "convertToPesetas" isn't taking the returned double of "askDollars". Can someone hand me a rope?
import java.util.Scanner;
public class Converter
{
public static void main(String[] args){
askDollars();
convertToPesetas();
}
public static double askDollars(){
System.out.println("Type the quantity of dollars:");
Scanner keyboard= new Scanner(System.in);
double dollars= keyboard.nextDouble();
System.out.println("Dollars: "+dollars);
return dollars;
}
public static double convertToPesetas(double dollars){
double pesetas = pesetas*166.386;
System.out.println(dollars+ "€ equals to: "+pesetas+" pesetas");
return pesetas;
}
}
Because you're not storing or supplying that value:
askDollars();
convertToPesetas();
Save the returned value in a variable and pass that variable to the next method:
double dollars = askDollars();
convertToPesetas(dollars);
Note: convertToPesetas also returns a value. You don't seem to need it to do that. But, you could use that if you take your design in a different direction. As an academic exercise for your next step, consider three methods:
One which asks for the user input.
One which converts the dollars value to the pesetas value. This has no input or output, just a method argument and a return value.
One which prints the output.
Each method would do exactly one, simple thing. And when you have this, you'll find that the second method is free to easily be moved to other objects, etc. because it's entirely independent and not coupled to the user interface in any way.
In my Java basic class my teacher told me to comment any arbitrary choice that I make when I write a default constructor for a class. (She told us that we must create a default constructor for every class that we design) So for example, I'm writing a class named RoomDimension, and I created a default constructor as follows:
public class RoomDimension {
//Fields
private double length; //Length of a carpet
private double width; //Width of a carpet
/**
*
*/
public RoomDimension(){
length = 0.0;
width = 0.0;
}
I'm using here 0.0 as my flag to indicate the user has entered nothing or an invalid input. Should I then comment the fact that 0.0 is used as an indication of an invalid input in the documentation comment(/**/)? I know that if I were to use -1 as my flag (or an initialization of a field in default constructor), I would definitely comment that -1 indicates an invalid input because I made that decision arbitrarily. I'm asking whether 0 has to be commented or not because I don't know if 0 is an arbitrary choice or not. Would you, as a programmer, bother to indicate that? Or, is it okay if I just assume that the user knows it without telling them?
As to whether zero should be commented, I think it would be best to indicate it is a flag in order to remind yourself in the future, or any other programmer that looks at your code.
As for using zero as a flag, I think it would be better practice to throw an exception when length and height are less than or equal to zero. It would be easier to read in the future, and more efficient to handle when a user does enter a non-positive number.
She told us that we must create a default constructor for every class
that we design
And I told for my teacher: Who don't know is teaching, who know is doing!
If you don't create a default constructor, the compiler will do it, did you know? - how about your teacher?
Many tools, which generates, transform data will cry, nags, crash if they don't find a COMPILED "default constructor". But they will completely ignore the comments.
So back to your class:
public class RoomDimension {
static {
System.out.println("I an a static initializer, If the classloader will touch your class, I will be called first! ex. RoomDimension.anyStaticmethod() or before new RoomDimension()");
}
{
System.out.println("I am instance initializer. whenever you call any constructor, I will run before the constructor body, try me with: new RoomDimension()");
}
//Fields
private double length; //Length of a carpet
private double width; //Width of a carpet
public RoomDimension() {
length = 0.0;
width = 0.0;
}
}
By the way in your code:
public RoomDimension() {
length = 0.0;
width = 0.0;
}
it is completely useless, because before constructor, it will be an initialisation and that will do exactly the same, because you have declared as properties and they will be initialize, before constructor:
private double length; //Length of a carpet
private double width; //Width of a carpet
If you want to know it is initialized or not, use Double instead of double and check for null value.
Ex:
private Double length; //Length of a carpet
private Double width; //Width of a carpet
I would set the values of those to be nullable.
public class RoomDimension
{
private double? length;
private double? width;
}
public RoomDimension()
{
}
What this does for you is allow the values of length and width to take the value of null. So when you call the default constructor, they are automatically set to null.
This will help you start thinking in terms of objects, because when you have objects that contain other objects you cant set all the contained objects to 0.0, you just create a null object. Also when you perform actions on that object you just check if its null beforehand this helps to avoid null reference exceptions.
Write a class Cone to represent a geometric cone.
Also write a main application that tests your cone class.
Provide the following methods:
A Constructor
Function Volume( )
Function SurfaceArea( )
Provide Get and Set methods for your entire
data vector.
Test all of your methods.
Loop from 1-100 and set the height and radius of
the cone using the loop counter or use random numbers.
Output the volume and surface area within the loop.
Code this far.
import java.util.Random;
class Cone{
public static void main(String []) {
Cone c = new Cone( );
Random r = new Random();
int x, y;
for (int i = 0; i < 1; i++) {
c.setR("%d");
c.setH("%d")
}
}
}
Your Random is unimplemented
c.setR(r.nextInt(99)+1);
This will randomly generate a random value between 1 and 100 and set it as your radius. You can do something similar for the height, and then finding the volume should be fairly self explanatory.
There is a significant difference between asking for help, and asking for your work to be done for you. I'd advise you to drop out of your Computer Science class if you're not willing to learn the fundamentals of Java by yourself.
Here, do something productive: https://docs.oracle.com/javase/tutorial/
Sorry if this is a bit vague. I am new to learning Java.
In my program I have two classes and one of the classes is for user input. The other class calculates that user input and then returns the calculations to the other class. In my calculations class I'm pretty sure I'm making myself work harder and than I should be. I want to have the result of my user input multiplied together but doing that in the calculations class.
Here is my Calculations class.
class Calculations{
double length, width ;
public double floorArea (double length, double width){
return length * width ;
}
public double floorAreaCost (double length, double width) {
return length * width * 6.50 ;
}
public double serviceCharge (double length, double width){
return length * width / 10 + 12.50 ;
}
}
What I want to be able to do is have return length * width = area. Then use that area variable for future reference in the floorAreaCost method and the service charge method. So instead of return length * width * 6.50 I would have area * 6.50
Here's my user input class as well.
import java.util.Scanner;
public class ApartmentUser{
static Scanner input = new Scanner(System.in);
public static void main (String args[]){
int length, width;
System.out.println("Enter the length of the apartment floor: " );
length = input.nextInt();
System.out.println("Enter the width of the apartment floor: " );
width = input.nextInt();
Calculations area = new Calculations();
System.out.println("The area of the apartment floor is: " + area.floorArea(length, width));
Calculations cost = new Calculations();
System.out.println("The cost of the apartment is: " + cost.floorAreaCost(length, width));
Calculations charge = new Calculations();
System.out.println("The service charge cost is: " + charge.serviceCharge (length, width));
}
}
Your methods should call the floorArea method, so for example method shown below
public double floorAreaCost (double length, double width) {
return length * width * 6.50 ;
}
would become
public double floorAreaCost (double length, double width) {
return this.floorArea(length, width) * 6.50 ;
}
That way, the floor area calculation is encapsulated inside one method only and can easily change in one step
First of all you shouldn't make so many Calculations objects, one is enough.
So what you should do is give the Calculations class a constructor like this.
class Calculations{
public double length, width, area;
public Calculations (int length, int width) {
this.length = length;
this.width = width;
area = width * length;
}
Now when you create youre Calculations object:
Calculations floor = new Calculations(int length, int width);
You directly have the area calculated and you can call the methods without having to input the parameters, because they're already saved in the Calculations class.
You can also work with multiple "rooms", because the informations are saved in the Calculations class.
Hope i could help you.
As written, your Calculations class defines a "stateless" object.
Within each function, the function parameters length and width
hide the member variables length and width,
so that the member variables are never use at all.
You should be able to delete the declaration of those member variables
without noticing any change in the behavior of your program.
This is not necessarily a bad thing. Stateless classes can be very useful.
For example, because Calculations is stateless, you do not need to
allocate three different instances to perform your three different functions.
You can call all the functions on the same instance, because none of the
functions can affect the "state" of the object and therefore cannot have
any hidden "side effects" on the results of functions called later.
The return from each function is determined just by the values you
pass to its two parameters.
The program does end up multiplying the same length and width together
three times when once would have been enough.
You will hardly notice the extra computing time in this example
(it is vastly overshadowed by everything else going on here),
but if you had to do millions of these calculations for one user input
you might then notice a difference.
One way to avoid the redundant multiplications
is to return area from the floorArea function,
but pass area (not length and width) as a single parameter to
each of the other functions.
You might also consider creating member variables of Calculations
to store the numbers 6.5, 10, and 12.5 that you use in some of your functions.
That would allow you to give those numbers meaningful, descriptive names.
It would also permit a more sophisticated version of the program to accept
new values of those constants to use in a Calculations object,
allowing the store to change its pricing without rewriting its software.
If you set those values during the construction of a Calculations object
and do not change them in any of the other functions, the object
is still stateless.
Or you could decide to change the class some other way. I see at least three other answers already, each of which proposes a legitimate design of a Calculations class, no two of those designs the same.
First off all when you define fields in your class, it's common practice to define the scope of the variable. So it would look something like this. Which only makes the variable accessible within the class, if you would access it from the main method, you should declare em public. But add your area as a variable.
private double area ;
You need to store your calculated Area on the object, use the keyword this for accessing that variable. When operations on the same object is done, it can be fetched in a similar fashion.
Update your code to this:
public double floorArea (double length, double width){
this.area = length * width;
return this.area;
}
public double serviceCharge (){
return this.area / 10 + 12.50 ;
}
I'm confusing myself here. My goal was to make a simple program that took the number of values the user wants to average, store them in an array (while adding them together) and finally giving the average of these numbers.
My thing is, I am trying to understand the concept of multiple classes and methods as I am new so I tried using another class just do do all the work, while the Main class would just create the object from the other class, and then run their methods. Maybe I am asking something impossible. Take a look at my code.
This is my Main class:
public class Main
{
public static void main(String[] args)
{
System.out.println("Please enter numbers to average together");
OtherClass averages = new OtherClass();
averages.collectNumbers();
averages.AverageNumbers();
}
}
Now I am not sure if anything goes in those parameters, or if I can even use "averages.AverageNumbers();" without creating another object with "OtherClass" called something else? I am pretty sure it's legal though.
Here is my other class for this project entitled "OtherClass"
import java.util.Scanner;
public class OtherClass // using this to name obj
{
public void collectNumbers() //name of our method that does things
{
Scanner sc = new Scanner(System.in);
System.out.println("how many integers would you like to average? ");
int givenNum = sc.nextInt();
System.out.println("Alright, I will average " + givenNum + " values. \nPress enter after each:");
int[] numCollect = new int[givenNum];
int sum = 0;
for (int i = 0; i < numCollect.length; i++)
{
numCollect[i] = sc.nextInt();
sum = sum + numCollect[i];
}
System.out.println(sum);
}
public int AverageNumbers(int givenNum, int sum)
{
int average = sum / givenNum;
System.out.println(average);
return average;
}
}
So when I run this now with the the method AverageNumbers, it does not work. I am suspecting that maybe I am passing in the integers wrong? I have been toying with it for about an hour now, so I am asking for help. How do I make this work?
This will work if you declare sum and givenNum as fields of your OtherClass, instead of as local variables. So, before the collectNumbers method, write
private int sum;
private int givenNum;
and remove the declarations of these two variables inside collectNumbers. So, for example, instead of
int givenNum = sc.getInt();
you'll just have
givenNum = sc.getInt();
because the variable already exists. Also change the declaration of the averageNumbers method to
public int averageNumbers()
because you no longer need to pass those two values in to this method.
This is the archetypical example of using the objects of a class to carry a small amount of data around, instead of just using a class as a way to group methods together. The two methods of this class work with sum and givenNum, so it makes sense to store these in each object of this class.
Lastly, in your averageNumbers method, you have an integer division, which will automatically round down. You probably want a floating point division instead, so you could write
double average = (double) sum / givenNum;
which converts sum to a double-precision floating point number before the division, and therefore does the division in floating point, instead of just using integers. Of course, if you make this change, you'll need to change the return type of this method to double too.