Alright so I'm taking an AP Computer Science course and up until now I've found the content easy and unchallenging because I already had a background in Java. However now I have run into an issue with some of the code that the course is providing me with and writing a function based off of it. I've googled it, and tested many different things to try and get it to work and to no avail. So hopefully you guys can shed some light on this and perhaps help me figure it out.
First the book provides me with this code as a basic Time class:
public class Time extends Object {
private int itsHour;
private int itsMin;
/** Create an object for the given hour and minute. If min
* is negative, adjust the values to make 0 <= min < 60. */
public Time (int hour, int min) { // constructor
super();
itsHour = hour;
for (itsMin = min; itsMin < 0; itsMin = itsMin + 60) {
itsHour--;
}
} //=======================
/** Return the time expressed in military time. */
public String toString() {
if (itsHour < 10) {
return ("0" + itsHour) + itsMin;
} else {
return ("" + itsHour) + itsMin;
}
}
/** Return the result of adding this Time to that Time. */
public Time add (Time that) {
// Read below at issue #2
}
}
That was the main class they gave us to work with and then they gave a class called TimeTester which is to be used to execute the commands. The comments dictate what should happen.
import javax.swing.JOptionPane;
class TimeTester {
public static void main (String[] args) {
Time t1 = new Time (13, 25);
Time t2 = new Time (8, -150);
JOptionPane.showMessageDialog (null, "1 " + t1.toString());
JOptionPane.showMessageDialog (null, "2 " + t2.toString());
Time t3 = t1.add (t2);
JOptionPane.showMessageDialog (null, "3 " + t3.toString());
t1 = t2.add (t3);
JOptionPane.showMessageDialog (null, "1 " + t1.toString());
System.exit (0);
} //=======================
}
Now like I said this code was literally handed to me it's making sense of the code and getting it to work for me that I just literally cannot do. So below are basically the key issues I'm running into.
1) I understand how its supposed to run and what the executors do, but I do not understand what exactly its doing to achieve the results.
2) The add function in the first set of code which was basically it's main class is the main part of the assignment. The assignment reads as follows:
Exercise 4.15 (harder) Write the Time method public Time add (Time
that): The executor returns a new Time object that is the sum of the
two, e.g., 0740 add 1430 is
2210. If the sum is more than 2359, drop the extra 24 hours, e.g., 1300 add 1400 is 300.
Assigned from: http://www.cs.ccsu.edu/~jones/chap04.pdf
When I carry over the values to the add function in the TimeTester executing "now.add(wait)" I go to pull that result using "that" but the values don't pull forward.
I've also tried to change up the functions to perhaps get my own understanding and make it work for me. I changed the Time later call in the TimeTester, and then edited the function add to accept 2 values. Then added this code to the add function:
public Time add (Time time1, Time time2) {
String t1String = time1.toString(); // Value is: "0730"
String t2String = time2.toString(); // Value is: "0245"
int t1convert = Integer.parseInt(t1String, 2); // Value is 730
int t2convert = Integer.parseInt(t2String, 2); // Value is: 245
int total = t1convert + t2convert; // Value added together is: 1015
return total; // Return value of total
}
So my call looked like this:
public static void main (String[] args) {
now = new Time (7, 30); // 7:30 in the morning
wait = new Time (2, 45); // 2 hours 45 minutes
later = now.add (now, wait); // produces 10:15 in the morning
JOptionPane.showMessageDialog(null, now + " + " + wait + " = " + later.toString());
System.exit (0);
}
However all that code would not compile and produce a result which could be returned to my TimeTester, it always produced a compile error of "incompatible types" referring to my return total; line. So it obviously cannot return Integers. So I am just absolutely stuck on what to do to make it add the two times.
3) I cannot use the built in Java time functions where it's formatted with semicolons. I know how to do that part which is why this different way is driving me up the wall.
4) I don't want you to write my code for me, I'd like to gain a better understanding of it and perhaps have my mistakes pointed out so that I can comprehend what in the world is going on with it.
I know it's a long post, but when I ask for help I like to be descriptive and provide everything I can because I know it's going to help me better in the long run and hopefully help the person who helps me track down an answer fast.
(PS. All of this is compiled and ran in a program called BlueJ. It's an online course so I have no instructor in class to ask about it all we have is a monitor.)
Consider a method to add two Time instances (a and b) and return a new Time instance; such a method would look like the inverse of the provided Time constructor loop, for (itsMin = min; itsMin < 0; itsMin = itsMin + 60), specifically - it should increment some hours count (perhaps by adding the hours from a and b) while the number of minutes is > 59 and subtracting 60 minutes at a time... This method might look something like this
public static Time add(Time a, Time b) { // Add two Time(s) together.
if (a == null) { // if a is null, just return b.
return b;
} else if (b == null) { // if b is null, just return a.
return a;
}
int hours = a.itsHour + b.itsHour; // Add the hours together.
int minutes = a.itsMin + b.itsMin; // Add the minutes together.
for (; minutes > 59; minutes -= 60) { // Increment hours as necessary, while
// decrementing the minute count by 60.
hours++;
}
return new Time(hours, minutes); // Return the new Time instance.
}
public static void main(String[] args) {
Time now = new Time(7, 30); // 7:30 in the morning
Time wait = new Time(2, 45); // 2 hours 45 minutes
Time later = Time.add(now, wait); // produces 10:15 in
// the morning
System.out.println(later);
}
Outputs
1015
The compiler is complaining that you are returning an int, when you defined the function return type to be "Time":
public Time add (Time time1, Time time2) {
String t1String = time1.toString(); // Value is: "0730"
String t2String = time2.toString(); // Value is: "0245"
int t1convert = Integer.parseInt(t1String, 2); // Value is 730
int t2convert = Integer.parseInt(t2String, 2); // Value is: 245
int total = t1convert + t2convert; // Value added together is: 1015
return total; // Return value of total
}
The return type is Time:
public Time add (Time time1, Time time2) ...
You return "total", which is of type "int":
int total = t1convert + t2convert;
return total; …
What you would need to do is to make a new Time object which has the answer stored inside of it. For example:
Time t3 = new Time(0, total); // This is assuming that "total" represents the minutes
Regarding the issue in the comment,
#Mike'Pomax'Kamermans Looking at your comment i managed to write this
line of code to see if i could execute it that way and I cannot. "Time
t1 = new Time(this.hour, that.hour); " spits out "cannot find symbol -
variable hour". Any insight into this? – user1686765 3 mins ago
"this.hour" is looking at the current Time instance, which is a instance of the Time class, for a member variable called "hour." If you go to your Time class, you will see that it only has some methods and 2 variables called "itsHour" and "itsMin". So it cannot find the variable "hour" because it does not exist. I think you meant to put "this.itsHour" in place of "this.hour".
Related
I would like to force a method to end after a certain amount of time even if it has not completed its task. How would I go about doing this?
Edit (added clarification and code):
I am programming a robot using Android Studio for the FTC (First Tech Challenge) robotics competition. To control the robot, I am using the FTC SDK (see https://github.com/ftctechnh/ftc_app).
The method works fine for going a particular distance and then stopping but after it stops by setting the power of all the motors to zero, it appears to get hung and no subsequent methods are invoked. Currently, it is only supposed to have the motors be stopped for one second before exiting but it appears to still get stuck on the first invocation of the method that sets the motor power to zero (setPower). For this reason, I would like to be able to terminate setPower after it has been running for a certain amount of time so that my method can exit and subsequent methods can be invoked.
Here is my method:
public void moveLine(DcMotor m1, DcMotor m2, DcMotor m3, DcMotor m4, double distance /* distance to move in meters */, double motorPower /* power to set the motors */) {
final double SPROCKET_CIRCUMFRENCE = Math.PI * 0.0652; //calculates the circumference of the sprocket
final int ENCODER_CPR_NR60 = 1680; //encoder counts for NeveRest 60
//final static int ENCODER_CPR_NR40 = 1120; //encoder counts for NeveRest 40
double amountOfRotationsCalc = distance / SPROCKET_CIRCUMFRENCE; //calculates the amount of rotations to move to reach the target distance
double amountOfEncUnitsCalc = ENCODER_CPR_NR60 * amountOfRotationsCalc; //calculates the amount of encoder units to move
//this gets the sum of the encoder positions of the drive motors
int currentEncPosSum = m1.getCurrentPosition() + m2.getCurrentPosition() + m3.getCurrentPosition() + m4.getCurrentPosition();
//this gets the average encoder position
int currentEncPosAvg = currentEncPosSum / 4;
//if the robot is supposed to be moving forward (positive distance), the motors will be set to positive values
if (distance > 0) {
//it may make sense to make this a while loop. Will this fix the issue?
if (currentEncPosAvg < amountOfEncUnitsCalc) {
m1.setPower(motorPower);
m2.setPower(motorPower);
m3.setPower(motorPower);
m4.setPower(motorPower);
} else {
//these stop the robot. Without them, it continues to move.
long start = System.currentTimeMillis();
long end = start + 1000;
while (System.currentTimeMillis() < end) {
m1.setPower(0);
m2.setPower(0);
m3.setPower(0);
m4.setPower(0);
}
return; //this is supposed to exit this method
}
} else {
//this is essentially the opposite of the code for going forwards
if (currentEncPosAvg > amountOfEncUnitsCalc) {
m1.setPower(-motorPower);
m2.setPower(-motorPower);
m3.setPower(-motorPower);
m4.setPower(-motorPower);
} else {
//these stop the robot. Without them, it continues to move.
long start = System.currentTimeMillis();
long end = start + 1000;
while (System.currentTimeMillis() < end) {
m1.setPower(0);
m2.setPower(0);
m3.setPower(0);
m4.setPower(0);
}
return;
}
}
}
long beginning = System.currentTimeMillis();
long end=beginning + yourTimeInMilliseconds;
while (end > System.currentTimeMillis()){
//your code here
}
I believe this is what you mean.
Some clarification, if you need any:
beginning is the current time in milliseconds.
end is obviously when it ends. (Start time plus delay)
While the time is still less than the set end time, the code keeps going.
I know this question is a bit old, but in the latest ftc_app Android SDKs it is recommended that for time aware methods and procedures that teams use the ElapsedTime class.
The most important thing to consider when pausing an opmode is that you can still shut it down when the stop button is pressed on the driver station app. you can make sure of this by including the opModeIsActive() method in your while condition
On our team we have a method for pausing OpModes that looks something like this. we have this declared in a separate class used for library purposes.
public static void pauseOpMode(LinearOpmode op, ElapsedTime et, double waitTime){
double startTime = et.milliseconds();
while (op.opModeIsActive() && et.milliseconds() < startTime + waitTime){}
}
Now that this method exists, in our OpMode we can create an Elapsed time Object and pass the necessarry parameters to the function required to pause the OpMode
class someOpMode extends LinearOpMode{
ElapsedTime gameTimer = new ElapsedTime();
#Override
public void RunOpMode(){
//pause program for 5 seconds
pauseOpMode(this,gameTimer,5000);
}
}
QUESTION:
How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?
CLARIFIER:
I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}
Info:
I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.
I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):
Random rand = new Random();
int i = 0;
String toEval;
String char;
String roll = txtField.getText();
while (i<roll.length) {
check if character at i position is a d, then highlight the numbers
after d until it comes to a special character/!aNumber
// so if d was found before 100, it will then highlight 100 and stop
// if the character is a symbol or the end of the string
if d appears {
char = rand.nextInt(#);
i + #'s of places;
// so when i++ occurs, it will move past whatever d# was in case
// d# was something like d100, d12, or d5291
} else {
char = roll.length[i];
}
toEval = toEval + char;
i++;
}
perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);
EDIT:
With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.
roll.split("(+-/*^)");
As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:
String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")
// Rough idea for long way
loop statement {
loop to check for parentheses {
set operation to be done first
}
if symbol {
loop for symbol check {
perform operations
}}} // ending this since it looks like a bad way to do it...
// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;
loop {
if (list[i].containsIgnoreCase(d)) {
val[]=list[i].splitIgnoreCase("d");
list[i] = 0;
while (re <= val[0]) {
list[i] = list[i] + (rand.nextInt(val[1]) + 1);
re++;
}
}
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String
wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):
(3d12^d2-2)+d4(2*d4/d2)
From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3
The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.
private Random rand = new Random();
/**
* #param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
*/
public int multiPartRoll(String roll) {
String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
int total = 0;
for (String partOfRoll : parts) { //roll each dice specified
total += singleRoll(partOfRoll);
}
return total;
}
/**
* #param roll can be fixed value, examples -1, +2, 15 or a dice to roll
* d6, +d20 -d100
*/
public int singleRoll(String roll) {
int di = roll.indexOf('d');
if (di == -1) //case where has no 'd'
return Integer.parseInt(roll);
int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
int result = rand.nextInt(diceSize) + 1; //roll the dice
if (roll.startsWith("-")) //negate if nessasary
result = -result;
return result;
}
I am creating some magic spells, and obviously I want a delay between each usage.
Now According to google, there are 1000000000 nanoseconds in a second.
However, the magic spell is recharging after less than two seconds.
#EventHandler
public void onInteract(PlayerInteractEvent e){
Player p = e.getPlayer();
if (p.getItemInHand().getType().equals(Material.BLAZE_ROD)){
{
{
if (!kam.containsKey(p.getName())) kam.put(p.getName(), (long) 0);
if (kam.get(p.getName()) < System.nanoTime()){
kam.remove(p.getName());
kam.put(p.getName(), System.nanoTime() + (1000000000 * 30));
//Do magic spell attack here.
}
}
}else{
p.sendMessage(ChatColor.AQUA + "Skill recharging!");
}
}
Obviously my code is trying to add the System.nanoTime() plus 30 seconds, and then checking if the current system nanoTime is greater than the one I put into the hashmap, and if it is, do the spell.
I suggest you print out the value 1000000000 * 30 and check it. You'll find it's wrapping around because it's too big to fit into an integer.
In other words, the following program:
public class Test
{
public static void main(String args[])
{
System.out.println(1000000000 * 30);
System.out.println(1000000000L * 30);
}
}
prints out:
-64771072
30000000000
So, if you use the long variant, it will work fine.
bare numeric literals in Java are treated as ints, and thus your calculation overflows. One way to fix this is to perform the calculation with long literals, by adding L after the literal:
kam.put(p.getName(), System.nanoTime() + (1000000000L * 30L));
Ok so here is my issue. I am trying to compare the annual sales of two or more sales reps in an ArrayList and am getting some strange results that I just can't figure out. I have to compare the two, then tell the user how much the rep with the lower sales needs to sell to take the lead. I have it broken into three classes. But I'm pretty sure this act is dependent on just two of those. The first is:
import java.util.ArrayList;
/**
*
* #author Cameron
*/
public class SalesRep {
private ArrayList<CompensationCalculator> pool;
public SalesRep(){
pool = new ArrayList<>();
}
public void setPool(ArrayList<CompensationCalculator> pool){
this.pool = pool;
}
public ArrayList<CompensationCalculator> getPool(){
return pool;
}
public void addToPool(CompensationCalculator salesRep){
pool.add(salesRep);
}
public String toString(String report){
double diff;
for(int i=0; i<pool.size(); i++){
if (pool.get(i).getSales() < pool.get(i++).getSales()){
diff = pool.get(i++).getSales() - pool.get(i).getSales();
report = pool.get(i).getName() + "needs to sell " +
diff + " to take the lead.";
}
if (pool.get(i).getSales() > pool.get(i++).getSales()){
diff = pool.get(i).getSales() - pool.get(i++).getSales();
report = pool.get(i++).getName() + "needs to sell " +
diff + " to take the lead.";
}
}
return report;
}
}
That class should compare the two reps in the array while this one displays it to the user:
import java.util.Scanner;
public class AnnualSales {
public static void main(String[] args){
CompensationCalculator test = new CompensationCalculator(); //Creates a new instance of the class
SalesRep testName = new SalesRep(); //Creates a new instance of the SalesRep class
String cont = new String(); //A string to represent if there ar emore names to be added
Scanner scan = new Scanner(System.in); //Allows for user input to be read
while (!cont.equalsIgnoreCase("n")){
System.out.println("What is the name of the sales representative? ");
test.setName(scan.next());
System.out.println("Please enter " + test.getName() +
"'s annual sales: ");
test.setSales(scan.nextDouble());
testName.addToPool(test);
System.out.println("Are there any more sales representatives you "
+ "would like to add? ");
cont = scan.next();
}
System.out.print(testName.getPool());
System.out.print(testName.toString());
}
}
Now there are no errors being found, the program compiles and executes without a problem. But as a result I get
`[compensationcalculator.CompensationCalculator#55f96302, compensationcalculator.CompensationCalculator#55f96302]compensationcalculator.SalesRep#3d4eac69'
I am extremely confused and have been working on just this method for three hours so I am sure I need a fresh pair of eyes. Any help or guidance would be amazing.
EDIT:
Ok so your suggestion to use a Comparator was deffinetely helpful. I was also confusing myself with unnecessary code so I reworked it a bit and now it is working except for one aspect. Here is the code that I changed:
public String compare(SalesRep rep1, SalesRep rep2){
NumberFormat fmt = NumberFormat.getCurrencyInstance();
Double diff;
if (rep1.getSales() > rep2.getSales()){
diff = rep1.getSales() - rep2.getSales();
return rep2.getName() + " needs to sell " + fmt.format(diff) +
" to take the lead.";}
else{
diff = rep2.getSales() - rep1.getSales();
return rep1.getName() + " needs to sell " + fmt.format(diff) +
" to take the lead.";}
}
I also renamed my classes to better organize them to account for the new requirements. Now the only problem is that it is giving a difference of the two sales as $0.0 no madder what I input. Am I calling on each objects sales incorrectly? I feel like I have run into this problem before but reviewing my past code isn't highlighting what I am doing wrong.
I don't see you call toString(String) but only toString(), that's why you'd get that "stange" output.
Btw, that report parameter of your toString(String) method seems quite odd, since you're not using it besides assignments. You should use a local variable in that case.
Another potential error:
if (pool.get(i).getSales() > pool.get(i++).getSales()){
diff = pool.get(i).getSales() - pool.get(i++).getSales();
report = pool.get(i++).getName() + "needs to sell " +
diff + " to take the lead.";
}
Here you are incrementing i three times, so you'd refer to 3 different indices in pool.
Suppose i = 0, then you'd get:
//the first i++ returns i (0) and then increments i to 1
if (pool.get(0).getSales() > pool.get(0).getSales()){
//here i is 1, thus the next i++ returns 1 and increments i to 2
diff = pool.get(1).getSales() - pool.get(1).getSales();
//here i is 2, so the next i++ returns 2 and increments i to 3
report = pool.get(2).getName() + "needs to sell " +
diff + " to take the lead.";
}
So in that second case you'd add 3 to i and thus advance the loop by 4, since the i++ in the loop's head also increments i once more. I'd suggest you use i + 1 in your loop body instead of i++.
Besides that, your design is quite odd, since class CompensationCalculator actually seems to define a sales rep.
Another thing: I'd probably sort the list of sales reps in descending order (hint: use a Comparator). Then element 0 would be the sales rep with the highest sales and the last element would be the sales rep with the lowest sales. Difference calculations would then be a piece of cake.
The toString that you are calling is the method inherited from Object. The toString method that you defined takes a String parameter.
System.out.print(testName.toString());
so override the proper method.
or use the returned String from your method.
String out;
out = testName.toString(out); // Strings are immutable
Add #override annotation to your toString method and move report in, lie so:
#Override
public String toString(){
String report;
.....
}
Let me first make it clear that this is for an assignment. I'm very new to programming so all guidance is greatly appreciated. The program I have to calculate is a parking fee charge for a $2.00 minimum for 3 hrs or less, .50 cents per additional hr, and charge is capped at $10/ per 24 hr period. Program must display most recent customer charge as well as running total. Constants must be initialized, Math.ceil must be used, and method calculateCharges must be used to solve each cust's charge. I get uber errors when I attempt to run this program, and you'll probably laugh when you see it, but where have I erred? I'm not looking for the answer to be handed to me, just looking for the logic behind how to get to the correctly written program. Please help!
package Parking;
import java.util.Scanner;
public class parking
{
private static final double THREE_HOURS = 2.00;
private static final double PER_HOUR_COST = .50;
private static final double WHOLE_DAY_COST = 10.00;
public static void main (String [] args)
{
double hoursParked = 0;
double cumulativeCharges = 0;
double storage1 = 0;
double storage2 = 0;
Scanner input = new Scanner(System.in);
System.out.print("\nThis program displays the charge for the most recent customer");
System.out.print(" as well as the running total of yesterday's receipts\n");
do
{ System.out.printf("Enter an number between 1-24 for hours parked in garage or -1 to quit:");
hoursParked = input.nextDouble ();
}
while((hoursParked > 0)&&(hoursParked <= 24)&&(hoursParked != -1));
if( hoursParked <= 3)
System.out.printf("Most recent customer's charge was: %.2f\n" , THREE_HOURS);
storage1 += THREE_HOURS;
if(hoursParked >= 18.01)
System.out.printf("Most recent customer's charge was:%.2f\n" , WHOLE_DAY_COST);
storage2 += WHOLE_DAY_COST;
double result = calculateCharges(hoursParked * PER_HOUR_COST);
System.out.printf("Most recent customer charge was:%.2f\n" , result);
cumulativeCharges = storage1 + storage2;
System.out.printf("Running total of yesterday's receipts is:%.2f\n" , cumulativeCharges);
} // end main
public static double calculateCharges (double hoursParked)
{
Math.ceil(hoursParked);
double total = hoursParked * PER_HOUR_COST;
return total;
} // end method calculateCharges
} // end class parking
In your while condition, the third condition is useless because if the value is positive, that necessarily means it is different than -1.
In your function you want to calculate the cost of parking time but you give as parameter a cost instead of a number of hours when you call your function. Is that normal? With that you will calculate the cost of the cost instead of the cost corresponding to a number of hours.
public static double calculateCharges (double hoursParked)
and
double result = calculateCharges(hoursParked * PER_HOUR_COST);
There's a couple things here.
Your while condition is checked at the end of the do loop, it is what allows you to break after reading hoursParked. Thus, the only way you are going to reach the code outside of the do loop (after the while), is if hoursParked is -1.
Secondly, when you do not have braces for your if conditions, you are only executing the first line after it, aka. the System.out.print's. Therefore, your first if condition will execute (printing the string), then storing 2.00 in storage1. Similarly, the second if condition will execute (printing the string), then storing 10.00 in storage2.
Because hoursParked is always -1, you are passing in (-1 * .5) to calculateCharges. You are not storing the result of Math.ceil() so it effectively does nothing. You are then returning (-.5 * .5) = -.25.
cumulativeCharges is just adding 2 + 10 in every case.
Suggestions - make sure you are encapsulating the code you want to execute inside the do loop, and only break after you have done your calculations on hoursParked.