Java: Count the number of times a value is input - java

I'm looking for a way to count the number of times a value is input in Java. To be more specific, I have to manage a Module class which has the properties: semester and code. If it is the first module to be added for semester 1, its code should be 101. The second for that semester would be 102 and similarly, the first module entered for semester 2 would be 201 and so on.
I've tried using a static instance variable count, but I cannot somehow manage to make it change based on the value of semester entered.
Any suggestion is appreciated. Thanks in advance!
--EDIT--
Below is the entire code of my class. I'm sorry if it's too lengthy.
package courseman;
/**
* #overview <code>Module</code> represents the module object of a CourseMan program
* #author
*
*/
public class Module {
private static int count = 1;
private String name;
private int semester;
private int credits;
private String code;
/**
* #effects Initializes a <code>Module</code> object
*
*/
public Module(){
name = "No name";
semester = 1;
credits = 0;
code = "M000";
}
/**
* #param newModule a <code>Module</code> object
* #effects Creates a <code>Module</code> object with <code>newModule</code>
*
*/
public Module (Module newModule){
if (newModule == null){
System.out.println("Fatal error creating module.");
System.exit(0);
}
name = newModule.name;
semester = newModule.semester;
credits = newModule.credits;
code = newModule.code;
}
/**
*
* #param newName a <code>String</code> to be set as a module's name
* #param newSemester an <code>integer</code> to be set as a module's semester
* #param newCredits an <code>integer</code> to be set as a module's credits
* #effects Creates a new <code>Module</code> object with predefined name, semester and credits
*/
public Module(String newName, int newSemester, int newCredits){
if(newName == null || newSemester <= 0 || newCredits <= 0){
System.out.println("Fatal error creating module.");
System.exit(0);
}
name = newName;
semester = newSemester;
credits = newCredits;
int no = semester*100 + count;
code = "M" + no;
count++;
}
/**
*
* #param newName a <code>String</code> to be set as a module's name
* #modifies <code>this.name</code>
* #effects Takes <code>newName</code> to update a module's name
*
*/
public void setName(String newName){
if(newName == null){
System.out.println("Fatal error setting module's name.");
System.exit(0);
}
name = newName;
}
/**
*
* #param newSemester an <code>int</code> to be set as a module's semester
* #modifies <code>this.semester</code>
* #effects Takes <code>newSemester</code> to update a module's semester
*
*/
public void setSemester(int newSemester){
if (newSemester <= 0){
System.out.println("Fatal error setting module's semester.");
System.exit(0);
}
semester = newSemester;
int no = (int) Integer.parseInt(code.substring(1));
if (((no - count - 1)/100) < semester){
no = semester*100 + (count - 1);
code = "M" + no;
}
}
/**
*
* #param newCredits an <code>integer</code> to be set as a module's number of credits
* #modifies <code>this.credits</code>
* #effects Takes <code>newCredits</code> to update a module's number of credits
*
*/
public void setCredits (int newCredits){
if (newCredits <= 0){
System.out.println("Fatal error setting module's credits.");
System.exit(0);
}
credits = newCredits;
}
/**
*
* #effects Returns a module's code
*/
public String getCode(){
return code;
}
/**
* #effects Returns a module's name
*
*/
public String getName(){
return name;
}
/**
* #effects Returns a module's semester
*
*/
public int getSemester(){
return semester;
}
/**
* #effects Returns a module's number of credits
*
*/
public int getCredits(){
return credits;
}
/**
* #effects Returns <code>String</code> representation of a <code>Module</code> object
*/
public String toString(){
return "Module: " + code + " - " + name + " - semester " + semester + " - " + credits + " credits";
}
/**
*
* #param otherModule a <code>Module</code> object to compare
* #effects Returns <code>true</code> if <code>this</code> points to the same
* object as <code>otherModule</code>, otherwise returns <code>false</code>
*/
public boolean equals(Module otherModule){
return (code.equals(otherModule.code));
}
}

You should manage a separate counter for semesters! Try using a static HashMap which maps the semester to the number of courses in that semester. When adding a new Module, you need to increment the appripriate count (or initialize it to 1 if absent).
Here's a skeleton:
class Module {
private static HashMap<Integer, Integer> courseCounts = new HashMap<Integer, Integer>();
public Module(int semester, String name) {
this.semester = semester;
this.name = name;
Integer count = courseCounts.get(semester);
if (count == null)
count = 0;
++count;
this.code = "M" + (semester * 100 + count);
courseCounts.put(semester, count);
}
}

Edit:
I thought the semester was it's own class. If you want to have a separate count for each semester you need to create a list of counts you can do this with a Map that has the Semester as a key and its count as its value.

Related

Why it is program showing the IllegalArgumentException I threw despite having the correct format for FillInQuestion? I put all class files for context

public class FillInQuestion extends Question {
public FillInQuestion(String sentence, DifficultyLevel diff) {
super(parseQ(sentence), parseA(sentence), diff);
}
/**
* Takes a sentence string and replace the answer surrounded by a specific patterb with a blank
*
* #param sentence
* #return finalquestion the question with a blank
* #throws IllegalAArgumentException if format is not met
*/
**private static String parseQ(String sentence){
int startindex = sentence.indexOf("_-");
int endindex = sentence.indexOf("-_");
if (startindex == -1 || endindex == -1 || endindex <= (startindex + 2)) {
throw new IllegalArgumentException("Fill in Question does not contain the correct format");
}
String answer = sentence.substring(startindex+2, endindex);
String finalquestion = sentence.replace("_-" + answer + "-_", "_________");
return finalquestion;**
}
/**
*
* #param sentence
* #return selected answer from a string
*/
private static String parseA(String sentence) {
int startindex = sentence.indexOf("_-");
int endindex = sentence.indexOf("-_");
return sentence.substring(startindex+2, endindex);
}
/**Creates a copy of FillinQuestion
*
* #return a copy of FillinQuestion
*
*/
#Override
public Question copy(){
return new FillInQuestion(this.getQuestion(), this.getDifficulty());
}
}
public class QuizManager {
/**
* Asks users for questions, take in user input and then have a score system
*
* #param questions ArrayList of Questions
* #throws Exception
*/
public static void giveQuiz(ArrayList<Question> questions) throws Exception {
Scanner s = new Scanner(System.in);
int score = 0;
if (questions.isEmpty()) { //Throws exception in the case of empty arraylist
throw new Exception("Questions Not Found Empty Quiz");
}
for (Question q : questions) {
System.out.println(q.displayQuestion());
System.out.print("Your answer: ");
String userAnswer = s.nextLine();
if (q.checkAnswer(userAnswer)) {
score++;
}
}
System.out.println("You scored " + score + " out of " + questions.size() + ".");
}
public static void main(String[] args) {
QuizMaker quizMaker = new QuizMaker("General Pop Quiz"); // New Object
//Questions
quizMaker.add(new Question("When did World War I started?", "1914", Question.DifficultyLevel.EASY));
quizMaker.add(new Question("How many fundamental states of matter are there? (State the number only)", "4", Question.DifficultyLevel.EASY));
quizMaker.add(new Question("Which three numbers have the same answer whether they are added or multiplied together?", "1, 2 and 3", Question.DifficultyLevel.MEDIUM));
quizMaker.add(new Question("How many wonders of the world are there (Numbers Only)", "7", Question.DifficultyLevel.EASY));
quizMaker.add(new Question("What is the capital city of Australia", "Canberra", Question.DifficultyLevel.MEDIUM));
quizMaker.add(new Question("What is the largest capital city in North America?", "Mexico City", Question.DifficultyLevel.HARD));
quizMaker.add(new Question("Who was the first person to create the first gasoline-powered car?", "Karl Benz", Question.DifficultyLevel.HARD));
quizMaker.add(new Question("State a palindrome number between 10 and 20", "11", Question.DifficultyLevel.EASY));
quizMaker.add(new Question("\n\nString str1 = \"InterviewBit\";\n"
+ "String str2 = \"InterviewBit\";\n"
+ " \n"
+ "System.out.println(str1 == str2);\n\nWhat will the code print?", "True", Question.DifficultyLevel.HARD));
quizMaker.add(new Question("I’m tall when I’m young, and I’m short when I’m old. What am I?", "Candle", Question.DifficultyLevel.MEDIUM));
**quizMaker.add(new FillInQuestion("The color _-white-_ is the most common color found on flags.", Question.DifficultyLevel.EASY));**
//quizMaker.add(new NumericQuestion("VALUE OF PI?", 3.14, 0.01, Question.DifficultyLevel.EASY));
ArrayList<Question> allQuestions = quizMaker.createQuiz();
ArrayList<Question> hardQuestions = quizMaker.createQuiz(Question.DifficultyLevel.HARD);
//Exception Handling
try {
System.out.println("Full Quiz for : ");
giveQuiz(allQuestions);
System.out.println("\nHard Quiz: ");
giveQuiz(hardQuestions);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
public class QuizMaker {
private String name;
private ArrayList<Question> pool;
/**
* Constructor with name as an instance
*
* #param name the name of the QuizMaker instance
*/
public QuizMaker(String name) {
this.name = name;
this.pool = new ArrayList<>();
}
/*
* Question is copied into the pool
*
* #param q Question q that will be added to the pool
*/
public void add(Question q) {
this.pool.add(q.copy());
}
/*
* #return the name of the QuizMaker Instance
*/
public String getName() {
return name;
}
/**
* Sets the name of the QuizMaker instance.
*
* #param name the new name of the QuizMaker instance
*/
public void setName(String name) {
this.name = name;
}
/**
* Creates quiz from the question pool
*
* #return an ArrayList of Question objects representing the quiz
*/
public ArrayList<Question> createQuiz() {
ArrayList<Question> quiz = new ArrayList<>();
for (Question q : pool) {
quiz.add(q.copy());
}
return quiz;
}
/**
* Creates a specific difficulty quiz from pool of questions
*
* #param difficulty the difficulty level of the questions
* #return an ArrayList of Question with the specific difficulty
*/
public ArrayList<Question> createQuiz(Question.DifficultyLevel difficulty) {
ArrayList<Question> quiz = new ArrayList<>();
for (Question q : pool) {
if (q.getDifficulty() == difficulty) {
quiz.add(q.copy());
}
}
return quiz;
}
}
public class Question {
/*
* Enum class representing the difficulty of the question
*/
public enum DifficultyLevel {
EASY, MEDIUM , HARD;
}
//Instance values
private String question;
private String answer;
private DifficultyLevel difficulty;
/**
* Constructs a question with the given question text, answer, and difficulty level.
*
* #param question the question string
* #param answer the answer string
* #param difficulty the difficulty level of the question
*/
public Question(String question, String answer, DifficultyLevel difficulty) {
this.question = question;
this.answer = answer;
this.difficulty = difficulty;
}
/**
* Constructs a new question with the given question and answer, and default difficulty level of `EASY`.
*
* #param question the question string
* #param answer the answer string
*/
public Question(String question, String answer) {
this.question = question;
this.answer = answer;
this.difficulty = DifficultyLevel.EASY;
}
/**
*
*
* #return question string
*/
public String getQuestion() {
return question;
}
/**
* Set Given Question
* #param question
*/
public void setQuestion(String question) {
this.question = question;
}
/**
*
* #return answer string
*/
public String getAnswer() {
return answer;
}
/**Set the answer
*
* #param answer from given answer
*/
public void setAnswer(String answer) {
this.answer = answer;
}
/**
*
* #return difficulty ENUM difficulty level
*/
public DifficultyLevel getDifficulty() {
return difficulty;
}
/**
* Set difficulty level
* #param difficulty
*/
public void setDifficulty(DifficultyLevel difficulty) {
this.difficulty = difficulty;
}
/**
*
* #param userInput the user's answer
* #return a boolean whether the answer is true or not
*/
public boolean checkAnswer(String userInput) {
if(userInput.equalsIgnoreCase(getAnswer())) {
return true;
}else
return false;
}
/**Displays the question and the difficulty level of the question
*
* #return whole question and its difficulty
*/
public String displayQuestion() {
return "Question: " + this.getQuestion() + "\nDifficulty: " + this.getDifficulty();
}
/**
* #return the string summary
*/
public String toString() {
return "Question: " + question + ", Answer: " + answer + ", Difficulty Level: " + difficulty;
}
/**Creates a new question with the same question, answer and difficulty
*
* #return a copy of the question
*/
public Question copy() {
return new Question(this.getQuestion(), this.getAnswer(), this.getDifficulty());
}
}
I expected to the code I bolded to run smoothly without throwing the exception I implemented. It shouldn't happen since the format is correct. I don't know what I did wrong but basically o parseQ(“The sky is _-blue-_”) should return “The sky is _________” but I tried with the method but it only throws the exception. Also I am not allowed to use regex patterns.

Can't call a method, trying to get a variable from one method to another

I am stuck trying to call a method. No matter what I do, I get an error that it can't find the symbol. I am trying to use the variables total (from the surfaceArea method) and volume (from the volume method).
The problems are in the toString method, where it cannot see the variables no matter what I do. I am sure it is something incredibly basic I a missing, so I hope someone can figure it out.
Here is the Error Log:
Ellipsoid.java:176: error: cannot find symbol
String vout = df.format(volume);
^
symbol: variable volume
location: class Ellipsoid
Ellipsoid.java:177: error: cannot find symbol
String sout = df.format(total);
^
symbol: variable total
location: class Ellipsoid
2 errors
And here is the code itself. I tried to make it as easy to read as possible:
/**
* This program lets the user enter values of and Ellipsoid.
* #version 02/05/2020
*/
public class Ellipsoid {
// fields
private String label;
private double a, b, c;
//public double total, volume;
// constructor
/**
* This constructor creates a ellipsoid and gets its information.
*
* #param labelIn is the label entered by the user.
* #param aIn is the a valuve entered by the user.
* #param bIn is the b valuve entered by the user.
* #param cIn is the c valuve entered by the user.
*/
public Ellipsoid(String labelIn, double aIn, double bIn, double cIn) {
setLabel(labelIn);
setA(aIn);
setB(bIn);
setC(cIn);
}
// methods
/**
* This method gets the label string.
* #return returns the label of the ellipsoid.
*/
public String getLabel() {
return label;
}
/**
* This method sets the label of the ellipsoid.
* #param labelIn is the label entered by the user.
* #return returns true or false depending on user input.
*/
public boolean setLabel(String labelIn) {
if (labelIn == null) {
return false;
}
else {
label = labelIn.trim();
return true;
}
}
/**
* This method gets the a values of the ellipsoid.
* #return returns a values of the ellipsoid.
*/
public double getA() {
return a;
}
/**
* This method sets the a value of the ellipsoid.
* #param aIn is the a value entered by the user.
* #return returns true or false depending on the user input.
*/
public boolean setA(double aIn)
{
if (aIn > 0)
{
a = aIn;
return true;
}
else
{
return false;
}
}
/**
* This method gets the b value of the ellipsoid.
* #return returns the b value of the ellipsoid.
*/
public double getB()
{
return b;
}
/**
* This method sets the b value of the ellipsoid.
* #param bIn is the b value entered by the user.
* #return returns true or false depending on the user input.
*/
public boolean setB(double bIn)
{
if (bIn > 0)
{
b = bIn;
return true;
}
else
{
return false;
}
}
/**
* This method gets the c value of the ellipsoid.
* #return returns the c value of the ellipsoid.
*/
public double getC()
{
return c;
}
/**
* This method sets the c value of the ellipsoid.
* #param cIn is the c value entered by the user.
* #return returns true or false depending on the user input.
*/
public boolean setC(double cIn)
{
if (cIn > 0)
{
c = cIn;
return true;
}
else
{
return false;
}
}
/**
* This method finds the volume of the ellipsoid.
* #return returns the volume of the ellipsoid.
*/
public double volume()
{
double volume = 4 * Math.PI * a * b * c;
volume = volume / 3;
return volume;
}
/**
* This method finds the surface area of the ellipsoid.
* #return returns the surface area.
*/
public double surfaceArea() {
double ab = (a * b);
ab = Math.pow(ab, 1.6);
double ac = a * c;
ac = Math.pow(ac, 1.6);
double bc = b * c;
bc = Math.pow(bc, 1.6);
double top = ab + ac + bc;
double bottom = top / 3;
double full = bottom * 1 / 1.6;
double total = 4 * Math.PI * full;
return total;
}
/**
* This method prints the information of the ellipsoid.
* #return returns the information of the ellipsoid.
*/
public String toString() {
DecimalFormat df = new DecimalFormat("#,##0.0###");
surfaceArea();
volume();
String aout = df.format(a);
String bout = df.format(b);
String cout = df.format(c);
String vout = df.format(volume);
String sout = df.format(total);
String output = "Ellipsoid \"" + label + "\" with axes a = " + aout
+ ", b = " + bout + ", c = " + cout + " units has:\n\tvolume = "
+ vout + " cubic units\n\tsurface area = "
+ sout + " square units";
return output;
}
}
volume and total are local members to volume() and surfaceArea() methods respectively. It is not visible in toString() method. But a, b and c are visible as they are declared class level. Try assigning returned values from those methods to local variables in toString() as below:
public String toString() {
DecimalFormat df = new DecimalFormat("#,##0.0###");
double total = surfaceArea();
double volume = volume();
....
String vout = df.format(volume);
String sout = df.format(total);
....
}
In the Ellipsoid class, you didn't declare the total and volume variables.
They are commented there, try to uncomment this line:
//public double total, volume;
Should help, but if you want to assign the values to those instance fields while calculating, change the double total and double total in the proper methods to this.total and this.volume.
This will allow you to both keep the data inside object and return it through method.

How to search for a string inside an ArrayList of a class

/**
* #param title title of the movie to search for
* #return the movie with the given title
* or null if there is no movie in the library with that title
*/
public Movie findMovieByTitle(String title)
{
for (Movie movie : movies){
if(movies.contains(title)){
return title;
}
else{
return null;
}
}
}
How can I find the title in the ArrayList? There are similar topics to this but they deal with a String ArrayList, I'm searching for a title in another class. Do I need to make a local variable and call a method from the Movie class?
This is the Movie class:
public class Movie
{
private String title;
private int runLength; // length of the movie in minutes
private int starRating; // rating from 1 to 4 stars (0 = not rated yet)
/**
* Create a movie with the title, run length, and number of stars given
* #param aTitle title of the movie
* #param aRunLength run length of the movie in minutes
* #param aStarRating star rating of the movie, a value from 1 to 4 inclusive
*/
public Movie(String aTitle, int aRunLength, int aStarRating)
{
title = aTitle;
runLength = aRunLength;
setStarRating(aStarRating);
}
/**
* Create a movie with the title and run length given
* #param aTitle title of the movie
* #param aRunLength run length of the movie in minutes
*/
public Movie(String aTitle, int aRunLength)
{
title = aTitle;
runLength = aRunLength;
starRating = 0;
}
/**
* #return title of the movie
*/
public String getTitle()
{
return title;
}
/**
* #return run length of the movie in minutes
*/
public int getRunLength()
{
return runLength;
}
/**
* #return rating in stars of the movie; a value of 0 means "not rated"
*/
public int getStarRating()
{
return starRating;
}
/**
* Set the star rating of this movie to the value given
* #param newRating new star rating of the movie
*/
public void setStarRating(int newRating)
{
if (newRating >= 1 && newRating <= 4) {
starRating = newRating;
}
else {
System.out.println("Error: Valid range for star rating is 1 to 4");
}
}
/**
* Reset the star rating of this movie to "not rated"
*/
public void resetStarRating()
{
starRating = 0;
}
/**
* Increase the star rating of this movie by 1
*/
public void increaseStarRating()
{
if (starRating < 4) {
starRating = starRating + 1;
}
}
/**
* Decrease the star rating of this movie by 1
*/
public void decreaseStarRating()
{
if (starRating > 1) {
starRating = starRating - 1;
}
}
/**
* Print information on this movie
*/
public void printMovieInfo()
{
System.out.println("---------------------------------");
System.out.println(title);
System.out.println("Run length: " + runLength);
if (starRating == 0) {
System.out.println("Rating: (no rating)");
}
else {
System.out.println("Rating: " + starRating + " stars");
}
System.out.println("---------------------------------");
}
}
public Movie findMovieByTitle(String title) {
return movies.stream() // open a stream on the movies collection
.filter(movie -> movie.getTitle().equals(title)) // filter them based on their title
.findFirst() // get the first matching item
.get(); // this might throw NoSuchElementException if no element found
}
Try this. It should work
public Movie findMovieByTitle(String title)
{
for (Movie movie : movies){
if(movie.getTitle().equals(title)){
return movie;
}
}
return null;
}

Issues with toString and Inheritance [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have I am having trouble figuring out an issue I have with a toString method. toString () must be changed so that it prints all the relevant information about the Player (and collection of
Items). Subclasses should overwrite the superclass toString (), but still use the toString ()
from the super class implementation when this reduces code duplication.
How do I go about doing this?
Player class:
import java.util.HashMap;
public class Player extends Character {
private String name;
private String type;
public static HashMap<String, Item> backpack;
private int maxCarryingCapacity;
/**Constructor
* Creates a player with health 100, an empty backpack
* and max carrying capacity 100
*
* #param nick the players name
* #param type the players type
* #param minDamage players minimum damage
* #param maxDamage players maximum damage
*/
public Player(String name, String type, int minDamage, int maxDamage) {
super(name, minDamage, maxDamage);
setName(name);
setType(type);
health = 100;
gold = 100;
backpack = new HashMap<String, Item>();
maxCarryingCapacity = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
/**
* Use an item in backpack
* #param itemName
* #return true if item is used, and false
* if there's no item by that name in the backpack
*/
public boolean useItem(String itemName) {
Item item = findItem(itemName);
if(item != null) {
System.out.println(name + " " + item.getAction() + " " + item.getName());
return true;
} else {
return false;
}
}
public boolean equipItem(String itemToEquip) {
Item item = findItem(itemToEquip);
if (item != null) {
this.minDamage = this.minDamage + item.getBonus();
return true;
} else {
return false;
}
}
/**
* Adds item to players inventory. An
* item can only be bought if the total weight does not
* exceed the players carrying capacity
* #param item
* #return true if the item is bought
*/
public boolean addItem(Item item) {
int totalWeight = totalWeight() + item.getWeight();
if(totalWeight <= maxCarryingCapacity){
backpack.put(item.getName(), item);
return true;
} else {
return false;
}
}
/**
* Find item in backpack
*
* #param name of item
* #return item, or null if item is not int the backpack
*/
public Item findItem(String itemName) {
return backpack.get(itemName);
}
/**
* Removes item from player's backpack and
* add item value to player's gold
*
* #param name of item to sell
* #return true if successful
*/
public boolean sellItem(String itemToSell) {
Item item = findItem(itemToSell);
if(item != null) {
gold += item.getValue();
backpack.remove(item.getName());
return true;
} else {
return false;
}
}
/**
* #return true if the player is alive
*/
public boolean isAlive() {
if(health > 0 && health <= 100) {
return true;
} else return false;
}
/**
* #return a string with player information
*/
#Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
/**
* #return the players type
*/
public String getType() {
return type;
}
/**Sets the players type
* Valid types: Mage, Ranger, Warrior, Rogue
* #param newType
*/
public void setType(String newType) {
newType = newType.toLowerCase().trim();
if(newType.equals("mage") || newType.equals("ranger") || newType.equals("warrior") || newType.equals("rogue")){
this.type = newType;
} else {
this.type = "Unspecified";
}
}
/**
* #param item
* #return current carrying weight
*/
private int totalWeight() {
int tempWeight = 0;
for(Item itemInBackpack : backpack.values()) {
tempWeight += itemInBackpack.getWeight();
}
return tempWeight;
}
public int attack(Monster currentEnemy) {
int damage = Utils.random(minDamage, maxDamage+1);
currentEnemy.changeHealth(-damage);
return damage;
}
}
The Character superclass (abstract class):
abstract class Character
{
public String name;
public static int health;
public int gold;
public int minDamage;
public int maxDamage;
public Character(String name, int minDamage, int maxDamage) {
setName(name);
health = 100;
gold = 100;
setMinDamage(minDamage);
setMaxDamage(maxDamage);
}
public Character () {
}
/**
* Changes the character health
* The health can not be less the 0 or "less than or euqal to" 100.
* #param healthPoints
*/
public void changeHealth(int healthPoints) {
int temp = health + healthPoints;
if(temp > 100) {
health = 100;
} else if (temp <= 0) {
health = 0;
} else {
health = temp;
}
}
/**
* #return true if the character is alive
*/
public boolean isDead() {
if(health > 0 && health <= 100) {
return false;
} else return true;
}
/**
* #return the characters name
*/
public String getName() {
return name;
}
/**Set to Unspecified if the string is empty
* #param name
*/
public void setName(String name) {
this.name = Utils.checkString(name);
}
/**
* #return the characters health
*/
public static int getHealth() {
return health;
}
/**
* Get minimum damage
* #return minimum damage
*/
public int getMinDamage() {
return minDamage;
}
/**
* Set minimum damage, if minDamage >= 5, minDamage is otherwise set to 5
* #param minimum Damage
*/
public void setMinDamage(int minDamage) {
this.minDamage = minDamage >= 5 ? minDamage : 5;
}
/**
* Get maximum damage
* #return maximum damage
*/
public int getMaxDamage() {
return maxDamage;
}
/**
* Set maximum damage, if maxDamage <= minDamage, maxDamage is set to minDamage +5
* #param maximum damage
*/
public void setMaxDamage(int maxDamage) {
this.maxDamage = maxDamage <= minDamage ? minDamage+5 : maxDamage;
}
/**
* Get money
* #return amount of money
*/
public int getGold() {
return gold;
}
/**
* Set money
* #param amount of money
*/
public void setGold(int gold) {
this.gold = Utils.checkNegativeInt(gold);
}
}
In general, given two classes, A and B and if class B extends A then B has all of the properties of A plus some of its own. Therefore, when you implement B's toString() method, you should do this:
#Override
public String toString() {
String newStuff = // description of the new variables
return super.toString() + newStuff;
// Now describe the elements of B that aren't included in A
}
However, your implementation doesn't give a basic toString() method for Character so calling super.toString() is equivalent to calling Object.toString(). Therefore you should first implement toString for your Character abstract class.
for example, you could do:
public String toString() {
return "Name: " + name + "\nHealth: " ... all the attributes
}
There is a lot of redundancy in your code though. First of all, both your Character class and your Player class have the same name variable, which goes against the point of inheritance. In fact, you never even use Player's name variable.
also, there is no point in creating getter/setter methods in Character if all the variables are declared public anyways. It is better to make them private and use getter/setters though.
Your abstract superclass has name and health, but not type or backpack. (I just noticed, thanks to user2573153's answer, that you also have name in your Player class; I don't think you want that.)
I think the first thing you want to do is to answer this question: Suppose you create a new subclass, and you don't override toString(), and then an object gets printed out. What would you want to see printed out?
Maybe you want the name and health printed out. So you can declare this in your abstract Character class (which I think shouldn't be called Character because java.lang already has a Character):
#Override
public String toString() {
String string = "Name: " + name + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
return string;
}
Then, if you wanted toString() in Player or Monster to add something to the end of that, it would be pretty easy:
#Override
public String toString() {
String string = super.toString(); // here's where you call the superclass version
string += "\n Type: " + type;
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return string;
}
In your actual code, however, you want the Type information inserted in the middle of the string that the superclass toString() would return. That makes things tougher. I can think of two ways to handle it. One would be to use some string manipulation methods to search for \n and insert the "Type" string in there. But I think it's better to split the string into two methods. You can put these in your Character class:
protected String nameString() {
return "Name: " + name;
}
protected String healthString() {
if(isAlive()) {
return "Is alive with health: " + health;
} else {
return "Is dead.";
}
}
Now, your toString() in Character might look like
#Override
public String toString() {
return nameString() + "\n" + healthString();
}
and in Player:
#Override
public String toString() {
return nameString() + " Type: " + type + "\n" + healthString();
}
and you still get to avoid duplicated code. (You don't need to say super.nameString() because your subclass will automatically inherit it and you don't plan to override it.)
Superclass methods aren't automatically called. When you override toString() in Player and you call toString() on an instance of Player the only code that gets run is Player's toString().
If you want to include the toString() of Character in your toString() of Player you need to make that explicit by calling super.toString() in Player's toString().
Your Player implementation of toString() could be amended to include my recommendation as follows:
/**
* #return a string with player information
*/
#Override
public String toString() {
String string = "Name: " + name + " Type: " + type + "\n";
if(isAlive()) {
string += "Is alive with health: " + health;
} else {
string += "Is dead.";
}
string += "\n"+ name + "'s backpack contains the following items: \n";
for(Item item : backpack.values()) {
string += item;
}
return super.toString() + string;
}
The salient part of this is changing:
return string;
To:
return super.toString() + string;

Getting error on JUnit test

So the assignment my professor has given does not allow me to edit anything on the JUnit test because our class that we have written has to match with her Javadoc. So everything is working fine except I am getting an error and 3 failures. No matter what I try I can't seem to fix these. How can I fix an error and make all tests pass without changing the JUnit Test, I just can't spot the error. Basically in general how do you get rid of errors in JUnits and failures while not changing the JUnit.
Here is my company class
/**
* #author Amin Oskoui
* This is the company class aka the data manager which contains the majority of the methods and holds the arraylist.
*/
import javax.swing.*;
import java.util.*;
public class Company {
private static final long serialVersionUID = 1L;//ensuring that the class corresponds with a serialized object
Employee a;
private String companyName;//name of company
final int maxCompanies = 2, maxEmployees = 7, maxSales = 1, maxDesign = 2, maxManufacturing = 4;
private static int numberOfCompanies;//the number of companies
private int numEmployees;//the number of employees
public int numDesign;//the number of employees in design
private int numManufacturing;// the number of employees in manufacturing
private int numSales;//the number of employees in sales
private ArrayList<Employee> employeeList;
/**
*
* #param cn parameter for cn
*/
public Company(String cn){
numEmployees = 0;
numSales = 0;
numDesign = 0;
numManufacturing = 0;
companyName = cn;
numberOfCompanies++;
employeeList = new ArrayList<Employee>();
}
/**
*
* #param employeeCount parameter for employeeCount
* #param numDesign parameter for numDesign
* #param numSales parameter for numSales
* #param numManufacturing parameter for numManufacturing
* #param companyName parameter for companyName
*/
public Company(int employeeCount, int numDesign, int numSales, int numManufacturing, int numOfCompanies) {
this.numEmployees = employeeCount;
this.numDesign = numDesign;
this.numSales = numSales;
this.numManufacturing = numManufacturing;
this.companyName = companyName;
numberOfCompanies++;
employeeList = new ArrayList<Employee>();
}
/**
*
* #param fName parameter for fName
* #param lName parameter for lName
* #param parameter for p
* #return
*/
public String addEmployee(String fName, String lName, String p) {
/**
* #return returns a string with an error message
*/
if (numEmployees >= maxEmployees) {
return "There is already 7 employees\nEmployee not added";
}
switch (p) {//switch statement for each case
case "Sales":
//if there's less than 1 salesman, add them to the list
if (numSales < maxSales) {
Employee employee = new Employee(fName, lName, p);
employeeList.add(employee);
numSales++;
numEmployees++;
return "Salesperson added successfully!";
}
else {
/**
* #return returns a string with an error message
*/
return "There is already a sales person\nEmployee not added";
}
case "Design":
if (numDesign < maxDesign) {
Employee employee = new Employee(fName, lName, p);
employeeList.add(employee);
numDesign++;
numEmployees++;
return "Designer added successfully!";
}
else {
/**
* #return returns a string with an error message
*/
return "There are already two design persons\nEmployee not added";
}
case "Manufacturing":
if (numManufacturing < maxManufacturing){
Employee employee = new Employee(fName, lName, p);
employeeList.add(employee);
numManufacturing++;
numEmployees++;
return "Manufacturer added successfully!";
}
else {
/**
* #return returns a string with an error message
*/
return "There are already four manufacturing persons\nEmployee not added";
}
}
/**
* #return return statement just to make sure the program operates properly.
*/
return "This should never appear";
}
public static int getNumCompanies(){//return the number of companies
return numberOfCompanies;
}
public int getNumEmployees(){//get the number of employees
return numEmployees;
}
public String printCompany(){//print the company with all of the positions
String companyPrint = companyName + "\n";
return companyName;
}
public String employeeListString() {
String s;
s = companyName + "\n";
for (Employee e : employeeList) {
s += e + "\n";
}
return s;
}
/**
* #param s passes the String s
*/
public void setCompanyName(String s) {
companyName = s;
}
public void clearEmployees() {
numEmployees = numDesign = numManufacturing = numSales = 0;
employeeList.clear();
}
#Override
public String toString() {//converts everything to a string
return "Company [position=" + ", companyName=" + companyName
+ ", employees=" + employeeList + ", numEmployees=" + numEmployees
+ ", numDesign=" + numDesign + ", numManufacturing="
+ numManufacturing + ", numSales=" + numSales + "]";
}
}
And here is the JUnit test for it.
import static org.junit.Assert.*;
import java.util.Scanner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* This is a JUnit test program to test the Company.
* The following classes must be defined and implemented:
* Position - enumeration
* Employee - data element
* Company - data manager
* #author Professor Myers changed by Prof. Justh
*
*/
public class CompanyTester {
/** A Company object reference used for testing */
Company company, studentCompany;
#Before
/** This method is run before each individual test
* Creates an object of Company and adds three
* Employees to the Company
*/
public void setUp() throws Exception {
company = new Company("New Source");
company.addEmployee("John", "Smith","Manufacturing");
company.addEmployee("Bob", "Brown", "Manufacturing");
company.addEmployee("Harold", "Jones", "Sales");
company.addEmployee("Betty","Boop", "Design");
//STUDENT: Create your own instance of company (studentCompany) and add employees.
//You will use this studentCompany instance in the STUDENT test methods
}
#After
/** This method is run after each individual test
* It sets the Company reference to null so the garbage
* collector can reclaim the memory used for the
* Company object
* #throws Exception
*/
public void tearDown() throws Exception {
company = null;
}
#Test
/**
* Test to
* 1. check if the number of employees is originally 4
* 2. Add another employee, and check if number of employees is 5
*
*/
public void testGetNumEmployees() {
assertEquals(4,company.getNumEmployees());
company.addEmployee("George", "Jones", "Design");
assertEquals(5, company.getNumEmployees());
company.addEmployee("Susie", "Smith", "Manufacturing");
assertEquals(6, company.getNumEmployees());
company.addEmployee("Susie", "Smiley", "Manufacturing");
assertEquals(7, company.getNumEmployees());
}
#Test
/**
* Use the studentCompany instance
* Test to
* 1. check the original number of employees
* 2. Add another employee, and check if number of employees has increased by 1
*
*/
public void testGetNumEmployeesSTUDENT() {
assertEquals(4,company.getNumEmployees());
company.addEmployee("John", "Mayhew", "Design");
assertEquals(5, company.getNumEmployees());
company.addEmployee("Sally", "Sams", "Manufacturing");
assertEquals(6, company.getNumEmployees());
company.addEmployee("Max", "Schmidt", "Manufacturing");
assertEquals(7, company.getNumEmployees()); }
#Test
/**
* Test to
* 1. add 3 new Employees as a manufacturing person
* check if recognizes there are already 4 manufacturing persons
* 2. add a new employee as a sales person
* check if recognizes there is already a a sales person
* 3. add 2 new employee as a design person
* check if recognizes there is already 2 design persons
*/
public void testAddEmployee() {
String result;
//add another designer - No problem, should return null
result = company.addEmployee("Bobby", "Match", "Design");
assertEquals(null, result);
//add another designer - already 2 designers - return error message
result = company.addEmployee("Albert","Pine", "Design");
assertEquals("There are already two design persons\nEmployee not added", result);
//add another sales person - already 1 sales person - return error message
result = company.addEmployee("Susie", "Smith", "Sales");
assertEquals("There is already a sales person\nEmployee not added", result);
//add another manufacturer - No problem, should return null
result = company.addEmployee("Benedict", "Cumberbatch", "Manufacturing");
assertEquals(null, result);
//add another manufacturer - No problem, should return null
result = company.addEmployee("Martin", "Freeman", "Manufacturing");
assertEquals(null, result);
//add another manufacturer - already 4 manufacturers - return error message
result = company.addEmployee("Andrew", "Scott", "Manufacturing");
assertEquals("There are already four manufacturing persons\nEmployee not added", result);
}
#Test
/**
* Test to
* 1. add a new Employees as a manufacturing person
* check if recognizes there are already 4 manufacturing persons
* 2. add a new employees as a sales person
* check if recognizes there is already a a sales person
* 3. add new employees as a design person
* check if recognizes there are already 2 design persons
*/
public void testAddEmployeeSTUDENT() {
fail("Test not yet implemented");
}
#Test
/**
* Test to:
* 1. Check if the company name is on the first line
* 2. Check if John is on the second line
* 3. Check if Bob is on the third line
* 4. Check if Harold is on the fourth line
* 5. Check if Betty is on the fifth line
*/
public void testPrintCompany() {
String result = company.printCompany();
Scanner company = new Scanner(result);
assertEquals("New Source",company.nextLine());
//extract three Employees
assertEquals("John", company.next());
company.nextLine(); //Smith Position design (rest of line)
assertEquals("Bob", company.next());
company.nextLine(); //Brown Position manufacturing (rest of line)
assertEquals("Harold",company.next()); //Harold
company.nextLine(); //Jones Position Sales (rest of line);
assertEquals("Betty",company.next());
}
#Test
/**
* Test to:
* 1. Check if the company name is on the first line
* 2. Check if other employees are in order as entered
*/
public void testPrintCompanySTUDENT() {
fail("Test not yet implemented");
}
#Test
public void testMoreThan1company()
{
//created company and studentCompany instances
assertEquals(2, Company.getNumCompanies());
//create another company instance
Company company2 = new Company("New Company");
assertEquals(3, Company.getNumCompanies());
}
}
Here is the employee class
/**
* #author This is the employee class which is also the data element in charge of holding the information for the employee entered by the user.
*/
import javax.swing.JOptionPane;
public class Employee {
private String fName;
private String lName;
private String p;
public Employee(String fName, String lName, String p) {
this.fName = fName;
this.lName = lName;
this.p = p;
}
public String getFName(){
return fName;
}
public String getLName(){
return lName;
}
public String getP(){
return p;
}
public String toString(){
return fName + " " + lName + " " + "Position: " + p;
}
}
Look through the tests. Look at what they expect your program to produce. Then look at what your program is producing. For example, this is from one of the tests:
String result;
//add another designer - No problem, should return null
result = company.addEmployee("Bobby", "Match", "Design");
assertEquals(null, result);
That means the test expects addEmployee() to return null when it is successful. Is that what your addEmployee() method does?
Now do that for all the tests and you'll have found all your errors.
Also, look at the output from jUnit. When an assert fails it gives you a pretty good idea why. It will say something like, expected xxxxx to be yyyyy but it was zzzzz instead.

Categories