def test_prepare_authors_and_their_publications_with_one_pub_with_too_big_contrib( ): data = { PUBLICATION_ID: ["0", "1", "2"], IS_MONOGRAPH: [1, 0, 0], PUBLICATION_POINTS_FOR_AUTHOR: [[69, 0, 1]], PUBLICATION_CONTRIB_FOR_AUTHOR: [[96.0, 0, 1.0]], AUTHOR_ID: ["a"], IS_EMPLOYEE: [1], IS_PHD_STUDENT: [0], CONTRIBUTION: [1.0], IS_IN_N: [1], INITIAL_PUBS: [[0 for _ in range(3)] for _ in range(3)], } authors = prepare_authors_and_their_publications(data) data = normalize_data(data) test_authors = prepare_test_authors(data) test_publications = [ Publication("0", True, 69, 96.0), Publication("2", False, 1, 1.0), ] test_authors[0].publications = test_publications test_authors[0].to_considerate = [test_publications[1]] assert authors == test_authors
def create_example_publications_list(): publications = [ Publication("1", False, 100.0, 0.5), Publication("2", False, 50.0, 1.0), Publication("3", False, 10.0, 1.0), ] return publications
def test_prepare_authors_and_their_publications_with_multiple_authors(): data = { PUBLICATION_ID: ["0", "1", "2"], IS_MONOGRAPH: [1, 1, 0], PUBLICATION_POINTS_FOR_AUTHOR: [[0, 0, 1], [2, 0, 0], [0, 1, 0]], PUBLICATION_CONTRIB_FOR_AUTHOR: [[0, 0, 1.0], [0.5, 0, 0], [0, 0, 0]], AUTHOR_ID: ["a", "b", "c"], IS_EMPLOYEE: [1, 1, 0], IS_PHD_STUDENT: [0, 1, 1], CONTRIBUTION: [1.0, 0.5, 1.0], IS_IN_N: [1, 1, 1], INITIAL_PUBS: [[0 for _ in range(3)] for _ in range(3)], } authors = prepare_authors_and_their_publications(data) data = normalize_data(data) test_authors = prepare_test_authors(data) test_authors[0].publications = [Publication("2", False, 1, 1.0)] test_authors[0].to_considerate = test_authors[0].publications test_authors[1].publications = [Publication("0", True, 2, 0.5)] test_authors[1].to_considerate = test_authors[1].publications test_authors[2].publications = [] test_authors[2].to_considerate = [] assert authors == test_authors
def update_current_sums(curr_sums: dict, pub: Pub, auth: Author) -> dict: """ Updates temporary values needed to run greedy algorithm. Instead of recount values in every loop iteration, we simply update them. Args: curr_sums: dictionary with values to update contrib_sum: sum of contributions from all accepted publicatons (float) monograph_sum: sum of contributions from all accepted monographs (float) phd_and_outsiders: sum of contributions from all accepted phds' and outsiders' publicatons (float) pub: newly accepted publication auth: publication's author Returns: dictionary with updated values """ monograph_sum = curr_sums["monograph_sum"] phd_and_outsiders = curr_sums["phd_and_outsiders"] if pub.is_monograph(): monograph_sum += pub.get_contribution() if auth.is_phd_student() or not auth.is_in_n(): phd_and_outsiders += pub.get_contribution() result = { "contrib_sum": curr_sums["contrib_sum"] + pub.get_contribution(), "monograph_sum": monograph_sum, "phd_and_outsiders": phd_and_outsiders, } return result
def accept_publication(self, pub: Publication) -> bool: self.__check_if_publication_is_on_publications_list(pub) if pub not in self.accepted_publications and self.__check_limits(pub): self.accepted_publications.append(pub) pub.set_is_accepted(True) self.__accepted_pubs_contrib_sum += pub.get_contribution() if pub.is_monograph(): self.__accepted_mons_contrib_sum += pub.get_contribution() return True return False
def __check_moographs_limit(self, pub: Publication) -> bool: tmp_mons_contrib = self.__accepted_mons_contrib_sum + pub.get_contribution( ) if self.is_phd: return True elif not pub.is_monograph(): return True elif tmp_mons_contrib <= MONOGRAPH_COEFFICIENT * self.contribution: return True elif pub.get_points() > MONOGRAPH_LIMIT_MAX_POINTS: return True return False
def prepare_test_publications(ids: List[str], mons: List[bool], points: List[float], ctbs: List[float]): pubs = [] for p_id, mon, pts, cbs in zip(ids, mons, points, ctbs): if pts > 0 and cbs > 0: pubs.append(Publication(p_id, mon, pts, cbs)) return pubs
def __check_limits_for_phd_students(self, pub: Publication) -> bool: tmp_contrib = self.__accepted_pubs_contrib_sum + pub.get_contribution() if not self.is_phd: return True elif tmp_contrib <= PUBLICATIONS_COEFFICIENT_FOR_PHD: return True return False
def create_complex_publications_list(): pubs = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] mons = [True, True, True, False, True, False, False, False, True, True] points = [100.0, 10.0, 90.0, 20.0, 80.0, 30.0, 70.0, 40.0, 60.0, 50.0] contribs = [1.0, 0.0, 0.5, 1.0, 0.0, 0.5, 1.0, 0.0, 0.5, 1.0] publications = [] for pub_id, is_mono, pts, contrib in zip(pubs, mons, points, contribs): publications.append(Publication(pub_id, is_mono, pts, contrib)) return publications
def create_example_publication( publication_id: str = "id", is_mono: bool = False, points: float = 10.0, contrib: float = 0.1, author: Author = None, accepted: bool = False, ): return Publication(publication_id, is_mono, points, contrib, author, accepted)
def consider_single_publication(pub: Pub, curr_sums: dict, data: dict) -> bool: """ Checks if publication will be accepted and checks limits. Args: pub: publication curr_sums: dictionary with sums needed to decide if publication meets the limits. Keys: contrib_sum: sum of contributions from all accepted publicatons (float) monograph_sum: sum of contributions from all accepted monographs (float) phd_and_outsiders: sum of contributions from all accepted phds' and outsiders' publicatons (float) data: dictionary with data from file Returns: True if publication meets the limits. Otherwise returns False """ mono_modif = 0 phd_out_modif = 0 if pub.is_monograph(): mono_modif = pub.get_contribution() if pub.get_author().is_phd_student() or not pub.get_author().is_employee(): phd_out_modif = pub.get_contribution() tmp_sums = { "contrib_sum": curr_sums["contrib_sum"] + pub.get_contribution(), "monograph_sum": curr_sums["monograph_sum"] + mono_modif, "phd_and_outsiders": curr_sums["phd_and_outsiders"] + phd_out_modif, } return check_limits(data, tmp_sums)
def create_publications_list( pubs: List[str], mons: List[int], points: List[float], contribs: List[float], init: List[int] = None, ): """ Creates publications list for single author. Args: pubs: list of publications' ids mons: list that defines which publications are monographs points: lists that contains points from publications for single author contribs: list that contains contributions from publications for single author Returns: List of publications. Publications with 0 points or 0.0 contribution are not contained """ if init is None: init = [0 for _ in range(len(pubs))] assert len(pubs) == len(mons) assert len(points) == len(contribs) assert len(pubs) == len(contribs) assert len(init) == len(pubs) result = [] for pub_id, is_mon, pts, contrib, ini in zip(pubs, mons, points, contribs, init): if pts > 0 and contrib > 0: is_mon = False if is_mon == 0 else True ini = False if ini == 0 else True result.append(Publication(pub_id, is_mon, pts, contrib, None, ini)) return result
def test_publication__init(): publication = Publication(PUBLICATION_ID, IS_MONO, POINTS, CONTRIBUTION) assert publication.id == PUBLICATION_ID assert publication.is_mono == IS_MONO assert publication.points == POINTS assert publication.contribution == CONTRIBUTION
def __check_limits(self, pub: Publication) -> bool: return (self.__accepted_pubs_contrib_sum + pub.get_contribution() <= BASIC_CONTRIB_COEFFICIENT)
def __check_publications_limit(self, pub: Publication) -> bool: tmp_contrib = self.__accepted_pubs_contrib_sum + pub.get_contribution() return tmp_contrib <= PUBLICATIONS_COEFFICIENT * self.contribution
def get_temporary_pub_rate(pub: Publication): return pub.get_points() / pub.get_contribution()