def _evaluate(self, x, # out, *args, **kwargs): """ This method iterate over an Individual, execute the refactoring operation sequentially, and compute quality attributes for the refactored version of the program, as objectives of the search params: x (Individual): x is an instance of Individual (i.e., a list of refactoring operations) """ # Stage 0: Git restore logger.debug("Executing git restore.") git_restore(config.PROJECT_PATH) update_understand_database(config.UDB_PATH) # Stage 1: Execute all refactoring operations in the sequence x logger.debug(f"Reached Individual with Size {len(x[0])}") for refactoring_operation in x[0]: refactoring_operation.do_refactoring() # Update Understand DB update_understand_database(config.UDB_PATH) # Stage 2: Computing quality attributes obj = DesignQualityAttributes(udb_path=config.UDB_PATH) o1 = obj.average_sum del obj o2 = testability_main(config.UDB_PATH) o3 = modularity_main(config.UDB_PATH) logger.info(f"QMOOD AVG Score: {o1}") logger.info(f"Testability Score: {o2}") logger.info(f"Modularity Score: {o3}") # Stage 3: Marshal objectives into vector out["F"] = np.array([-1 * o1, -1 * o2, -1 * o3], dtype=float)
def execute_from_txt_log(self, input_file_path): """ input_file_path: The path of input data from log. Example: Take a look at ./input.txt """ with open(input_file_path, 'r') as f: data = f.read().split('\n') for row in data: refactoring_name = re.search(', (.+?)(\w+)*\(', row).group()[1:-1].strip() params = re.search('{(.+?)}', row).group().strip() params = params.replace("'", '"') params = params.replace("False", "false") params = params.replace("True", "true") params = json.loads(params) if params.get('udb_path'): params['udb_path'] = config.UDB_PATH if params.get('project_dir'): params['project_dir'] = config.PROJECT_PATH if params.get('file_path'): params['file_path'] = params['file_path'].replace( self.file_path_base_dir_old, config.PROJECT_ROOT_DIR) print(refactoring_name, params) res = REFACTORING_MAIN_MAP[refactoring_name](**params) print(f"Executed {refactoring_name} with status {res}") update_understand_database(config.UDB_PATH) print('-' * 100)
def _evaluate(self, x, # out, *args, **kwargs): """ This method iterate over a population, execute the refactoring operations in each individual sequentially, and compute quality attributes for the refactored version of the program, as objectives of the search Args: x (Population): x is a matrix where each row is an individual, and each column a variable. \ We have one variable of type list (Individual) ==> x.shape = (len(Population), 1) """ objective_values = [] for k, individual_ in enumerate(x): # Stage 0: Git restore logger.debug("Executing git restore.") git_restore(config.PROJECT_PATH) logger.debug("Updating understand database after git restore.") update_understand_database(config.UDB_PATH) # Stage 1: Execute all refactoring operations in the sequence x logger.debug(f"Reached Individual with Size {len(individual_[0])}") for refactoring_operation in individual_[0]: refactoring_operation.do_refactoring() # Update Understand DB logger.debug(f"Updating understand database after {refactoring_operation.name}.") update_understand_database(config.UDB_PATH) # Stage 2: arr = Array('d', range(self.n_obj_virtual)) if self.evaluate_in_parallel: # Stage 2 (parallel mood): Computing quality attributes p1 = Process(target=calc_qmood_objectives, args=(arr,)) p2 = Process(target=calc_testability_objective, args=(config.UDB_PATH, arr,)) p3 = Process(target=calc_modularity_objective, args=(config.UDB_PATH, arr,)) p1.start(), p2.start(), p3.start() p1.join(), p2.join(), p3.join() o1 = sum([i for i in arr[:6]]) / 6. o2 = arr[6] o3 = arr[7] else: # Stage 2 (sequential mood): Computing quality attributes qmood_quality_attributes = DesignQualityAttributes(udb_path=config.UDB_PATH) o1 = qmood_quality_attributes.average_sum o2 = testability_main(config.UDB_PATH, initial_value=config.CURRENT_METRICS.get("TEST", 1.0)) o3 = modularity_main(config.UDB_PATH, initial_value=config.CURRENT_METRICS.get("MODULE", 1.0)) del qmood_quality_attributes # Stage 3: Marshal objectives into vector objective_values.append([-1 * o1, -1 * o2, -1 * o3]) logger.info(f"Objective values for individual {k}: {[-1 * o1, -1 * o2, -1 * o3]}") # Stage 4: Marshal all objectives into out dictionary out['F'] = np.array(objective_values, dtype=float)
def _evaluate( self, x, # out, *args, **kwargs): """ This method iterate over an Individual, execute the refactoring operation sequentially, and compute quality attributes for the refactored version of the program, as objectives of the search params: x (Individual): x is an instance of Individual (i.e., a list of refactoring operations) """ # Git restore` logger.debug("Executing git restore.") git_restore(config.PROJECT_PATH) update_understand_database(config.UDB_PATH) # Stage 1: Execute all refactoring operations in the sequence x logger.debug(f"Reached Individual with Size {len(x[0])}") for refactoring_operation in x[0]: refactoring_operation.do_refactoring() # Update Understand DB update_understand_database(config.UDB_PATH) # Stage 2: Computing quality attributes qmood = DesignQualityAttributes(udb_path=config.UDB_PATH) o1 = qmood.reusability o2 = qmood.understandability o3 = qmood.flexibility o4 = qmood.functionality o5 = qmood.effectiveness o6 = qmood.extendability del qmood o7 = testability_main(config.UDB_PATH) o8 = modularity_main(config.UDB_PATH) logger.info(f"Reusability Score: {o1}") logger.info(f"Understandability Score: {o2}") logger.info(f"Flexibility Score: {o3}") logger.info(f"Functionality Score: {o4}") logger.info(f"Effectiveness Score: {o5}") logger.info(f"Extendability Score: {o6}") logger.info(f"Testability Score: {o7}") logger.info(f"Modularity Score: {o8}") # Stage 3: Marshal objectives into vector out["F"] = np.array([ -1 * o1, -1 * o2, -1 * o3, -1 * o4, -1 * o5, -1 * o6, -1 * o7, -1 * o8, ], dtype=float)
) # Post-Paste: Reference Injection parse_and_walk( file_path=target_class_file, listener_class=ReferenceInjectorAndConstructorListener, has_write=True, method_text=method_text, source_class=source_class, method_map=method_map, imports=None, has_empty_cons=listener.has_empty_cons, ) # db.close() return True # Tests if __name__ == '__main__': from codart.utility.directory_utils import update_understand_database update_understand_database("C:/Users/Administrator/Downloads/udbs/jvlt-1.3.2.udb") main( source_class="XMLFormatter", source_package="net.sourceforge.jvlt.io", target_class="Entry", target_package="net.sourceforge.jvlt.core", method_name="getXMLForEntryInfo", udb_path="C:/Users/Administrator/Downloads/udbs/jvlt-1.3.2.udb" )
def execute_from_json_log(self, input_file_path=None, reset=True): if input_file_path is None: input_file_path = glob.glob( os.path.join(self.log_directory, 'best_refactoring_sequences*.json'))[0] # log_project_info(reset_=True, ) population = [] with open(input_file_path, 'r', encoding='utf-8') as fp: population_trimmed = json.load(fp) for chromosome in population_trimmed: chromosome_new = [] for gene_ in chromosome: refactoring_params = gene_[1] if refactoring_params.get('udb_path'): refactoring_params['udb_path'] = config.UDB_PATH if refactoring_params.get('project_dir'): refactoring_params['project_dir'] = config.PROJECT_PATH if refactoring_params.get('file_path'): refactoring_params['file_path'] = refactoring_params[ 'file_path'].replace(self.file_path_base_dir_old, config.PROJECT_ROOT_DIR) if refactoring_params.get('class_path'): refactoring_params['class_path'] = refactoring_params[ 'class_path'].replace(self.file_path_base_dir_old, config.PROJECT_ROOT_DIR) chromosome_new.append((REFACTORING_MAIN_MAP[gene_[0]], refactoring_params, gene_[0])) population.append(chromosome_new) # print(population) # quit() applicability_map = { 'Project': [], 'Sequence': [], 'Applied refactorings': [], 'Rejected refactorings': [] } for k, refactoring_sequence in enumerate(population): true_refactorings_count = 0 false_refactorings_count = 0 reset_project() # Apply sequence X to system S for refactoring_operation in refactoring_sequence: res = refactoring_operation[0](**refactoring_operation[1]) update_understand_database(config.UDB_PATH) if res: true_refactorings_count += 1 else: false_refactorings_count += 1 config.logger.info( f"Executed {refactoring_operation[2]} with status {res}") applicability_map['Project'].append(config.PROJECT_NAME) applicability_map['Sequence'].append(k) applicability_map['Applied refactorings'].append( true_refactorings_count) applicability_map['Rejected refactorings'].append( false_refactorings_count) continue # Dump refactored project dump_path = os.path.join( config.PROJECT_ROOT_DIR, f'{config.PROJECT_NAME}_refactored_with_algorithm{config.PROBLEM}_rand', f'dump{k}') if not os.path.exists(config.PROJECT_ROOT_DIR): os.mkdir(dump_path) shutil.copytree(config.PROJECT_PATH, dump_path) # Compute quality metrics log_project_info( reset_=False, quality_attributes_path=os.path.join( config.PROJECT_LOG_DIR, 'best_refactoring_sequences_objectives_extended.csv'), generation='-1', # config.MAX_ITERATIONS, testability_verbose=True, testability_log_path=os.path.join( config.PROJECT_LOG_DIR, f'classes_testability2_for_problem_{config.PROBLEM}_best_sequence_{k}.csv' )) # Log applied and rejected refactorings df = pd.DataFrame(data=applicability_map) df.to_csv(os.path.join(config.PROJECT_LOG_DIR, 'applicability_map.csv'), index=False) if reset: reset_project()
] all_metrics = [] for metric in attrs: cache = getattr(self, f'_{metric}') if cache is None: all_metrics.append(getattr(self, metric)) else: all_metrics.append(cache) return round(sum(all_metrics) / len(all_metrics), 5), round(sum(all_metrics), 5) if __name__ == '__main__': from codart.utility.directory_utils import update_understand_database update_understand_database(config.UDB_PATH) print(f"UDB path: {config.UDB_PATH}") design_quality_attribute = DesignQualityAttributes(config.UDB_PATH) metrics_dict = { "DSC": design_quality_attribute.DSC, "NOH": design_quality_attribute.NOH, "ANA": design_quality_attribute.ANA, "MOA": design_quality_attribute.MOA, "DAM": design_quality_attribute.DAM, "CAMC": design_quality_attribute.CAMC, "CIS": design_quality_attribute.CIS, "NOM": design_quality_attribute.NOM, "DCC": design_quality_attribute.DCC, "MFA": design_quality_attribute.MFA, "NOP": design_quality_attribute.NOP
# Random search for improving reusability while k < MAX_ITERATIONS and limit > 0: print("Iteration No.", k) index = random.randint(0, limit - 1) limit -= 1 print(f"index is {index}") individual = rand_pop.pop(index) print(f"len(individual) is {len(individual)}") # git restore prev changes git_restore(project_dir) # execute individual for refactoring, params in individual: print(params) try: refactoring(**params) except Exception as e: print(e) # update understand database update_understand_database(udb_path) # calculate objective obj_score = DesignQualityAttributes(udb_path=udb_path).reusability print("Objective Score", obj_score) if obj_score < score: score = obj_score best_answer = individual k += 1 print("=" * 75) print("Best Score", score) print("Best Answer", best_answer)
def _evaluate(self, x, out, *args, **kwargs): """ This method iterate over a population, execute the refactoring operations in each individual sequentially, and compute quality attributes for the refactored version of the program, as objectives of the search. By default, elementwise_evaluation is set to False, which implies the _evaluate retrieves a set of solutions. Args: x (Population): x is a matrix where each row is an individual, and each column a variable.\ We have one variable of type list (Individual) ==> x.shape = (len(Population), 1) """ objective_values = [] for k, individual_ in enumerate(x): # Stage 0: Git restore logger.debug("Executing git restore.") git_restore(config.PROJECT_PATH) logger.debug("Updating understand database after git restore.") update_understand_database(config.UDB_PATH) # Stage 1: Execute all refactoring operations in the sequence x logger.debug(f"Reached an Individual with size {len(individual_[0])}") for refactoring_operation in individual_[0]: res = refactoring_operation.do_refactoring() # Update Understand DB logger.debug(f"Updating understand database after {refactoring_operation.name}.") update_understand_database(config.UDB_PATH) # Stage 2: arr = Array('d', range(self.n_obj)) if self.evaluate_in_parallel: # Stage 2 (parallel mood): Computing quality attributes p1 = Process(target=calc_qmood_objectives, args=(arr,)) if self.n_obj == 8: p2 = Process(target=calc_testability_objective, args=(config.UDB_PATH, arr,)) p3 = Process(target=calc_modularity_objective, args=(config.UDB_PATH, arr,)) p1.start(), p2.start(), p3.start() p1.join(), p2.join(), p3.join() else: p1.start() p1.join() else: # Stage 2 (sequential mood): Computing quality attributes qmood_quality_attributes = DesignQualityAttributes(udb_path=config.UDB_PATH) arr[0] = qmood_quality_attributes.reusability arr[1] = qmood_quality_attributes.understandability arr[2] = qmood_quality_attributes.flexibility arr[3] = qmood_quality_attributes.functionality arr[4] = qmood_quality_attributes.effectiveness arr[5] = qmood_quality_attributes.extendability if self.n_obj == 8: arr[6] = testability_main(config.UDB_PATH, initial_value=config.CURRENT_METRICS.get("TEST", 1.0)) arr[7] = modularity_main(config.UDB_PATH, initial_value=config.CURRENT_METRICS.get("MODULE", 1.0)) if self.verbose_design_metrics: design_metrics = { "DSC": [qmood_quality_attributes.DSC], "NOH": [qmood_quality_attributes.NOH], "ANA": [qmood_quality_attributes.ANA], "MOA": [qmood_quality_attributes.MOA], "DAM": [qmood_quality_attributes.DAM], "CAMC": [qmood_quality_attributes.CAMC], "CIS": [qmood_quality_attributes.CIS], "NOM": [qmood_quality_attributes.NOM], "DCC": [qmood_quality_attributes.DCC], "MFA": [qmood_quality_attributes.MFA], "NOP": [qmood_quality_attributes.NOP] } self.log_design_metrics(design_metrics) del qmood_quality_attributes # Stage 3: Marshal objectives into vector objective_values.append([-1 * i for i in arr]) logger.info(f"Objective values for individual {k}: {[i for i in arr]}") # Stage 4: Marshal all objectives into out dictionary out['F'] = np.array(objective_values, dtype=float)