CodeHS Billboard Class AP CS A - java

I am struggling with the CodeHS Java problem Billboard Top 10. I am trying to reference a Musician object within the top10 ArrayList, but I keep getting the error:
non-static variable top10 cannot be referenced from a static context.
Here is the code I have for this segment:
public void add(Musician m) {
//if less than 10 musicians on the list and musician has platinum status, add musician to top10 array list
if(m.getIsPlatinum(m.getAlbumsSold())&&top10.size()<10) {
top10.add(m);
}
//if already 10 musicians (and platinum), call replace method
else if(m.getIsPlatinum(m.getAlbumsSold())&&top10.size()==10) {
replace(m);
}
// else print musician couldn't be added to top10 list
else System.out.println("The musician could not be added to the top10 list.");
}
public static void replace(Musician replacer) {
//if lowest # weeks on top40 is lower than # weeks of new musician: replace old
Musician temp = top10.get(0);
int lowest40Weeks = temp.getWeeksInTop40();
int lowestIndex = 0;
for(int i = 0; i<top10.size(); i++) {
temp = top10.get(i);
if(temp.getWeeksInTop40()<lowest40Weeks) {
lowest40Weeks = temp.getWeeksInTop40();
lowestIndex = i;
}
}
if(lowest40weeks<replacer.getWeeksInTop40()) {
top10.set(lowestIndex, replacer);
System.out.println(replacer.getName() + " has replaced " + top10.get(lowestIndex).getName() + " on the top 10 list.");
}
//print message to user about replacement
//else print musician can't be added because not enough weeks on top40
else {
System.out.println(replacer.getName() + " could not be added to the top 10 list because they do not have enough weeks in the top 40.");
}
}
All of my issues are in the replace method when I reference top10 in a method.
Any help would be appreciated!

Why is Replace static in the first place?
You can't reference a variable that isn't static in a function that is. So just make the replace function not static.

Related

I have made a Java programme but has repetition problem

I have created that Java programme but it have repetition problem, I want that if one question has done either right or wrong it must not be ask again.
It should ask 10 question only. I have tried alot to change but every time I am getting error.
I have created that Java programme but it have repetition problem, I want that if one question has done either right or wrong it must not be ask again.
It should ask 10 question only. I have tried alot to change but every time I am getting error.
package examapp;
import java.util.Random;
import javax.swing.JOptionPane;
public class Examapp {
static int nQuestions = 0; static int nCorrect = 0;
public static void main(String[] args) {
int prevNum=0;
int sum=0;
do{
Random rand = new Random();
int randomNum = rand.nextInt((11 - 1) + 1) + 1;
if(randomNum==prevNum){
prevNum=randomNum;
}
else if(randomNum==1){
String question1;
question1 = "What was the name of Google in late 90s?\n";
question1+="A. Googol\n";
question1+="B. Gigablast\n";
question1+="C. Backrub\n";
question1+="D. Google\n";
question1+="Marks=9";
check(question1,"C");
sum=sum+1;
}
else if(randomNum==2){
String question2;
question2 = "\"Do no evil\" is a tagline of?\n";
question2+="A. Yahoo\n";
question2+="B. Google\n";
question2+="C. Bing\n";
question2+="D. Duck Duck Go\n";
question2+="Marks=9";
check(question2,"B");
sum=sum+1;
}
else if(randomNum==3){
String question3;
question3 = "Which of the following is fully Object Oriented Programming Language?\n";
question3+="A. SmallTalk\n";
question3+="B. Kotlin\n";
question3+="C. Java\n";
question3+="D. F#\n";
question3+="Marks=9";
check(question3,"A");
sum=sum+1;
}
else if(randomNum==4){
String question4;
question4 = "Which among the following is not a mobile Operating System?\n";
question4+="A. Bada\n";
question4+="B. Safari\n";
question4+="C. WebOS\n";
question4+="D. MeeGo\n";
question4+="Marks=9";
check(question4,"B");
sum=sum+1;
}
else if(randomNum==5){
String question5;
question5 = "Which of the following is a correct format of Email address?\n";
question5+="A. info.website.com\n";
question5+="B. info#website.com\n";
question5+="C. info#website#com\n";
question5+="D. info.website#com\n";
question5+="Marks=9";
check(question5,"B");
sum=sum+1;
}
else if(randomNum==6){
String question6;
question6 = "What is the shortcut key of printing a document for computer having windows?\n";
question6+="A. Ctrl + Shift + P\n";
question6+="B. Alt + P\n";
question6+="C. Ctrl + Alt + P\n";
question6+="D. Ctrl + P\n";
question6+="Marks=9";
check(question6,"D");
sum=sum+1;
}
else if(randomNum==7){
String question7;
question7 = "Computer software includes\n";
question7+="A. Packaged programs\n";
question7+="B. Operating system programs\n";
question7+="C. Applications programs\n";
question7+="D. All of these\n";
question7+="Marks=9";
check(question7,"D");
}
else if(randomNum==8){
String question8;
question8 = "A function inside another function is called a _______ function\n";
question8+="A. Nested\n";
question8+="B. Round\n";
question8+="C. Sum\n";
question8+="D. Grouped\n";
question8+="Marks=9";
check(question8,"A");
sum=sum+1;
}
else if(randomNum==9){
String question9;
question9 = "What does HTTP stands for?\n";
question9+="A. Hypertext Transfer Plotter\n";
question9+="B. Hypertext Transfer Plot\n";
question9+="C. Hypertext Transfer Protocol\n";
question9+="D. Head Tail Transfer Protocol\n";
question9+="Marks=9";
check(question9,"C");
sum=sum+1;
}
else if(randomNum==10){
String question10;
question10 = "The term 'Pentium' is realted to\n";
question10+="A. DVD\n";
question10+="B. Hard Disk\n";
question10+="C. Microprocessor\n";
question10+="D. Mouse\n";
question10+="Marks=9";
check(question10,"C");
sum=sum+1;
}
else{
prevNum=randomNum;
}
}while(sum<=9);
JOptionPane.showMessageDialog(null,nCorrect + " correct out of 10" + " questions");
JOptionPane.showMessageDialog(null,"Total Obtained Marks="+(nCorrect*9));
}
public static String ask(String question) {
while(true) {
String answer = JOptionPane.showInputDialog(question);
answer = answer.toUpperCase();
if(!(answer.equals("A") || answer.equals("B") || answer.equals("C") || answer.equals("D"))){
JOptionPane.showMessageDialog(null,"Invalid Answer");
continue;
}
return answer;
}
}
static void check(String question, String correctAnswer) {
nQuestions++;
String answer = ask(question);
if(answer.equals(correctAnswer)) {
nCorrect++;
}
else {
}
}
}
Thank you!
Your main is quite cluttered. By the time you get to the bottom, you have already forgotten what was on top, such as that it is a very large do-while block. If I were you, I would put the questions and answers in an array, list or even better in your own question object. Then you could use array shuffle to put them in different order for each run and omit all the if-else blocks. It is best to also pull your initialization from random out of the loop so that you don't create a new object with every iteration.
In order to answer your question, so that you do not use an already generated random number again, you must somehow remember the already generated ones. For example, use a list.
public static void main(String[] args) {
Random rand = new Random();
List<Integer> list = new ArrayList<>();
int count = 0;
int randomNum;
do{
randomNum = rand.nextInt(10)+1;
while(list.contains(randomNum)){
randomNum = rand.nextInt(10)+1;
}
list.add(randomNum);
count++;
// rest of your code goes here
}while( count < 10);
System.out.println(list);
}

Going through a list to count how many times a value is there... Not working in Java

I created a list from a text document. I then created a loop to go through it and count every time "strawberry" is in it. But I'm not sure why, it is not working.
I know my list gets created correctly because my print statement at the end returns the correct value. But then it doesn't add up the flavors or the number of times strawberry is present.
import java.util.List;
import java.util.ArrayList;
public class IceCream {
public static void main(String[] args) {
int count, strawberry, average, i;
List<String> flavors = new ArrayList<String>();
TextIO.readFile("src/icecream.dat");
while (TextIO.eof() == false) {
flavors.add(TextIO.getln());
}
count = 0;
strawberry = 0;
for (i = 0; i < flavors.size(); i++); {
count++;
if ( flavors.equals("Strawberry")) {
strawberry++;
}
}
TextIO.putln(flavors.size());
average = strawberry / count * 100;
TextIO.putln("" + count + " ice cream cones were sold. "
+ strawberry + " were strawberry flavored, "
+ "which is a total of " + average + "% of the ice cream cones sold.");
}
}
You are wanting to use ArrayList::get
and compare the Object using equals
if ( flavors.get(i).equals("Strawberry")) {
strawberry++;
}
edit
Also remove the last ; on for (i = 0; i < flavors.size(); i++);
Apart from Scary's answer, you have a semicolon after your for-loop. A semicolon is an empty statement, so you're running an empty statement 374 times, while increasing i to be the size of your list. Afterwards you run the block that was supposed to be the loop's body exactly once, but now i is too big for your list.
Remove the semicolon.
Do not declare your variables god knows where, declare them where you need them. That way you would've gotten a compile error, as i would only be available inside and not outside the loop.
You are comparing the ArrayList object with the String "Strawberry". What you really want is to compare each element with the String. So the statement should be
if(flavors.get(i).equals("Strawberry")) {
strawberry++;
}

how do I check if an array is empty?

This is my code, the output will print only the first course, I don't know what is wrong, I'd like some help :(
public class student {
private long student_ID;
private int[] listOfCourses= new int[5];
private double[] Mark=new double[5];
private int numCoures;
public student(long student_ID) {
this.student_ID=student_ID;
}
long getStudentID() {
return student_ID;
}
int getnumCoures(){
return numCoures;
}
void addCourse(int CN) {
for(int i=0 ; i<listOfCourses.length ; i++){
if (listOfCourses[i]==0) {
listOfCourses[i]=CN;
}
}
numCoures++;
}
void addMark(int CN,double M) {
for(int i=0 ; i<listOfCourses.length ; i++) {
if(listOfCourses[i]==CN) {
Mark[i]=M;
}
}
}
void print() {
System.out.println("NAME OF student "+student_ID);
for(int i=0 ; i<numCoures ; i++) {
System.out.println("NAME OF COURSE "+listOfCourses[i]+" MARK "+Mark[i]);
}
}
}
The main method:
public static void main(String[] args) {
student S1 = new student(1000000001);
S1.addCourse(200);
S1.addCourse(201);
S1.addCourse(202);
S1.addMark(200, 100);
S1.addMark(201, 99);
S1.addMark(202, 98);
student S2 = new student(1111111111);
S2.addCourse(300);
S2.addCourse(301);
S2.addMark(300, 70);
S2.addMark(301, 99);
S1.print();
S2.print();
}
Output:
NAME OF student 1000000001
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 200 MARK 100.0
NAME OF student 1111111111
NAME OF COURSE 300 MARK 70.0
NAME OF COURSE 300 MARK 70.0
This is what gave you trouble. The first time you call, you will assign CN to all the courses from 0 to 4.
void addCourse(int CN){
for(int i=0 ; i<listOfCourses.length ; i++){
if (listOfCourses[i]==0) {
listOfCourses[i]=CN;
}
}
numCoures++;
}
Suggestion
void addCourse(int CN){
if (numCoures >= 5) return; // actually, you should throw an exception here
listOfCourses[numCoures] = CN;
numCoures++;
}
Your problem is your addCourse() method:
void addCourse(int CN) {
for (int i = 0; i < listOfCourses.length; i++) {
if (listOfCourses[i] == 0) {
listOfCourses[i] = CN;
}
}
numCoures++;
}
Think about what happens here. When you add the first course, the array is all 0. Hence, the condition listOfCourses[i] == 0 will always yield true and you will fill the whole array with that course number. The next time you try to add a course, the condition will always evaluate to false, hence nothing changes (apart from numCoures).
This also means that you could call addCourse() very often and increase numCoures to some ridiculous number that doesn't have any meaning anymore.
Possible solution
An easy fix would be to actually use numCoures when adding a new course:
void addCourse(int CN) {
if (numCoures < listOfCourses.length) {
listOfCourses[numCoures++] = CN;
}
}
Here, we first check if numCoures is still within the array's bounds. If so, we insert the given course number at index numCoures, which would be 0 the first time around and so on. With the ++ as suffix, numCoures will also be increased after it has been evaluated.
Solution using a HashMap
However, I suggest you replace your plain arrays with one of the many helpful Java collections (unless this is an exercise that explicitly asks you to use plain arrays?). For example, you could go with a HashMap. A map associates a key with a value. This seems to fit your scenario quite well: the course number can be the key and the mark can be the value.
We would declare this as follows:
private HashMap<Integer, Float> courses = new HashMap<>();
Also, don't forget that you will need import java.util.HashMap; at the top of your file.
Your addCourse() method could then become:
void addCourse(int courseNum) {
courses.put(courseNum, null);
}
And addMark() would become:
void addMark(int courseNum, double mark) {
courses.replace(courseNum, mark);
}
If you look up HashMap's put() and replace() methods, you'll notice that we could have used put() in addMark() as well, but I feel like your intent is clearer this way.
Two more methods should now be changed:
int getNumCourses() {
return courses.size();
}
I'll leave the print() to you.
Also, you can now get rid of these three, as they have been replaced by our neat HashMap:
private int[] listOfCourses = new int[5]; // bye bye
private double[] Mark = new double[5]; // cya
private int numCoures; // sayounara
Benefits of using a Map
A student can have more than 5 courses
Your code becomes shorter and easier to read
Your code also becomes less prone to error
Changing or removing courses or grades is easily possible
Additional notes:
You should pay more attention to the names of your classes, variables and methods. I'll point out what I noticed:
The class student should be Student (classes should start with an upper case letter)
The variable Mark should be mark (variables should start with a lower case letter)
The method getnumCoures() should be getNumCourses() )(methods should be camelCase and you mistyped courses)
The variable student_ID and the method getStudentID() could be simplified to id and getID() - we already know that we're dealing with a student!
The addCourse method sets all 5 elements of listOfCourses to the value supplied in the first call. To fix this, you want to exit the loop after setting the value by using a break statement. Otherwise, the code marches through the entire array:
void addCourse(int CN) {
for (int i = 0; i < listOfCourses.length; i++) {
if (listOfCourses[i] == 0) {
listOfCourses[i] = CN;
break;
}
}
numCoures++;
}
There are better ways to accomplish the goals of this program. What happens if a student has more than 5 courses? Look up java.util.List and java.util.Map.
Output is:
NAME OF student 1000000001
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 201 MARK 99.0
NAME OF COURSE 202 MARK 98.0
NAME OF student 1111111111
NAME OF COURSE 300 MARK 70.0
NAME OF COURSE 301 MARK 99.0

Java not recognizing elements in ArrayList?

I have a program where I make an arraylist to hold some cab objects. I keep getting an error that what I get from the message is that java does not recognize that the arraylist has objects in it. This is the error that I am getting.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at edu.Tridenttech.MartiC.app.CabOrginazer.main(CabOrginazer.java:48)
This is the code that i am trying to get to work
public class CabOrginazer {
private static List<CabProperties> cabs = new ArrayList<CabProperties>();
private static int count = 0;
private static boolean found = false;
public void cabOrginazer()
{
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CabRecordReaper reaper = new CabRecordReaper("C:/CabRecords/September.txt");
CabProperties cabNum;
for(int i = 0; i < 20; i++)
{
cabNum = new CabProperties();
cabs.add(cabNum);
}
while(reaper.hasMoreRecords())
{
CabRecord file = reaper.getNextRecord();
for(int j = 0; j < cabs.size(); j++)
{
if(cabs.get(j).getCabID() == file.getCabId())
{
found = true;
cabs.get(j).setTypeAndValue(file.getType(), file.getValue(), file.getPerGallonCost());
cabs.get(j).setDate(file.getDateString());
break;
}
}
if(found == false)
{
cabs.get(count).setCabId(file.getCabId());
count++;
}
/*for(CabProperties taxi : cabs)
{
if(taxi.getCabID() == file.getCabId())
{
found = true;
taxi.setTypeAndValue(file.getType(), file.getValue(), file.getPerGallonCost());
taxi.setDate(file.getDateString());
break;
}
}*/
}
for(CabProperties taxi : cabs)
{
System.out.print("cab ID: " + taxi.getCabID());
System.out.print("\tGross earning: " + taxi.getGrossEarn());
System.out.print("\tTotal Gas Cost: " + taxi.getGasCost());
System.out.print("\tTotal Service Cost: " + taxi.getServiceCost());
System.out.println();
}
}
}
line 48 is the inside of that if statement where it says cabs.get(count).setCabId(file.getCabId());
with the little knowledge I have of Java. Java should know that there are elements inside of cabs and I should be able to set that id of the cab. What can cause Java not to recognize that the arraylist is populated?
The list isn't populated with an element at item count. Look at the exception: you've got 20 elements in the list, so the valid indexes are 0 to 19 inclusive. You're asking for record 20 (i.e. the 21st record). That doesn't exist.
It sounds like your block should be something like:
if (!found)
{
CabProperties properties = new CabProperties();
properties.setCabId(file.getCabId());
// Probably set more stuff
cabs.add(properties);
}
You may well be able to get rid of the count variable entirely - and your initial population of the list with dummy properties. It's very odd to populate a list like that to start with - that's typically something you do with an array which has a fixed size. One of the main benefits of using a List such as ArrayList is that it's dynamically sized.
Java is recognizing the members just fine. You have 20 members in the array, indexed from index 0 through index 19.
You are asking for index 20, which does not exist.
The loop for:
while(reaper.hasMoreRecords())
must be running many more times than you expect, and your data is hitting the found == false if condition (which you can just say if (!found) { ... ) many times, and on the 21st time it fails with the index-out-of-bounds exception.
You should figure out how to use your debugger too.

Working with Generic arrays [duplicate]

This question already has answers here:
Java generics and Array's
(5 answers)
Closed 8 years ago.
Good day. I have been learning java the last few months. So I created a generic array as follows.
public class Implementation<T> implements IMatrix<T>{
private T[][] genMatrix;
private Integer numberRows;
private Integer NumberCols;
public Implementation(){
generateMatrix();
for(int i = 0;i< numberRows;i++)
{
for(int j =0;j< numberCols;j++)
{
JOptionPane.showInputDialog("Enter value for row " + (i+1) + " and for column " + (j+1)))
}
}
multiplyScalar(5);
}
//generate the array
public void generateMatrix(){
String rowString = JOptionPane.showInputDialog("Enter the number of rows!");
numberRows = Integer.parseInt(rowString);
String colString = JOptionPane.showInputDialog("Enter the number of cols!");
numberCols = Integer.parseInt(colString);
final Object[][] arrayO = (T[][])new Object[numberRows][numberCols];
genMatrix = (T[][])arrayO;
}
//writeElements to the array;
public void writeElem(int x, int y, T value){
genMatrix[x][y] = value;
}
//now that those members are done I have created a method to access the data
public T getElem(Integer i, Integer j){
return (T)genMatrix[i][j];
}
This is where my problem now exists. I have made this two dimensional array. I would like to multiply each value in this array by a Integer c. I have attempted it in the following way and all failed.
public IMatrix<T> multiplyScalar(Integer c) throws MatrixException {
// TODO Auto-generated method stub
for(int i = 0; i< numberRows; i++)
{
for(int j=0;j<numberCols;j++)
{
/**
THIS IS THE POINT AT WHICH IT CRASHES
*/
System.out.println(((Integer)(getElement(i, j)) * c));
}
}
return null;
}
}
The program crashes because of a ClassCastException. I have tried everything in my knowledge to get this to work. I can not multiply the two dimensional array with a Integer. Please help. This uses a interface with many more functions that is irrelevant. Please note that there is a strong possibility that this code crashes as I can not upload the original code.
The problem is that Java doesn't support operator polymorphism. You need T to extend Number and then use method calls. Its a bit more verbose than what one might like though. Its explained quiet well here:
Predefining multiplication for generics in java

Categories

Resources