def test_filters() -> None:
    """ Test the functionality of the filters.

    We are only giving you a couple of tests here, you should expand both the
    dataset and the tests for the different types of applicable filters
    """
    customers = create_customers(test_dict)
    process_event_history(test_dict, customers)

    # Populate the list of calls:
    calls = []
    hist = customers[0].get_history()
    # only consider outgoing calls, we don't want to duplicate calls in the test
    calls.extend(hist[0])

    # The different filters we are testing
    filters = [DurationFilter(), CustomerFilter(), ResetFilter()]

    # These are the inputs to each of the above filters in order.
    # Each list is a test for this input to the filter
    filter_strings = [["L50", "G10", "L0", "50", "AA", ""],
                      ["5555", "1111", "9999", "aaaaaaaa", ""], ["rrrr", ""]]

    # These are the expected outputs from the above filter application
    # onto the full list of calls
    expected_return_lengths = [[1, 2, 0, 3, 3, 3], [3, 3, 3, 3, 3], [3, 3]]

    for i in range(len(filters)):
        for j in range(len(filter_strings[i])):
            result = filters[i].apply(customers, calls, filter_strings[i][j])
            assert len(result) == expected_return_lengths[i][j]
Exemple #2
0
def test_task4() -> None:
    # Filtering
    input_dictionary = import_data()
    customers = create_customers(input_dictionary)
    process_event_history(input_dictionary, customers)

    # Populate the list of calls:
    calls = []
    for customer in customers:
        hist = customer.get_history()
        calls.extend(hist[0])

    # The different filters we are testing

    # You need write LocationFilter test yourself
    filters = [
        DurationFilter(),
        CustomerFilter(),
        ResetFilter()
    ]

    # These are the inputs to each of the above filters in order.
    # Each list is a test for this input to the filter
    filter_strings = [
        ["L50", "G10", "L0", "50", "AA", "", "L100"],
        ["5555", "1111", "6020", "7930", "3087", "5524", "abc", ""],
        ["rrrr", ""]
    ]

    # These are the expected outputs from the above filter application
    # onto the full list of calls
    expected_return_lengths = [
        [122, 975, 0, 1000, 1000, 1000, 261],
        [1000, 1000, 59, 22, 22, 45, 1000, 1000],
        [1000, 1000]
    ]

    for i in range(len(filters)):
        for j in range(len(filter_strings[i])):
            result = filters[i].apply(customers, calls, filter_strings[i][j])
            assert len(result) == expected_return_lengths[i][j], str(filters[i].__class__.__name__) + ", with keyword " + filter_strings[i][j] + " produce wrong result"
Exemple #3
0
    def handle_window_events(self, customers: List[Customer],
                             drawables: List[Call]) \
            -> List[Call]:
        """Handle any user events triggered through the pygame window.
        The <drawables> are the objects currently displayed, while the
        <customers> list contains all customers from the input data.
        Return a new list of Calls, according to user input actions.
        """
        new_drawables = drawables
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self._quit = True
            elif event.type == pygame.KEYDOWN:
                f = None
                num_threads = 1

                if event.unicode == "d":
                    f = DurationFilter()
                elif event.unicode == "l":
                    f = LocationFilter()
                elif event.unicode == "c":
                    f = CustomerFilter()
                elif event.unicode == "r":
                    f = ResetFilter()
                    num_threads = 1

                if f is not None:

                    def result_wrapper(fun: Callable[
                        [List[Customer], List[Call], str],
                        List[Call]], customers: List[Customer],
                                       data: List[Call], filter_string: str,
                                       res: List) -> None:
                        """A final wrapper to return the result of the operation
                        """
                        res.append(fun(customers, data, filter_string))

                    def threading_wrapper(customers: List[Customer],
                                          data: List[Call],
                                          filter_string: str) -> List[Call]:
                        """A wrapper for the application of filters with
                        threading
                        """
                        chunk_sz_calls = math.ceil(
                            (len(data) + num_threads - 1) / num_threads)
                        print("Num_threads:", num_threads)
                        print("Chunk_calls:", chunk_sz_calls)
                        threads = []
                        results = []
                        for i in range(num_threads):
                            res = []
                            results.append(res)
                            t = threading.Thread(
                                target=result_wrapper,
                                args=(f.apply, customers,
                                      data[i * chunk_sz_calls:(i + 1) *
                                           chunk_sz_calls], filter_string,
                                      res))
                            t.daemon = True
                            t.start()
                            threads.append(t)
                            # f.apply(customers, data, filter_string)
                        # Wait to finish
                        for t in threads:
                            t.join()

                        # Now reconstruct the data
                        new_data = []
                        for res in results:
                            new_data.extend(res[0])
                        return new_data

                    new_drawables = self.entry_window(str(f), customers,
                                                      drawables,
                                                      threading_wrapper)

                # Perform the billing for a selected customer:
                if event.unicode == "m":
                    try:

                        def get_customer(customers: List[Customer],
                                         found_customer: List[Customer],
                                         input_string: str) -> None:
                            """ A helper to find the customer specified in the
                            input string appends to the found_customer the
                            matching customer
                            """
                            try:
                                for c in customers:
                                    if c.get_id() == int(input_string):
                                        found_customer.append(c)
                            except ValueError:
                                pass

                        customer = []
                        self.entry_window(
                            "Generate the bill for the customer "
                            "with ID:", customers, customer, get_customer)

                        if len(customer) == 0:
                            raise ValueError

                        # Just want to return the parsed input string
                        def get_input_date(customer: List[Customer],
                                           drawables: List[Call],
                                           input_string: str) \
                                -> Optional[List[int]]:
                            """ A helper to get the input date """
                            try:
                                return [
                                    int(s.strip())
                                    for s in input_string.split(',')
                                ]
                            except ValueError:
                                return None

                        date = self.entry_window(
                            "Bill month and year: "
                            "month, year", customers, drawables,
                            get_input_date)
                        if date is None or date == ([], []):
                            raise ValueError

                        customer[0].print_bill(date[0], date[1])

                    except ValueError:
                        print("ERROR: bad formatting for input string")
                    except IndexError:
                        print("Customer not found")

            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    self._mouse_down = True
                elif event.button == 4:
                    self._map.zoom(-0.1)
                elif event.button == 5:
                    self._map.zoom(0.1)
            elif event.type == pygame.MOUSEBUTTONUP:
                self._mouse_down = False
            elif event.type == pygame.MOUSEMOTION:
                if self._mouse_down:
                    self._map.pan(pygame.mouse.get_rel())
                else:
                    pygame.mouse.get_rel()
        return new_drawables