# Organize musicians into rows, with weight and population restrictions

So I just completed this project for my java programming class and was wondering if there was any way I could streamline it to really impress my professor. Here were the instructions, followed by my code.

The University of Miami's "Band of the Hour" needs a program to organize where the musicians will stand when they play at away games. Each away stadium is different, so when they arrive the conductor gets the following information from the local organizer:

The number of rows they have to stand on. The maximum number of rows is 10. The rows are labelled with capital letters, 'A', 'B', 'C', etc.

For each row, the number of positions in the row. The maximum number of positions is 8. The positions are numbered with integers, 1, 2, 3, etc.

The conductor then starts assigning people to positions, but is constrained by weight limits: Musicians, fully clothed and holding their instruments, weigh from 45kg to 200kg, and the total weight of a row may not exceed 100kg per position (e.g., a row with 5 positions may not have more than 500kg of musicians on it). The conductor wants a program that allows musicians to be added and removed from positions, while ensuring the constraints are all met. At any stage the conductor wants to be able to see the current assignment - the weight in each position (0kg for vacant positions) and the total & average weight for each row.

The program must be menu driven, with options to:

• Add a musician (by weight) to a vacant position.
• Remove a musician from an occupied position.
• Print the current assignment.
• Exit (so the musicians can start playing)

The program must be reasonably idiot proof:

• Menu options must be accepted in upper and lower case.
• Row letters must be accepted in upper and lower case.
• All input must be checked to be in range, and if not the user must be asked to input again.
• You may assume that numeric input will be syntactically correct.
import java.util.Scanner;

public class Main {

private static Scanner keyboard = new Scanner(System.in);

public static void main(String[] args) {

//values

int positions;
int rowNumber;
char userInput;
char rowLetter;
double musicianWeight = 0;
double tot = 0;
int j;
int i;

System.out.println();
System.out.println("Welcome to the Band of the Hour");
System.out.println("-------------------------------");

//create array

System.out.print("Please enter number of rows\t\t: ");
rowNumber = keyboard.nextInt();

double[][] positionsArray = new double[rowNumber][5];
int[] rowPositions = new int[rowNumber];

while (rowNumber < 1 || rowNumber > 10) {
System.out.print("ERROR: Out of range, try again            : ");
rowNumber = keyboard.nextInt();
}
for (int row = 0; row < rowNumber; row++) {
System.out.print("Please enter the number of positions in row " + (char) (row + (int) 'A') + " : ");
positions = keyboard.nextInt();
rowPositions[row] = positions;
while (positions < 0 || positions > 8) {
System.out.print("ERROR: Out of range, try again              : ");
positions = keyboard.nextInt();
}
positionsArray = new double[rowNumber][positions];
}
do {
System.out.println();
System.out.print(" (A)dd, (R)emove, (P)rint          e(X)it : ");
userInput = keyboard.next().charAt(0);
userInput = Character.toUpperCase(userInput);

switch (userInput) {
case 'A': {
System.out.print("Please enter row letter : ");
while (true) {
rowLetter = keyboard.next().charAt(0);
rowLetter = Character.toUpperCase(rowLetter);
if (rowLetter - 'A' < rowNumber)
break;
System.out.print("ERROR: Out of range, try again : ");
}
System.out.print("Please enter position number (1 to " + rowPositions[rowLetter - 'A'] + " ) : ");
positions = keyboard.nextInt();
while (true) {
if (positions >= 0 && positions <= rowPositions[rowLetter - 'A'])
break;
System.out.print("ERROR: Out of range, try again : ");
}
if (positionsArray[rowLetter - 'A'][positions - 1] != 0) {
System.out.println("ERROR: There is already a musician there.");
break;
}
else {
System.out.print("Please enter weight (45.0 to 200.0) : ");
while (true) {
musicianWeight = keyboard.nextDouble();
if (musicianWeight >= 45.0 && musicianWeight <= 200.0)
break;
System.out.print("Error: Out of range, try again : ");
}
}
tot = tot + musicianWeight;
if (tot > 500) {
System.out.println("ERROR: That would exceed the average weight limit.");
}
else {
positionsArray[rowLetter - 'A'][positions - 1] = musicianWeight;
}
}
break;

//remove musician

case 'R' : {
System.out.print("Please enter row letter : ");

while (true) {
rowLetter = keyboard.next().charAt(0);

rowLetter = Character.toUpperCase(rowLetter);

if (rowLetter - 'A' < rowNumber)
break;
System.out.print("ERROR: Out of range, try again : ");
}

System.out.print("Please enter position number (1 to " + rowPositions[rowLetter - 'A'] + " ) : ");

while (true) {
positions = keyboard.nextInt();

if (positions >= 0 && positions <= rowPositions[rowLetter - 'A'])

break;

System.out.print("ERROR: Out of range, try again : ");

}

if (positionsArray[rowLetter-'A'][positions-1] == 0)

System.out.println("ERROR: That spot is vacant.");

else {

positionsArray[rowLetter-'A'][positions-1] = 0;

System.out.print("****** Musician removed.");
System.out.println();
}
}

//print layout
break;
case 'P' : {
System.out.println();
for (i = 0; i < rowNumber; i++) {
System.out.print((char) (i + 65) + ": ");
tot = 0;
for (j = 0; j < rowPositions[i]; j++) {
System.out.printf("%3.1f\t", positionsArray[i][j]);
tot += positionsArray[i][j];
}
System.out.printf("\t\t[%6.1f,%6.1f]\n", tot, (tot / rowPositions[i]));
}
break;
}

//end program
case 'X' : {
System.exit(0);
}
default :
System.out.print("ERROR: Invalid option, try again           :");
break;
}
} while (userInput != 'X');
}
}


How can I streamline this code?

Welcome to code review and thanks for sharing your code.

Here are some points to consider:

• declare variables as close to their usage as possible.

You declared (almost) all your variable at the beginning of your main method which makes it hard to improve your code later on. This applies especially to i and j which are used in for loops and should be declared inside them.

• avoid short variable names.

Will you remember what tot is in 6 month?

• do not use the else branch of an if statement as an error handler. Instead of

        while (true) {
rowLetter = keyboard.next().charAt(0);
rowLetter = Character.toUpperCase(rowLetter);
if (rowLetter - 'A' < rowNumber)
break;
System.out.print("ERROR: Out of range, try again : ");
}


it should be:

        boolean isInputValid = false;
do {
rowLetter = keyboard.next().charAt(0);
rowLetter = Character.toUpperCase(rowLetter);
isInputValid = (rowLetter - 'A' < rowNumber)
if (!isInputValid)
System.out.print("ERROR: Out of range, try again : ");
} while (!isInputValid);

• avoid magic numbers

your code has some literals that need explanation: what is 5 in new double[rowNumber][5];? This should be a constant having a meaningful name:

   private static final int MAX_POSITION = 5;
// ...
public static void main(String[] args){
// ...
double[][] positionsArray = new double[rowNumber][MAX_POSITION];