OOP Ticket Price Program - java

So this one is a bit lengthy. I'm trying to finish off a program where ticket price varies depending on purchase date. I need the Tester.Java to take the info from the objects, and output the proper price depending on the ticket type. I have already set a set of if statements in the Tester, but I am now at an impass on how to finish this program off. I will paste my code below.
Tester (contains the main method):
package tester;
import java.util.Scanner;
public class Tester extends Ticket{
/**
* #param args the command line arguments
*/
public static void main(String[] args){
Scanner db = new Scanner(System.in);
Ticket firstTicket = new Ticket();
System.out.println("The first ticket: "+firstTicket.toString());
int x = 0;
while(x!=2){
if(x==2){
System.out.println("Goodbye.");
}
else{
System.out.println("What type of ticket are you purchasing?");
System.out.println("1.Walk Up");
System.out.println("2.Advance");
System.out.println("3.Student Advance");
int t = db.nextInt();
if(t==1){
}
if(t==2){
}
if(t==3){
}
}
System.out.println("Do you need another ticket?");
x= db.nextInt();
}
}
}
Ticket (Super class):
package tester;
import java.util.Scanner;
public class Ticket {
public int ticket;
public double price;
/**
* holds default values for ticket number and price
*/
public Ticket(){
super();
this.ticket=1;
this.price=15.0;
}
/**
* Stores the values for ticket number and the price, based upon ticket type
* #param ticket
* #param price
*/
public Ticket(int ticket, double price){
this.ticket=ticket;
this.price=price;
}
/**
* returns the value of price
* #return price
*/
public double getPrice(){
return price;
}
#Override
public String toString(){
return "Ticket #" + ticket + " Ticket price: $"+ price;
}
}
Walkup Ticket:
package tester;
/**
*
* #author dylan
*/
public class WalkupTicket extends Ticket{
/**
* holds the price of a walkup ticket 50$
*/
public WalkupTicket(){
this.price=50;
ticket++;
}
}
Advance Ticket:
package tester;
import java.util.Scanner;
public class AdvanceTicket extends Ticket {
/**
* stores the values of an advance ticket, depending on how many days before
* the event it is purchased
*/
public AdvanceTicket(){
Scanner db = new Scanner(System.in);
System.out.println("How many days before the event are you purchasing your ticket?");
int days = db.nextInt();
// days before is 10 or less days
if(days >= 10){
price=30;
ticket++;
}
// days before is more than 10
else{
this.price=40;
ticket++;
}
}
}
Student Advance Ticket:
package tester;
import java.util.Scanner;
public class StudentAdvanceTicket extends AdvanceTicket{
/**
* stores the values of an advance ticket, depending on how many days before
* the event it is purchased, with student discount.
*/
public StudentAdvanceTicket(){
Scanner db = new Scanner(System.in);
System.out.println("How many days before the event are you purchasing your ticket?");
int days = db.nextInt();
System.out.println("Are you a student?");
System.out.println("1. Yes");
System.out.println("2. No");
int stud = db.nextInt();
// days before is 10 or less days
if(days >= 10 && stud == 1){
price=15;
ticket++;
}
// days before is more than 10
if(days <= 10 && stud == 1){
this.price=20;
ticket++;
}
}
}
I feel like I'm making a simple mistake, but I am new to OOP so I'm having bit of trouble with this.

Are you supposed to be saving a total for all tickets bought or just the one ticket at a time total?
For walk-up tickets you don't have to do anything. Its a flat $50 total.
For Advance and StudentAdvance you would create a new object of that type and the way you have it the constructor will display the menu for how many days in advance and what not. You can then get the total from that.
As for the structure of your code it is not ideal. The object's constructor should not have all that code in it. They should have a ShowMenu function that will display the menu to the user and read their input. The constructor should be blank for the most part.
You also don't need three different ticket objects. One ticket object should be able to handle all this by itself. The ticket object can show the menu and handle the different prices based on user input. If you need to save a total or the different tickets you can have an array of ticket objects on the main method. You can then loop through that array to display or sum the tickets.
Hope this helps.

Your question is pretty broad, but well, some thoughts on your input:
Names matter. It is good that you made a first step and that you are using a specific package (instead of the default package); but tester says nothing. You could call it dylan.tickets for example: to make clear A) its your thing and B) it is about that ticket system
It seems that you are serious about your work, thus: do not use a static main to drive testcases. Using JUnit and simple testcases is really easy. And beyond that: driving tests "manually" using a main is cumbersome and error prone. Unit tests are almost automatically automated.
More importantly: tests that just print something are almost useless. If your code behaves unexpectedly, you might only notice when you carefully check that printed output. As said: use unit tests, and Junit assert calls to check expected versus actual results of method calls. Because then you will be told when you make changes that break functionality which was previously working.
You absolutely avoid to ask for user input in so many different places. Meaning: the reasonable thing is that a class has a constructor or setter methods; and that all the arguments required to instantiate the new object are given to that object. If at all, your main uses a scanner and asks the user for input. But all your "business logic" objects do not require any "user interaction" at all. You see, you actually want to start the whole project without using a scanner. You want to hardcode things like AdvancedTicket at = new AdvancedTicket(100); - because now you can easily code all kinds of different objects; and start your program again and again. Your current solution requires you to enter all such data manually ... every time you re-start your program! So: no scanner usage in constructors. Never!
Then: good OO is about behavior, not about state. Meaning: you dont use public fields to spread information. If at all, your fields should be protected; but even that is most often not a good idea. You want to isolate your classes from each other ...
The core problem: it seems that nobody told you yet about FCoI. You should favor composition over inheritance. Meaning: you dont just put A extends B everywhere. There is absolutely no reason that your Tester class extends Ticket. The tester is a Tester, not a ticket!
As said: that last point is the most important one. You are careful about making A a subclass of B; very often, it is more appropriate to maybe have A own a B object, but not to make A a B!

Related

Questions about creating UML Class diagram from Java program - default constructor? Are there no attributes in this example?

I have a class where I have to manually create a UML diagram for the program below. In order to understand better, I automatically created a UML diagram in Eclipse with ObjectAid.
I have a few questions I would like to understand:
Of the three sections class, attributes, and methods, why is "PayrollDialog()" included in the methods section? Is it because you should always include the default constructor?
Are JOptionPane.showInputDialog really not considered for the methods section? Why not? I ask because I notice getting the user name, hours worked, and pay rate are not included.
Are there really no attributes to be listed in the UML for this program? I think this is correct because they are not listed under the public class PayrollDialog.
Is the UML diagram listed really accurate for this program? If not, what should it look like? I find it hard to believe the assignment is that simple.
import javax.swing.JOptionPane;
/**
4 * This program demonstrates using dialogs
* with JOptionPane.
*/
public class PayrollDialog
{
public static void main(String[] args)
{
String inputString; // For reading input
String name; // The user's name
int hours; // The number of hours worked
double payRate; // The user's hourly pay rate
double grossPay; // The user's gross pay
// Get the user's name.
name = JOptionPane.showInputDialog("What is " +
"your name? ");
// Get the hours worked.
inputString =
JOptionPane.showInputDialog("How many hours " +
"did you work this week? ");
// Convert the input to an int.
hours = Integer.parseInt(inputString);
// Get the hourly pay rate.
inputString =
JOptionPane.showInputDialog("What is your " +
"hourly pay rate? ");
// Convert the input to a double.
payRate = Double.parseDouble(inputString);
// Calculate the gross pay.
grossPay = hours * payRate;
// Display the results.
JOptionPane.showMessageDialog(null, "Hello " +
name + ". Your gross pay is $" +
grossPay);
// End the program.
System.exit(0);
}
}
Yes you are basically correct.
JOptionPane is not listed in the Class Diagram because it is found in javax.swing.JOptionPane and its not globally declared as property/attribute or method of your PayrollDialog class.
Based on your source code, there are no global properties/attribute declared.
For example
class PayrollDialog{
static JFrame f; // this would appear as property in UML
public static void main(String[] args){..}
}

Java Shooting targets

I have been working on this for almost one week. The question is mainly about shooting the target. So we ask the user to input v0, degree, x0, and y0. We will be setting two targets(500,0)&(1000,0).
I think I did all the methods correctly except for the main methos.
The question I am having now is I have no idea about how to put the "return"s back to the main method.(For example, I got the time and I returned it, but how can I output "The time it took to get to the groud is +time+".
It is my first time working with method questions, I would be happy to see some advice!!
Also I've been told to give the user 4 chances to play this game and give the user to choose whether they are going to start again or exit. I saw many people useing boolean to work this part, but I have no idea about how to use it.
The following is what I got so far:
import java.io.*;
public class AngryBirdGame{
public static void main(String[] args) throws IOException{
int vo,degree = 0,xo = 0,yo = 0;
System.out.println("This game is the Angry Bird Game. You will be trying to hit the target.");
System.out.println("One of the targets of the game is (500,0)");
System.out.println("The other target of the game is (1000,0)");
System.out.println("Please enter the initial velocity");
vo=velocity();
System.out.println("Please enter the angle of elevation(0-90 degrees)");
degree=degree(degree);
System.out.println("Please enter the horizontal starting point(50-500)");
xo=horizontal(xo);
System.out.println("Please enter the vertical starting point");
yo=vertical(yo);
result(0);
}
In order to allow the user to play multiple games, you need a loop in your main() method. Also, as a matter of organization, it would be convenient to define a class that encapsulated all the data the user needs to provide to get a game started. (The class AngryBirdGame probably works just fine for that.) You can then extract all the logic for obtaining the user's input into a separate method that returns an instance of the game data class, or null if the user doesn't want to play any more. Similarly, you should define a method that returns the result of the game so you can report the result to the user each time through the loop.
Finally, my guess is that your input variables should be floating point numbers (or maybe even double) rather than int values. It's hard to do trajectory calculations accurately using integer values only.
Putting all that together, here's an outline of what it might look like:
public class AngryBirdGame {
float vo, degree, xo, yo;
public static void main(String[] args) {
printOneTimeIntro();
Scanner in = new Scanner(System.in);
for (int i = 0, AngryBirdGame game = getGameInfo(in);
i < 4 && game != null;
i++, game = getGameInfo()) {
float time = game.play();
System.out.format("The time it took to get to the ground is %f%n", time);
}
}
/**
* A static method to print a one-time introduction to the program.
*/
private static void printOneTimeIntro() {
System.out.println("This game is the Angry Bird Game. You will be trying to hit the target.");
}
/**
* A static method to check whether the user wants to play and, if so,
* to collect all the game info.
*
* #return a game object, or {#code null} if the user no longer wants to play.
*/
private static AngryBirdGame getGameInfo(Scanner in) {
// first check if the user wants to play
System.out.println("Do you want to play (y/n)? ");
String input = in.next();
if (input.toLowerCase().startsWith("n")) {
return null;
}
// if so, create a game object and get all the input
AngryBirdGame game = new AngryBirdGame();
System.out.println("One of the targets of the game is (500,0)");
System.out.println("The other target of the game is (1000,0)");
System.out.println("Please enter the initial velocity");
game.v0 = in.nextFloat();
// TODO: get rest of input
return game;
}
/**
* An instance method that plays the game once everything is initialized.
*
* #return the time it takes for the trajectory to complete
*/
private float play() {
float time;
// TODO: calculate the game time to reach the ground
return time;
}
}
Note that if you want to return more information than just the trajectory time, you might want to define a second class to contain everything you want returned and use that as the return value from play().

need to figure out how to manipulate the mutator to figure out a class according to professor, I am confusd on how to do that

I know we aren't suppose to post homework problems but I am having issues I have talked with him and after 45 minutes I am more confused then I was before he said that this was suppose to be confusing.
So we are working on making our own classes and one of them was making a class to later be used in a weight converter on other planets (mainly the Moon, Mercury, Venus, Jupiter and Saturn) I have managed to make the class (code below)
/*
* WeightConverter class
* Class Description - A Java class for converting weight on different plants
* Author: J. Wilson
* Date: 2/24/2015
* Filename: WeightConverter.java
*/
// class beginning
class WeightConverter {
//create the variable that stores the conversion rate
private double weightchange;
//the constructor
public WeightConverter(double weight){
weightchange=weight;
}
//accessor
public double smallstep(){
return weightchange;
}
//mutator for the needed variable
public void setweightratio(double number){
weightchange=number;
}
//and the method convert.
public double convert(double planet){
return planet*weightchange;
}
}
//end of class
but he added the stipulation that "In this WeightCalculator class, I expect you to use each method you created at least once.or lose a point for each one your don't use " I asked him how I go about it and after a 45 minute talk i'm more confused then before after he mentioned I can take my mutator and just manipulate that here is what I have currently and it works so far
/*
* WeightConverter on other planets
* Program Description - weightchanger
* Author: J.Wilson
* Date: 2/24/2015
* Filename: WeightCalculator.java
*/
//import statements
import java.util.*; //example
// class beginning
class WeightCalculator {
public static void main(String[] args ) {
//Declare variables area
WeightConverter test;
Scanner scan = new Scanner ( System.in );//reads what is entered into the keyboard by the user
double pounds;
//Program beginning messages to user here
System.out.println("Hello! Welcome to my weight converter program");
System.out.println();//blank space
System.out.println("Please enter your weight (in pounds): ");
pounds=scan.nextDouble();
WeightConverter moon = new WeightConverter(.167);
System.out.println("Your weight on the moon is " + moon.convert(pounds));
//Collect inputs from user or read in data here
//Echo input values back to user here
//Main calculations and code to
//Output results here
//End program message
System.out.println();
System.out.println("Hope you enjoyed using this program!");
}// end main method
}// end class
can anyone explain by what he means by using my mutator more than once? or in laymans terms how to go about doing it?
It sounds like you should be using setWeightRatio() each time you want to get the weight on a new planet.
You first created the moon object and set its weight and then later used that set weight in moon.convert()
Next you should setWeightRatio() to a different amount (for Jupiter or Venus or whatever) and that will set the weightChange variable to the new double you just passed in. Then when you use convert() it will access the new weightChange variable and compute based on that.
I would create a single planet object and then reset its weightChange variable through the mutator as necessary. Then use convert() between setting new weight ratio.
You professor said that you have to use all the methods in your class at least once, correct?
your setweightratio method is useless (this should be obvious, as you havent used it !). it sets the class variable weightchange to its input argument, but the same thing happens in the constructor, so you would not need to call it again.
You have two options:
You've already returned moon weight to the user. When the next planet is in question, keep your WeightConverter instance and call moon.setweightratio(ratio of Venus or whatever). Using moon.convert(pounds) will then use the new ratio.
Alternatively, remove the setweightratio method all together (so you don't get points off for not using it) and create WeightConverter objects for each planet. This is less elegant.

Code Format, Structure, consistency

Hello I am a beginner and currently trying to learn java programming.
The question in the textbook:
Write a program that helps a person decide whether to buy a hybrid car. Your program’s inputs should be:
•The cost of a new car
•The estimated miles driven per year
•The estimated gas price •The efficiency in miles per gallon
•The estimated resale value after 5 years
Compute the total cost of owning the car for five years. (For simplicity, we will not take the cost of financing into account.) Obtain realistic prices for a new and used hybrid and a comparable car from the Web. Run your program twice, using today’s gas price and 15,000 miles per year. Include pseudocode and the program runs with your assignment.
My question: I got the code right, my program runs perfectly. My main concern is how can I present this in a professional manner. How can I structure it professionally, what would I have to do in order to have it published (for example). I am trying to get in the habit of having my codes organized and neatly presented. Any suggestions would help, thanks!
public class car
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("Car Model: ");
String carModel = in.nextLine();
System.out.print("Cost of Car: ");
int costOfCar = in.nextInt();
System.out.print("The estimated miles driven per year: ");
int milesDriven = in.nextInt();
System.out.print("The estimated gas price: ");
int gasPrice = in.nextInt();
System.out.print("Efficiency in miles per gallon: ");
int milesPerGallon = in.nextInt();
System.out.print("Estimated resale value after 5 years: ");
int retailValue = in.nextInt();
double carEfficiency = (double) gasPrice / milesPerGallon;
double milesDrivenCost = (double) milesDriven * carEfficiency * 5; //5 years of driving
double retailValueInFiveYears = retailValue;
double carUseLoss = costOfCar - retailValueInFiveYears;
double totalCost = carUseLoss + milesDrivenCost;
System.out.print(carModel + " will cost you after 5 years: ");
System.out.format(" %,d%n", Math.round(totalCost));
}
}
I hope that's not your real indentation.
Use Java naming conventions. In particular, class car should be 'Car'.
I would have said add a few comments, but variable names are pretty descriptive.
Add JavaDoc comments to the class and to the main method.
Always close resources explicitly.
The user could want to enter several of the inputs with decimals. Use doubles instead of ints. Scanner will accept numbers with no decimals too.
Perhaps you could include the generated JavaDoc HTML output.
Java code:
import java.util.Scanner;
/**
* Computes a car's 5-year cost of ownership.
* Usage:
* java Car
*
* #author Mario Rossi
*/
public class Car {
/**
* Computes a car's 5-year cost of ownership.
*
* #param args Not used.
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Car Model: ");
String carModel = in.nextLine();
System.out.print("Cost of Car: ");
double costOfCar = in.nextDouble();
System.out.print("Estimated miles driven per year: ");
double milesDriven = in.nextDouble();
System.out.print("Estimated gas price in $ per gallon: ");
double gasPrice = in.nextDouble();
System.out.print("Efficiency in miles per gallon: ");
double milesPerGallon = in.nextDouble();
System.out.print("Estimated resale value after 5 years: ");
double retailValueInFiveYears = in.nextDouble();
in.close();
double carEfficiency = gasPrice / milesPerGallon;
double milesDrivenCost = milesDriven * carEfficiency * 5; //5 years of driving
double carUseLoss = costOfCar - retailValueInFiveYears;
double totalCost = carUseLoss + milesDrivenCost;
System.out.print(carModel + " will cost you after 5 years: ");
System.out.format(" %,.2f%n", totalCost );
}
}
First of all you need to use the Object Oriented approach i.e. follow the rules:
Abstraction : Identify the entities as classes and their attributes
and operations. you have created a class Car but not defined its
attributes and operations properly so think around it.
Enacapsulation: Data hiding, make sure you use the proper access
specifiers for your Class attributes and operations
Inheritence: Car is quite an abstract thing, so you better define an
abstract class. And inherit real classes such as Ford Car, Merc Car
from your base Car class.
Polymorphism : When you define your Car and its subclasses, you may
have to override the methods define in your abstract class into your
child classses.
Packaging the software: You can do it in multiple ways:
Package it is an executable jar, so a user can simply double click it and run
Create an exe file, which internally calls your java code.
etc
you may have to write a release note or a small documentation to mention that jre should be installed on the computer, path should be set etc.
hope it helps!
as you said you are beginner and started to learn the java, you should always keep the following things in mind,
As Java is object oriented and your program is like as c program you must use the OOPs concepts like class, object and all.
While writing the program you should use the proper indentation.
While giving names for variables, methods use proper naming conventions and don't forget to give comments so that new users can get for what purpose what things you have given.
As you learn new thing try to implement these in your programs or in project.
Try the packages and try to keep small classes and programs so that you will not get confused in the future as well as other users too.
If you find this answer is useful then don't forget to mark as accepted..

How to write a method to calculate compound interest by the year?

public class Balance {
public static void main(String[] args) {
System.out.printf("%.2f\n", balance(0.0, 0.0, 0.0));
}
/**
* #param principal
* #param rate
* #param years
* #return
*/
public static double balance(double principal, double rate, double years) {
double amount = 0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the initial investment amount: ");
principal = sc.nextDouble();
System.out.print("Enter the interest rate: ");
rate = sc.nextDouble();
System.out.print("Enter the number of years: ");
years = sc.nextDouble();
for (int i = 1; i < years; i++) {
amount = principal * Math.pow(1.0 + rate, years);
amount += principal;
}
return amount - principal;
}
}
My problem is with the printf line that I am using within the main method. Eclipse wants me to change the method balance from void to Object[]. When I do this I must return a value from balance. So I guess my question is, how would I return the proper value? Am I on the right track? Thank you for your time and constructive criticism. :)
EDIT - Thanks for the help everyone, much appreciated :) My math is off. I end up with 1000 more than I should have. hmmm.
So should I just take a 1000 from amount like so:
return amount - 1000;
Or this:
return amount - principal;
EDIT this is what I am going with since it is due tonight. Thanks to all for the assistance. :)
A few points:
balance() cannot be void, because you use its return value in S.out.printf(). Do you want balance to print to the screen, or do you want it to yield a number?
Your loop for (years = 0; years > 10; years++) won't run. Think about why. It might help to convert the for into a while, to visualize why.
You read in years as a double, but then use it as a counter in your loop. What type should it actually be?
Your balance() function takes three parameters, then immediately gets input and obliterates them. Do you want balance() to be provided these numbers, or do you want it to fetch them?
Otherwise, you seem to be on the right track.
The problem is that balance doesn't return anything, (it's a void function). Change it to:
public static double balance(double principal, double rate, double years) {
...
And inside that function, return the balance.
Java is telling you it wants an Object[] because printf is defined like this:
public static void printf(String format, Object ... params) {
// params is an Object[]
}
What this lets you do is pass parameters like this:
printf("some string", first, second, etc);
It lets you pass as many parameters as you want, and the function can handle them as if you passed an array.
It's exactly the same as if it was defined like this:
public static void printf(String format, Object[] params);
And you used it like this:
printf("some string", new Object[] { first, second, etc});
It's just easier to use.
EDIT:
The other option is to not print anything in main, but I would definitely advise returning the result and printing it in main. This follows the principle of making each function do as little as possible. balance should just calculate the balance. Printing it is unrelated.
Please consider a more drastic re-working of your code; as it is, your balance() function is doing all the work of your program (and your printf() line feels like an afterthought). If you break apart your code based on what the code does, I think you can do much better:
create a function that prompts the user and then reads in their input
create a function that calls the previous function three times for principal, rate, and years
create a function that computes and populates a payment schedule. Keep track of year, balance, payment, principal payment, and interest payment. (Or just the variables you're interested in -- but be aware that programs tend to grow new features, and these variables are often the second thing that users (or professors) ask to know when paying down a loan.)
create a function that prints the selected columns from your payment schedule.
create a function that orchestrates the previous functions.
When you re-write your program to use a GUI or webservice in three weeks, you'll definitely thank yourself for having written each function to do one task, and do it well. You'll also find it far easier to test smaller pieces of code that do only one task.
There is the risk of over engineering a too-generic solution -- what I'm really trying to suggest is a functional decomposition of your code into multiple smaller routines that do exactly what their name says. You might never move the program into a GUI or webservice or whatever, but you'll definitely be happier when someone reports that your amortization schedule is wrong, that you can control it via simpler programming, rather than having to re-type inputs all day long.
Yours is wrong, do this:
public static void main(String[] args) {
balance(1000.0, .05, 8.5);
}

Categories