Example #1
0
def delete_entity(db_name):
    if db_name == "worker":
        worker_id = user_input.get_id()

        if not CheckInput.check_worker_existence(worker_id):
            print("There is no such worker in db!\n")
        else:
            db.delete_worker(worker_id)

    elif db_name == "journal":
        journal_id = user_input.get_id()

        if not CheckInput.check_journal_existence(journal_id):
            print("There is no such journal in db!\n")
        else:
            db.delete_journal(journal_id)

    elif db_name == "department":
        department_id = user_input.get_id()

        if not CheckInput.check_department_existence(department_id):
            print("There is no such department in db!\n")
        else:
            db.delete_department(department_id)

    elif db_name == "worker_card":
        worker_card_id = user_input.get_id()

        if not CheckInput.check_worker_card_existence(worker_card_id):
            print("There is no such worker card in db!\n")
        else:
            db.delete_worker_card(worker_card_id)
    def read_renter_list_entity_update_input(self):
        renterListEntity = RentingListScheme()
        renterListEntity.car_number = input("enter car number: ")
        while not CheckInput.test_car_number(renterListEntity.car_number):
            renterListEntity.car_number = input("Wrong input!\nTry again: ")

        renterListEntity.date = input("enter renting date(format: year-mm-dd): ")
        while not CheckInput.test_date(renterListEntity.date):
            renterListEntity.date = input("Wrong input!\nTry again: ")
        if CheckInput.check_renting_list_entity_existence(renterListEntity.car_number, renterListEntity.date):
            renterListEntity.driver_license = input("enter renter driver license: ")
            while not CheckInput.test_driver_license(renterListEntity.driver_license):
                renterListEntity.driver_license = input("Wrong input!\nTry again: ")

            while not CheckInput.check_renter_existence(renterListEntity.driver_license):
                renter_entity = RenterScheme()
                input_str = ""
                input_str = input("There is no such renter!\nWanna add?\n(y/n): ")
                for case in switch(input_str):
                    if case('y'):
                        renter_entity = self.read_renter_input()
                        renterListEntity.driver_license = renter_entity.driver_license
                        db.insert_renter(renter_entity)
                        break
                    if case('n'):
                        print("can't insert renting list entity")
                        return
                    else:
                        print("____________________")
                        print("no such option, try again!")
        else:
            print("There's no such renting list entity")
            return None

        return renterListEntity
Example #3
0
    def read_worker_card_update_input(self):
        worker_card_entity = WorkerCardScheme()
        worker_card_entity.id = input("enter id: ")
        if CheckInput.check_worker_card_existence(worker_card_entity.id):
            worker_card_entity.worker_id = input("enter worker_id: ")
            while not CheckInput.check_worker_existence(
                    worker_card_entity.worker_id):
                input_str = input(
                    "There is no such worker!\nWanna add?\n(y/n): ")
                for case in switch(input_str):
                    if case('y'):
                        worker_entity = self.read_worker_input()
                        worker_card_entity.worker_id = worker_entity.id
                        db.insert_worker(worker_entity)
                        break
                    if case('n'):
                        print("can't insert worker card ")
                        return
                    else:
                        print("____________________")
                        print("no such option, try again!")

            worker_card_entity.is_active = input("enter is active: ")
            while worker_card_entity.is_active != "True" and worker_card_entity.is_active != "False":
                worker_card_entity.is_active = input(
                    "Wrong input!\nTry again: ")

            return worker_card_entity
        else:
            print("There is no such worker card in db!")
            return None
Example #4
0
    def read_journal_update_input(self):
        journal_entity = JournalScheme()
        journal_entity.id = input("enter id: ")
        if CheckInput.check_journal_existence(journal_entity.id):
            print("exit timestamp:")
            journal_entity.exit = self.get_date()
            print("entrance timestamp:")
            journal_entity.entrance = self.get_date()
            journal_entity.worker_id = input("worker id: ")
            while not CheckInput.check_worker_existence(
                    journal_entity.worker_id):

                input_str = input(
                    "There is no such worker!\nWanna add?\n(y/n): ")
                for case in switch(input_str):
                    if case('y'):
                        worker_entity = self.read_worker_input()
                        journal_entity.worker_id = worker_entity.id
                        db.insert_worker(worker_entity)
                        break
                    if case('n'):
                        print("can't insert journal")
                        return
                    else:
                        print("____________________")
                        print("no such option, try again!")
            return journal_entity
        else:
            print("There is no such journal in db!")
            return None
Example #5
0
 def read_worker_update_input(self):
     workerEntity = WorkerScheme()
     workerEntity.name = input("enter worker name: ")
     workerEntity.id = input("enter worker id: ")
     if CheckInput.check_worker_existence(workerEntity.id):
         workerEntity.is_still_working = input(
             "enter worker is still working (True/False): ")
         while workerEntity.is_still_working != "True" and workerEntity.is_still_working != "False":
             workerEntity.is_still_working = input(
                 "Wrong input!\nTry again: ")
         workerEntity.department_id = input("enter department id: ")
         while not CheckInput.check_department_existence(
                 workerEntity.department_id):
             input_str = input(
                 "There is no such department!\nWanna add?\n(y/n): ")
             for case in switch(input_str):
                 if case('y'):
                     department_entity = self.read_department_input()
                     workerEntity.department_id = department_entity.id
                     db.insert_department(department_entity)
                     break
                 if case('n'):
                     print("can't insert worker")
                     return
                 else:
                     print("____________________")
                     print("no such option, try again!")
         return workerEntity
     else:
         print("There is no such worker in db!")
         return None
Example #6
0
 def export_items_by_id(self, product_id: str, count: int = 1) -> None:
     """
     Exports Items from the inventory by product id.
     """
     CheckInput.check_type(product_id, str)
     item = self.get_item_by_product_id(product_id)
     self.export_items(item, count)
Example #7
0
def delete_entity(db_name):
    if db_name == "cars":
        car_number = user_input.get_car_number_input()

        if not CheckInput.check_car_existence(car_number):
            print("There is no such car in db!\n")
        else:
            db.delete_car(car_number)

    elif db_name == "renters":
        driver_license = input("enter renter driver license: ")
        while not CheckInput.test_driver_license(driver_license):
            driver_license = input("Wrong input!\nTry again: ")

        if not CheckInput.check_renter_existence(driver_license):
            print("There is no such renter in db!\n")
        else:
            db.delete_renter(driver_license)

    elif db_name == "renting_list":
        car_number = user_input.get_car_number_input()
        date = input("enter renting date(format: year-mm-dd): ")
        while not CheckInput.test_date(date):
            date = input("Wrong input!\nTry again: ")

        if not CheckInput.check_renting_list_entity_existence(
                car_number, date):
            print("There is no such renting list entity in db!\n")

        else:
            db.delete_renting_list_entity(car_number, date)
Example #8
0
 def _check_input(self, size: Size, stuffing: Stuffing, fabric: Fabric,
                  has_glow: bool, name: str, description: str,
                  product_id: str) -> None:
     CheckInput.check_type(size, Size)
     CheckInput.check_type(stuffing, Stuffing)
     CheckInput.check_type(fabric, Fabric)
     CheckInput.check_type(has_glow, bool)
     CheckInput.check_all_input_type([name, description, product_id], str)
Example #9
0
 def _check_input(self, colour: Colours, size: Size, stuffing: Stuffing,
                  fabric: Fabric, name: str, description: str,
                  product_id: str) -> None:
     CheckInput.check_type(colour, Colours)
     CheckInput.check_type(stuffing, Stuffing)
     CheckInput.check_type(fabric, Fabric)
     CheckInput.check_type(size, Size)
     CheckInput.check_all_input_type([name, description, product_id], str)
Example #10
0
 def _check_input(self, sound_effects_number: int, colour: Colours,
                  has_batteries: bool, name: str, description: str,
                  product_id: str) -> None:
     CheckInput.check_type(sound_effects_number, int)
     CheckInput.check_type(colour, Colours)
     CheckInput.check_type(has_batteries, bool)
     CheckInput.check_all_input_type([name, description, product_id], str)
     CheckInput.check_value_is_lower_equal_than_threshold(
         sound_effects_number, 0)
 def create_item(self, inventory_type: InventoryEnum, **product_details) -> Item:
     """
     Constructs an item based on the inventory type.
     """
     CheckInput.check_type(inventory_type, InventoryEnum)
     if inventory_type == InventoryEnum.TOY:
         return self.create_toy(**product_details)
     if inventory_type == InventoryEnum.STUFFED_ANIMAL:
         return self.create_stuffed_animal(**product_details)
     return self.create_candy(**product_details)
 def read_renter_update_input(self):
     renterEntity = RenterScheme()
     renterEntity.driver_license = input("enter renter driver license: ")
     while not CheckInput.test_driver_license(renterEntity.driver_license):
         renterEntity.driver_license = input("Wrong input!\nTry again: ")
     if CheckInput.check_renter_existence(renterEntity.driver_license):
         renterEntity.first_name = input("enter new renter first name: ")
         renterEntity.last_name = input("enter new renter last name: ")
         return renterEntity
     else:
         print("There is no such renter in db!")
         return None
Example #13
0
 def _check_input(self, rooms_number: int, dimensions: float, min_age: int,
                  has_batteries: bool, name: str, description: str,
                  product_id: str) -> None:
     """
     Checks input.
     """
     CheckInput.check_all_input_type([rooms_number, min_age], int)
     CheckInput.check_type(dimensions, int, float)
     CheckInput.check_type(has_batteries, bool)
     CheckInput.check_all_input_value_is_lower_equal_than_threshold(
         [rooms_number, dimensions, min_age], 0)
     CheckInput.check_all_input_type([description, product_id, name], str)
Example #14
0
 def _check_input(self, speed: float, jump_height: float,
                  is_grow_in_dark: bool, spider_type: SpiderType,
                  min_age: int, has_batteries: bool, name: str,
                  description: str, product_id: str) -> None:
     """
     Checks input.
     """
     CheckInput.check_all_input_type([speed, jump_height, min_age], int,
                                     float)
     CheckInput.check_type(spider_type, SpiderType)
     CheckInput.check_all_input_type([is_grow_in_dark, has_batteries], bool)
     CheckInput.check_all_input_type([name, description, product_id], str)
     CheckInput.check_all_input_value_is_lower_equal_than_threshold(
         [speed, jump_height, min_age], 0)
Example #15
0
 def NN_prediction(self, data, model_path=None):
     """
     Predicting output with given data
     :param data (df): input data
     :param model_path (str): trained model directory. If none, run NN_model train and save the trained modle to the model path
     :return: predicted result of the given data
     """
     # check na data
     data = CheckInput().check_na(data)
     data = np.array(data).reshape((data.shape[0], data.shape[1]))
     # load model
     model_file = model_path + "/" + self.prefix + "-model.json"
     model_weight_file = model_path + "/" + self.prefix + "-model.weight.h5"
     logging.info("Loading model...")
     model = None
     try:
         with open(model_file, 'r') as json_string:
             logging.info("Loading model...")
             model_json = json_string.read()
             model = model_from_json(model_json)
             json_string.close()
     except Exception, e:
         logging.error(
             "Model file is not found! This model should be provided by %s",
             model_path,
             exc_info=True)
Example #16
0
 def _check_input_type(
         order_number: int,
         product_id: str,
         name: str,
         quantity: int,
         item_type: InventoryEnum,
         product_details: dict,
         factory: FestiveSeasonFactory) -> None:
     """
     Checks if all inputs are valid.
     """
     CheckInput.check_all_input_type([product_id, name], str)
     CheckInput.check_all_input_type([order_number, quantity], int)
     CheckInput.check_type(item_type, InventoryEnum)
     CheckInput.check_type(product_details, dict)
     CheckInput.check_type(factory, FestiveSeasonFactory)
    def read_renter_input(self):
        renterEntity = RenterScheme()
        renterEntity.first_name = input("enter renter first name: ")
        renterEntity.last_name = input("enter renter last name: ")
        renterEntity.driver_license = input("enter renter driver license: ")
        while not CheckInput.test_driver_license(renterEntity.driver_license):
            renterEntity.driver_license = input("Wrong input!\nTry again: ")

        return renterEntity
    def read_car_input(self):
        carEntity = CarScheme()
        carEntity.name = input("enter car name: ")
        carEntity.color = input("enter car color: ")
        carEntity.model = input("enter car model: ")
        carEntity.car_number = input("enter car number: ")
        while not CheckInput.test_car_number(carEntity.car_number):
            carEntity.car_number = input("Wrong input!\nTry again: ")

        carEntity.price_per_day = input("enter car's price per day: ")
        while not CheckInput.test_price(carEntity.price_per_day):
            carEntity.price_per_day = input("Wrong input!\nTry again: ")

        carEntity.has_automatic_transmission = input("enter car if car has automatic transmision (True/False): ")
        while carEntity.has_automatic_transmission != "True" and carEntity.has_automatic_transmission != "False":
            carEntity.has_automatic_transmission = input("Wrong input!\nTry again: ")

        return carEntity
Example #19
0
 def read_department_update_input(self):
     department_entity = DepartmentScheme()
     department_entity.id = input("enter id: ")
     if CheckInput.check_department_existence(department_entity.id):
         department_entity.production = input("enter production: ")
         return department_entity
     else:
         print("There is no such department in db!")
         return None
    def read_car_update_input(self):
        carEntity = CarScheme()
        carEntity.car_number = input("enter car number: ")
        while not CheckInput.test_car_number(carEntity.car_number):
            carEntity.car_number = input("Wrong input!\nTry again: ")
        if CheckInput.check_car_existence(carEntity.car_number):
            carEntity.name = input("enter new car name: ")
            carEntity.color = input("enter new car color: ")
            carEntity.model = input("enter new car model: ")
            carEntity.price_per_day = input("enter new car's price per day: ")
            while not CheckInput.test_price(carEntity.price_per_day):
                carEntity.price_per_day = input("Wrong input!\nTry again: ")

            carEntity.has_automatic_transmission = input("enter if new car has automatic transmision (True/False): ")
            while carEntity.has_automatic_transmission != "True" and carEntity.has_automatic_transmission != "False":
                carEntity.has_automatic_transmission = input("Wrong input!\nTry again: ")

            return carEntity
        else:
            print("There is no such car in db!")
            return None
Example #21
0
 def MiniBatchKmeans(self, df, **kwargs):
     """
     Mini-Batch Kmeans clustering, especially suitable for large data sets. See detailed arguments in sklearn.cluster.MiniBatchKmeans method
     :param df (pd.Dataframe): input df
     :param kwargs: parameters for mini-Batch-Kmeans clustering
                      kmin (int):  minimum cluster numbers generated
                      kmax (int): maximum cluster numbres generated
                      max_iter (int): maximum iterations before stopping
                      batch_size (int): size of mini batches
                      verbose (bool): verbosity mode.
     :return: df with labels
     """
     kmin = kwargs.pop('kmin', 8)
     kmax = kwargs.pop('kmax', 20)
     df = CheckInput().check_na(df)
     scaler = StandardScaler().fit(df)
     df_scale = scaler.fit_transform(df)
     # init dictionaries to hold inetia scores, labels, BIC scores
     labels, bics, inertias = {}, {}, {}
     for n_cluster in range(kmin, kmax):
         mbkm = MiniBatchKMeans(n_clusters=n_cluster, **kwargs)
         with warnings.catch_warnings():
             warnings.simplefilter("ignore", category=DeprecationWarning)
             mbkm.fit(np.array(df_scale))
         labels[n_cluster] = mbkm.labels_
         cur_centers = mbkm.cluster_centers_
         inertias[n_cluster] = mbkm.inertia_
         # get index of data in each cluster
         cluster_index = [[] for i in range(n_cluster)]
         for i in range(
                 n_cluster
         ):  # or np.sort(np.unique(labels[n_cluster])) if not start with 0
             cluster_index[i] = np.arange(len(
                 labels[n_cluster]))[labels[n_cluster] == i]
         bics[n_cluster] = XMeans().BIC(np.array(df_scale), cluster_index,
                                        cur_centers)
     # get the maximum bic value and corresponding labels
     opt_n_cluster = max(bics, key=bics.get)
     logging.info("Optimal cluster number has BIC value %f",
                  bics[opt_n_cluster])
     opt_labels = labels[opt_n_cluster]
     logging.info(
         "The optimum clusters found is %d. And the inertia scores for each cluster count are %s",
         int(opt_n_cluster), str(inertias))
     df['labels'] = opt_labels
     return df
Example #22
0
 def DBSCAN_clustering(self, df, eps=0.5, min_samps=8):
     """
     :param df: input df for clustering rows
     :param eps: maximum distance between 2 samples to be considered as in same cluster
     :param min_samps: minimum number of neighbouring samples for a point to be considered as core point
     :return: df with labels of each row
     """
     # check input df
     df = CheckInput().check_na(df)
     scaler = StandardScaler().fit(df)
     # scale along columns
     df_scale = scaler.fit_transform(df)
     # compute DBSCAN
     db = DBSCAN(eps=eps, min_samples=min_samps,
                 algorithm='ball_tree').fit(df_scale)
     # logging.info("Silhouette Coefficient: %s", str(silhouette_samples(df, db.labels_)))
     df['label'] = db.labels_
     return df
Example #23
0
    def check_if_item_enough(self, product_id: str, count: int) -> bool:
        """
        Checks if the inventory has enough stock for exporting this item.

        :return: True if it has enough items, False if not
        """
        CheckInput.check_type(product_id, str)
        CheckInput.check_type(count, int)
        CheckInput.check_value_is_lower_equal_than_threshold(count, 0)
        item = self.get_item_by_product_id(product_id)
        if item is None:
            return False
        return self._items[item] >= count
Example #24
0
    def export_items(self, item: Item, count: int = 1) -> None:
        """
        Exports Items from the inventory.

        :param item: Item
        :param count: the number of item, default is 1
        """
        CheckInput.check_type(item, Item)
        CheckInput.check_type(count, int)
        CheckInput.check_value_is_lower_equal_than_threshold(count, 0)
        if item not in self._items.keys():
            raise KeyError(item, "Inventory doesn't have this item")
        if self._items[item] < count:
            raise ValueError("The Inventory doesn't have enough stock for %s" %
                             item)
        self._items[item] -= count
Example #25
0
    def import_items(self, item: Item, count: int = 100) -> None:
        """
        Add Items stock. If the item already existed in the inventory, increase the count.
        Else put the item into inventory.

        :param item: Item
        :param count: the number of item, default is 1
        """
        CheckInput.check_type(item, Item)
        CheckInput.check_type(count, int)
        CheckInput.check_value_is_lower_equal_than_threshold(count, 0)
        if count < 100:
            count = 100
        if item in self._items.keys():
            self._items[item] += count
            return None
        self._items[item] = count
Example #26
0
 def X_means(self, df, **kwargs):
     """
     X-means algorithm for clustering input dataframe
     :param df: input dataframe
     :param kwargs: parameters for kmeans algorithm, including:
                     kmin (int): the minimum clusters classified, default: 2
                     kmax (int): maximum clusters classified, default: None
                     init (str or np.ndarray): ways to initialize first set of centers -
                                             'kmeans++', 'random', or user-provided array of center coordinates
                     bic_cutoff (float): bic criterion for terminate center splitting, default: 1.0
                     max_iter (int): maximum iteration for kmeans cluster in specified region, default: 1000
                     kmeans_tole (float): center distance change criterion during kmeans clustering, default: 0.01
     :return: df with labels
     """
     df = CheckInput().check_na(df)
     scaler = StandardScaler().fit(df)
     df_scale = scaler.fit_transform(df)
     # convert df to np.array
     logging.info("Initializing X-means clustering!")
     model = XMeans(**kwargs).fit(np.asarray(df_scale))
     # logging.info("Silhouette Coefficient: %0.3s", str(silhouette_samples(df, model.labels)))
     df['labels'] = model.labels
     return df
Example #27
0
 def Kmeans(self, df, **kwargs):
     # similar parrameter settings with previous minibatch kmeans
     kmin = kwargs.pop('kmin', 8)
     kmax = kwargs.pop('kmax', 20)
     df = CheckInput().check_na(df)
     scaler = StandardScaler().fit(df)
     df_scale = scaler.fit_transform(df)
     # init dictionaries to hold inetia scores, labels, BIC scores
     labels, bics, inertias = {}, {}, {}
     for n_cluster in range(kmin, kmax):
         km = KMeans(n_clusters=n_cluster, **kwargs)
         with warnings.catch_warnings():
             warnings.simplefilter("ignore", category=DeprecationWarning)
             km.fit(np.array(df_scale))
         labels[n_cluster] = km.labels_
         cur_centers = km.cluster_centers_
         inertias[n_cluster] = km.inertia_
         # get index of data in each cluster
         cluster_index = [[] for i in range(n_cluster)]
         for i in range(
                 n_cluster
         ):  # or np.sort(np.unique(labels[n_cluster])) if not start with 0
             cluster_index[i] = np.arange(len(
                 labels[n_cluster]))[labels[n_cluster] == i]
         bics[n_cluster] = XMeans().BIC(np.array(df_scale), cluster_index,
                                        cur_centers)
     # get the maximum bic value and corresponding labels
     opt_n_cluster = max(bics, key=bics.get)
     logging.info("Optimal cluster number has BIC value %f",
                  bics[opt_n_cluster])
     # clustering on whole df
     opt_labels = labels[opt_n_cluster]
     logging.info(
         "The optimum clusters found is %d. And the inertia scores for each cluster count are %s",
         int(opt_n_cluster), str(inertias))
     df['labels'] = opt_labels
     return df
Example #28
0
 def get_date(self):
     date = input("enter timestamp(format: %Y-%m-%d %H:%M:%S): ")
     while not CheckInput.test_timestamp(date):
         date = input("Wrong input!\nTry again: ")
     return date
 def _check_input(self, contains_nuts: bool, variety: ToffeeVariety,
                  has_lactose: bool, name: str, description: str,
                  product_id: str) -> None:
     CheckInput.check_all_input_type([contains_nuts, has_lactose], bool)
     CheckInput.check_type(variety, ToffeeVariety)
     CheckInput.check_all_input_type([name, description, product_id], str)
Example #30
0
 def hierarchical_clustering(self,
                             df,
                             kmax=20,
                             method='ward',
                             dist='euclidean',
                             treeplot_dir='.',
                             show_plot=True):
     """
     :param df (pd.dataframe): input df
     :param kmax (int): max number of clusters to generate
     :param method (str): algorithm to perform hierarchical clustering;
                     'ward', 'complete', 'average'
     :param dist (str): distance method to compute the linkage;
                 'euclidean', 'l1', 'l2', 'manhatton', 'cosine', 'precomputed'
                 when method is 'ward', only 'euclidean' is accepted.
     :param treeplot_dir (str): directory to get the hierarchical clustering tree plot.
                         PS: The name indicate the sample length
     :param show_plot (bool): show cophenetic correlation coefficient and dendrogram plot or not
     :return: df with labels
     """
     if not os.path.exists(treeplot_dir):
         os.makedirs(treeplot_dir)
     df = CheckInput().check_na(df)
     scaler = StandardScaler().fit(df)
     df_scale = scaler.fit_transform(df)
     hc_z = linkage(df_scale, method=method, metric=dist)
     # compute the cophenetic correlation coefficient to check if the clustering preserve original distances
     coph_coef, coph_dist = cophenet(hc_z, pdist(df_scale))
     logging.info(
         "Cophenetic correlation coefficient of this hierarchical clustering is %0.3f",
         coph_coef)
     # use elbow method to automatically determine the number of clusters
     last_30 = hc_z[-kmax:, 2]
     idx = np.arange(1, len(last_30) + 1)
     # 2nd derivatives of the distances
     acce = np.diff(last_30, 2)
     # get the knee point: if the last iteration is the max value in acce, we want to 2 clusters
     n_clusters = acce[::-1].argmax() + 2
     logging.info("Clusters: %d", n_clusters)
     # visualize the elbow method plot
     file_symbol = len(df.columns)
     out_elbow = treeplot_dir + "/" + "hc-elbow.%s.S%s.png" % (method,
                                                               file_symbol)
     # plot the distance of last 30 clusters iteratively (inverse the order of distance)
     if show_plot:
         plt.title("Elbow method for cluster number selection")
         plt.xlabel("Iteration")
         plt.ylabel("Distance")
         plt.plot(idx, last_30[::-1])
         # the first and the last distance cannot compute 2nd derivatives
         plt.plot(idx[1:-1], acce[::-1])
         plt.tight_layout()
         plt.savefig(out_elbow, dpi=200)
         plt.close()
     # get labels of each point
     labels = fcluster(hc_z, n_clusters, criterion='maxclust')
     # compute the silhoutte coefficient
     # logging.info("Sihoutte coeffient of hierarchical clustering is %s", str(silhouette_samples(df, labels)))
     df['label'] = labels
     # visualize the dendrogram clustering tree for further check
     out_dendro = treeplot_dir + "/" + "hc-dendrogram.%s.N%d.S%s.png" % (
         method, n_clusters, file_symbol)
     if show_plot:
         plt.title("Hierarchical clustering dendrogram (lastp)")
         plt.xlabel("Cluster size")
         plt.ylabel("Distance")
         dendrogram(
             hc_z,
             p=n_clusters,
             truncate_mode='lastp',
             show_leaf_counts=True,
             leaf_rotation=90,
             leaf_font_size=12,
             show_contracted=True,
         )
         plt.tight_layout()
         plt.savefig(out_dendro, dpi=200)
         plt.close()
     return df