Beispiel #1
0
 def cs_filter(data_frame: pd.DataFrame) -> pd.DataFrame:
     """Filter out all commits that are not in the case study if one was
     selected."""
     if case_study is None or data_frame.empty:
         return data_frame
     # use a trie for fast prefix lookup
     revisions = CharTrie()
     for revision in case_study.revisions:
         revisions[revision.hash] = True
     return data_frame[data_frame["revision"].apply(
         lambda x: revisions.has_node(x.hash) != 0)]
Beispiel #2
0
class Solver:
    def __init__(self, cells, dictionary=None):
        self.cells = [
            Cell(
                c['letter'],
                c.get('points', 1),
                c.get('P', 1),
                c.get('S', 1),
            ) for c in cells
        ]
        self.letters = [c['letter'] for c in cells]
        self.candidates = {}  # word => (positions, value)
        self.dictionary = dictionary
        if not dictionary:
            self.dictionary = CharTrie()
            print('Loading custom words ... ', end="")
            with open('SK-custom.txt') as f:
                self.dictionary.update(
                    (w, True) for w in f.read().splitlines())
                print(len(self.dictionary))

    def word_value(self, visited):
        val = 0
        S = 1
        for pos in visited:
            cell = self.cells[pos]
            val += cell.points * cell.P
            S *= cell.S
        return val * S

    def next_char(self, visited, pos):
        visited = visited + (pos, )
        word = ''.join((self.letters[p] for p in visited))
        has = self.dictionary.has_node(word)
        if has & CharTrie.HAS_VALUE:
            newval = self.word_value(visited)
            if self.candidates.get(word, (None, 0))[1] < newval:
                self.candidates[word] = (visited, newval)
            # print(word)

        # Don't continue if thera are no words with this prefix
        if not has & CharTrie.HAS_SUBTRIE:
            return

        row = pos // 4
        col = pos % 4
        prev_row = row - 1
        next_row = row + 1
        prev_col = col - 1
        next_col = col + 1

        if next_row < 4:
            # Adds the charcter S the current pos
            pos = next_row * 4 + col
            if pos not in visited:
                self.next_char(visited, pos)
            #Adds the character SE the current pos
            pos = next_row * 4 + next_col
            if next_col < 4 and pos not in visited:
                self.next_char(visited, pos)

        if next_col < 4:
            # Adds the charcter E of the current pos
            pos = row * 4 + next_col
            if pos not in visited:
                self.next_char(visited, pos)
            #Adds the character NE the current pos
            pos = prev_row * 4 + next_col
            if prev_row >= 0 and pos not in visited:
                self.next_char(visited, pos)

        if prev_row >= 0:
            # Adds the charcter N the current pos
            pos = prev_row * 4 + col
            if pos not in visited:
                self.next_char(visited, pos)
            # Adds the charcter NW of the current pos
            pos = prev_row * 4 + prev_col
            if prev_col >= 0 and pos not in visited:
                self.next_char(visited, pos)

        if prev_col >= 0:
            # Adds the charcter W of the current pos
            pos = row * 4 + prev_col
            if pos not in visited:
                self.next_char(visited, pos)
            # Adds the charcter SW of the current pos
            pos = next_row * 4 + prev_col
            if next_row < 4 and pos not in visited:
                self.next_char(visited, pos)

    def solve_and_swipe(self):
        for pos in range(0, 16):
            self.next_char((), pos)

        # sort by length
        pyautogui.moveTo(x0, y0, duration=0.1)
        pyautogui.click(duration=0.1)
        for word, visited_val in self.candidates.items():
            print(word, visited_val[1])
            self.swipe(visited_val[0])

    def swipe(self, positions):
        grid = 94
        pos = positions[0]
        pyautogui.moveTo(x0 + (pos % 4) * grid,
                         y0 + (pos // 4) * grid,
                         duration=0.1)
        pyautogui.mouseDown(button='left',
                            logScreenshot=False,
                            _pause=False,
                            duration=0.1)
        for pos in positions[1:]:
            pyautogui.moveTo(x0 + (pos % 4) * grid,
                             y0 + (pos // 4) * grid,
                             duration=0.1)
        pyautogui.mouseUp(button='left',
                          logScreenshot=False,
                          _pause=False,
                          duration=0.1)
class Save:
    def __init__(self, season='recent'):
        self.athlete_web = nx.DiGraph()
        self.athletes_by_name = CharTrie()
        self.athletes_by_id = {}
        self.athletes_by_index = []
        self.race_history = set()
        self.athletes_considered = set()
        self.rankings = []
        self.search_queue = []
        self.season = season

    @classmethod
    def load(self, filename='my_save.bin'):
        with open(filename, 'rb') as file:
            s = pickle.load(file)
        return s

    def save(self, filename='my_save.bin'):
        with open(filename, 'wb') as file:
            pickle.dump(self, file)

    def update_athlete(self, athlete):
        if athlete.id in self:
            self[athlete.id].merge(athlete)
        else:
            self.athletes_by_id[athlete.id] = athlete
            self.athletes_by_name[athlete.name] = athlete
            self.athletes_by_index.append(athlete.id)
            self.athlete_web.add_node(athlete.id)

    def consider_athlete(self, a_ID):
        self.athletes_considered.add(a_ID)

    def add_race(self, race):
        self.race_history.add(race)

    def get_prefix_matches(self, name, count):
        if self.athletes_by_name.has_node(name):
            return tuple(map(lambda athlete: athlete.name + ': ' + str(athlete.id), \
             self.athletes_by_name.values(prefix=name)[:count]))
        else:
            return ()

    def get_ranking(self, id):
        return self.rankings.index(id) + 1

    def update_graph(self):
        for race in self.race_history:
            surpassers = []
            for runner_id in map(lambda x: x[0], race.results):
                for surpasser_id in surpassers:
                    self[runner_id].lose()
                    if self.athlete_web.has_edge(surpasser_id, runner_id):
                        self.athlete_web[surpasser_id][runner_id]['count'] += 1
                    else:
                        self.athlete_web.add_edge(surpasser_id,
                                                  runner_id,
                                                  count=1)
                surpassers.append(runner_id)

        for persons_defeated in map(lambda item: item[1],
                                    self.athlete_web.adj.items()):
            for person_defeated, connection in persons_defeated.items():
                connection['weight'] = connection['count'] / self[
                    person_defeated].losses

    #takes athletes as starting points and dives into athletic.net.
    def import_data(self, num_races_to_add, athlete_id=None, progress_frame=None, backup_csv=None, \
     focus_local=False, season='recent'):
        if athlete_id:
            self.search_queue.append(athlete_id)
        race_scraper.search_for_races(self, num_races_to_add, \
         progress_frame=progress_frame, focus_local=focus_local, season=season)
        self.update_graph()
        self.update_rankings()

        if backup_csv:
            with open(backup_csv, 'r') as file:
                reader = csv.reader(file)
                athletes = set(map(tuple, reader))
            with open(backup_csv, 'a') as file:
                writer = csv.writer(file, delimiter=',')
                for athlete in self.athletes_by_id.values():
                    if (athlete.name, str(athlete.id)) not in athletes:
                        writer.writerow([athlete.name, athlete.id])

    def update_rankings(self, precision=100):
        system = nx.to_numpy_array(self.athlete_web)
        rankings_by_index = self.get_rankings(system, precision=precision)
        score_pairs = [(self.athlete_at_index(pair[0]), pair[1])
                       for pair in enumerate(rankings_by_index)]
        score_pairs.sort(key=lambda x: -1 * x[1])
        self.rankings = list(map(lambda x: x[0], score_pairs))

    #We also assign an index elf.get_rankings(system)l athletes so we can reclaim them from a vector/matrix.
    def athlete_at_index(self, index):
        return self.athletes_by_index[index]

    def get_rankings(self, matrix, precision=100):
        current_scores = np.full(len(matrix), 1)
        for _ in range(precision):
            current_scores = np.matmul(matrix, current_scores)
        return current_scores

    #can subscript Save object using either athlete or athlete id for the same result.
    def __getitem__(self, request):
        if type(request) == int:
            return self.athletes_by_id[request]
        return self.athletes_by_name[request]

    def __contains__(self, request):
        if type(request) == int:
            return request in self.athletes_by_id
        return request in self.athletes_by_name

    def __len__(self):
        return len(self.athletes_by_index)

    def __repr__(self):
        return 'Save object containing ' + str(len(self)) + ' athletes.'

    def __str__(self):
        return ''.join([str(a[0] + 1) + '. ' + str(self.athletes_by_id[a[1]]) + '\n' for \
         a in enumerate(self.rankings)])