コード例 #1
0
    def test_getters_and_setters(self):
        tg_simple = graph.graph(self.simple_dict)
        simple_with_new_element = self.simple_dict.copy()
        simple_with_new_element['C'] = {}
        simple_with_new_element['C']['D'] = 5
        tg_simple.put_edge('C', 'D', 5)
        self.assertEqual(tg_simple.graph_please(), simple_with_new_element,
                         'Put edge works properly')

        self.assertEqual(tg_simple.get_edge('A', 'B'), 2, 'get_edge() works')

        self.assertTrue(tg_simple.edge_exists('A', 'C'))
        self.assertFalse(tg_simple.edge_exists('not', 'exist'))

        self.assertEqual(tg_simple.distance(['A', 'B', 'C']), 4,
                         'Distance calculated on a route works')
        self.assertEqual(tg_simple.distance(['A', 'A', 'A']), 0,
                         'Distance on a route taht does not exist is 0')

        #####
        # input errors
        #####

        tg_input_errors = graph.graph(self.medium_dict)
        tg_input_errors.put_edge('A', 'D', 'F')
        tg_input_errors.put_edge('A', 222, 4)
        tg_input_errors.put_edge(None, 'D', 5)
        self.assertEqual(
            tg_simple.graph_please(), simple_with_new_element,
            '3 inserts of bizarre inputs are ignored. Errors are not thrown ')

        self.assertIsNone(tg_simple.get_edge('not', 'exist'),
                          'get_edge() works on bad input')
コード例 #2
0
    def test_constructors(self):
        tg_empty = graph.graph()
        self.assertEqual(tg_empty.graph_please(), self.empty_dict,
                         'Constructor with no params gives empty graph')
        tg = graph.graph(self.simple_dict)
        self.assertEqual(
            tg.graph_please(), self.simple_dict,
            'Constructor with dictionary gives dictionary as the graph')

        # Input Errors
        tg_with_list = graph.graph(self.empty_list)
        self.assertEqual(tg_with_list.graph_please(), self.empty_dict,
                         'Constructor with list gives empty graph')
        tg_with_string = graph.graph('string here')
        self.assertEqual(tg_with_string.graph_please(), self.empty_dict,
                         'Constructor with string  gives empty graph')
        bizarre_dictionary = {'A': 4, 'B': {'C': '4', 'D': 4}}
        only_valid_values_from_bizarre = {'A': {}, 'B': {'D': 4}}
        tg_bizarre = graph.graph(bizarre_dictionary)
        self.assertEqual(
            tg_bizarre.graph_please(), only_valid_values_from_bizarre,
            'Constructor with invalid values in the dictionary ignores bad input'
        )
コード例 #3
0
    def test_list_methods(self):
        tg = graph.graph(self.large_dict)
        expected_list = ['A', 'C']
        self.assertCountEqual(tg.neighbours_going_out_list('D'), expected_list,
                              'neighbours list finds neighbours of D')
        self.assertCountEqual(tg.neighbours_going_out_list('L'),
                              self.empty_list,
                              'neighbours list finds neighbours of L - none')

        #####
        # input errors
        #####

        self.assertEqual(tg.neighbours_going_out_list('Z'), self.empty_list,
                         'neighbours_going_out_list() on node that !exist')
コード例 #4
0
    def test_graph_methods(self):
        tg = graph.graph(self.simple_dict)
        expected_graph = {'B': {'C': 2}}
        self.assertEqual(
            tg.graph_with_node_removed('A').graph_please(), expected_graph,
            'Node removal works 1 of 2')

        tg = graph.graph(self.large_dict)
        expected_graph = {
            'C': {
                'H': 45,
                'D': 5
            },
            'B': {
                'C': 3,
                'D': 6
            },
            'E': {
                'B': 3,
                'F': 3
            },
            'D': {
                'C': 3
            },
            'G': {
                'H': 14
            },
            'F': {
                'E': 2,
                'D': 7,
                'G': 2
            },
            'I': {
                'H': 2,
                'J': 2
            },
            'H': {
                'I': 2,
                'C': 45,
                'J': 2
            },
            'K': {
                'J': 15,
                'L': 4
            },
            'J': {
                'I': 2,
                'H': 2,
                'K': 15
            }
        }
        self.assertEqual(
            tg.graph_with_node_removed('A').graph_please(), expected_graph,
            'Node removal works 2 of 2')

        expected_graph = {
            'A': {
                'C': 4,
                'B': 9
            },
            'C': {
                'H': 45,
                'D': 5
            },
            'B': {
                'C': 3,
                'D': 6
            },
            'E': {
                'A': 33,
                'B': 3,
                'F': 3
            },
            'D': {
                'A': 5,
                'C': 3
            },
            'G': {
                'H': 14
            },
            'F': {
                'A': 12,
                'E': 2,
                'D': 7,
                'G': 2
            },
            'I': {
                'H': 2,
                'J': 2
            },
            'H': {
                'I': 2,
                'C': 45,
                'J': 2
            },
            'K': {
                'J': 15
            },
            'J': {
                'I': 2,
                'H': 2,
                'K': 15
            }
        }
        self.assertEqual(
            tg.graph_with_node_removed('L').graph_please(), expected_graph,
            'Node removal works on leaf nodes (no outgoing edges)')

        #####
        # input errors
        #####

        tg = graph.graph(self.medium_dict)
        self.assertEqual(
            tg.graph_with_node_removed('noelement').graph_please(),
            self.medium_dict, 'Node removal works for nodes that do not exist')
コード例 #5
0
    def test_route_methods(self):

        short = graph.graph(self.simple_dict)
        self.assertEqual(short.shortest_route('A', 'D'), self.empty_list,
                         ' shortest_route() works - test 1 of 3')

        med = graph.graph(self.medium_dict)
        self.assertEqual(med.shortest_route('A', 'F'), self.empty_list,
                         ' shortest_route() works - test 2 of 3')

        expected_list = ['A', 'C', 'H', 'J', 'K', 'L']
        large = graph.graph(self.large_dict)
        self.assertEqual(large.shortest_route('A', 'L'), expected_list,
                         ' shortest_route() works - test 3 of 3')

        expected_list = ['A', 'C', 'D', 'A']
        self.assertEqual(large.shortest_route('A', 'A'), expected_list,
                         ' shortest_route() works on a loop, from A to A')

        self.assertFalse(short.route_exists(['A', 'A']))
        self.assertTrue(large.route_exists(['F', 'A', 'B', 'D', 'C', 'H']))
        self.assertFalse(large.route_exists(['C', 'E']))

        expected_list = [['F', 'E', 'A'], ['F', 'E', 'B', 'C', 'D', 'A'],
                         ['F', 'E', 'B', 'D', 'A'], ['F', 'D', 'A']]
        self.assertCountEqual(
            med.calculate_all_routes('F', 'A'), expected_list,
            ' calculate_all_routes() on medium sample data ')

        exptected_list = []
        graph_of_unconnected_nodes = graph.graph({'A': {}, 'B': {}})
        self.assertIsNone(
            graph_of_unconnected_nodes.calculate_all_routes('A', 'B'),
            ' calculate_all_routes() on unconnected graph')
        self.assertEqual(graph_of_unconnected_nodes.shortest_route('A', 'B'),
                         self.empty_list,
                         ' shorest_route() on unconnected graph')
        self.assertFalse(graph_of_unconnected_nodes.route_exists(['A', 'B']),
                         ' route_exists() on unconnected graph')

        expected_list = []
        empty_graph = graph.graph()
        self.assertIsNone(empty_graph.calculate_all_routes('A', 'B'),
                          ' calculate_all_routes() on empty graph')
        self.assertEqual(empty_graph.shortest_route('A', 'B'), self.empty_list,
                         ' shorest_route() on empty graph')
        self.assertFalse(empty_graph.route_exists(['A', 'B']),
                         ' route_exists() on empty graph')

        #####
        # input errors
        #####

        self.assertEqual(
            large.shortest_route('A', 'Z'), self.empty_list,
            ' shortest_route() works on nodes that do no exist - test 1 of 3')
        self.assertEqual(
            large.shortest_route('X', 'A'), self.empty_list,
            ' shortest_route() works on nodes that do no exist - test 2 of 3')
        self.assertEqual(
            large.shortest_route('X', 'Z'), self.empty_list,
            ' shortest_route() works on nodes that do no exist - test 3 of 3')

        self.assertEqual(large.shortest_route(1, 'A'), self.empty_list,
                         ' shortest_route() works on integers - test 1 of 3')
        self.assertEqual(large.shortest_route('C', 1), self.empty_list,
                         ' shortest_route() works on integers - test 2 of 3')
        self.assertEqual(large.shortest_route(1, 4), self.empty_list,
                         ' shortest_route() works on integers - test 3 of 3')

        self.assertFalse(short.route_exists(['A', 'Z']))
        self.assertFalse(short.route_exists(['Z', 'C']))
        self.assertFalse(short.route_exists(['Z', 'Z']))
        self.assertFalse(short.route_exists(self.empty_list))
コード例 #6
0
def main():
    """
    None -> None
    This serves as the main program.
    """

    # Initialize classes. Argparser, statistics, information collector, graph and parser.
    arg_parser = argparser()
    stats_record = statistics()
    info_collector = collector()
    epi_graph = graph()
    file_parser = parser()

    # Get the options from the arguments passed in by the user.
    print("Gathering simulation parameters...")
    options = arg_parser.collect_and_return_args()
    options.R_0 = abs(float(options.R_0))
    options.life_time = abs(float(options.life_time))
    options.death_rate = abs(float(options.death_rate))
    options.infected_count = abs(int(options.infected_count))
    options.daily_travel_percentage = abs(
        float(options.daily_travel_percentage))
    travel_p = options.daily_travel_percentage
    if (travel_p >= .003):
        os.system('cls' if os.name == 'nt' else 'clear')
        raise Exception(
            "ERROR: Daily travel percentage must be less than .003.")
    # Get the total amount of initially infected people.
    initial_inf_count = abs(options.infected_count)
    file_parser.open_and_read_city_file(
        options.cities_file)  # Read the city file and save info into parser.
    file_parser.open_and_read_plane_file(
        options.planes_file)  # Read the plane file and save info into parser.
    # Get the total number of hours the program should simulate based on the number of days it should run.
    days_to_run = abs(int(round(float(options.sim_time))))

    if (options.life_time == 0):
        os.system('cls' if os.name == 'nt' else 'clear')
        raise Exception("ERROR: Life time must be greater than zero.")
    hours_to_run = (days_to_run * 24)

    cities = list(
    )  # Create a list to hold all city classes used in simulation.
    # Declare rate of reproduction, hour, and day variables for the main loop.
    hour = 1
    day = 1
    total_person_count = 0
    if (days_to_run < 2):
        os.system('cls' if os.name == 'nt' else 'clear')
        raise Exception(
            "ERROR: Epidemic simulation needs to run longer than 2 days.")
    # Create list of cities.
    for c in file_parser.cities_list:
        nc = city(c, file_parser.planes_list, travel_p, options)
        cities.append(nc)
        stats_record.add_city(nc)

    # Add cities as locations to visit and calculate distance between cities.
    for i in cities:
        for j in cities:
            i.add_cities(j)
        total_person_count += len(i.people)
    # Infect the correct amount of people.
    num_inf = 0
    while (num_inf < initial_inf_count):
        # Choose the city and person randomly to infect.
        city_to_inf = random.choice(cities)
        #choose a random person to infect in that city
        person_to_inf = random.choice(city_to_inf.people)
        #check to make sure that person is not already infected
        if (person_to_inf.infected == True):
            #if that person is already infected continue and find somebody who is not
            continue
        #once you found somebody infect them
        person_to_inf.infect()
        #add to the infected count and decrease the healthy count for that city
        city_to_inf.inf_count += 1
        city_to_inf.healthy_count -= 1
        num_inf += 1

    # Clear the system to display proper program information.
    os.system('cls' if os.name == 'nt' else 'clear')

    # indexes for totals, used in people totals
    dead_count_ind = 0
    infected_count_ind = 1
    immune_count_ind = 2
    healthy_count_ind = 3

    infected_travelers_per_day = 0

    try:
        while (stats_record.Re > 0.3):

            # Program has run for the total number of hours requested, exit.
            if (hours_to_run == hour):
                break

            # Increment hour after checking if the simulation reached the end.
            hour += 1

            # totals of people status
            people_totals = [0, 0, 0, 0]
            flight_total = 0
            healthy_each_day = 0
            # Call update methods for city objects and record data.
            for location in cities:
                stats_record.add_vessels(location.tick())
                # If end of day, add totals for each location.
                people_totals[dead_count_ind] += location.dead_count
                people_totals[infected_count_ind] += location.inf_count
                people_totals[immune_count_ind] += location.immune_count
                people_totals[healthy_count_ind] += location.healthy_count
                healthy_each_day += location.healthy_count
                flight_total += location.flights_counter
                if (hour % 24 == 0):
                    info_collector.track_healthy(location.healthy_count,
                                                 location.name)
                    infected_travelers_per_day += location.sent_infected_people
                    location.sent_infected_people = 0
                    location.flights_counter = 0

            stats_record.Re = float(people_totals[healthy_count_ind] /
                                    stats_record.totalPop) * options.R_0
            if not people_totals[infected_count_ind]:
                break

            # Collect daily contagion information for graphing purposes.

            if (hour % 24 == 0):
                info_collector.add_to_daysplot(day)
                info_collector.add_to_dplot(people_totals[dead_count_ind])
                info_collector.add_to_iplot(people_totals[infected_count_ind])
                info_collector.add_to_implot(people_totals[immune_count_ind])
                info_collector.add_flights(flight_total)
                info_collector.add_infected_travelers(
                    infected_travelers_per_day)
                infected_travelers_per_day = 0

                info_collector.total_healthy.append(healthy_each_day)
                day += 1

            # Call update method for vƒessel objects and update the active and inactive vessel lists.
            for vessel in stats_record.activevessels:
                if vessel.tick():
                    stats_record.activevessels.remove(
                        vessel)  #remove an active flight from actives list
                    stats_record.inactivevessels.append(
                        vessel)  #add flight to inactive flights list

            # Display the current contagion information
            stats_record.curr_contagion_info(hour, hours_to_run)

    except:
        print("\nWARNING: Keyboard interrupt. Printing statistics...")
        stats_record.print_stats(days_to_run, total_person_count)
        sys.stdout.write("\n")
        return

    #print overal simulation statistics
    stats_record.print_stats(days_to_run, total_person_count)
    sys.stdout.write("\n")
    #produce a time series graph of the contagion spreading over the period of time the simulation modeled.
    stats_record.print_time_series_table(info_collector.days_plot,
                                         info_collector.immune_plot,
                                         info_collector.infected_plot,
                                         info_collector.dead_plot)
    epi_graph.create_and_show_graphs(
        info_collector.days_plot, info_collector.immune_plot,
        info_collector.infected_plot, info_collector.dead_plot,
        info_collector.healthy_city_info, info_collector.flight_info,
        info_collector.infected_travelers_plot)
    sys.stdout.write("\n")

    return