def get(self, user: Union[User, Member]) -> List[str]: """ Get a corpus from the source of truth by user ID. """ self.assert_registered(user) corpus = cast(List[str], self.bot.redis.hvals(f"corpus:{user.id}")) if len(corpus) == 0: raise NoDataError(f"No data available for user {user}.") return corpus
def see_grades(self): """ Returns a string representing all disciplines ordered by their average grades Input: - Output: string - all disciplines ordered by their average grades """ disciplines_with_grades = self.repository.get_disciplines_with_grades() if len(disciplines_with_grades) < 1: raise NoDataError("No disciplines with grades to show") disciplines_with_grades = sorted(disciplines_with_grades, key=lambda d: d.value, reverse=True) disciplines_to_show = "\nDisciplines with grades in descending order of average grades:" count = 1 for d in disciplines_with_grades: disciplines_to_show += "\n" + str( count ) + ". " + d.discipline_name + " with the average of " + d.get_formated_average( ) count += 1 return disciplines_to_show
def see_best_students(self): """ Returns a string representing all students ordered by their average grades Input: - Output: string - all students ordered by their average grades """ best_students = self.repository.get_best_students() if len(best_students) < 1: raise NoDataError("No students with grades to show") best_students = sorted(best_students, key=lambda b: b.value, reverse=True) students_to_show = "\nBest students in descending order of average grades:" count = 1 for b in best_students: students_to_show += "\n" + str( count ) + ". " + b.student_name + " with the average of " + b.get_formated_average( ) count += 1 return students_to_show
def build_list(self, repository, header = "All students and diciplines"): """ Parses a repository's data into a string to be printed Input: Repository - repository to parse string - header to show at the beginning of the generated string Output: string - the parsed repository """ if repository.is_empty(): raise NoDataError("No data to show") data_string = "\n" data_string += header if repository.has_students() and repository.has_disciplines(): data_string += "\n" + generator.generate_chars('-', 121) + "\n|" + generator.generate_chars(' ', 4) + "Students" + generator.generate_chars(' ', 47) + "|" + generator.generate_chars(' ', 4) + "Disciplines" + generator.generate_chars(' ', 44) + "|\n" + generator.generate_chars('-', 121) students_length = len(repository.students.data) disciplines_length = len(repository.disciplines.data) max_length = max(students_length, disciplines_length) for i in range(max_length): if i < students_length: student_string = str(repository.students.data[i]) data_string += "\n| " + student_string + generator.generate_chars(' ', 57 - len(student_string)) + " | " else: data_string += "\n|" + generator.generate_chars(' ', 59) + "| " if i < disciplines_length: discipline_string = str(repository.disciplines.data[i]) data_string += discipline_string + generator.generate_chars(' ', 57 - len(discipline_string)) + " |" else: data_string += generator.generate_chars(' ', 58) + "|" data_string += "\n" + generator.generate_chars('-', 121) return data_string if repository.has_students(): data_string += "\n" + generator.generate_chars('-', 60) + "\nStudents\n" + generator.generate_chars('-', 60) for student in repository.students.data: data_string += "\n" + str(student) return data_string if repository.has_disciplines(): data_string += "\n" + generator.generate_chars('-', 60) + "\nDisciplines\n" + generator.generate_chars('-', 60) for discipline in repository.disciplines.data: data_string += "\n" + str(discipline) return data_string
async def forget(self, ctx: commands.Context, maybe_user: str = None, *args) -> None: """ Make Parrot delete all the data it has about you. """ if maybe_user is not None: try: userlike = Userlike() user = await userlike.convert(ctx, maybe_user) except UserNotFoundError: for command in self.forget.commands: if command.name == maybe_user: await command(ctx, *args) return raise else: user = ctx.author if user != ctx.author and ctx.author.id not in self.bot.owner_ids: raise UserPermissionError( "You are not allowed to make Parrot forget other users.") if not self.bot.corpora.has(user): raise NoDataError(f"No data available for user {user}.") confirm_code = ctx.message.id # Keep track of this confirmation by storing some information about it # in a dict. self.pending_confirmations[confirm_code] = { "author": ctx.author, "corpus_owner": user, } embed = ParrotEmbed( title="Are you sure?", description= f"This will permantently delete the data of {user}.\nTo confirm, paste the following command:\n`{self.bot.command_prefix}forget confirm {confirm_code}`", color_name="orange", ) embed.set_footer( text="Action will be automatically canceled in 1 minute.") await ctx.send(embed=embed, reference=ctx.message) # Delete the confirmation after 1 minute. await asyncio.sleep(60) try: del self.pending_confirmations[confirm_code] except KeyError: pass
def see_failing_students(self): """ Returns a string representing the failing students Input: - Output: string - all failing students """ faillings = self.services.get_failing_students() if len(faillings) < 1: raise NoDataError("No students failing at one or more disciplines") students_to_show = "\nStudents failing:" count = 1 for f in faillings: students_to_show += "\n" + str(count) + ". " + f.student_name + " at " + f.discipline_name + " with the average of " + f.get_formated_average() count += 1 return students_to_show
def download(url: str) -> dict: """Download and map raw data""" response = requests.get(url) ticker = re.findall(r'(?<=http://openinsider.com/screener\?s=)\w+', url)[0] soup = BeautifulSoup(response.text, 'lxml') try: table = pd.read_html(str(soup.findAll('table', {'class': 'tinytable'})))[0] except ValueError as e: raise ValueError(e.__str__() + f' - {ticker.upper()}') if len(table.columns) != 16: # unable to download error handling raise NoDataError(f'Unable to find data for {ticker.upper()}') table = table.drop(['X', '1d', '1w', '1m', '6m'], axis=1) table.columns = [ 'filingDate', 'startingDate', 'ticker', 'insiderName', 'insiderTitle', 'tradeType', 'price', 'quantity', 'sharesOwned', 'changeInSharesOwned', 'value' ] companyInfo = soup.find('div', {'id': 'subjectDetails'}).text.split(' - ') name = soup.find('div', { 'class': 'h1title' }).text.split(' - ')[1].strip().replace("'", "''") ticker = soup.find('div', { 'class': 'h1title' }).text.split(' - ')[0].strip().replace("'", "''") sector = companyInfo[0].strip().replace("'", "''") subSector = companyInfo[1].strip().replace("'", "''") industry = companyInfo[2].strip().replace("'", "''") cik = re.findall(r'\d+', ''.join(companyInfo))[0] company = datacontainer.Company(name, ticker, cik, sector, subSector, industry) rawTrades = datacontainer.Trades(table, company) return rawTrades
def delete_message(self, user: Union[User, Member], message_id: int) -> None: """ Delete a message (or list of messages) from a corpus. """ num_deleted = self.bot.redis.hdel(f"corpus:{user.id}", str(message_id)) if num_deleted == 0: raise NoDataError(f"No data available for user {user}.")
def delete(self, user: Union[User, Member]) -> None: """ Delete a corpus from the source of truth. """ num_deleted = self.bot.redis.delete(f"corpus:{user.id}") if num_deleted == 0: raise NoDataError(f"No data available for user {user}.")