# Path: pyDEA/core/utils/dea_utils.py
# def calculate_nb_pages(nb_data_rows, nb_table_rows):
#     ''' Calculates number of pages given number of data rows and number of rows
#         in the table.
# 
#         Note:
#             first row is reserved for categories.
# 
#         Args:
#             nb_data_rows (int): number of data rows.
# 
#                 Warning:
#                     It must be a positive number. Otherwise the function
#                     will return incorrect value.
# 
#             nb_table_rows (int): number of rows in the table.
# 
#                 Warning:
#                     It must be a positive number. Otherwise the function
#                     will return incorrect value.
# 
#         Returns:
#             int: number of pages
# 
#         Example:
#             >>> calculate_nb_pages(100, 10)
#             >>> 12
#             >>> calculate_nb_pages(25, 20)
#             >>> 2
#             >>> calculate_nb_pages(0, 20)
#             >>> 1
#             >>> calculate_nb_pages(10, 25):
#             >>> 1
# 
#     '''
#     if nb_table_rows:
#         base = int(nb_data_rows / (nb_table_rows - 1))
#         if nb_data_rows % (nb_table_rows - 1) != 0:
#             base += 1
#         return max(base, 1)
#     return 0
# 
# def calculate_start_row_index(curr_page, nb_table_rows):
#     ''' Calculates row index of data that will be displayed given
#         current page and number of rows in the table.
# 
#         Note:
#             The first row of the table is reserved for displaying categories.
# 
#         Args:
#             curr_page (int): current page number. Pages start from 1.
#             nb_table_rows (int): number of rows in the table.
# 
#         Returns:
#             int: data row index
#     '''
#     if (curr_page == 0):
#         return 0
#     return (curr_page - 1) * (nb_table_rows - 1)


from tkinter import E, N, W, Spinbox, StringVar
from tkinter.ttk import Frame, Button
from pyDEA.core.utils.dea_utils import calculate_nb_pages, calculate_start_row_index
        remove_row_btn.grid(row=1, column=1, sticky=N+E+W, pady=3)
        columns_spinbox = Spinbox(self, from_=1, to=100, width=3,
                                  textvariable=self.col_str_var)
        columns_spinbox.grid(row=2, column=0, pady=3, padx=3)
        add_column_btn = Button(self, text='Add column(s)',
                                command=self.add_columns)
        add_column_btn.grid(row=2, column=1, sticky=N+E+W, pady=3)
        remove_column_btn = Button(self, text='Remove column(s)',
                                   command=self.remove_columns)
        remove_column_btn.grid(row=3, column=1, sticky=N+E+W, pady=3)
        clear_all_btn = Button(self, text='Clear all', command=clear_all_fnc)
        clear_all_btn.grid(row=4, column=1, sticky=N+E+W, pady=3)

    def add_rows(self):
        ''' Adds rows to the data table. Number of rows is specified in Spinbox.
            If invalid value is given in Spinbox, only one row is added.
            Rows are added to the end of the table.
        '''
        nb_rows = self.get_nb_to_add(self.row_str_var)
        for i in range(nb_rows):
            self.table.add_row()

        # if data is displayed on multiple pages, when adding new row
        # we re-display data
        if len(self.table.cells) > 1:
            start_row = self.table.cells[1][0].data_row
            if start_row != -1:
                if len(self.table.data) - start_row >= self.table.nb_rows - 1:
                    # we need to reposition data on several pages
                    self.table.display_data(start_row)

# Path: pyDEA/core/utils/dea_utils.py
# def calculate_nb_pages(nb_data_rows, nb_table_rows):
#     ''' Calculates number of pages given number of data rows and number of rows
#         in the table.
# 
#         Note:
#             first row is reserved for categories.
# 
#         Args:
#             nb_data_rows (int): number of data rows.
# 
#                 Warning:
#                     It must be a positive number. Otherwise the function
#                     will return incorrect value.
# 
#             nb_table_rows (int): number of rows in the table.
# 
#                 Warning:
#                     It must be a positive number. Otherwise the function
#                     will return incorrect value.
# 
#         Returns:
#             int: number of pages
# 
#         Example:
#             >>> calculate_nb_pages(100, 10)
#             >>> 12
#             >>> calculate_nb_pages(25, 20)
#             >>> 2
#             >>> calculate_nb_pages(0, 20)
#             >>> 1
#             >>> calculate_nb_pages(10, 25):
#             >>> 1
# 
#     '''
#     if nb_table_rows:
#         base = int(nb_data_rows / (nb_table_rows - 1))
#         if nb_data_rows % (nb_table_rows - 1) != 0:
#             base += 1
#         return max(base, 1)
#     return 0
# 
# def calculate_start_row_index(curr_page, nb_table_rows):
#     ''' Calculates row index of data that will be displayed given
#         current page and number of rows in the table.
# 
#         Note:
#             The first row of the table is reserved for displaying categories.
# 
#         Args:
#             curr_page (int): current page number. Pages start from 1.
#             nb_table_rows (int): number of rows in the table.
# 
#         Returns:
#             int: data row index
#     '''
#     if (curr_page == 0):
#         return 0
#     return (curr_page - 1) * (nb_table_rows - 1)


# Path: pyDEA/core/gui_modules/table_modifier_gui.py
from tkinter import E, N, W, Spinbox, StringVar
from tkinter.ttk import Frame, Button
from pyDEA.core.utils.dea_utils import calculate_nb_pages, calculate_start_row_index

        remove_row_btn.grid(row=1, column=1, sticky=N+E+W, pady=3)
        columns_spinbox = Spinbox(self, from_=1, to=100, width=3,
                                  textvariable=self.col_str_var)
        columns_spinbox.grid(row=2, column=0, pady=3, padx=3)
        add_column_btn = Button(self, text='Add column(s)',
                                command=self.add_columns)
        add_column_btn.grid(row=2, column=1, sticky=N+E+W, pady=3)
        remove_column_btn = Button(self, text='Remove column(s)',
                                   command=self.remove_columns)
        remove_column_btn.grid(row=3, column=1, sticky=N+E+W, pady=3)
        clear_all_btn = Button(self, text='Clear all', command=clear_all_fnc)
        clear_all_btn.grid(row=4, column=1, sticky=N+E+W, pady=3)

    def add_rows(self):
        ''' Adds rows to the data table. Number of rows is specified in Spinbox.
            If invalid value is given in Spinbox, only one row is added.
            Rows are added to the end of the table.
        '''
        nb_rows = self.get_nb_to_add(self.row_str_var)
        for i in range(nb_rows):
            self.table.add_row()

        # if data is displayed on multiple pages, when adding new row
        # we re-display data
        if len(self.table.cells) > 1:
            start_row = self.table.cells[1][0].data_row
            if start_row != -1:
                if len(self.table.data) - start_row >= self.table.nb_rows - 1:
                    # we need to reposition data on several pages
                    self.table.display_data(start_row)

                    nb_pages = calculate_nb_pages(len(self.table.data),