Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

program works when stepping through but doesn't when running

Tags:

java

I'm writing a program that displays flight information as seen bellow:

package d.airlineData.engine;

import java.time.Duration;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;

import a.airlineData.exceptions.NoFlightsException;
import c.airlineData.exceptions.NoAirportException;
import d.airlineData.graph.Airport;
import d.airlineData.graph.Flight;
import d.airlineData.graph.FlightGraph;

public class FlightGrapher {

    private FlightGraph fg;

    public FlightGrapher() throws NoFlightsException {      
        throw new NoFlightsException();
    }

    public FlightGrapher(ArrayList<Flight> flights) throws NoFlightsException  {
        fg = new FlightGraph();

        for(Flight flight: flights) {
            fg.addAirport(flight.getAirportA());
            fg.addAirport(flight.getAirportB());

            try {
                fg.addFlight(flight);
            } catch (NoAirportException e) {
                System.err.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public void printAll() {
        HashSet<Airport> airports = fg.getAirports();

        for(Airport airport : airports) {
            System.out.println(airport + ":");
            try {
                Iterator<Flight> it = fg.getFlightsFor(airport);
                while(it.hasNext()) {
                    System.out.println("\t" + it.next());
                    System.out.println();
                }

            } catch (NoAirportException e) {
                System.err.println(e.getMessage() + " while attempting to get flights for " + airport);
                e.printStackTrace();
            }
        }

    }
        public void printItinerary(Airport airportA, Airport airportB) {
    System.out.println("Leg\tLeave\t\tAt\tOn\tArrive\tAt");
    printItinerary(airportA,airportB, 1, 0.0, Duration.ofHours(0));
}

private void printItinerary(Airport airportA, Airport airportB, int leg, double totalPrice, Duration totalDuration) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    System.err.println("Enters method printItinerary");
    System.err.println("airportA "  + airportA);
    System.err.println("airportB "  + airportB);
    System.err.println("leg " + leg);
    System.err.println("total price " + totalPrice);
    System.err.println("Duration " + totalDuration.toMinutes() + "mins");
    System.err.println();
    while(aFlights.hasNext()) {

        Flight currentFlight = aFlights.next();
        System.err.println("Enters while of printItinerary currentFlight: ");
        System.err.println(currentFlight);
        if(currentFlight.getAirportB().equals(airportB)) {

            System.out.println(leg + "\t" +
                    currentFlight.getAirportA() + "\t" +
                    currentFlight.getDepartureTime() + "\t" +
                    currentFlight.getFlightNumber() + "\t" +
                    currentFlight.getAirportB() + "\t" +
                    currentFlight.getArrivalTime());

            System.out.println();
            System.out.println("Total journey costs\t= £" + (currentFlight.getPrice() + totalPrice));
            System.out.println("Total time in air\t= " + (currentFlight.getFlightDuration().plus(totalDuration)));

            return;

        }else {
            System.err.println("enters else " + "currentFlight " + currentFlight.getAirportB() + " airport B " + airportB );
            System.err.println();
            if(hasAPath(currentFlight.getAirportB(), airportB)) {
                System.out.println(leg + "\t" +
                        currentFlight.getAirportA() + "\t" +
                        currentFlight.getDepartureTime() + "\t" +
                        currentFlight.getFlightNumber() + "\t" +
                        currentFlight.getAirportB() + "\t" +
                        currentFlight.getArrivalTime());

                printItinerary(currentFlight.getAirportB(), airportB, leg + 1, 
                        (currentFlight.getPrice() + totalPrice), 
                        (currentFlight.getFlightDuration().plus(totalDuration)));   
            }
        }
    }       
}

private boolean hasAPath(Airport airportA, Airport airportB) {
    System.err.println("Enters hasAPath with airportA " + airportA + " airportB " + airportB);
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        System.err.println("Enters while of hasAPath currentFlight: ");
        System.err.println(currentFlight);
        if(currentFlight.getAirportB().equals(airportB)) {  
            System.err.println("returns true for airportA " + airportA + " airportB " + airportB );
            return true;            
        }else {
            System.err.println("Calls hasAPath with airportA " + currentFlight.getAirportB() + " airportB " + airportB);
            return hasAPath(currentFlight.getAirportB(), airportB);
        }

    }
    System.err.println("returns false for airportA " + airportA + " airportB " + airportB );
    return false;
}

    public static void main(String[] args) {
        ArrayList<Flight> flights = new ArrayList<>();
        HashMap<String, Airport> airports = new HashMap<>();

        airports.put("Edinburgh", new Airport("Edinburgh")); 
        airports.put("Heathrow", new Airport("Heathrow")); 
        airports.put("Amsterdam", new Airport("Amsterdam")); 
        airports.put("Boston", new Airport("Boston")); 
        airports.put("Montreal", new Airport("Montreal")); 
        airports.put("Chicago", new Airport("Chicago")); 
        airports.put("Toronto", new Airport("Toronto")); 
        airports.put("New Delhi", new Airport("New Delhi")); 
        airports.put("Shanghai", new Airport("Shanghai")); 
        airports.put("Hong Kong", new Airport("Hong Kong")); 

        flights.add(new Flight(airports.get("Edinburgh"),airports.get("Heathrow"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 110.0));

        flights.add(new Flight(airports.get("Heathrow"),airports.get("Amsterdam"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 100.0));

        flights.add(new Flight(airports.get("Heathrow"),airports.get("Boston"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 230.0));

        flights.add(new Flight(airports.get("Boston"),airports.get("Chicago"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 150.0));

        flights.add(new Flight(airports.get("Boston"),airports.get("Montreal"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 100.0));

        flights.add(new Flight(airports.get("Montreal"),airports.get("Toronto"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 90.0));

        flights.add(new Flight(airports.get("Edinburgh"),airports.get("Chicago"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 560.0));

        flights.add(new Flight(airports.get("New Delhi"),airports.get("Shanghai"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 430.0));

        flights.add(new Flight(airports.get("Shanghai"),airports.get("Hong Kong"),
                "B7982",LocalTime.of(22,10),LocalTime.of(23,15), 230.0));


        Iterator<Entry<String,Airport>> airportIt = airports.entrySet().iterator();

        while(airportIt.hasNext()) {
            Entry<String, Airport> pair = airportIt.next();
            Airport airport = pair.getValue();
            for(Flight flight: flights) {
                if(flight.getAirportA().equals(airport)) {
                    airport.addOutgoingFlight(flight);
                }
            }
        }

        try {
            FlightGrapher fg = new FlightGrapher(flights);
            //fg.printAll();
            fg.printItinerary(airports.get("Edinburgh"), airports.get("Toronto")); // steps into this method
        } catch (NoFlightsException e) {
            System.err.println(e.getMessage() + " when trying to make a flight between a nonexistant airport");
            e.printStackTrace();
        }

    }

}

The problem I have is when using the method:

printItinerary(Airport airportA, Airport airportB, int leg, double totalPrice, Duration totalDuration)

It doesn't execute for some reason when normally running, but when I step though the program using the debugger everything executes fine and I get a meaningful output (not very well formatted, but something I can work with), why is this happening?

The output should look like this :

Leg    Leave      At    On    Arrive    At
1      Edinburgh  10:30 BA345 Heathrow  11:30
2      Heathrow   14:00 BA657 Boston    15:30
3      Boston     18:00 AA652 Montreal  19:30
4      Montreal   22:00 AA216 Toronto   23:30

Total Journey Cost = £530
Total Time in the Air = 4 hrs 20 min

I get this when I just run it normally:

Leg    Leave      At    On    Arrive    At

and this when I step though (or run on debug):

Leg     Leave           At      On      Arrive      At
1       Edinburgh       22:10   B7982   Heathrow          23:15
2       Heathrow        22:10   B7982   Boston      23:15
3       Boston  22:10   B7982   Montreal            23:15
4       Montreal        22:10   B7982   Toronto     23:15

Total journey costs = £530.0
Total time in air   = PT4H20M

the stepping though part is what I want to be outputted (I'll work on the formatting later)

eddit: I've added a bunch of outputs on the error stream and here is the output when I run it... for some reason it stops in the "hasAPath" method:

Leg Leave       At  On  Arrive  At
Enters method printItinerary
airportA Edinburgh
airportB Toronto
leg 1
total price 0.0
Duration 0mins

Enters while of printItinerary currentFlight: 
Flight between Edinburgh & Chicago:
        For: £560.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
enters else currentFlight Chicago airport B Toronto

Enters hasAPath with airportA Chicago airportB Toronto
returns false for airportA Chicago airportB Toronto
Enters while of printItinerary currentFlight: 
Flight between Edinburgh & Heathrow:
        For: £110.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
enters else currentFlight Heathrow airport B Toronto

Enters hasAPath with airportA Heathrow airportB Toronto
Enters while of hasAPath currentFlight: 
Flight between Heathrow & Amsterdam:
        For: £100.0
        Flight Number: B7982
        Leaves at: 22:10
        Arrives at: 23:15
        Duration: 1hr 5min
Calls hasAPath with airportA Amsterdam airportB Toronto
Enters hasAPath with airportA Amsterdam airportB Toronto
returns false for airportA Amsterdam airportB Toronto

at this point it should return out and then check hasAPath for the next flight which would be Boston and Toronto, which would then check all Bostons outgoign flights to see if their airports have a connection with toronto... and so on

like image 601
James Avatar asked Nov 09 '22 01:11

James


1 Answers

Problem solved. The answer was that when you run in debug it runs though all of the possibilities even if you return the answer, this is why it evaluated to true and worked, I changed the has a path method from this :

private boolean hasAPath(Airport airportA, Airport airportB) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        if(currentFlight.getAirportB().equals(airportB)) {         
            return true;            
        }else {             
            return hasAPath(currentFlight.getAirportB(), airportB);
        }

    }

    return false;
}

To this:

private boolean hasAPath(Airport airportA, Airport airportB) {
    Iterator<Flight> aFlights = airportA.getOutgoingFlights();
    while(aFlights.hasNext()) {
        Flight currentFlight = aFlights.next();
        if(currentFlight.getAirportB().equals(airportB)) {              
            return true;            
        }else {
            if(hasAPath(currentFlight.getAirportB(), airportB)) {
                return true;
            }else {
                continue;
            }
        }

    }
    return false;
} 

If anyone else is looking this problem then I suggest placing outputs to the console at each block of your code and following through what is happening, the execution model in debug mode must be different from that in normal running.

like image 80
James Avatar answered Nov 15 '22 06:11

James