Hi ! i’m having issues solving the
Captain’s Log exercise that introduces the Random class and methods, i did the exercise pretty easily but somehow no matter what i do i keep failing the same test, the testing wants my random code to generate specific values which makes no sense to me, i’m not sure if i’m the one wrong or if there’s a problem with the testing, thank you in advance for your help/advice. Here’s my code:
import java.util.Random;
class CaptainsLog {
private static final char[] PLANET_CLASSES = new char[]{'D', 'H', 'J', 'K', 'L', 'M', 'N', 'R', 'T', 'Y'};
private Random random;
CaptainsLog(Random random) {
this.random = random;
}
char randomPlanetClass() {
int i = random.nextInt(PLANET_CLASSES.length);
return PLANET_CLASSES[i];
}
String randomShipRegistryNumber() {
int i = 1000 + random.nextInt(9000);
return String.format("NCC-%d", i);
}
double randomStardate() {
double i = 41000 + 1000 * random.nextDouble();
return i;
}
Here’s the test i’m failing:
@Test
@Tag("task:2")
@DisplayName("Generating a random ship registry number")
public void testRandomShipRegistryNumber() {
assertThat(new CaptainsLog(random1).randomShipRegistryNumber()).isEqualTo("NCC-8773");
assertThat(new CaptainsLog(random2).randomShipRegistryNumber()).isEqualTo("NCC-2473");
assertThat(new CaptainsLog(random3).randomShipRegistryNumber()).isEqualTo("NCC-9576");
}
Expecting:
<"NCC-6258">
to be equal to:
<"NCC-8773">
but was not.
Exception: org.opentest4j.AssertionFailedError:
Expecting:
<"NCC-6258">
to be equal to:
<"NCC-8773">
but was not.
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at CaptainsLogTest.testRandomShipRegistryNumber(CaptainsLogTest.java:48)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Looks like random1 may not be seeded to the expected value.
I double-checked the example implementation (which is what I used to generate the expected values using the seeds provided by the test suite) and it looks like it contains a bug: it calls random.nextInt(8999) instead of random.nextInt(9000)… How embarrassing!
Would you be willing to submit a PR to fix this? It would involve changing the example implementation to fix the bug and then updating the test case to expect the correct values (which are NCC-6258, NCC-1683 and NCC-4922 respectively).
Thank you guys for such a quick answer on my doubt, i’m fairly new to exercism(and to programming in general) so i don’t know how to submit a PR to fix the bug. I’m willing to help if you teach me how though
@sanderploegsma Sander i think i did what you asked me to do i hope i did good because it’s my first PR. I submitted two one on the implementation code and one on the testing file.
I think this bug has returned and/or that there might be a problem with the test methodology here in that it only allows for a specific solution but the spec doesn’t clarify what that is.
random.nextInt(1000, 9999); will result in:
expected: “NCC-6258”
but was: “NCC-8773”
random.nextInt(10999) - 1000 will result in:
expected: “NCC-6258”
but was: “NCC-6222”
Because there are multiple ways to solve the problem as given it might not be best to test it with a specific value unless it is a little clearer that only one solution will work and a little more guidance about what that solution is?
I assume there is also another method that will pass the updated test, but wasn’t able to find any guidance and don’t have time to keep digging today. Maybe the hint could be updated to explain what is required/expected here?
Your code contains the same problem that was fixed in the example code. Random ranges exclude the given end value from the list of possible values, so random.nextInt(1000, 9999) would never ever return 9999. To possibly get 9999 increase the end to random.nextInt(1000, 10000) and you should pass the test (I haven’t tested it).
Edit: random.nextInt(10999) - 1000 will sometimes yield values below 1000 and so you can’t solve the problem like this.
Fantastic - thank you! I did wonder if it was something incredibly obvious like that.
I’ll go make a suggestion that the “hint” be updated with a note re: overloaded nextInt method max range being exclusive which would solve my concern re: the failing test being a bit obscure.