HI all, I was wondering if anybody can help me to understand this exercise:
"A small airline has just purchased a computer for its new automated reservation system. Write an application to assign seas on each flight of the airline's only plane
(capacity: 10 seats).
Your application should display the following alternatives: 'Please type 1 for First class and please type 2 for economy'. If the user types 1, your application
should assign a seat in the first class section (seats 1-5), if he types 2 in the economy section ( seats 6-10). Your application should then display
a boarding pass indicating the person's seat number and whether it's in the first-class or economy.
Use a 1 dimensional array of primitive type boolean to represent the seating chart of the plane. Initialize all the elements to false to indicate that all the
seats are empty. As each seat is assigned set the corresponding element of the array to true to indicate that the seat is no longer available. Your application
should never assign a seat that has already been assigned. When the economy section is full ask the person if it is acceptable to be placed in the first class section
and vice versa. If yes make the appropriate sear assignment. If not display the message 'next flight leaves in 3 hrs'"

Ok so there are a few things that I am not sure about. But first let me show you what I came up with so far:

//ex 7.19 p 333 deitel and deitel
//Seats.java
import java.util.Random;
public class Seats{
    private int final NUMBER_OF_SEATS = 10;
    private boolean[] seats;
    private int firstSeat;
    private int secondSeat;
    Random randomNumbers = new Random();

    //constructor
    public Seats(){
        //initializing array
        seats = new boolean[ NUMBER_OF_SEATS ];
        //set values to false - doesn't it do automatically?
        for( int counter = 0; counter < seats.length; counter++ ){
            seats[ counter ] = false;
        }//end of loop      
    }//end of constructor

    public void assignSeats( int seatClass ){
        if( seatClass == 1 ){
            for( int counter = 0; counter < seats.length / 2; counter++ ){
                //generate random number between 1 and 5
                firstSeat = 1 + randomNumbers.nextInt(5);
                seats[ firstSeat - 1 ] = true;//firstSeat - 1 to make sure the right element is selected

            }
        }

        else if( seatClass == 2 ){
            for( int counter = 0; counter < seats.length / 2; counter++ ){
            //generates numbers between 6 and 10
            secondSeat = 6 + randomNumbers.nextint(5);
            seats[ secondSeat - 1 ] = true;//secondSeat - 1 to make sure the right element is selected

        }
    }
}//end of class

and this:

//ex 7.19 p 333 deitel and deitel
//SeatsTest.java
import javax.swing.JOptionPane;
public class SeatsTest{
    public static void main( String[] args ){
        Seats seatingPlan = new Seats();
        //display message
        String action = JOptionPane.showInputDialog( "Please type 1 for First Class and 2 for Economy Class." );
        //create message
        String message = String.format( "Thank you. You have chosen %s class.", action );
        //display message
        JOptionPane.showMessageDialog( null, message ); 

        assignSeats( action );

    }
}

Obviously I am not finished yet as you can see.
When assignSeats() is called I use a for loop with a counter smaller than seats.length / 2 because I need to run it only 5 times. Now say the user selects 1 for first class:
assignSeats(), because of the loop, will assign all the first class seats and then when all the seats are filled in, will ask whether the user wants to be seated in the
second class. This happens on the first (and only) call. The thing is it will effectively be only one user taking potentially all the seats in the plane, do you know what I mean? Is that what the exercise is asking?
If so, then I will continue to develop it, but I would have thought that the program should have taken inputs from different users, then store them in memory somehow.
I don't understand if this is what the exercise wants me to do, what do you think? Just one very important thing to notice though: this exercise is on chapter 7 (Arrays)
so I haven't done a great deal so far and part of me thinks that the author wants to keep the exercise as simple as possible and take input from one user rather than
multiple ones, because storing values in memory might be too advanced for students at this point of the book. ANy advice's welcome as usual.
thanks

The exercise doesn't say so explicitly, but it is clear by implication that it expects you to present the 1 or 2 option repeatedly. It certainly doesn't want you to assign many seats for each input as you are doing, because it explicitly says "assign a seat" (emphasis mine). So since it says that all seats start out empty, the only way you can fill either section is to take input many times.

The exercise doesn't say anything about assigning seats randomly. It also doesn't say that you can't, but it is making the exercise slightly harder to do it that way.

It is a serious warning sign that you felt the need to explain why you were using seats.length / 2. It means that you are aware that it is confusing in your code and therefore you should either comment it or do it differently. I suggest that you use constant fields for all of the numbers that you are given in the exercise, such as FIRST_CLASS_START, FIRST_CLASS_END, ECON_START, ECON_END. Even better, you could define an enum like

public enum Section { FIRST(1,5), ECON(6,10);
    public final int start;
    public final int end;
    private Section(int start, int end) { this.start = start; this.end = end; }
}

"Your application should never assign a seat that has already been assigned." This means that you must not choose a random seat and simply set it to true the way you do on line 25 and 26. You need to find the seats that are unassigned and only choose one of those seats. The easiest way would be to always choose the first unassigned seat, but if you want it to be random then just count the unassigned seats and go randomNumbers.nextInt(count).

Edited 3 Years Ago by bguild

thanks bguild. I don't feel confortable using enum, for some reasons I don't like them, so if I can do without I feel happier.
About the issue of one user taking all the seats, I think I could sort this out by enclosing all my code in a while loop, something that allows the program to quit when you input a specific value, something like "q" for the sake of argument, so that the options at the beginning will be: 'press 1 for 1st class, 2 for 2nd and q to quit the application' and do this all over again till the seats run out. This means I will lose the two for loops for( int counter = 0; counter < seats.length / 2; counter++ ) because I will have to assign a seat for each user therefore resolving the issue - well the confusion perhaps - with seats.length / 2.

Not entirely sure what you mean by using more constants, I thought the only one I needed was the one indicating the element of the arrays, 10. The exercise says to use only one array so I thought I will do with just seats[]. If I use FIRST and SECOND then I will have to use 2 arrays, or I think it might be more complicated.

I kind of like the idea of randomness, not sure why, it's just cool, but if it turns out to be too complicated I will abandon it.
To make sure that I don't assign seats that have been already been assigned, yes I will have to somehow check the seats before assigning another one, I haven't got to that stage yet sorry, will do it next, probably I will check what element in the array has been set to true.

I hope it all makes sense.

I will keep going and leave this thread open anyway because I have a feeling I will post again on this program

I don't feel confortable using enum, for some reasons I don't like them, so if I can do without I feel happier.

I do hope you will reconsider that. Enums were added to the language in Java 1.5 because Java needed them, and so do you. They are not difficult to use, but they do eliminate many kinds of difficult bugs, ie they make it much harder to write buggy code. Your code will be so much better if you use them, and you will be a much better coder.

Edited 3 Years Ago by JamesCherrill

ah, I see everybody likes enum : - ), unfortunately I don't know enough about the language to provide a valid argument not to use them, so if you guys say they are useful then, so it is. The thing is, if I use an enum in the exercise abovem then I won't be able to use a class I believe, and I have always thought that learning how to use classes is somehow more important. At least this is one of the things I remember from when I was doing C++
@Starstreak: yes you're right, but rest assured that my ariline booking system won't be used by anybody else other than myself! : - )

Edited 3 Years Ago by Violet_82

ehm ... you wont' be able to use a class? how exactly do you mean that?
for a simple application you could also create two arrays, one with the seats for business, and one with economic class.

ok sorry, I thought enum and classes were mutually exclusive, in that if I use an enum here I won't need to use a class, but I seem to understand that's not the case. Well, i will see how it goes and then post back. I think the exercise wants me to use only one array

also possible.
create a class seat, with two subclasses 'Economic' and 'Business'. fill the first x places with Economic seats, the others with Business.
or create a two dimensional array.

in case you do the first, you either keep track of how many business and economic seats are there, or:

Seat[] mySeats ...;

for ( Seat seat : mySeats ){
  if ( seat instanceof Economic ){

  }
  else{

  }
  }

something like that could help as well

thanks stultuske, I forgot to mention that my choice are pretty limited in that I haven't done subclasses as yet so I don't quite know how to use them as yet, and the exercise is asking to use a 1 dimensional array. I appreciate you guys want me to follow the good practice, but I have only got as far as arrays (chapeter 7 of the book), so even if there are probably many many ways to solve this exercise I don't have many options, that's another reason why I wanted to stick to classes and not enum

if you don't want to use subclasses, you can create your class Seat which contains a final instance variable isBusinessClass.
the first x/2 Seats you instantiate as: new Seat(false); // just business class
and the rest you instantiate as: new Seat(true);

thanks, I have done some more work on it, not sure if it makes sense though:

//ex 7.19 p 333 deitel and deitel
//SeatsTest.java
import javax.swing.JOptionPane;
public class SeatsTest{
    public static void main( String[] args ){
        Seats seatingPlan = new Seats();


        //display message
        String action = JOptionPane.showInputDialog( "Please type 1 for First Class and 2 for Economy Class, 0 to quit" );
        //create message            
        String message = String.format( "Thank you. You have chosen %s class.", action );
        //display message
        JOptionPane.showMessageDialog( null, message );                 
        while(action != 0){
            seatingPlan.assignSeats( action );      
            //ask for input again
            action = JOptionPane.showInputDialog( "Please type 1 for First Class and 2 for Economy Class, 0 to quit" );
            //create message            
            message = String.format( "Thank you. You have chosen %s class.", action );
            //display message
            JOptionPane.showMessageDialog( null, message );                 


        }       
    }
}

and the other file:

//ex 7.19 p 333 deitel and deitel
//Seats.java
import java.util.Random;
public class Seats{
    private int final NUMBER_OF_SEATS = 10;
    private int final PASSENGER_CLASSES = NUMBER_OF_SEATS / 2;//to get first class seats(first 5 seats of the array) and second class (last 5 seats of array)
    private boolean[] seats;
    private int firstSeat;
    private int secondSeat;
    //private boolean seatAvailable;
    Random randomNumbers = new Random();

    //constructor
    public Seats(){
        //initializing array
        seats = new boolean[ NUMBER_OF_SEATS ];
        //set values to false - doesn't it do automatically?
        for( int counter = 0; counter < seats.length; counter++ ){
            seats[ counter ] = false;
        }//end of loop      
    }//end of constructor

    public void assignSeats( int seatClass ){
        if( seatClass == 1 ){
            firstSeat = generateFirstClassSeats();
            int trueValuesCounter;//will check if all the values of the array are true
            boolean theSeat = seats[ firstSeat - 1 ];
            while(theSeat){
                trueValuesCounter++;
                firstSeat = generateFirstClassSeats();
                theSeat = seats[ firstSeat - 1 ];
                if(trueValuesCounter == PASSENGER_CLASSES)
                break;
            }                   
            seats[ firstSeat - 1 ] = true;      
        }

        else if( seatClass == 2 ){          
            secondSeat = generateSecondClassSeats();
            int trueValuesCounter;//will check if all the values of the array are true
            boolean theSeat = seats[ secondSeat - 1 ];
            while(theSeat){
                trueValuesCounter++;
                secondSeat = generateSecondClassSeats();
                theSeat = seats[ secondSeat - 1 ];
                if(trueValuesCounter == PASSENGER_CLASSES)
                break;
            }
        seats[ secondSeat - 1 ] = true; 
        }
    }//end of assignSeats

    //generate first class seats
    private int generateFirstClassSeats(){
        //generate random number between 1 and 5
        int theSeat = 1 + randomNumbers.nextInt(PASSENGER_CLASSES);
        return theSeat;
    }
    //generate second class seats
    private int generateSecondClassSeats(){
        //generates numbers between 6 and 10
        int theSeat = 6 + randomNumbers.nextint(PASSENGER_CLASSES);
        return theSeat;
    }



}//end of class

Right. in the first file I use a while look so that I keep the program running till the user enters 0 to quit the application and then call assignSeats( ) that gets things going. That's where I have problems. You see I have to make sure that I don't reassign the same seat again of course and this is what I am attempting to do in here:

public void assignSeats( int seatClass ){
        if( seatClass == 1 ){
            firstSeat = generateFirstClassSeats();
            int trueValuesCounter;//will check if all the values of the array are true
            boolean theSeat = seats[ firstSeat - 1 ];
            while(theSeat){
                trueValuesCounter++;
                firstSeat = generateFirstClassSeats();
                theSeat = seats[ firstSeat - 1 ];
                if(trueValuesCounter == PASSENGER_CLASSES)
                break;
            }                   
            seats[ firstSeat - 1 ] = true;      
        }

        else if( seatClass == 2 ){          
            secondSeat = generateSecondClassSeats();
            int trueValuesCounter;//will check if all the values of the array are true
            boolean theSeat = seats[ secondSeat - 1 ];
            while(theSeat){
                trueValuesCounter++;
                secondSeat = generateSecondClassSeats();
                theSeat = seats[ secondSeat - 1 ];
                if(trueValuesCounter == PASSENGER_CLASSES)
                break;
            }
        seats[ secondSeat - 1 ] = true; 
        }
    }//end of assignSeats

Because the exercise 'divides' the array of seats in 2 (first class and second class) I then count up to 5 like in
if(trueValuesCounter == PASSENGER_CLASSES)
and in
int theSeat = 1 + randomNumbers.nextInt(PASSENGER_CLASSES);

I just want to draw your attention on this fragment:

while(theSeat){
                trueValuesCounter++;
                firstSeat = generateFirstClassSeats();
                theSeat = seats[ firstSeat - 1 ];
                if(trueValuesCounter == PASSENGER_CLASSES)
                break;
            }                   
            seats[ firstSeat - 1 ] = true;

As said above I am trying not to assign the same seat twice. Here if a seat has been assigned already I call again generateFirstClassSeats() and get another value so that when
theSeat
becomes false I get out of the loop. When instead all the seats have been assigned
trueValuesCounter
will have a value of 5 and therefore I will come out of the loop anyway. Problem is that when all the seats are assigned this
seats[ firstSeat - 1 ] = true;
will effectively reassign the seat again, and that shouldn't happen but I can't find a way around this. I spent the whole evening trying to rearrange the code but I can't find a solution to that. What do you guys think?

About your solutions stultuske would isBusinessClass replace the array altogether?
thanks

Ignore ideas that don't use a boolean[] because they are contrary to the instructions of your exercise. What your exercise is trying to teach you is how to break up a problem into appropriately small and meaningful subroutines. When you fill your toolbox with private methods that do useful things, you'll find this problem gets easier.

First, save yourself from having to write things twice and pass in which section of seats you are working with as an argument. Instead of generateFirstClassSeats() and generateSecondClassSeats(), notice what happens if you have generateSeats(seatClass). Not only have you saved yourself from writing two almost identical methods when one would have done, but assignSeats would be enormously simplified. This is the sort of simplification that makes the whole problem easier.

I wonder why all these "seats" are plural when each method is doing only one seat. Plural usually means more than one, and you should be learning to choose your method names well when you do these exercises. It is one of the most important things you can do to make your code easy to read.

Your array numbers the seats from 0 to NUMBER_OF_SEATS - 1. I think you should also do that, to save yourself from having to repeatedly subtract 1. It's easier to add one to the seat number when you report to the user. You don't really want to complicate your code by converting back and forth between two different numbering systems.

You should be designing with future changes in mind. Real software often needs to be modified and it is very important to predict what those modifications will look like so you can prepare for them in advance. On the contrary, you seem to have assumed that the first class and economy sections will always be the same size. Even worse, you provide a NUMBER_OF_SEATS constant that someone might naively modify thinking they found an easy way to make your software work for a different size of plane, but instead they would have broken your software because the economy section would still start at seat 6.

For your toolbox, I recommend that you write a method that takes two seat numbers and returns a count of the number of available seats between the given seats. You can also write a method that takes two seat numbers and returns one of the available seats between the given seats, or throws an exception if there is no available seat. Both of those methods are much simpler than the full exercise, but once you have those tools you will be able to complete the exercise much more easily by using them.

bguild, thanks. I think I will have to spend sometime on this program by the look of it:-)!
I am working to simplify the code as per your suggestion. I have a few questions:

-Even worse, you provide a NUMBER_OF_SEATS constant that someone

I appreciate this, but somehow I have to set the size of the array, and if not like a constant I am not sure how to do it. The seat capacity needs to be specified by the program and not entered by the user, so not sure how I would set it without using a constant? I can't use the array lenght because the array hasn't been declared yet

Instead of generateFirstClassSeats() and generateSecondClassSeats(), notice what happens if you have generateSeats(seatClass)

Point taken. I am in the process of making changes: To assign seats something like this:

public void assignSeats( int seatClass ){       
        firstSeat = generateClassSeats(seatClass);
        //checkSeat();
        theSeat = seats[ firstSeat ];
        //determine 1st or 2nd class
        if( firstSeat <= seats[ seats.lenght-1 ] / 2 ){
        ...

I haven't finished the assignSeats method yet but this gives you an idea I suppose. the condition of the if statement makes sure that whatever the lenght of the array, I can always safely divide it in 2 and obtain half seats for first class and half for the second class. What do you think?

To generate seats, as you have mentioned:

//generate  class seats
    private int generateClassSeats(int classType){
        //generate random number between 0 and 9 if the maximum number of seats is 10
        int theSeat = randomNumbers.nextInt(NUMBER_OF_SEATS);
        return theSeat;
    }

which is, indeeed, simpler. I am still using the constant in here but I don't need to subtract 1 anymore, I will add 1 when necessary in the output.

I will continue working along this line then and try to use only 1 assignSeats() rather than 2. I will post the result or ( more likely) more questions.

thanks

I have to set the size of the array, and if not like a constant I am not sure how to do it. The seat capacity needs to be specified by the program and not entered by the user, so not sure how I would set it without using a constant?

My point wasn't that you should avoid using a constant; that's wrong. Use constants for all of your important numbers. My point was that you should make your program so it won't break if the values of your constants change. Imagine that someone wants to use your program for a plane with 11 seats instead of 10 seats. The point of having a NUMBER_OF_SEATS constant is lost if it can't be changed. This means that you should also have constants that define which seats are first class and which seats are economy. Those constants should be right next to the NUMBER_OF_SEATS field and there should be a comment saying that if you change one you have to change the others to match.

I see what you mean now. I am thinking though I might not need constants for first class seats and second class seats because I can determine them with seats[ seats.lenght-1 ] / 2 if I need to.

Now, I have made some changes following your feedback, but I have a few problems:

//ex 7.19 p 333 deitel and deitel
//SeatsTest.java
import javax.swing.JOptionPane;
public class SeatsTest{
    public static void main( String[] args ){
        Seats seatingPlan = new Seats();


        //display message
        String action = JOptionPane.showInputDialog( "Please type 1 for First Class and 2 for Economy Class, 0 to quit" );
        //create message            
        String message = String.format( "Thank you. You have chosen %s class.", action );
        //display message
        JOptionPane.showMessageDialog( null, message );                 
        while(action != 0){         
            seatingPlan.assignFirstSeats( action );                     
            //ask for input again
            action = JOptionPane.showInputDialog( "More seats? Please type 1 for First Class and 2 for Economy Class, 0 to quit" );
            //create message            
            message = String.format( "Thank you. You have chosen %s class.", action );
            //display message
            JOptionPane.showMessageDialog( null, message );         
        }
            System.out.print("You are exiting the application. Thank you.\n");
    }
}

Here I have removed completely the code determining whether the user's input is 1 or 2, I will take care of it somewhere else. As long as it is not 0 then we are fine.

The second file is this:

//ex 7.19 p 333 deitel and deitel
//Seats.java
import java.util.Random;
public class Seats{
    private int final NUMBER_OF_SEATS = 10; 
    private boolean[] seats;
    private int firstSeat;
    private int secondSeat;
    //private boolean seatAvailable;
    Random randomNumbers = new Random();

    //constructor
    public Seats(){
        //initializing array
        seats = new boolean[ NUMBER_OF_SEATS ];
        //set values to false - doesn't it do automatically?
        for( int counter = 0; counter < seats.length; counter++ ){
            seats[ counter ] = false;
        }//end of loop      
    }//end of constructor

    public void assignSeats( int seatClass ){       
        firstSeat = generateClassSeats();

        //check that I don't reassign the seat
        checkSeat( firstSeat );

        //assign the seat
        seats[ firstSeat ] = true;

        //theSeat = seats[ firstSeat ];
            //determine 1st or 2nd class
            if( seatClass == 1 ){
                    System.out.printf("Your seat number is %d and it is in first class", firstSeat + 1 );
            }
            else if( seatClass == 2 ){
                System.out.printf("Your seat number is %d and it is in second class", firstSeat + 1 );
            }

    }//end of assignFirstSeats

    //generate  class seats
    private int generateClassSeats(){
        //generate random number between 0 and 9 if the maximum number of seats is 10
        int theSeat = randomNumbers.nextInt(NUMBER_OF_SEATS);
        return theSeat;
    }



    private void checkSeat(int seatNumber){     
        boolean theSeat = seats[ seatNumber ];
        while(theSeat){
            seatNumber = generateFirstClassSeats();
            theSeat = seats[ seatNumber ];
        }
        return seatNumber;
    }

}//end of class

Ok here I have a few problems:
1)I have simplified assignSeats(): when I enter it I call generateClassSeats() straight away and generate a seat. Then I check the seat with checkSeat( firstSeat ); and I have a problem there because when the seats are all full this loop runs forever. Is there a better way to check seats than this? I was thinking to perhaps create another array (of int) that contains the seats and use that to determine whether a seat has been already assigned. What do you reckon? I think that the seat check (whether it has come out or not) and whether the first/second class is full should be done in the same function?
thanks

As per the assignment, if a seat is already allocated, then it is set to true, so the check surely must simply see if a seat has this value. I guess with your random assignment it might take a few attemps.

What is the intended purpose of checkSeat? I see at one point you try to return a value from it, but everywhere else you seem to think it has no return value. "Check that I don't reassign the seat" doesn't really describe what it does very well. How exactly do you plan to have it prevent you from reassigning the seat? Once assignSeats is finished running checkSeat, it goes ahead and assigns the seat no matter what checkSeat did.

The only hope that checkSeat could have to prevent assigning an already assigned seat would be to prevent assignSeats from continuing, and that can only be done by either going into an infinite loop or else throwing an exception, and neither one of those things is a good idea.

Your generateClassSeats generates a number between 0 and 9, but what purpose does that serve? According to your project you always need to choose a seat in one section or the other one depending on the user's choice. Choosing a random seat from the entire plane doesn't help; that is like choosing the section randomly.

bguild, thanks for getting back to me. I have made some changes that seems to address the above issues.
I post the whole file because it is easier to see the changes since there are quite a few:

//ex 7.19 p 333 deitel and deitel
//Seats.java
import java.util.Random;
public class Seats{
    private int final NUMBER_OF_SEATS = 10; 
    private boolean[] seats;
    private int firstSeat;
    private int secondSeat;
    private int firstClassCounter;//counter for first class
    private int secondClassCounter//counter for second class
    Random randomNumbers = new Random();

    //constructor
    public Seats(){
        //initializing array
        seats = new boolean[ NUMBER_OF_SEATS ];
        //set values to false - doesn't it do automatically?
        for( int counter = 0; counter < seats.length; counter++ ){
            seats[ counter ] = false;
        }//end of loop      
    }//end of constructor

    public void assignSeats( int seatClass ){       
        firstSeat = generateClassSeats( seatClass );//pass the user choice

        //check that I don't reassign the seat
        if((firstClassCounter <= seats.lenght / 2) || (secondClassCounter <= seats.lenght / 2)){  
            firstSeat = checkSeat( firstSeat );
            //assign the seat
            seats[ firstSeat ] = true;

        }


        //check the status of first and second class seats
        if (firstSeat < seats[ seats.lenght-1 ] / 2){//if firstSeat < 4
            firstClassCounter++;//increase first class counter
        }
        else if(firstSeat > seats[ seats.lenght-1 ] / 2){//if firstSeat > 4
            secondClassCounter++;//increase second class counter
        }

        //theSeat = seats[ firstSeat ];
            //determine 1st or 2nd class
            if( seatClass == 1 ){
                    System.out.printf("Your seat number is %d and it is in first class", firstSeat + 1 );
            }
            else if( seatClass == 2 ){
                System.out.printf("Your seat number is %d and it is in second class", firstSeat + 1 );
            }

    }//end of assignFirstSeats

    //generate  class seats
    private int generateClassSeats( int userChoice ){
        //generate random number between 0 and 9 if the maximum number of seats is 10
        if( userChoice == 1 ){
            int theSeat = randomNumbers.nextInt( ( seats.length - 1 ) / 2 );//half of the size of the array, hence first class
        }
        else if( userChoice == 2 ){
            int theSeat = 1 + randomNumbers.nextInt( NUMBER_OF_SEATS - 1 / 2 );//second half of the size of the array, hence second class
        }

        return theSeat;
    }

    private int checkSeat(int seatNumber){//if seat already assigned, find the next available one

        boolean theSeat = seats[ seatNumber ];
        while(theSeat){
            seatNumber = generateFirstClassSeats();
            theSeat = seats[ seatNumber ];
        }
        return seatNumber;
    }


    }

}//end of class

in assignSeats() I have 2 counters now firstClassCounter and secondClassCounter: when they are both less than 5 (in case of 10 seats plane) method checkSeat() is called firstSeat = checkSeat( firstSeat ); and will make sure that if the seat chosen has already been assigned, another
one is generated by calling again generateFirstClassSeats() and returns the new seat back to the caller.

Then the appropriate counter is incremented and when these 2 conditions if (firstSeat < seats[ seats.lenght-1 ] / 2) and else if(firstSeat > seats[ seats.lenght-1 ] / 2)
become false heckSeat() doestn't run so no infinite loop : -)!

Your generateClassSeats generates a number between 0 and 9, but what purpose does that serve?

Gosh I have no idea what possessed me to do that, apologies, I have amended it to generate the correct numbers as you can see from above using if statements.

Finally, the constants: on a general note, I think in this code even if you modify the constant, it should work because it divides the seats in two halves (if the constant is odd precisely 2 halves if it is odd then you have more first class seats than second class). You have mentioned previously that it would be a good idea to have 2 extra constants, one for first class seats and another one for the second class. In view of the amendments, do you think it is still necessary? I thought about those 2 constants quite a bit, and I am not sure how to declare them, or rather, I am not too sure what values to assign to them. An hypothetical FIRST_CLASS_SEATS should probable have value of 5 - assuming a plane of 10 seats - but then, it has to be changed all the time the number of seats change, so it doesn't seem that feasible. The SECOND_CLASS_SEATS instead - still assuming a plane of 10 seats - which value should it have?

Let me know if the code is better now, I will start coding the last bit now, which is, if the first class is full, give the user the possibility to
get a seat in second class and vice versa
thanks for your help

An hypothetical FIRST_CLASS_SEATS should probable have value of 5 - assuming a plane of 10 seats - but then, it has to be changed all the time the number of seats change, so it doesn't seem that feasible.

It is always a good idea to imagine how requirements are likely to change in the future. That is usually hard to do, but sometimes it is easy. Imagine that someone finds your project and wants to use it for an airplane that isn't the airplane described in your book. If your project is done well, that should be the least that it is ready for, but you're not aiming to be ready for that because you're making the strange assumption that half the seats on the airplane will be first class and half of them will be economy. That happens to be true for your exercise, but surely you don't think it is true of planes in general. It is just a coincidence, but I already count five places in your code where you depend on it being always true.

You are correct that FIRST_CLASS_SEATS would probably need to change whenever the number of seats on the plane changes, but if you have no way of changing the number of first class seats then there is no chance that you'll ever need to change the number of seats. You'll never find another plane that is exactly half first class and half economy, so your software will be useless for all other planes.

Your seats array is a boolean[]. You shouldn't be dividing its elements by 2; division is only for numbers.

I think you should stop doing things twice. It seems like you do everying once for first class and then you do it again for economy, but there is no need for that because the only difference between first class and economy is where the seats are on the plane. If you write a methods sectionStart(int seatClass) and sectionEnd(int seatClass), then those methods can be the only place you ever need to worry about which section you are dealing with. Using those methods you can check if there are any seats available in your section, you can choose a seat in your section, and you can search for the first unassigned seat in your section, all without knowing or caring whether your section is first class or economy.

For example:

int available = 0;
for(int i = sectionStart(seatClass); i <= sectionEnd(seatClass); i++)
    if(seats[i]) available++;

Your checkSeat is not good. You are repeatedly choosing a random seat until you find one that is available, but when the plane fills up and only one seat is left available checkSeat could end up looping for a very long time. If generateFirstClassSeats were using a real random number generator instead of a pseudorandom number generator, then checkSeat might actually run forever. There are far better strategies available for solving your problem.

thanks bguild, I appreciate that planning for future is good, to be honest it didn't really crossed
my mind when I started the exercise, because this forward-thinking wasn't required by the exercise.

Your seats array is a boolean[]. You shouldn't be dividing its elements by 2; division is only for numbers

This is not correct, I am not diving the elements of the array by tow, but the lenght of the array which is an integer

Ok, so let's try to then put things in order here.
Constants: we want 3 constants:

private int NUMBER_OF_SEATS = 10; I think you said it isn't a good idea to have it as final
private int FIRST_CLASS_SEATS = 5;
private int SECOND_CLASS_SEATS = ?; what should be the value of this constant then?

I think you should stop doing things twice.

Ok so you propose only 2 methods methods sectionStart(int seatClass)and sectionEnd(int seatClass),that do everything (check if there are seats available, choose a seat in the relevant section and check for the unassignedseat in that specific section). These 2 methods will effectively replace checkSeat() and quite a bit of the code in assignSeats() - I suppose I will need to keep
generateClassSeats() because it seems to be doing its job ok although I will need to modify it slightly when I add the constants

Your checkSeat is not good. There are far better strategies available for solving your problem.

What would be a better way to do this?
thanks

private int NUMBER_OF_SEATS = 10; I think you said it isn't a good idea to have it as final
private int FIRST_CLASS_SEATS = 5;
private int SECOND_CLASS_SEATS = ?; what should be the value of this constant then?

for your current code, there is no problem with putting them as final.
and for that other question:
the total amount of seats = 10 ... 5 are first_class, well, second_class, that's the remaining number.
10 - 5

I just assume that he means: what if in a next application, you need to be able to have planes with different amount of seats?

in that case, you'll need to create a class Plane with (at least) two instance members:
1. int nrOfFirstClassSeats;
2. int nrOfSecondClassSeats;

but I doubt you'll need to go that far.

Ok so you propose only 2 methods methods sectionStart(int seatClass) and sectionEnd(int seatClass), that do everything

That is not even close to what I meant. The beauty of those methods it that they do almost nothing, making them very easy to write, but at the same time they have such power that using them would make your entire project much easier to finish and much easier to modify in the future.

All that sectionStart is supposed to do is return the array index of the first seat of the section, and all sectionEnd is supposed to do is return the index of the last seat of the section. Using them, you can stop worrying about whether you are working with first class or economy, and most of all you can stop writing things twice, once for first class and once for economy. Instead of dividing the length of the array by 2 or any other tricky technique to find the end of the section, you just call sectionEnd(seatClass). Calling that method doesn't actually do anything for you, but having that number so easily will make everything else easier.

And in the future if you ever wanted to change the sections, like putting first class in the back of the plane or making it tiny, the only things you would need to modify would be the two small methods that don't do anything complicated: sectionStart and sectionEnd.

And in the future if you ever wanted to change the sections, like putting first class in the back of the plane or making it tiny, the only things you would need to modify would be the two small methods that don't do anything complicated: sectionStart and sectionEnd.

why? the physical location of those seats on the plane are irrelevant to the code. the only thing that matters is the number of seats, which are easiest kept in either instance variables, or, for the application at hand, where there is no use of different planes or instances of them, in (what may just as well be) final variables.

the physical location of those seats on the plane are irrelevant to the code.

The physical location of seats matters to the code just enough to allow the code to display a boarding pass. That's part of the requirements. Also, the exercise instructions demand that the seats of the plane be represented by an array, so the location of the seats in that array is relevant to the code.

Edited 3 Years Ago by bguild

no, it doesn't.

Your application should display the following alternatives: 'Please type 1 for First class and please type 2 for economy'. If the user types 1, your application
should assign a seat in the first class section (seats 1-5), if he types 2 in the economy section ( seats 6-10). Your application should then display
a boarding pass indicating the person's seat number and whether it's in the first-class or economy.

nowhere in this text is anything said about the physical layout of the plane, it just states: there are 10 seats, 5 economical, 5 business. the locations 1-5 and 6-10 are just the location (and yes, location, not index) of the seat in the array.

guess the simplest way would be: want to enter a seat:

set x to 1
set y to 5
if ( seat = economy ) x += 5 and y += 5

from arrayIndex x-1 till y-1
if ( element = false ) set to true.

ok chaps, I appreciate you have diverging opinions and I can't really butt in because I know only very little. SO why don' we start just from scratch again? I think I have made a very big mistake at the beginning, which is not producing any pseudo code but start the development straight away.
So here's some pseudocode, maybe that will help me. Once I get that right I suppose it shouldn't be too bad to build the program. Needless to say my pseudocode has some issues, as in I am doing a few things twice. I know bguild doestn' like that so perhaps you guys can help me with the pseudocode first and then I can move on to build the application?

Please type 1 or 2 to choose the class, 0 to quit
    if 1
        generate seat at random from values smaller than the last index of the last seat of the section (10-5 = 5 so index 4)
    else if 2
        generate seat at random from values bigger than index4 of the array and smaller than the last index of the last seat of the section array.length - 1 

    check whether seat has been already assigned
    if so generate seat again till you find a seat that hasn't been assigned to
    if not assign the seat and display boarding pass

    if first class has no seats and second has
        ask user if he/she wants to have a seat in the second class
        if no, display "teh next plane leaves in 3 hrs"
        else if yes 
            generate seat in the second clas
            check the seat hasn't been assigned yet
            assign the seat
            print the boarding pass

    else if second class has no seats and first has
        ask user if he/she wants to have a seat in the second class
        if no, display "teh next plane leaves in 3 hrs"
        else if yes 
            generate seat in the second clas
            check the seat hasn't been assigned yet
            assign the seat
            print the boarding pass

Edited 3 Years Ago by Violet_82

why are you generating seats - at random - ?
that'll cost at efficiƫncy of your code, since you can't 100% avoid a random generator to generate the same result over and over (sure, unlikely, but still)

actually, you are not supposed to generate seats. the seats are there, they're a basic part of your code.

that boolean array with seats? that's not where you will add seats, those are your actual seats. you're already starting with a pseudo code that is more difficult than you should have:

Please type 1 or 2 to choose the class, 0 to quit
set takenFlag -> 0 // default
    if 1
        set takenFlag -> 1
        select the first available seat in economic class, and assign it.
        if assignment worked -> set takenFlag -> 2 // if assignment worked, basically, there is a seat left
    else if 2
        set takenFlag -> 3
        select the first available seat in business class, and assign it
        if assigning worked -> set takenFlag -> 4
    end-if

if takenFlag = 2 OR takenFlag = 4
   display boarding pass
else if takenFlag = 2
  // this means, you asked economic, but wasn't any left
  ask: do you want to upgrade y/n
    if answer = y
      select the first available seat in business class, and assign it
      if assigning fails
        print "Sorry, no seats available in business class"
       else
        display boarding pass
       end-if
    else
      display "the next plane leaves in 3 hrs"
    end-if
else if takenFlag = 3 // you asked business, but no more space
  ask: do you want to downgrade y/n
     if answer = y
       select the first available seat in economic class and assign it
       if assigning fails
         display "sorry, no more seats available"
       else
         display boarding pass
       end-if
     else
       display "the next plane leaves in 3 hrs"
     end-if
end-if

just a bit of an idea of what you can do, and as you've probably noticed, it wouldn't be very hard to re-use parts of that code for both tasks.

why are you generating seats - at random - ?

well becasue the exercise doesn's say not to, and having done random numbers recently I thought it would be a good idea to do that. I thought about efficiency to be honest, and I didn't think it was such a big deal for such a small program. And also, I couldnt' think of another way to assign seats. That said, happy not to use random number generators if you think isn't necessary.

Now, to go back at your pseudocode, got a couple of questions:
1)not entirely sure what takenFlag does, what is that flagging? you set takenFlag = 0, then takenFlag=1 all the way up to 4

2)if I don't assign seats with a random number generator, how do I actually do it?

3) not quite clear with this:

if takenFlag = 2 OR takenFlag = 4
   display boarding pass
else if takenFlag = 2
  // this means, you asked economic, but wasn't any left

if the flag is equal to 2 means that you have assigned a seat in economic class, but then you say that if takenFlag =2 there are no seats in economic?
Same story when takenFlag is equal to 3: that variable is set to 3 just after the user has chosen 2nd class so how do I relate that to the fact that there are no seats available in second class?
thanks

going for random numbers is overhead. next to your array with seats, you would (for each time you assign a seat) also keep track of all the possible seats you checked whether they are available or not.

basically, your setup for your plane is:

boolean[] seats = new boolean[10];

so, you write a assignSeat() function, which takes 1 int as parameter:
1 -> economical
2 -> business

public boolean assignSeat(int type){ // the boolean you return just let's you know whether you succeeded or not
int firstI = 0;  // firstIndex
int lastI = 4;
  if ( type == 2 ){
    firstI += 5;
    lastI += 5;
  }  
  for ( int i = firstI; i <= lastI; i++ ){
    if ( !seats[i] ){ // the element = false? this seat hasn't been assigned yet, assign it
      seats[i] = true;
      return true; // let the user know assigning a seat succeeded
    }
  }
  // if the method reaches this point, it means no seats were still available,
  return false;
}

and that little piece of code is a very huge part of your code.
you could also return the index to which you assign the place, and -1 if assigning failed, that way, you could use that index for the display of the boarding pass.

This question has already been answered. Start a new discussion instead.