I am basically being asked to take the Unicode value of a string, multiply it by 10% and add whatever level the object currently has. It's frustrating because as it turns out I have the logic down including the code yet I still get an error that says: expected:<0> but was:<8>. Any suggestions, maybe it's just a slight nuance I have to make in the logic, although I'm fairly certain it's right. Take note of the getLevel method because that's where the error is
public class PouchCreature implements Battleable {
private String name;
private int strength;
private int levelUps;
private int victoriesSinceLevelUp;
/**
* Standard constructor. levelUps and victoriesSinceLevelUp start at 0.
*
* #param nameIn desired name for this PouchCreature
* #param strengthIn starting strength for this PouchCreature
*/
public PouchCreature(String nameIn, int strengthIn) {
this.name = nameIn;
this.strength = strengthIn;
this.levelUps = 0;
this.victoriesSinceLevelUp = 0;
}
/**
* Copy constructor.
*
* #param other reference to the existing object which is the basis of the new one
*/
public PouchCreature(PouchCreature other) {
this.name=other.name;
this.strength=other.strength;
this.levelUps=other.levelUps;
this.victoriesSinceLevelUp=other.victoriesSinceLevelUp;
}
/**
* Getter for skill level of the PouchCreature, which is based on the
* first character of its name and the number of levelUps it has.
* Specifically, the UNICODE value of the first character in its name
* taken %10 plus the levelUps.
*
* #return skill level of the PouchCreature
*/
public int getLevel() {
int value = (int)((int)(getName().charAt(0)) * 0.1);
return value + this.levelUps;
}
You've said you're supposed to increase the value by 10%. What you're actually doing, though, is reducing it 90% by taking just 10% of it (and then truncating that to an int). 67.0 * 0.1 = 6.7, which when truncated to an int is 6.
Change the 0.1 to 1.1 to increase it by 10%:
int value = (int)((int)(getName().charAt(0)) * 1.1);
// --------------------------------------------^
There, if getName() returns "Centaur" (for instance), the C has the Unicode value 67, and value ends up being 73.
We need to see the code you're calling the class with and that is generating your error message. Why is it expecting 0? 8 seems like a valid return value from the information you've given.
Related
I am using JavaBDD to do some computation with BDDs.
I have a very large BDD with many variables and I want to calculate how many ways it can be satisfied with a small subset of those variables.
My current attempt looks like this:
// var 1,2,3 are BDDVarSets with 1 variable.
BDDVarSet union = var1;
union = union.union(var2);
union = union.union(var3);
BDD varSet restOfVars = allVars.minus(union);
BDD result = largeBdd.exist(restOfVars);
double sats = result.satCount(); // Returns a very large number (way too large).
double partSats = result.satCount(union) // Returns an inccorrect number. It is documented that this should not work.
Is the usage of exist() incorrect?
After a bit of playing around I understood what my problem was.
double partSats = result.satCount(union);
Does return the correct answer. What it does is calculate how many possible solutions there are, and divides the solution by 2^(#vars in set).
The reason I thought satCount(union) does not work is due to an incorrect usage of exist() somewhere else in the code.
Here is the implementation of satCound(varSet) for reference:
/**
* <p>Calculates the number of satisfying variable assignments to the variables
* in the given varset. ASSUMES THAT THE BDD DOES NOT HAVE ANY ASSIGNMENTS TO
* VARIABLES THAT ARE NOT IN VARSET. You will need to quantify out the other
* variables first.</p>
*
* <p>Compare to bdd_satcountset.</p>
*
* #return the number of satisfying variable assignments
*/
public double satCount(BDDVarSet varset) {
BDDFactory factory = getFactory();
if (varset.isEmpty() || isZero()) /* empty set */
return 0.;
double unused = factory.varNum();
unused -= varset.size();
unused = satCount() / Math.pow(2.0, unused);
return unused >= 1.0 ? unused : 1.0;
}
Though I am sure that this answer is simple, I am not sure that is asked of me for this assignment. Here is the full code that I have written (so just a return!) as well as the instructions that were given:
package code;
/**
* This class contains a variety of methods that will be used throughout the Ratings and Reviews
* project.
*/
public class Utilities{
/**
* Computes the average of two ratings
*
* #param rating0 An integer rating in the range of 1-5 inclusive
* #param rating1 An integer rating in the range of 1-5 inclusive
* #return the average of rating0 and rating1 as a double
*/
public double averageRating(int rating0, int rating1){
return ((rating0 + rating1) / 2); // Don't forget to replace this return statement with your own
}
Sorry for bad structure upon pasting it. I think my return is suitable for what is being done, provided that the rating could be just anything. I know that it can only be between 1-5, though, so how would one go about specifying that?
How about throwing an InvalidArgumentException if the range is violated?
e.g.
public double averageRating(int rating0, int rating1){
if (rating0 < 1 || rating0 > 5 || rating1 < 1 || rating1 > 5) {
throw new InvalidArgumentException("Rating out of range");
}
return ((rating0 + rating1) / 2.0); // Don't forget to replace this return statement with your own
}
This query can be answered only after going through the history of previous query where the Part I of the solution is discussed.
Following is the solution, I wrote for Part IIa and PartIIb, I need clarification before writing PartIIc i.e., toOcean() method.
/* RunLengthEncoding.java */
package Project1;
/**
* The RunLengthEncoding class defines an object that run-length encodes an
* Ocean object. Descriptions of the methods you must implement appear below.
* They include constructors of the form
*
* public RunLengthEncoding(int i, int j, int starveTime);
* public RunLengthEncoding(int i, int j, int starveTime,
* int[] runTypes, int[] runLengths) {
* public RunLengthEncoding(Ocean ocean) {
*
* that create a run-length encoding of an Ocean having width i and height j,
* in which sharks starve after starveTime timesteps.
*
* The first constructor creates a run-length encoding of an Ocean in which
* every cell is empty. The second constructor creates a run-length encoding
* for which the runs are provided as parameters. The third constructor
* converts an Ocean object into a run-length encoding of that object.
*
* See the README file accompanying this project for additional details.
*/
class RunLengthEncoding {
/**
* Define any variables associated with a RunLengthEncoding object here.
* These variables MUST be private.
*/
private DList2 list;
private int sizeOfRun;
private int width;
private int height;
private int starveTime;
/**
* The following methods are required for Part II.
*/
/**
* RunLengthEncoding() (with three parameters) is a constructor that creates
* a run-length encoding of an empty ocean having width i and height j,
* in which sharks starve after starveTime timesteps.
* #param i is the width of the ocean.
* #param j is the height of the ocean.
* #param starveTime is the number of timesteps sharks survive without food.
*/
public RunLengthEncoding(int i, int j, int starveTime) {
this.list = new DList2();
this.list.insertFront(TypeAndSize.Species.EMPTY, i*j);
this.sizeOfRun = 1;
this.width = i;
this.height = j;
this.starveTime = starveTime;
}
/**
* RunLengthEncoding() (with five parameters) is a constructor that creates
* a run-length encoding of an ocean having width i and height j, in which
* sharks starve after starveTime timesteps. The runs of the run-length
* encoding are taken from two input arrays. Run i has length runLengths[i]
* and species runTypes[i].
* #param i is the width of the ocean.
* #param j is the height of the ocean.
* #param starveTime is the number of timesteps sharks survive without food.
* #param runTypes is an array that represents the species represented by
* each run. Each element of runTypes is Ocean.EMPTY, Ocean.FISH,
* or Ocean.SHARK. Any run of sharks is treated as a run of newborn
* sharks (which are equivalent to sharks that have just eaten).
* #param runLengths is an array that represents the length of each run.
* The sum of all elements of the runLengths array should be i * j.
*/
public RunLengthEncoding(int i, int j, int starveTime,
TypeAndSize.Species[] runTypes, int[] runLengths) {
this.list = new DList2();
this.sizeOfRun = 0;
this.width = i;
this.height = j;
this.starveTime = starveTime;
if(runTypes.length != runLengths.length){
System.out.println("lengths are unequal");
}else{
for(int index=0; index < runTypes.length; index++){
this.list.insertFront(runTypes[index], runLengths[index]);
this.sizeOfRun++;
}
}
}
/**
* restartRuns() and nextRun() are two methods that work together to return
* all the runs in the run-length encoding, one by one. Each time
* nextRun() is invoked, it returns a different run (represented as a
* TypeAndSize object), until every run has been returned. The first time
* nextRun() is invoked, it returns the first run in the encoding, which
* contains cell (0, 0). After every run has been returned, nextRun()
* returns null, which lets the calling program know that there are no more
* runs in the encoding.
*
* The restartRuns() method resets the enumeration, so that nextRun() will
* once again enumerate all the runs as if nextRun() were being invoked for
* the first time.
*
* (Note: Don't worry about what might happen if nextRun() is interleaved
* with addFish() or addShark(); it won't happen.)
*/
/**
* restartRuns() resets the enumeration as described above, so that
* nextRun() will enumerate all the runs from the beginning.
*/
public void restartRuns() {
this.sizeOfRun = 0;
}
/**
* nextRun() returns the next run in the enumeration, as described above.
* If the runs have been exhausted, it returns null. The return value is
* a TypeAndSize object, which is nothing more than a way to return two
* integers at once.
* #return the next run in the enumeration, represented by a TypeAndSize
* object.
*/
public TypeAndSize nextRun() {
TypeAndSize obj = null;
if(this.sizeOfRun > 0){
obj = this.list.nTh(this.sizeOfRun);
this.sizeOfRun--;
}
return obj;
}
}
==========
/* DList2.java */
package Project1;
/**
* A DList2 is a mutable doubly-linked list. Its implementation is
* circularly-linked and employs a sentinel (dummy) node at the sentinel
* of the list.
*/
class DList2 {
/**
* sentinel references the sentinel node.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
protected DListNode2 sentinel;
protected long size;
/* DList2 invariants:
* 1) sentinel != null.
* 2) For any DListNode2 x in a DList2, x.next != null.
* 3) For any DListNode2 x in a DList2, x.prev != null.
* 4) For any DListNode2 x in a DList2, if x.next == y, then y.prev == x.
* 5) For any DListNode2 x in a DList2, if x.prev == y, then y.next == x.
* 6) size is the number of DListNode2s, NOT COUNTING the sentinel
* (denoted by "sentinel"), that can be accessed from the sentinel by
* a sequence of "next" references.
*/
/**
* DList2() constructor for an empty DList2.
*/
public DList2() {
this.sentinel = new DListNode2();
this.sentinel.next = this.sentinel;
this.sentinel.prev = this.sentinel;
this.size = 0;
}
/**
* insertFront() inserts an object of type TypeAndSizeAndHungerAndStarveTime at the front of a DList2.
*/
void insertFront(TypeAndSize.Species runType, int runLength) {
DListNode2 newNode = new DListNode2(runType, runLength);
newNode.next = this.sentinel.next;
this.sentinel.next.prev = newNode;
this.sentinel.next = newNode;
this.sentinel.next.prev = this.sentinel;
this.size++;
}
/**
* nTh() returns the nTh node
* #param nTh
* #return
*/
TypeAndSize nTh(int nTh){
DListNode2 node = this.sentinel.prev;
int index = 1;
while(index < nTh ){
node = node.prev;
}
return node.runObject;
}
}
============================
/* DListNode2.java */
package Project1;
/**
* A DListNode2 is a node in a DList2 (doubly-linked list).
*/
class DListNode2 {
/**
* item references the item stored in the current node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
TypeAndSize runObject;
DListNode2 prev;
DListNode2 next;
/**
* DListNode2() constructor.
*/
DListNode2() {
this.runObject = null;
this.prev = null;
this.next = null;
}
DListNode2(TypeAndSize.Species runType, int runLength) {
this.runObject = new TypeAndSize(runType, runLength);
this.prev = null;
this.next = null;
}
}
===================================
/* TypeAndSize.java */
/* DO NOT CHANGE THIS FILE. */
/* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */
package Project1;
/**
* Each TypeAndSize object represents a sequence of identical sharks, fish,
* or empty cells. TypeAndSizes are your way of telling the test program
* what runs appear in your run-length encoding. TypeAndSizes exist solely
* so that your program can return two integers at once: one representing
* the type (species) of a run, and the other representing the size of a run.
*
* TypeAndSize objects are not appropriate for representing your run-length
* encoding, because they do not represent the degree of hunger of a run of
* sharks.
*
* #author Jonathan Shewchuk
*/
class TypeAndSize {
Species type; // runType EMPTY, SHARK, or FISH
int size; // Number of cells in the run for that runType.
enum Species{EMPTY,SHARK,FISH}
/**
* Constructor for a TypeAndSize of specified species and run length.
* #param species is Ocean.EMPTY, Ocean.SHARK, or Ocean.FISH.
* #param runLength is the number of identical cells in this run.
* #return the newly constructed Critter.
*/
TypeAndSize(Species species, int runLength) {
if (species == null) {
System.out.println("TypeAndSize Error: Illegal species.");
System.exit(1);
}
if (runLength < 1) {
System.out.println("TypeAndSize Error: runLength must be at least 1.");
System.exit(1);
}
this.type = species;
this.size = runLength;
}
}
======================================
For reference, complete skeleton of code for assignment is given in link
In the given link, following paragraph says:
Part II(c): Implement a toOcean() method in the RunLengthEncoding class, which converts a run-length encoding to an Ocean object. To accomplish this, you will need to implement a new addShark() method in the Ocean class, so that you can specify the hunger of each shark you add to the ocean. This way, you can convert an Ocean to a run-length encoding and back again without forgetting how hungry each shark was.
My question:
In PartIIa and PartIIb of the solution written in RunLenghtEncoding() 5 argument constructor, I am not capturing hungerLevel property of Shark due to the reason mentioned in method comments -
Any run of sharks is treated as a run of newborn sharks (which are equivalent to sharks that have just eaten).
I would like to know, What exactly toOcean() method mean, when. i do not capture hungerLevel of Shark runType. Am I suppose to convert the Compressed form of Ocean to an 'existing Ocean' or 'new Ocean'? Please help me, am stuck here.
Note: This is self learning course published in 2006. No mentor available for this course. Also suggest me, if this is the right place to discuss such queries
It says that
Any run of sharks is treated as a run of newborn sharks (which are equivalent to sharks that have just eaten).
So when you have to re-create the Ocean, you can treat any run of sharks as sharks with hungerLevel 0. In Part III you do have to keep track of the hungerLevel, however. But for Part II c they leave that out for the moment being.
We have configured iReport to generate the following graph:
The real data points are in blue, the trend line is green. The problems include:
Too many data points for the trend line
Trend line does not follow a Bezier curve (spline)
The source of the problem is with the incrementer class. The incrementer is provided with the data points iteratively. There does not appear to be a way to get the set of data. The code that calculates the trend line looks as follows:
import java.math.BigDecimal;
import net.sf.jasperreports.engine.fill.*;
/**
* Used by an iReport variable to increment its average.
*/
public class MovingAverageIncrementer
implements JRIncrementer {
private BigDecimal average;
private int incr = 0;
/**
* Instantiated by the MovingAverageIncrementerFactory class.
*/
public MovingAverageIncrementer() {
}
/**
* Returns the newly incremented value, which is calculated by averaging
* the previous value from the previous call to this method.
*
* #param jrFillVariable Unused.
* #param object New data point to average.
* #param abstractValueProvider Unused.
* #return The newly incremented value.
*/
public Object increment( JRFillVariable jrFillVariable, Object object,
AbstractValueProvider abstractValueProvider ) {
BigDecimal value = new BigDecimal( ( ( Number )object ).doubleValue() );
// Average every 10 data points
//
if( incr % 10 == 0 ) {
setAverage( ( value.add( getAverage() ).doubleValue() / 2.0 ) );
}
incr++;
return getAverage();
}
/**
* Changes the value that is the moving average.
* #param average The new moving average value.
*/
private void setAverage( BigDecimal average ) {
this.average = average;
}
/**
* Returns the current moving average average.
* #return Value used for plotting on a report.
*/
protected BigDecimal getAverage() {
if( this.average == null ) {
this.average = new BigDecimal( 0 );
}
return this.average;
}
/** Helper method. */
private void setAverage( double d ) {
setAverage( new BigDecimal( d ) );
}
}
How would you create a smoother and more accurate representation of the trend line?
This depends on the behavior of the item you are measuring. Is this something that moves (or changes) in a manner that can be modeled?
If the item is not expected to change, then your trend should be the underlying mean value of the entire sample set, not just the past two measurements. You can get this using Bayes theorem. The running average can be calculated incrementally using the simple formula
Mtn1 = (Mtn * N + x) / (N+1)
where x is the measurement at time t+1, Mtn1 is the mean a time t+1, Mtn is the mean at time t, and N is the number of measurements taken by time t.
If the item you are measuring fluctuates in a manner that can be predicted by some underlying equation, then you can use a Kalman filter to provide a best estimate of the next point based on the previous (recent) measurements and the equation that models the predicted behavior.
As a starting point, the Wikipedia entry on Bayesian estimators and Kalman Filters will be helpful.
Resulting Image
The result is still incomplete, however it clearly shows a better trend line than that in the question.
Calculation
There were two key components missing:
Sliding window. A List of Double values that cannot grow beyond a given size.
Calculation. A variation on the accept answer (one less call to getIterations()):
((value - previousAverage) / (getIterations() + 1)) + previousAverage
Source Code
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import net.sf.jasperreports.engine.fill.AbstractValueProvider;
import net.sf.jasperreports.engine.fill.JRFillVariable;
import net.sf.jasperreports.engine.fill.JRIncrementer;
/**
* Used by an iReport variable to increment its average.
*/
public class RunningAverageIncrementer
implements JRIncrementer {
/** Default number of tallies. */
private static final int DEFAULT_TALLIES = 128;
/** Number of tallies within the sliding window. */
private static final int DEFAULT_SLIDING_WINDOW_SIZE = 30;
/** Stores a sliding window of values. */
private List<Double> values = new ArrayList<Double>( DEFAULT_TALLIES );
/**
* Instantiated by the RunningAverageIncrementerFactory class.
*/
public RunningAverageIncrementer() {
}
/**
* Calculates the average of previously known values.
* #return The average of the list of values returned by getValues().
*/
private double calculateAverage() {
double result = 0.0;
List<Double> values = getValues();
for( Double d: getValues() ) {
result += d.doubleValue();
}
return result / values.size();
}
/**
* Called each time a new value to be averaged is received.
* #param value The new value to include for the average.
*/
private void recordValue( Double value ) {
List<Double> values = getValues();
// Throw out old values that should no longer influence the trend.
//
if( values.size() > getSlidingWindowSize() ) {
values.remove( 0 );
}
this.values.add( value );
}
private List<Double> getValues() {
return values;
}
private int getIterations() {
return getValues().size();
}
/**
* Returns the newly incremented value, which is calculated by averaging
* the previous value from the previous call to this method.
*
* #param jrFillVariable Unused.
* #param tally New data point to average.
* #param abstractValueProvider Unused.
* #return The newly incremented value.
*/
public Object increment( JRFillVariable jrFillVariable, Object tally,
AbstractValueProvider abstractValueProvider ) {
double value = ((Number)tally).doubleValue();
recordValue( value );
double previousAverage = calculateAverage();
double newAverage =
((value - previousAverage) / (getIterations() + 1)) + previousAverage;
return new BigDecimal( newAverage );
}
protected int getSlidingWindowSize() {
return DEFAULT_SLIDING_WINDOW_SIZE;
}
}
Is there a way to add references to one or more of a method's parameters from the method documentation body?
Something like:
/**
* When {#paramref a} is null, we rely on b for the discombobulation.
*
* #param a this is one of the parameters
* #param b another param
*/
void foo(String a, int b)
{...}
As far as I can tell after reading the docs for javadoc there is no such feature.
Don't use <code>foo</code> as recommended in other answers; you can use {#code foo}. This is especially good to know when you refer to a generic type such as {#code Iterator<String>} -- sure looks nicer than <code>Iterator<String></code>, doesn't it!
The correct way of referring to a method parameter is like this:
As you can see in the Java Source of the java.lang.String class:
/**
* Allocates a new <code>String</code> that contains characters from
* a subarray of the character array argument. The <code>offset</code>
* argument is the index of the first character of the subarray and
* the <code>count</code> argument specifies the length of the
* subarray. The contents of the subarray are copied; subsequent
* modification of the character array does not affect the newly
* created string.
*
* #param value array that is the source of characters.
* #param offset the initial offset.
* #param count the length.
* #exception IndexOutOfBoundsException if the <code>offset</code>
* and <code>count</code> arguments index characters outside
* the bounds of the <code>value</code> array.
*/
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = new char[count];
this.count = count;
System.arraycopy(value, offset, this.value, 0, count);
}
Parameter references are surrounded by <code></code> tags, which means that the Javadoc syntax does not provide any way to do such a thing. (I think String.class is a good example of javadoc usage).
I guess you could write your own doclet or taglet to support this behaviour.
Taglet Overview
Doclet Overview
Here is how it is written in Eclipse Temurin JDK 8 sources:
It looks like the only way is or {#code }, but it's not a link - it's just formatting.