From 032a11cada11f5b6465cf8cc69e1923e95a502f0 Mon Sep 17 00:00:00 2001 From: Aaron Cutright Date: Thu, 18 Mar 2021 20:30:31 -0400 Subject: [PATCH 01/19] Accept stdin args for terminal.py --- terminal.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/terminal.py b/terminal.py index 7dcf72edb9c..e5faa38c273 100644 --- a/terminal.py +++ b/terminal.py @@ -82,6 +82,7 @@ def main(): # Print first welcome message and help print("\nWelcome to Gamestonk Terminal 🚀\n") should_print_help = True + parsed_stdin = False # Loop forever and ever while True: @@ -90,8 +91,12 @@ def main(): print_help(s_ticker, s_start, s_interval, b_is_stock_market_open()) should_print_help = False - # Get input command from user - if session and gtff.USE_PROMPT_TOOLKIT: + # Get input command from stdin or user + if not parsed_stdin and len(sys.argv) > 1: + as_input = " ".join(sys.argv[1:]) + parsed_stdin = True + print(f"{get_flair()}> {as_input}") + elif session and gtff.USE_PROMPT_TOOLKIT: as_input = session.prompt(f"{get_flair()}> ", completer=completer) else: as_input = input(f"{get_flair()}> ") From 90fa67f8dc0427f316cad4688fe12e2f1dd8e544 Mon Sep 17 00:00:00 2001 From: didier Date: Fri, 19 Mar 2021 19:05:25 +0000 Subject: [PATCH 02/19] Refactor comparison analysis menu --- .../comparison_analysis/ca_controller.py | 224 ++++++++++++++++++ .../comparison_analysis/ca_menu.py | 168 ------------- .../comparison_analysis/yahoo_finance_api.py | 10 +- 3 files changed, 230 insertions(+), 172 deletions(-) create mode 100644 gamestonk_terminal/comparison_analysis/ca_controller.py delete mode 100644 gamestonk_terminal/comparison_analysis/ca_menu.py diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py new file mode 100644 index 00000000000..b790a9a63b4 --- /dev/null +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -0,0 +1,224 @@ +"""Comparison Analysis Controller Module""" +__docformat__ = "numpy" + +import argparse +import requests +from typing import List +from datetime import datetime +import pandas as pd + +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal import config_terminal as cfg +from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn +from gamestonk_terminal.comparison_analysis import yahoo_finance_api as yf_api +from gamestonk_terminal.menu import session +from prompt_toolkit.completion import NestedCompleter + + +class ComparisonAnalysisController: + """Comparison Analysis Controller class""" + + # Command choices + CHOICES = [ + "help", + "q", + "quit", + "get", + "select", + "historical", + "corr", + ] + + def __init__( + self, stock: pd.DataFrame, ticker: str, start: datetime, interval: str + ): + """Constructor""" + self.user = False + self.similar = [] + self.stock = stock + self.ticker = ticker + self.start = start + self.interval = interval + self.ca_parser = argparse.ArgumentParser(add_help=False, prog="ca") + self.ca_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + @staticmethod + def print_help(self): + """Print help""" + + s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"] + + if self.start: + print( + f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})" + ) + else: + print(f"\n{s_intraday} Stock: {self.ticker}") + + s_similar_source = ("Polygon API", "User")[self.user] + + if self.similar: + print(f"[{s_similar_source}] Similar Companies: {', '.join(self.similar)}") + else: + print(f"No similar companies [{s_similar_source}]") + + print("\nComparison Analysis Mode:") + print(" help show this comparison analysis menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print(" get get similar companies [Polygon API]") + print(" select select similar companies") + print("") + if self.similar: + print(" historical historical data comparison") + print(" corr correlation between similar companies") + print("") + return + + @staticmethod + def get_similar_companies(self, other_args: List[str]): + """ Get similar companies. [Source: Polygon API] """ + parser = argparse.ArgumentParser( + add_help=False, + prog="get", + description="""Get similar companies to compare with.""", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + result = requests.get( + f"https://api.polygon.io/v1/meta/symbols/{self.ticker.upper()}/company?&apiKey={cfg.API_POLYGON_KEY}" + ) + + if result.status_code == 200: + self.similar = result.json()["similar"] + print(f"[Polygon API] Similar Companies: {', '.join(self.similar)}") + self.user = False + else: + print(result.json()["error"]) + + except Exception as e: + print(e) + + print("") + return + + @staticmethod + def select_similar_companies(self, other_args: List[str]): + """ Select similar companies, e.g. NIO,XPEV,LI""" + parser = argparse.ArgumentParser( + add_help=False, + prog="select", + description="""Select similar companies to compare with.""", + ) + parser.add_argument( + "-s", + "--similar", + dest="l_similar", + type=lambda s: [str(item) for item in s.split(",")], + default=[], + help="similar companies to compare with.", + ) + + try: + # For the case where a user uses: 'select NIO,XPEV,LI' + if other_args: + if "-" not in other_args[0]: + other_args.insert(0, "-s") + + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + self.similar = ns_parser.l_similar + self.user = True + + except Exception as e: + print(e) + + print("") + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + (known_args, other_args) = self.ca_parser.parse_known_args(an_input.split()) + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help command""" + self.print_help(self) + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - quit the program""" + return True + + def call_get(self, other_args: List[str]): + """Process get command""" + self.get_similar_companies(self, other_args) + + def call_select(self, other_args: List[str]): + """Process select command""" + self.select_similar_companies(self, other_args) + + def call_historical(self, other_args: List[str]): + """Process historical command""" + yf_api.historical( + other_args, self.stock, self.ticker, self.start, self.interval, self.similar + ) + + def call_corr(self, other_args: List[str]): + """Process correlation command""" + yf_api.correlation( + other_args, self.stock, self.ticker, self.start, self.interval, self.similar + ) + + +def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str): + """Comparison Analysis Menu""" + + ca_controller = ComparisonAnalysisController(stock, ticker, start, interval) + ca_controller.call_help(None) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in ca_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (ca)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (ca)> ") + + try: + process_input = ca_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exist\n") + continue diff --git a/gamestonk_terminal/comparison_analysis/ca_menu.py b/gamestonk_terminal/comparison_analysis/ca_menu.py deleted file mode 100644 index 0e2d86fd19b..00000000000 --- a/gamestonk_terminal/comparison_analysis/ca_menu.py +++ /dev/null @@ -1,168 +0,0 @@ -import argparse -import requests - -from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn - -from gamestonk_terminal.comparison_analysis import yahoo_finance_api as yf_api - - -def get_similar_companies(l_args, s_ticker): - """ Get similar companies. [Source: Polygon API] """ - parser = argparse.ArgumentParser( - add_help=False, - prog="get", - description="""Get similar companies to compare with.""", - ) - - l_similar = [] - try: - ns_parser = parse_known_args_and_warn(parser, l_args) - if not ns_parser: - return - - result = requests.get( - f"https://api.polygon.io/v1/meta/symbols/{s_ticker}/company?&apiKey={cfg.API_POLYGON_KEY}" - ) - - if result.status_code == 200: - l_similar = result.json()["similar"] - - except Exception as e: - print(e) - - print("") - return l_similar - - -def select_similar_companies(l_args): - """ Select similar companies, e.g. NIO,XPEV,LI""" - parser = argparse.ArgumentParser( - add_help=False, - prog="select", - description="""Select similar companies to compare with.""", - ) - parser.add_argument( - "-s", - "--similar", - dest="l_similar", - type=lambda s: [str(item) for item in s.split(",")], - default=[], - help="similar companies to compare with.", - ) - - try: - # For the case where a user uses: 'select NIO,XPEV,LI' - if l_args: - if "-" not in l_args[0]: - l_args.insert(0, "-s") - - ns_parser = parse_known_args_and_warn(parser, l_args) - if not ns_parser: - return - - print("") - return ns_parser.l_similar - - except Exception as e: - print(e) - print("") - return [] - - -def print_comparison_analysis(s_ticker, s_start, s_interval, l_similar, b_user): - """ Print help """ - - s_intraday = (f"Intraday {s_interval}", "Daily")[s_interval == "1440min"] - - if s_start: - print(f"\n{s_intraday} Stock: {s_ticker} (from {s_start.strftime('%Y-%m-%d')})") - else: - print(f"\n{s_intraday} Stock: {s_ticker}") - - s_similar_source = ("Polygon API", "User")[b_user] - - if l_similar: - print(f"[{s_similar_source}] Similar Companies: {', '.join(l_similar)}") - else: - print(f"No similar companies [{s_similar_source}]") - - print("\nComparison Analysis Mode:") - print(" help show this comparison analysis menu again") - print(" q quit this menu, and shows back to main menu") - print(" quit quit to abandon program") - print("") - print(" get get similar companies [Polygon API]") - print(" select select similar companies") - print("") - print(" historical historical data comparison") - print(" corr correlation between similar companies") - print("") - return - - -def ca_menu(df_stock, s_ticker, s_start, s_interval): - - # Add list of arguments that the comparison analysis parser accepts - ca_parser = argparse.ArgumentParser(prog="ca", add_help=False) - ca_parser.add_argument( - "cmd", - choices=[ - "help", - "q", - "quit", - "get", - "select", - "historical", - "corr", - ], - ) - - b_user = False - l_similar = get_similar_companies([], s_ticker) - print_comparison_analysis(s_ticker, s_start, s_interval, l_similar, b_user) - - # Loop forever and ever - while True: - # Get input command from user - as_input = input(f"{get_flair()} (ca)> ") - - # Parse fundamental analysis command of the list of possible commands - try: - (ns_known_args, l_args) = ca_parser.parse_known_args(as_input.split()) - - except SystemExit: - print("The command selected doesn't exist\n") - continue - - if ns_known_args.cmd == "help": - print_comparison_analysis(s_ticker, s_start, s_interval, l_similar, b_user) - - elif ns_known_args.cmd == "q": - # Just leave the CA menu - return False - - elif ns_known_args.cmd == "quit": - # Abandon the program - return True - - elif ns_known_args.cmd == "get": - l_similar = get_similar_companies(l_args, s_ticker) - b_user = False - - elif ns_known_args.cmd == "select": - l_similar = select_similar_companies(l_args) - b_user = True - - elif ns_known_args.cmd == "historical": - yf_api.historical( - l_args, df_stock, s_ticker, s_start, s_interval, l_similar - ) - - elif ns_known_args.cmd == "corr": - yf_api.correlation( - l_args, df_stock, s_ticker, s_start, s_interval, l_similar - ) - - else: - print("Command not recognized!") diff --git a/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py b/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py index edd3e726d4d..163ff3c09d7 100644 --- a/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py +++ b/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py @@ -108,9 +108,10 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): plt.show() print("") + except SystemExit: + print("Similar companies need to be provided", "\n") except Exception as e: - print(e) - print("") + print(e, "\n") def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar): @@ -209,6 +210,7 @@ def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar): print("") + except SystemExit: + print("Similar companies need to be provided", "\n") except Exception as e: - print(e) - print("") + print(e, "\n") From 482c032af702df33f218b74e50ae01e35621c276 Mon Sep 17 00:00:00 2001 From: didier Date: Fri, 19 Mar 2021 19:12:01 +0000 Subject: [PATCH 03/19] Thoughs of the day under feature flag --- gamestonk_terminal/feature_flags.py | 10 ++++++++++ terminal.py | 20 +++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/gamestonk_terminal/feature_flags.py b/gamestonk_terminal/feature_flags.py index f8360c1872b..3eaebcd2bb2 100644 --- a/gamestonk_terminal/feature_flags.py +++ b/gamestonk_terminal/feature_flags.py @@ -1,9 +1,16 @@ from distutils.util import strtobool import os +# Use coloring features USE_COLOR = strtobool(os.getenv("GTFF_USE_COLOR", "True")) + +# Select console flair (choose from config_terminal.py list) USE_FLAIR = os.getenv("GTFF_USE_FLAIR") or "stars" + +# Enable interactive matplotlib mode USE_ION = strtobool(os.getenv("GTFF_USE_ION", "True")) + +# Enable Prompt Toolkit USE_PROMPT_TOOLKIT = strtobool(os.getenv("GTFF_USE_PROMPT_TOOLKIT", "False")) # Enable Prediction features @@ -11,3 +18,6 @@ ENABLE_PREDICT = strtobool(os.getenv("GTFF_ENABLE_PREDICT", "False")) # Enable plot autoscaling USE_PLOT_AUTOSCALING = strtobool(os.getenv("GTFF_USE_PLOT_AUTOSCALING", "False")) + +# Enable thoughts of the day +ENABLE_THOUGHTS_DAY = strtobool(os.getenv("GTFF_ENABLE_THOUGHTS_DAY", "False")) diff --git a/terminal.py b/terminal.py index 6b995ffb1fe..9f43e129766 100644 --- a/terminal.py +++ b/terminal.py @@ -22,7 +22,7 @@ from gamestonk_terminal.menu import session from gamestonk_terminal.papermill import papermill_controller as mill from gamestonk_terminal.behavioural_analysis import ba_controller from gamestonk_terminal.technical_analysis import ta_menu as tam -from gamestonk_terminal.comparison_analysis import ca_menu as cam +from gamestonk_terminal.comparison_analysis import ca_controller from gamestonk_terminal.options import op_menu as opm from gamestonk_terminal.fred import fred_menu as fm from gamestonk_terminal.portfolio import port_menu @@ -86,12 +86,13 @@ def main(): print("\nWelcome to Gamestonk Terminal 🚀\n") should_print_help = True - print("-------------------") - try: - thought.get_thought_of_the_day() - except Exception as e: - print(e) - print("") + if gtff.ENABLE_THOUGHTS_DAY: + print("-------------------") + try: + thought.get_thought_of_the_day() + except Exception as e: + print(e) + print("") # Loop forever and ever while True: @@ -148,7 +149,8 @@ def main(): else: print( - "No ticker selected. Use 'load ticker' to load the ticker you want to look at." + "No ticker selected. Use 'load ticker' to load the ticker you want to look at.", + "\n", ) main_cmd = True @@ -181,7 +183,7 @@ def main(): b_quit = rm.res_menu(s_ticker, s_start, s_interval) elif ns_known_args.opt == "ca": - b_quit = cam.ca_menu(df_stock, s_ticker, s_start, s_interval) + b_quit = ca_controller.menu(df_stock, s_ticker, s_start, s_interval) elif ns_known_args.opt == "fa": b_quit = fam.fa_menu(s_ticker, s_start, s_interval) From 3adaa0187785d446b14e873e7c835a8c5ca6d1db Mon Sep 17 00:00:00 2001 From: didier Date: Fri, 19 Mar 2021 19:12:24 +0000 Subject: [PATCH 04/19] pedantic part I --- gamestonk_terminal/main_helper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gamestonk_terminal/main_helper.py b/gamestonk_terminal/main_helper.py index 2444b02d122..bd74782c34e 100644 --- a/gamestonk_terminal/main_helper.py +++ b/gamestonk_terminal/main_helper.py @@ -278,6 +278,7 @@ def candle(s_ticker: str, s_start: str): candle_linewidth=1.0, candle_width=0.8, volume_linewidth=1.0 ), ) + print("") def view(l_args, s_ticker, s_start, s_interval, df_stock): From 77a6fd58276a54fcf4aa9fc0934b9a0f19efc87f Mon Sep 17 00:00:00 2001 From: didier Date: Fri, 19 Mar 2021 19:13:44 +0000 Subject: [PATCH 05/19] Use upper letters in stock loaded --- gamestonk_terminal/main_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestonk_terminal/main_helper.py b/gamestonk_terminal/main_helper.py index bd74782c34e..6496f714735 100644 --- a/gamestonk_terminal/main_helper.py +++ b/gamestonk_terminal/main_helper.py @@ -157,7 +157,7 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock): return [s_ticker, s_start, s_interval, df_stock] # Update values: - s_ticker = ns_parser.s_ticker + s_ticker = ns_parser.s_ticker.upper() s_start = ns_parser.s_start_date s_interval = str(ns_parser.n_interval) + "min" From 4cf1590872af71c284f6347e174cd7d21d604ff2 Mon Sep 17 00:00:00 2001 From: didier Date: Fri, 19 Mar 2021 20:43:41 +0000 Subject: [PATCH 06/19] Compare multiple tickers income --- .../comparison_analysis/ca_controller.py | 8 + .../comparison_analysis/market_watch_api.py | 429 ++++++++++++++++++ gamestonk_terminal/helper_funcs.py | 4 +- 3 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 gamestonk_terminal/comparison_analysis/market_watch_api.py diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py index b790a9a63b4..0041e58ff32 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -11,6 +11,7 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn from gamestonk_terminal.comparison_analysis import yahoo_finance_api as yf_api +from gamestonk_terminal.comparison_analysis import market_watch_api as mw_api from gamestonk_terminal.menu import session from prompt_toolkit.completion import NestedCompleter @@ -27,6 +28,7 @@ class ComparisonAnalysisController: "select", "historical", "corr", + "income", ] def __init__( @@ -77,6 +79,8 @@ class ComparisonAnalysisController: print(" historical historical data comparison") print(" corr correlation between similar companies") print("") + print(" income income financials comparison") + print("") return @staticmethod @@ -193,6 +197,10 @@ class ComparisonAnalysisController: other_args, self.stock, self.ticker, self.start, self.interval, self.similar ) + def call_income(self, other_args: List[str]): + """Process income command""" + mw_api.compare_income(other_args, self.ticker, self.similar) + def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str): """Comparison Analysis Menu""" diff --git a/gamestonk_terminal/comparison_analysis/market_watch_api.py b/gamestonk_terminal/comparison_analysis/market_watch_api.py new file mode 100644 index 00000000000..3f76a3d67e5 --- /dev/null +++ b/gamestonk_terminal/comparison_analysis/market_watch_api.py @@ -0,0 +1,429 @@ +""" Comparison Analysis Market Watch View """ +__docformat__ = "numpy" + +import argparse +import requests +import pandas as pd +from bs4 import BeautifulSoup +from typing import List, Dict, Tuple +from gamestonk_terminal.helper_funcs import ( + get_user_agent, + parse_known_args_and_warn, + patch_pandas_text_adjustment, + financials_colored_values, +) +from gamestonk_terminal import feature_flags as gtff + + +def compare_income(other_args: List[str], ticker: str, similar: List[str]): + """Compare income between companies + + Parameters + ---------- + other_args : List[str] + Command line arguments to be processed with argparse + ticker : str + Main ticker to compare income + similar : List[str] + Similar companies to compare income with + """ + parser = argparse.ArgumentParser( + add_help=False, + prog="income", + description=""" + Prints either yearly or quarterly income statement the company, and compares + it against similar companies. [Source: Market Watch] + """, + ) + parser.add_argument( + "-s", + "--similar", + dest="l_similar", + type=lambda s: [str(item) for item in s.split(",")], + default=[], + help="similar companies to compare with.", + ) + parser.add_argument( + "-a", + "--also", + dest="l_also", + type=lambda s: [str(item) for item in s.split(",")], + default=[], + help="apart from loaded similar companies also compare with.", + ) + parser.add_argument( + "-q", + "--quarter", + action="store_true", + default=False, + dest="b_quarter", + help="Quarter financial data flag.", + ) + parser.add_argument( + "-t", + "--timeframe", + dest="s_timeframe", + type=str, + default=None, + help="Specify yearly/quarterly timeframe. Default is last.", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + if ns_parser.l_similar: + similar = ns_parser.l_similar + + similar += ns_parser.l_also + + # Add main ticker to similar list of companies + similar.insert(0, ticker) + + l_timeframes, ddf_financials = prepare_comparison_financials( + similar, "income", ns_parser.b_quarter + ) + + if ns_parser.s_timeframe: + if ns_parser.s_timeframe not in l_timeframes: + raise ValueError( + f"Timeframe {ns_parser.s_timeframe} should be one of {l_timeframes}" + ) + s_timeframe = ns_parser.s_timeframe + else: + s_timeframe = l_timeframes[-1] + + df_financials_compared = combine_similar_financials( + ddf_financials, similar, s_timeframe + ) + + if gtff.USE_COLOR: + df_financials_compared = df_financials_compared.applymap( + financials_colored_values + ) + + patch_pandas_text_adjustment() + pd.set_option("display.max_colwidth", None) + pd.set_option("display.max_rows", None) + + df_financials_compared.index.name = s_timeframe + print(df_financials_compared.to_string()) + print("") + + except Exception as e: + print(e) + print("") + return + + +def balance(l_args, s_ticker): + parser = argparse.ArgumentParser( + add_help=False, + prog="balance", + description=""" + Prints either yearly or quarterly assets from balance sheet of the company. + The following fields are expected: Cash & Short Term Investments, Cash & Short Term + Investments Growth, Cash Only, Short-Term Investments, Cash & ST Investments / Total + Assets, Total Accounts Receivable, Total Accounts Receivable Growth, Accounts + Receivables, Net, Accounts Receivables, Gross, Bad Debt/Doubtful Accounts, Other + Receivable, Accounts Receivable Turnover, Inventories, Finished Goods, Work in + Progress, Raw Materials, Progress Payments & Other, Other Current Assets, + Miscellaneous Current Assets, Net Property, Plant & Equipment, Property, Plant & + Equipment - Gross, Buildings, Land & Improvements, Computer Software and Equipment, + Other Property, Plant & Equipment, Accumulated Depreciation, Total Investments and + Advances, Other Long-Term Investments, Long-Term Note Receivables, Intangible Assets, + Net Goodwill, Net Other Intangibles, Other Assets. + + Prints either yearly or quarterly liabilities and shareholders' equity from balance + sheet of the company. The following fields are expected: ST Debt & Current Portion LT + Debt, Short Term Debt, Current Portion of Long Term Debt, Accounts Payable, Accounts + Payable Growth, Income Tax Payable, Other Current Liabilities, Dividends Payable, + Accrued Payroll, Miscellaneous Current Liabilities, Long-Term Debt, Long-Term Debt + excl. Capitalized Leases, Non-Convertible Debt, Convertible Debt, Capitalized Lease + Obligations, Provision for Risks & Charges, Deferred Taxes, Deferred Taxes - Credits, + Deferred Taxes - Debit, Other Liabilities, Other Liabilities (excl. Deferred Income), + Deferred Income, Non-Equity Reserves, Total Liabilities / Total Assets, Preferred Stock + (Carrying Value), Redeemable Preferred Stock, Non-Redeemable Preferred Stock, Common + Equity (Total), Common Equity/Total Assets, Common Stock Par/Carry Value, Retained + Earnings, ESOP Debt Guarantee, Cumulative Translation Adjustment/Unrealized For. Exch. + Gain, Unrealized Gain/Loss Marketable Securities, Revaluation Reserves, Treasury Stock, + Total Shareholders' Equity, Total Shareholders' Equity / Total Assets, Accumulated + Minority Interest, Total Equity, Total Current Assets, Total Assets, Total Current + Liabilities, Total Liabilities, and Liabilities & Shareholders' Equity. + [Source: Market Watch] + """, + ) + + parser.add_argument( + "-q", + "--quarter", + action="store_true", + default=False, + dest="b_quarter", + help="Quarter fundamental data flag.", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, l_args) + if not ns_parser: + return + + df_financials = prepare_df_financials(s_ticker, "balance", ns_parser.b_quarter) + + if gtff.USE_COLOR: + df_financials = df_financials.applymap(financials_colored_values) + + patch_pandas_text_adjustment() + pd.set_option("display.max_colwidth", None) + pd.set_option("display.max_rows", None) + + print(df_financials.to_string(index=False)) + print("") + + except Exception as e: + print(e) + print("") + return + + +def cash(l_args, s_ticker): + parser = argparse.ArgumentParser( + add_help=False, + prog="cash_flow", + description=""" + Prints either yearly or quarterly cash flow operating activities of the company. + The following fields are expected: Net Income before Extraordinaries, Net Income + Growth, Depreciation, Depletion & Amortization, Depreciation and Depletion, + Amortization of Intangible Assets, Deferred Taxes & Investment Tax Credit, Deferred + Taxes, Investment Tax Credit, Other Funds, Funds from Operations, Extraordinaries, + Changes in Working Capital, Receivables, Accounts Payable, Other Assets/Liabilities, + and Net Operating Cash Flow Growth. + Prints either yearly or quarterly cash flow investing activities of the company. + The following fields are expected: Capital Expenditures, Capital Expenditures Growth, + Capital Expenditures/Sales, Capital Expenditures (Fixed Assets), Capital Expenditures + (Other Assets), Net Assets from Acquisitions, Sale of Fixed Assets & Businesses, + Purchase/Sale of Investments, Purchase of Investments, Sale/Maturity of Investments, + Other Uses, Other Sources, Net Investing Cash Flow Growth. + Prints either yearly or quarterly cash flow financing activities of the company. + The following fields are expected: Cash Dividends Paid - Total, Common Dividends, + Preferred Dividends, Change in Capital Stock, Repurchase of Common & Preferred Stk., + Sale of Common & Preferred Stock, Proceeds from Stock Options, Other Proceeds from Sale + of Stock, Issuance/Reduction of Debt, Net, Change in Current Debt, Change in Long-Term + Debt, Issuance of Long-Term Debt, Reduction in Long-Term Debt, Other Funds, Other Uses, + Other Sources, Net Financing Cash Flow Growth, Net Financing Cash Flow/Sales, Exchange + Rate Effect, Miscellaneous Funds, Net Change in Cash, Free Cash Flow, Free Cash Flow + Growth, Free Cash Flow Yield, Net Operating Cash Flow, Net Investing Cash Flow, Net + Financing Cash Flow. + [Source: Market Watch] + """, + ) + + parser.add_argument( + "-q", + "--quarter", + action="store_true", + default=False, + dest="b_quarter", + help="Quarter fundamental data flag.", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, l_args) + if not ns_parser: + return + + df_financials = prepare_df_financials(s_ticker, "cashflow", ns_parser.b_quarter) + + if gtff.USE_COLOR: + df_financials = df_financials.applymap(financials_colored_values) + + patch_pandas_text_adjustment() + pd.set_option("display.max_colwidth", None) + pd.set_option("display.max_rows", None) + + print(df_financials.to_string(index=False)) + print("") + + except Exception as e: + print(e) + print("") + return + + +def prepare_df_financials( + ticker: str, statement: str, quarter: bool = False +) -> pd.DataFrame: + """Builds a DataFrame with financial statements for a given company + + Parameters + ---------- + ticker : str + Company's stock ticker + statement : str + Either income, balance or cashflow + quarter : bool, optional + Return quarterly financial statements instead of annual, by default False + + Returns + ------- + pd.DataFrame + A DataFrame with financial info + + Raises + ------ + ValueError + If statement is not income, balance or cashflow + """ + financial_urls = { + "income": { + "quarter": "https://www.marketwatch.com/investing/stock/{}/financials/income/quarter", + "annual": "https://www.marketwatch.com/investing/stock/{}/financials/income", + }, + "balance": { + "quarter": "https://www.marketwatch.com/investing/stock/{}/financials/balance-sheet/quarter", + "annual": "https://www.marketwatch.com/investing/stock/{}/financials/balance-sheet", + }, + "cashflow": { + "quarter": "https://www.marketwatch.com/investing/stock/{}/financials/cash-flow/quarter", + "annual": "https://www.marketwatch.com/investing/stock/{}/financials/cash-flow", + }, + } + + if statement not in financial_urls.keys(): + raise ValueError(f"type {statement} is not in {financial_urls.keys()}") + + if quarter: + period = "quarter" + else: + period = "annual" + + text_soup_financials = BeautifulSoup( + requests.get( + financial_urls[statement][period].format(ticker), + headers={"User-Agent": get_user_agent()}, + ).text, + "lxml", + ) + + # Define financials columns + a_financials_header = list() + for financials_header in text_soup_financials.findAll( + "th", {"class": "overflow__heading"} + ): + a_financials_header.append(financials_header.text.strip("\n").split("\n")[0]) + + s_header_end_trend = ("5-year trend", "5- qtr trend")[quarter] + df_financials = pd.DataFrame( + columns=a_financials_header[0 : a_financials_header.index(s_header_end_trend)] + ) + + find_table = text_soup_financials.findAll( + "div", {"class": "element element--table table--fixed financials"} + ) + + if not find_table: + return df_financials + + financials_rows = find_table[0].findAll( + "tr", {"class": ["table__row is-highlighted", "table__row"]} + ) + + for a_row in financials_rows: + constructed_row = list() + financial_columns = a_row.findAll( + "td", {"class": ["overflow__cell", "overflow__cell fixed--column"]} + ) + + if not financial_columns: + continue + + for a_column in financial_columns: + column_to_text = a_column.text.strip() + if "\n" in column_to_text: + column_to_text = column_to_text.split("\n")[0] + + if column_to_text == "": + continue + constructed_row.append(column_to_text) + + df_financials.loc[len(df_financials)] = constructed_row + + return df_financials + + +def prepare_comparison_financials( + similar: List[str], statement: str, quarter: bool +) -> Tuple[List[str], Dict[str, pd.DataFrame]]: + """Builds a dictionary of DataFrame with financial statements for list of tickers + + Parameters + ---------- + similar : List[str] + List of similar stock tickers + statement : str + Either income, balance or cashflow + quarter : bool + Return quarterly financial statements instead of annual, by default False + + Returns + ------- + List[str] + List of index headers + Dict[str, pd.DataFrame] + A dictionary of DataFrame with financial info from list of similar tickers + """ + + financials = {} + # Get financial dataframe of each company + for symbol in similar: + financials[symbol] = prepare_df_financials( + symbol, statement, quarter + ).set_index("Item") + + items = [] + # Get common headers between tickers + for symbol in similar: + if len(financials[symbol].columns) > len(items): + items = financials[symbol].columns + + # Add columns with N/A when data is not available, to have similar columns + for symbol in similar: + if len(financials[symbol].columns) < len(items): + for item in items: + if item not in financials[symbol].columns: + financials[symbol][item] = "N/A" + financials[symbol] = financials[symbol].reindex(sorted(items), axis=1) + + return list(items), financials + + +def combine_similar_financials( + financials: Dict[str, pd.DataFrame], + similar: List[str], + timeframe: str, +) -> pd.DataFrame: + """Builds a DataFrame with financial statements from a certain timeframe of a list of tickers + + Parameters + ---------- + Dict[str, pd.DataFrame] + A dictionary of DataFrame with financial info from list of similar tickers + similar : List[str] + List of similar stock tickers + statement : str + Either income, balance or cashflow + + Returns + ------- + pd.DataFrame + A DataFrame with financial statements from a certain timeframe of a list of tickers + """ + + compare_financials = financials[similar[0]][timeframe].to_frame() + compare_financials.rename(columns={timeframe: similar[0]}, inplace=True) + + for symbol in similar[1:]: + compare_financials[symbol] = financials[symbol][timeframe] + + return compare_financials diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py index 1f0ab039d11..7449951a1a8 100644 --- a/gamestonk_terminal/helper_funcs.py +++ b/gamestonk_terminal/helper_funcs.py @@ -293,7 +293,9 @@ def parse_known_args_and_warn(parser, l_args): def financials_colored_values(val: str) -> str: - if sum(c.isalpha() for c in val) < 2: + if val == "N/A": + val = f"{Fore.YELLOW}{val}{Style.RESET_ALL}" + elif sum(c.isalpha() for c in val) < 2: if "%" in val: if "-" in val: val = f"{Fore.RED}{val}{Style.RESET_ALL}" From 9194d4af6fa6bfc0b52a8ce4bcd1e82b07b2dabc Mon Sep 17 00:00:00 2001 From: didier Date: Sat, 20 Mar 2021 00:59:30 +0000 Subject: [PATCH 07/19] Add income,cashflow,balance comparison --- .../comparison_analysis/ca_controller.py | 14 +- .../comparison_analysis/market_watch_api.py | 319 ++++++++++++------ gamestonk_terminal/helper_funcs.py | 5 +- 3 files changed, 229 insertions(+), 109 deletions(-) diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py index 0041e58ff32..deb6d26cf63 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -29,6 +29,8 @@ class ComparisonAnalysisController: "historical", "corr", "income", + "balance", + "cash", ] def __init__( @@ -80,6 +82,8 @@ class ComparisonAnalysisController: print(" corr correlation between similar companies") print("") print(" income income financials comparison") + print(" balance balance financials comparison") + print(" cash cash financials comparison") print("") return @@ -126,7 +130,7 @@ class ComparisonAnalysisController: "-s", "--similar", dest="l_similar", - type=lambda s: [str(item) for item in s.split(",")], + type=lambda s: [str(item).upper() for item in s.split(",")], default=[], help="similar companies to compare with.", ) @@ -201,6 +205,14 @@ class ComparisonAnalysisController: """Process income command""" mw_api.compare_income(other_args, self.ticker, self.similar) + def call_balance(self, other_args: List[str]): + """Process balance command""" + mw_api.compare_balance(other_args, self.ticker, self.similar) + + def call_cash(self, other_args: List[str]): + """Process cash command""" + mw_api.compare_cashflow(other_args, self.ticker, self.similar) + def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str): """Comparison Analysis Menu""" diff --git a/gamestonk_terminal/comparison_analysis/market_watch_api.py b/gamestonk_terminal/comparison_analysis/market_watch_api.py index 3f76a3d67e5..c5d82065396 100644 --- a/gamestonk_terminal/comparison_analysis/market_watch_api.py +++ b/gamestonk_terminal/comparison_analysis/market_watch_api.py @@ -39,15 +39,15 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]): "-s", "--similar", dest="l_similar", - type=lambda s: [str(item) for item in s.split(",")], - default=[], + type=lambda s: [str(item).upper() for item in s.split(",")], + default=similar, help="similar companies to compare with.", ) parser.add_argument( "-a", "--also", dest="l_also", - type=lambda s: [str(item) for item in s.split(",")], + type=lambda s: [str(item).upper() for item in s.split(",")], default=[], help="apart from loaded similar companies also compare with.", ) @@ -73,29 +73,31 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]): if not ns_parser: return - if ns_parser.l_similar: - similar = ns_parser.l_similar - - similar += ns_parser.l_also + l_similar = ns_parser.l_similar + l_similar += ns_parser.l_also # Add main ticker to similar list of companies - similar.insert(0, ticker) + l_similar.insert(0, ticker) l_timeframes, ddf_financials = prepare_comparison_financials( - similar, "income", ns_parser.b_quarter + l_similar, "income", ns_parser.b_quarter ) if ns_parser.s_timeframe: if ns_parser.s_timeframe not in l_timeframes: raise ValueError( - f"Timeframe {ns_parser.s_timeframe} should be one of {l_timeframes}" + f"Timeframe selected should be one of {', '.join(l_timeframes)}" ) s_timeframe = ns_parser.s_timeframe else: s_timeframe = l_timeframes[-1] + print( + f"Other available {('yearly', 'quarterly')[ns_parser.b_quarter]} timeframes are: {', '.join(l_timeframes)}\n" + ) + df_financials_compared = combine_similar_financials( - ddf_financials, similar, s_timeframe + ddf_financials, l_similar, s_timeframe, ns_parser.b_quarter ) if gtff.USE_COLOR: @@ -107,147 +109,224 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]): pd.set_option("display.max_colwidth", None) pd.set_option("display.max_rows", None) - df_financials_compared.index.name = s_timeframe + if not ns_parser.b_quarter: + df_financials_compared.index.name = s_timeframe + print(df_financials_compared.to_string()) print("") except Exception as e: - print(e) - print("") + print(e, "\n") return -def balance(l_args, s_ticker): +def compare_balance(other_args: List[str], ticker: str, similar: List[str]): + """Compare balance between companies + + Parameters + ---------- + other_args : List[str] + Command line arguments to be processed with argparse + ticker : str + Main ticker to compare income + similar : List[str] + Similar companies to compare income with + """ parser = argparse.ArgumentParser( add_help=False, - prog="balance", + prog="compare_balance", description=""" - Prints either yearly or quarterly assets from balance sheet of the company. - The following fields are expected: Cash & Short Term Investments, Cash & Short Term - Investments Growth, Cash Only, Short-Term Investments, Cash & ST Investments / Total - Assets, Total Accounts Receivable, Total Accounts Receivable Growth, Accounts - Receivables, Net, Accounts Receivables, Gross, Bad Debt/Doubtful Accounts, Other - Receivable, Accounts Receivable Turnover, Inventories, Finished Goods, Work in - Progress, Raw Materials, Progress Payments & Other, Other Current Assets, - Miscellaneous Current Assets, Net Property, Plant & Equipment, Property, Plant & - Equipment - Gross, Buildings, Land & Improvements, Computer Software and Equipment, - Other Property, Plant & Equipment, Accumulated Depreciation, Total Investments and - Advances, Other Long-Term Investments, Long-Term Note Receivables, Intangible Assets, - Net Goodwill, Net Other Intangibles, Other Assets. - - Prints either yearly or quarterly liabilities and shareholders' equity from balance - sheet of the company. The following fields are expected: ST Debt & Current Portion LT - Debt, Short Term Debt, Current Portion of Long Term Debt, Accounts Payable, Accounts - Payable Growth, Income Tax Payable, Other Current Liabilities, Dividends Payable, - Accrued Payroll, Miscellaneous Current Liabilities, Long-Term Debt, Long-Term Debt - excl. Capitalized Leases, Non-Convertible Debt, Convertible Debt, Capitalized Lease - Obligations, Provision for Risks & Charges, Deferred Taxes, Deferred Taxes - Credits, - Deferred Taxes - Debit, Other Liabilities, Other Liabilities (excl. Deferred Income), - Deferred Income, Non-Equity Reserves, Total Liabilities / Total Assets, Preferred Stock - (Carrying Value), Redeemable Preferred Stock, Non-Redeemable Preferred Stock, Common - Equity (Total), Common Equity/Total Assets, Common Stock Par/Carry Value, Retained - Earnings, ESOP Debt Guarantee, Cumulative Translation Adjustment/Unrealized For. Exch. - Gain, Unrealized Gain/Loss Marketable Securities, Revaluation Reserves, Treasury Stock, - Total Shareholders' Equity, Total Shareholders' Equity / Total Assets, Accumulated - Minority Interest, Total Equity, Total Current Assets, Total Assets, Total Current - Liabilities, Total Liabilities, and Liabilities & Shareholders' Equity. - [Source: Market Watch] + Prints either yearly or quarterly balance statement the company, and compares + it against similar companies. [Source: Market Watch] """, ) - + parser.add_argument( + "-s", + "--similar", + dest="l_similar", + type=lambda s: [str(item).upper() for item in s.split(",")], + default=similar, + help="similar companies to compare with.", + ) + parser.add_argument( + "-a", + "--also", + dest="l_also", + type=lambda s: [str(item).upper() for item in s.split(",")], + default=[], + help="apart from loaded similar companies also compare with.", + ) parser.add_argument( "-q", "--quarter", action="store_true", default=False, dest="b_quarter", - help="Quarter fundamental data flag.", + help="Quarter financial data flag.", + ) + parser.add_argument( + "-t", + "--timeframe", + dest="s_timeframe", + type=str, + default=None, + help="Specify yearly/quarterly timeframe. Default is last.", ) try: - ns_parser = parse_known_args_and_warn(parser, l_args) + ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return - df_financials = prepare_df_financials(s_ticker, "balance", ns_parser.b_quarter) + l_similar = ns_parser.l_similar + l_similar += ns_parser.l_also + + # Add main ticker to similar list of companies + l_similar.insert(0, ticker) + + l_timeframes, ddf_financials = prepare_comparison_financials( + l_similar, "balance", ns_parser.b_quarter + ) + + if ns_parser.s_timeframe: + if ns_parser.s_timeframe not in l_timeframes: + raise ValueError( + f"Timeframe selected should be one of {', '.join(l_timeframes)}" + ) + s_timeframe = ns_parser.s_timeframe + else: + s_timeframe = l_timeframes[-1] + + print( + f"Other available {('yearly', 'quarterly')[ns_parser.b_quarter]} timeframes are: {', '.join(l_timeframes)}\n" + ) + + df_financials_compared = combine_similar_financials( + ddf_financials, l_similar, s_timeframe, ns_parser.b_quarter + ) if gtff.USE_COLOR: - df_financials = df_financials.applymap(financials_colored_values) + df_financials_compared = df_financials_compared.applymap( + financials_colored_values + ) patch_pandas_text_adjustment() pd.set_option("display.max_colwidth", None) pd.set_option("display.max_rows", None) - print(df_financials.to_string(index=False)) + if not ns_parser.b_quarter: + df_financials_compared.index.name = s_timeframe + + print(df_financials_compared.to_string()) print("") except Exception as e: - print(e) - print("") + print(e, "\n") return -def cash(l_args, s_ticker): +def compare_cashflow(other_args: List[str], ticker: str, similar: List[str]): + """Compare balance between companies + + Parameters + ---------- + other_args : List[str] + Command line arguments to be processed with argparse + ticker : str + Main ticker to compare income + similar : List[str] + Similar companies to compare income with + """ parser = argparse.ArgumentParser( add_help=False, - prog="cash_flow", + prog="compare_cashflow", description=""" - Prints either yearly or quarterly cash flow operating activities of the company. - The following fields are expected: Net Income before Extraordinaries, Net Income - Growth, Depreciation, Depletion & Amortization, Depreciation and Depletion, - Amortization of Intangible Assets, Deferred Taxes & Investment Tax Credit, Deferred - Taxes, Investment Tax Credit, Other Funds, Funds from Operations, Extraordinaries, - Changes in Working Capital, Receivables, Accounts Payable, Other Assets/Liabilities, - and Net Operating Cash Flow Growth. - Prints either yearly or quarterly cash flow investing activities of the company. - The following fields are expected: Capital Expenditures, Capital Expenditures Growth, - Capital Expenditures/Sales, Capital Expenditures (Fixed Assets), Capital Expenditures - (Other Assets), Net Assets from Acquisitions, Sale of Fixed Assets & Businesses, - Purchase/Sale of Investments, Purchase of Investments, Sale/Maturity of Investments, - Other Uses, Other Sources, Net Investing Cash Flow Growth. - Prints either yearly or quarterly cash flow financing activities of the company. - The following fields are expected: Cash Dividends Paid - Total, Common Dividends, - Preferred Dividends, Change in Capital Stock, Repurchase of Common & Preferred Stk., - Sale of Common & Preferred Stock, Proceeds from Stock Options, Other Proceeds from Sale - of Stock, Issuance/Reduction of Debt, Net, Change in Current Debt, Change in Long-Term - Debt, Issuance of Long-Term Debt, Reduction in Long-Term Debt, Other Funds, Other Uses, - Other Sources, Net Financing Cash Flow Growth, Net Financing Cash Flow/Sales, Exchange - Rate Effect, Miscellaneous Funds, Net Change in Cash, Free Cash Flow, Free Cash Flow - Growth, Free Cash Flow Yield, Net Operating Cash Flow, Net Investing Cash Flow, Net - Financing Cash Flow. - [Source: Market Watch] + Prints either yearly or quarterly cash statement the company, and compares + it against similar companies. [Source: Market Watch] """, ) - + parser.add_argument( + "-s", + "--similar", + dest="l_similar", + type=lambda s: [str(item).upper() for item in s.split(",")], + default=similar, + help="similar companies to compare with.", + ) + parser.add_argument( + "-a", + "--also", + dest="l_also", + type=lambda s: [str(item).upper() for item in s.split(",")], + default=[], + help="apart from loaded similar companies also compare with.", + ) parser.add_argument( "-q", "--quarter", action="store_true", default=False, dest="b_quarter", - help="Quarter fundamental data flag.", + help="Quarter financial data flag.", + ) + parser.add_argument( + "-t", + "--timeframe", + dest="s_timeframe", + type=str, + default=None, + help="Specify yearly/quarterly timeframe. Default is last.", ) try: - ns_parser = parse_known_args_and_warn(parser, l_args) + ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return - df_financials = prepare_df_financials(s_ticker, "cashflow", ns_parser.b_quarter) + l_similar = ns_parser.l_similar + l_similar += ns_parser.l_also + + # Add main ticker to similar list of companies + l_similar.insert(0, ticker) + + l_timeframes, ddf_financials = prepare_comparison_financials( + l_similar, "cashflow", ns_parser.b_quarter + ) + + if ns_parser.s_timeframe: + if ns_parser.s_timeframe not in l_timeframes: + raise ValueError( + f"Timeframe selected should be one of {', '.join(l_timeframes)}" + ) + s_timeframe = ns_parser.s_timeframe + else: + s_timeframe = l_timeframes[-1] + + print( + f"Other available {('yearly', 'quarterly')[ns_parser.b_quarter]} timeframes are: {', '.join(l_timeframes)}\n" + ) + + df_financials_compared = combine_similar_financials( + ddf_financials, l_similar, s_timeframe, ns_parser.b_quarter + ) if gtff.USE_COLOR: - df_financials = df_financials.applymap(financials_colored_values) + df_financials_compared = df_financials_compared.applymap( + financials_colored_values + ) patch_pandas_text_adjustment() pd.set_option("display.max_colwidth", None) pd.set_option("display.max_rows", None) - print(df_financials.to_string(index=False)) + if not ns_parser.b_quarter: + df_financials_compared.index.name = s_timeframe + + print(df_financials_compared.to_string()) print("") except Exception as e: - print(e) - print("") + print(e, "\n") return @@ -381,19 +460,23 @@ def prepare_comparison_financials( symbol, statement, quarter ).set_index("Item") - items = [] - # Get common headers between tickers - for symbol in similar: - if len(financials[symbol].columns) > len(items): - items = financials[symbol].columns + if quarter: + items = financials[similar[0]].columns - # Add columns with N/A when data is not available, to have similar columns - for symbol in similar: - if len(financials[symbol].columns) < len(items): - for item in items: - if item not in financials[symbol].columns: - financials[symbol][item] = "N/A" - financials[symbol] = financials[symbol].reindex(sorted(items), axis=1) + else: + items = [] + # Get common headers between tickers + for symbol in similar: + if len(financials[symbol].columns) > len(items): + items = financials[symbol].columns + + # Add columns with N/A when data is not available, to have similar columns + for symbol in similar: + if len(financials[symbol].columns) < len(items): + for item in items: + if item not in financials[symbol].columns: + financials[symbol][item] = "N/A" + financials[symbol] = financials[symbol].reindex(sorted(items), axis=1) return list(items), financials @@ -402,28 +485,52 @@ def combine_similar_financials( financials: Dict[str, pd.DataFrame], similar: List[str], timeframe: str, + quarter: bool, ) -> pd.DataFrame: """Builds a DataFrame with financial statements from a certain timeframe of a list of tickers Parameters ---------- - Dict[str, pd.DataFrame] + financials : Dict[str, pd.DataFrame] A dictionary of DataFrame with financial info from list of similar tickers similar : List[str] List of similar stock tickers statement : str Either income, balance or cashflow - + quarter : bool + False for yearly data, True for quarterly Returns ------- pd.DataFrame A DataFrame with financial statements from a certain timeframe of a list of tickers """ - compare_financials = financials[similar[0]][timeframe].to_frame() - compare_financials.rename(columns={timeframe: similar[0]}, inplace=True) + # Quarter data is a bit more confusing for comparison due to the fact that + # the reports may occur at slight different moments. Hence we rely on the + # order set by the Market Watch website - for symbol in similar[1:]: - compare_financials[symbol] = financials[symbol][timeframe] + if quarter: + compare_financials = financials[similar[0]][timeframe].to_frame() + compare_financials.rename(columns={timeframe: similar[0]}, inplace=True) + earnings_dates = [timeframe] + idx = len(financials[similar[0]].columns) - list( + financials[similar[0]].columns + ).index(timeframe) + + for symbol in similar[1:]: + report_quarter_date = list(financials[symbol].columns)[-idx] + earnings_dates.append(report_quarter_date) + compare_financials[symbol] = financials[symbol][report_quarter_date] + + compare_financials.columns = pd.MultiIndex.from_tuples( + zip(earnings_dates, compare_financials.columns), + ) + + else: + compare_financials = financials[similar[0]][timeframe].to_frame() + compare_financials.rename(columns={timeframe: similar[0]}, inplace=True) + + for symbol in similar[1:]: + compare_financials[symbol] = financials[symbol][timeframe] return compare_financials diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py index 7449951a1a8..ae83fca3972 100644 --- a/gamestonk_terminal/helper_funcs.py +++ b/gamestonk_terminal/helper_funcs.py @@ -293,8 +293,8 @@ def parse_known_args_and_warn(parser, l_args): def financials_colored_values(val: str) -> str: - if val == "N/A": - val = f"{Fore.YELLOW}{val}{Style.RESET_ALL}" + if val == "N/A" or str(val) == "nan": + val = f"{Fore.YELLOW}N/A{Style.RESET_ALL}" elif sum(c.isalpha() for c in val) < 2: if "%" in val: if "-" in val: @@ -303,6 +303,7 @@ def financials_colored_values(val: str) -> str: val = f"{Fore.GREEN}{val}{Style.RESET_ALL}" elif "(" in val: val = f"{Fore.RED}{val}{Style.RESET_ALL}" + return val From 78e7ce96c0565859a3496904224722388401b747 Mon Sep 17 00:00:00 2001 From: didier Date: Sat, 20 Mar 2021 01:00:05 +0000 Subject: [PATCH 08/19] ordering of imports --- gamestonk_terminal/comparison_analysis/market_watch_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestonk_terminal/comparison_analysis/market_watch_api.py b/gamestonk_terminal/comparison_analysis/market_watch_api.py index c5d82065396..8c564b2c483 100644 --- a/gamestonk_terminal/comparison_analysis/market_watch_api.py +++ b/gamestonk_terminal/comparison_analysis/market_watch_api.py @@ -2,10 +2,10 @@ __docformat__ = "numpy" import argparse +from typing import List, Dict, Tuple import requests import pandas as pd from bs4 import BeautifulSoup -from typing import List, Dict, Tuple from gamestonk_terminal.helper_funcs import ( get_user_agent, parse_known_args_and_warn, From 195d6b157dc70be3f64a1373638b0616acae5a78 Mon Sep 17 00:00:00 2001 From: didier Date: Sat, 20 Mar 2021 01:09:19 +0000 Subject: [PATCH 09/19] doesn't like initialization inside constructor? --- .../comparison_analysis/ca_controller.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py index deb6d26cf63..6c8158b1fe4 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -34,11 +34,17 @@ class ComparisonAnalysisController: ] def __init__( - self, stock: pd.DataFrame, ticker: str, start: datetime, interval: str + self, + stock: pd.DataFrame, + ticker: str, + start: datetime, + interval: str, + similar: List[str], + user: bool, ): """Constructor""" - self.user = False - self.similar = [] + self.similar = similar + self.user = user self.stock = stock self.ticker = ticker self.start = start @@ -217,7 +223,9 @@ class ComparisonAnalysisController: def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str): """Comparison Analysis Menu""" - ca_controller = ComparisonAnalysisController(stock, ticker, start, interval) + ca_controller = ComparisonAnalysisController( + stock, ticker, start, interval, [], False + ) ca_controller.call_help(None) while True: From 31f20fc18738e9c6d6194257d11900396817a2aa Mon Sep 17 00:00:00 2001 From: Aaron Cutright Date: Fri, 19 Mar 2021 21:13:40 -0400 Subject: [PATCH 10/19] Try to fix tensorflow issue on py^3.7, add linters to pyproject see issues #226, #236 --- poetry.lock | 487 ++++++++++++++++++++++++++++++++----------------- pyproject.toml | 7 + 2 files changed, 322 insertions(+), 172 deletions(-) diff --git a/poetry.lock b/poetry.lock index 45b449e6623..e4c01cf7575 100644 --- a/poetry.lock +++ b/poetry.lock @@ -85,6 +85,19 @@ dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest", "sphinx", "wheel", "p docs = ["sphinx"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] +[[package]] +name = "astroid" +version = "2.5.1" +description = "An abstract syntax tree for Python with inference support." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} +wrapt = ">=1.11,<1.13" + [[package]] name = "astunparse" version = "1.6.3" @@ -296,14 +309,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "convertdate" -version = "2.3.1" +version = "2.3.2" description = "Converts between Gregorian dates and other calendar systems.Calendars included: Baha'i, French Republican, Hebrew, Indian Civil, Islamic, ISO, Julian, Mayan and Persian." category = "main" optional = false python-versions = ">=3.5" [package.dependencies] -pymeeus = ">=0.3.6,<0.3.8 || >0.3.8,<=1" +pymeeus = ">=0.3.13,<=1" pytz = ">=2014.10" [package.extras] @@ -331,7 +344,7 @@ six = "*" [[package]] name = "cython" -version = "0.29.14" +version = "0.29.17" description = "The Cython compiler for writing C extensions for the Python language." category = "main" optional = false @@ -363,7 +376,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "deprecated" -version = "1.2.11" +version = "1.2.12" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." category = "main" optional = true @@ -468,6 +481,20 @@ torch = ">=1.1.0" tqdm = ">=4.26.0" transformers = ">=3.5.0,<=3.5.1" +[[package]] +name = "flake8" +version = "3.9.0" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + [[package]] name = "flatbuffers" version = "1.12" @@ -538,28 +565,27 @@ tqdm = "*" [[package]] name = "gensim" -version = "3.8.3" +version = "3.8.2" description = "Python framework for fast Vector Space Modelling" category = "main" optional = true python-versions = "*" [package.dependencies] -Cython = "0.29.14" numpy = ">=1.11.3" -scipy = ">=0.18.1" +scipy = ">=1.0.0" six = ">=1.5.0" smart-open = ">=1.8.1" [package.extras] distributed = ["Pyro4 (>=4.27)"] -docs = ["pytest", "pytest-rerunfailures", "mock", "cython", "nmslib", "pyemd", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn", "Pyro4 (>=4.27)", "sphinx (<=2.4.4)", "sphinx-gallery", "sphinxcontrib.programoutput", "sphinxcontrib-napoleon", "matplotlib", "plotly", "memory-profiler", "annoy", "pyro4", "nltk", "statsmodels", "pandas"] -test = ["pytest", "pytest-rerunfailures", "mock", "cython", "nmslib", "pyemd", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn"] -test-win = ["pytest", "pytest-rerunfailures", "mock", "cython", "nmslib", "pyemd", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn"] +docs = ["pytest", "pytest-rerunfailures", "mock", "cython", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn", "Pyro4 (>=4.27)", "sphinx", "sphinxcontrib-napoleon", "plotly", "pattern (<=2.6)", "sphinxcontrib.programoutput"] +test = ["pytest", "pytest-rerunfailures", "mock", "cython", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn"] +test-win = ["pytest", "pytest-rerunfailures", "mock", "cython", "testfixtures", "Morfessor (==2.0.2a4)", "python-Levenshtein (>=0.10.2)", "visdom (>0.1.8.7)", "scikit-learn"] [[package]] name = "google-auth" -version = "1.27.1" +version = "1.28.0" description = "Google Authentication Library" category = "main" optional = true @@ -620,7 +646,7 @@ name = "h5py" version = "2.10.0" description = "Read and write HDF5 files from Python" category = "main" -optional = true +optional = false python-versions = "*" [package.dependencies] @@ -694,7 +720,7 @@ idna = ">=2.0" [[package]] name = "importlib-metadata" -version = "3.7.2" +version = "3.7.3" description = "Read metadata from Python packages" category = "main" optional = false @@ -808,6 +834,19 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "isort" +version = "5.7.0" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.extras] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] + [[package]] name = "janome" version = "0.4.1" @@ -889,7 +928,7 @@ qtconsole = "*" [[package]] name = "jupyter-client" -version = "6.1.11" +version = "6.1.12" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -904,11 +943,11 @@ traitlets = "*" [package.extras] doc = ["sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -test = ["jedi (<=0.17.2)", "ipykernel", "ipython", "mock", "pytest", "pytest-asyncio", "async-generator", "pytest-timeout"] +test = ["async-generator", "ipykernel", "ipython", "mock", "pytest-asyncio", "pytest-timeout", "pytest", "jedi (<0.18)"] [[package]] name = "jupyter-console" -version = "6.2.0" +version = "6.3.0" description = "Jupyter terminal console" category = "main" optional = false @@ -1026,6 +1065,14 @@ python-versions = "*" [package.dependencies] six = "*" +[[package]] +name = "lazy-object-proxy" +version = "1.5.2" +description = "A fast and thorough lazy object proxy." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "lunarcalendar" version = "0.0.9" @@ -1091,6 +1138,14 @@ pillow = ">=6.2.0" pyparsing = ">=2.0.3,<2.0.4 || >2.0.4,<2.1.2 || >2.1.2,<2.1.6 || >2.1.6" python-dateutil = ">=2.1" +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "mistune" version = "0.8.4" @@ -1117,7 +1172,7 @@ python-versions = "*" [[package]] name = "mplfinance" -version = "0.12.7a7" +version = "0.12.7a10" description = "Utilities for the visualization, and visual analysis, of financial data" category = "main" optional = false @@ -1638,6 +1693,14 @@ python-versions = "*" [package.dependencies] pyasn1 = ">=0.4.6,<0.5.0" +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pycparser" version = "2.20" @@ -1646,6 +1709,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pyflakes" +version = "2.3.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pygments" version = "2.8.1" @@ -1654,9 +1725,27 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "pylint" +version = "2.7.2" +description = "python code static checker" +category = "dev" +optional = false +python-versions = "~=3.6" + +[package.dependencies] +astroid = ">=2.5.1,<2.6" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.7" +toml = ">=0.7.1" + +[package.extras] +docs = ["sphinx (==3.5.1)", "python-docs-theme (==2020.12)"] + [[package]] name = "pymeeus" -version = "0.5.9" +version = "0.5.11" description = "Python implementation of Jean Meeus astronomical routines" category = "main" optional = false @@ -1691,11 +1780,14 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pyrsistent" -version = "0.17.3" +version = "0.14.11" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false -python-versions = ">=3.5" +python-versions = "*" + +[package.dependencies] +six = "*" [[package]] name = "pysocks" @@ -1809,7 +1901,7 @@ py = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "qtconsole" -version = "5.0.2" +version = "5.0.3" description = "Jupyter Qt console" category = "main" optional = false @@ -1856,11 +1948,11 @@ six = "*" [[package]] name = "rapidfuzz" -version = "1.2.1" +version = "1.3.0" description = "rapid fuzzy string matching" category = "main" optional = false -python-versions = ">=2.7" +python-versions = ">=3.5" [[package]] name = "regex" @@ -2061,7 +2153,7 @@ webhdfs = ["requests"] [[package]] name = "soupsieve" -version = "2.2" +version = "2.2.1" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false @@ -2193,7 +2285,7 @@ python-versions = "*" [[package]] name = "terminado" -version = "0.9.2" +version = "0.9.3" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." category = "main" optional = false @@ -2391,16 +2483,16 @@ test = ["pytest (>=2.7.3)"] [[package]] name = "urllib3" -version = "1.26.3" +version = "1.26.4" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "user-agent" @@ -2468,7 +2560,7 @@ name = "wrapt" version = "1.12.1" description = "Module for decorators, wrappers and monkey patching." category = "main" -optional = true +optional = false python-versions = "*" [[package]] @@ -2517,8 +2609,7 @@ prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "t [metadata] lock-version = "1.1" python-versions = "^3.6.8" -content-hash = "184502c6b8d4b7db5baa4323e7f70b2585c6140c304583f0678e24681b8f9c9b" - +content-hash = "8b892e0dc807e52b9f8ece6c5bb60b1e5881e66c72426fe1ffe2faee2930cf87" [metadata.files] absl-py = [ @@ -2600,6 +2691,10 @@ argon2-cffi = [ {file = "argon2_cffi-20.1.0-cp39-cp39-win32.whl", hash = "sha256:e2db6e85c057c16d0bd3b4d2b04f270a7467c147381e8fd73cbbe5bc719832be"}, {file = "argon2_cffi-20.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a84934bd818e14a17943de8099d41160da4a336bcc699bb4c394bbb9b94bd32"}, ] +astroid = [ + {file = "astroid-2.5.1-py3-none-any.whl", hash = "sha256:21d735aab248253531bb0f1e1e6d068f0ee23533e18ae8a6171ff892b98297cf"}, + {file = "astroid-2.5.1.tar.gz", hash = "sha256:cfc35498ee64017be059ceffab0a25bedf7548ab76f2bea691c5565896e7128d"}, +] astunparse = [ {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, @@ -2711,8 +2806,8 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] convertdate = [ - {file = "convertdate-2.3.1-py3-none-any.whl", hash = "sha256:ede4b0bfbef002de8e31b9d8c03dc619a210915ce453e7a4826ac8808110fcff"}, - {file = "convertdate-2.3.1.tar.gz", hash = "sha256:4eabe5cab9f7890c6bddab2133502de9d116ad81f2fcf16c4858fef2b737e328"}, + {file = "convertdate-2.3.2-py3-none-any.whl", hash = "sha256:8f5e9efc2b71410d33217012c0a215f83463f765c94d5883bf656ce7a962b888"}, + {file = "convertdate-2.3.2.tar.gz", hash = "sha256:57df962a6047534f1452c390ad48e3dc5c83052ad83ad6dd78d60ae22f99214c"}, ] cssselect = [ {file = "cssselect-1.1.0-py2.py3-none-any.whl", hash = "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf"}, @@ -2723,38 +2818,39 @@ cycler = [ {file = "cycler-0.10.0.tar.gz", hash = "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"}, ] cython = [ - {file = "Cython-0.29.14-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:47e5e1502d52ef03387cf9d3b3241007961a84a466e58a3b74028e1dd4957f8c"}, - {file = "Cython-0.29.14-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1dcdaa319558eb924294a554dcf6c12383ec947acc7e779e8d3622409a7f7d28"}, - {file = "Cython-0.29.14-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:7bc18fc5a170f2c1cef5387a3d997c28942918bbee0f700e73fd2178ee8d474d"}, - {file = "Cython-0.29.14-cp27-cp27m-win32.whl", hash = "sha256:89458b49976b1dee5d89ab4ac943da3717b4292bf624367e862e4ee172fcce99"}, - {file = "Cython-0.29.14-cp27-cp27m-win_amd64.whl", hash = "sha256:c0b24bfe3431b3cb7ced323bca813dbd13aca973a1475b512d3331fd0de8ec60"}, - {file = "Cython-0.29.14-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7f89eff20e4a7a64b55210dac17aea711ed8a3f2e78f2ff784c0e984302583dd"}, - {file = "Cython-0.29.14-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:6c53338c1811f8c6d7f8cb7abd874810b15045e719e8207f957035c9177b4213"}, - {file = "Cython-0.29.14-cp34-cp34m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:521340844cf388d109ceb61397f3fd5250ccb622a1a8e93559e8de76c80940a9"}, - {file = "Cython-0.29.14-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:75c2dda47dcc3c77449712b1417bb6b89ec3b7b02e18c64262494dceffdf455e"}, - {file = "Cython-0.29.14-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:05eb79efc8029d487251c8a2702a909a8ba33c332e06d2f3980866541bd81253"}, - {file = "Cython-0.29.14-cp34-cp34m-win32.whl", hash = "sha256:1fc5bdda28f25fec44e4721677458aa509d743cd350862270309d61aa148d6ff"}, - {file = "Cython-0.29.14-cp34-cp34m-win_amd64.whl", hash = "sha256:0c70e842e52e2f50cc43bad43b5e5bc515f30821a374e544abb0e0746f2350ff"}, - {file = "Cython-0.29.14-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:094d28a34c3fa992ae02aea1edbe6ff89b3cc5870b6ee38b5baeb805dc57b013"}, - {file = "Cython-0.29.14-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:280573a01d9348d44a42d6a9c651d9f7eb1fe9217df72555b2a118f902996a10"}, - {file = "Cython-0.29.14-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:773c5a98e463b52f7e8197254b39b703a5ea1972aef3a94b3b921515d77dd041"}, - {file = "Cython-0.29.14-cp35-cp35m-win32.whl", hash = "sha256:986f871c0fa649b293061236b93782d25c293a8dd8117c7ba05f8a61bdc261ae"}, - {file = "Cython-0.29.14-cp35-cp35m-win_amd64.whl", hash = "sha256:78c3068dcba300d473fef57cdf523e34b37de522f5a494ef9ee1ac9b4b8bbe3f"}, - {file = "Cython-0.29.14-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:f3818e578e687cdb21dc4aa4a3bc6278c656c9c393e9eda14dd04943f478863d"}, - {file = "Cython-0.29.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bb487881608ebd293592553c618f0c83316f4f13a64cb18605b1d2fb9fd3da3e"}, - {file = "Cython-0.29.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:03f6bbb380ad0acb744fb06e42996ea217e9d00016ca0ff6f2e7d60f580d0360"}, - {file = "Cython-0.29.14-cp36-cp36m-win32.whl", hash = "sha256:b8ab3ab38afc47d8f4fe629b836243544351cef681b6bdb1dc869028d6fdcbfb"}, - {file = "Cython-0.29.14-cp36-cp36m-win_amd64.whl", hash = "sha256:298ceca7b0f0da4205fcb0b7c9ac9e120e2dafffd5019ba1618e84ef89434b5a"}, - {file = "Cython-0.29.14-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:fe666645493d72712c46e4fbe8bec094b06aec3c337400479e9704439c9d9586"}, - {file = "Cython-0.29.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4074a8bff0040035673cc6dd365a762476d6bff4d03d8ce6904e3e53f9a25dc8"}, - {file = "Cython-0.29.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a14aa436586c41633339415de82a41164691d02d3e661038da533be5d40794a5"}, - {file = "Cython-0.29.14-cp37-cp37m-win32.whl", hash = "sha256:41e7068e95fbf9ec94b41437f989caf9674135e770a39cdb9c00de459bafd1bc"}, - {file = "Cython-0.29.14-cp37-cp37m-win_amd64.whl", hash = "sha256:05e8cfd3a3a6087aec49a1ae08a89171db991956209406d1e5576f9db70ece52"}, - {file = "Cython-0.29.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e8fab9911fd2fa8e5af407057cb8bdf87762f983cba483fa3234be20a9a0af77"}, - {file = "Cython-0.29.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d4039bb7f234ad32267c55e72fd49fb56078ea102f9d9d8559f6ec34d4887630"}, - {file = "Cython-0.29.14-cp38-cp38-win32.whl", hash = "sha256:c7894c06205166d360ab2915ae306d1f7403e9ce3d3aaeff4095eaf98e42ce66"}, - {file = "Cython-0.29.14-cp38-cp38-win_amd64.whl", hash = "sha256:a0f495a4fe5278aab278feee35e6102efecde5176a8a74dd28c28e3fc5c8d7c7"}, - {file = "Cython-0.29.14.tar.gz", hash = "sha256:e4d6bb8703d0319eb04b7319b12ea41580df44fd84d83ccda13ea463c6801414"}, + {file = "Cython-0.29.17-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:8ef49cafea89d99ffc2cf37af2f0f2b7d219080574f14a422f701bcaa85c7167"}, + {file = "Cython-0.29.17-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:4f35752adfd4855d39e38bf08eb6d02f7aa88b1bb420ab86e6d2e37ccd7c88c2"}, + {file = "Cython-0.29.17-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:00faa77500ca2f865fd7f3126f86e77de3ec0d855dd6cf92fc85b57ebed11655"}, + {file = "Cython-0.29.17-cp27-cp27m-win32.whl", hash = "sha256:fce2e7f500b1456f96d5b8ceefba243cae7018ad8b3f791e62c20a0f0fbba71c"}, + {file = "Cython-0.29.17-cp27-cp27m-win_amd64.whl", hash = "sha256:b19a1aa98192d44d7254613a1f9c382ef381deb79289f2ff446d1447d19085aa"}, + {file = "Cython-0.29.17-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:785d6e88a3bb10ce6425d23f0a740a21b0bfc9e8d371fea7edba0eaa0ec57d96"}, + {file = "Cython-0.29.17-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ea75bbc076d4a5605d04c72c8c7a933f51473b0bcecd79295256b9ecd75cca49"}, + {file = "Cython-0.29.17-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:5c501742a92cbcef8f3c21d1dcba9c073b37f1218af3586957901730ac6b6665"}, + {file = "Cython-0.29.17-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:179ad5569dc101e3e0d9d04305f9a5e03fbf8acf9d93fb543340f8c1a8fb054b"}, + {file = "Cython-0.29.17-cp34-cp34m-win32.whl", hash = "sha256:c78fd0bdf5915f4df730298e6cc7197e4c6aa5285d7c37491366a38125b3e0ab"}, + {file = "Cython-0.29.17-cp34-cp34m-win_amd64.whl", hash = "sha256:4e8d351ee840a4e491f8f0a64da19923ada0ce09d2d818bce0ae6ce1b6837aeb"}, + {file = "Cython-0.29.17-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c56f658ab6f387619a3668cd78cf2d3459324d9ea3cb39cce4d72ef5bce8f318"}, + {file = "Cython-0.29.17-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a5ebd8fe5a3d97924bd89d449914d1c5b6d084f4b124a4eb28e4412d09fb0f20"}, + {file = "Cython-0.29.17-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7cec6bd82fd92f85790908fdc7a43a8a5442606e6d771d5b32a1ab8a39ad1a65"}, + {file = "Cython-0.29.17-cp35-cp35m-win32.whl", hash = "sha256:96d18413a33aa5ce51a5554615ba01e3fdb26126d8678459330d052f0bdf60ec"}, + {file = "Cython-0.29.17-cp35-cp35m-win_amd64.whl", hash = "sha256:86ae455b1dd7041b4b8a15499fe72f3d3f990f78a794deb799ee2ef7db389ca0"}, + {file = "Cython-0.29.17-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b6f7d2cf2f6b246fd04696d6d346489628f94f72a4988682ea0591b632370a1f"}, + {file = "Cython-0.29.17-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:7d597733ad0e7fc545df39100ee3b24290ce35586466dee4fa6018d4b8815d72"}, + {file = "Cython-0.29.17-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3950ae725472ae47bfb41c6bfdb3869a8ac27b5f30405f599a51398512afa224"}, + {file = "Cython-0.29.17-cp36-cp36m-win32.whl", hash = "sha256:809896928abce18e7c91a28b2705473ca4f15b9a53f433495845a882e15c09d8"}, + {file = "Cython-0.29.17-cp36-cp36m-win_amd64.whl", hash = "sha256:14e218a93d4f2e43e0063a5a0f7f26fe1783d5d20700216c5c4ff092c4553488"}, + {file = "Cython-0.29.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f7b20838f2534ad0d231c4c6e09acbdd40fb995a9671bb05839f7879093ec5e3"}, + {file = "Cython-0.29.17-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:719eddf050a1c8b0abbd74b0c388523cf618c3d9fe3bf20a350f4eafa43776e6"}, + {file = "Cython-0.29.17-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2a98c9f852b266f0b9a147da4b6699cf6da24b817375f74d51986312373689ab"}, + {file = "Cython-0.29.17-cp37-cp37m-win32.whl", hash = "sha256:4dbb58f963f6283b31b4ddac44e4f684527b06923efdec72ecb54e70ee91c766"}, + {file = "Cython-0.29.17-cp37-cp37m-win_amd64.whl", hash = "sha256:788192badd3b1ebb1a72a5c6cc2a07b692ca4c1c1fe4431fdd3c0e439e2c0a6d"}, + {file = "Cython-0.29.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e146b4b4ed4937a40e9e5c27b264adfce4ae4b7640d46eeffd3eef123b0170a2"}, + {file = "Cython-0.29.17-cp38-cp38-manylinux1_i686.whl", hash = "sha256:dcfee6312cf8f4f4839bae22f323a0e885c4237e2187202ab12def8a5460ca4c"}, + {file = "Cython-0.29.17-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c68f3015cbb0f5bc402829bad0a6b907889413f2e28cc0873dc1443de0f1a808"}, + {file = "Cython-0.29.17-cp38-cp38-win32.whl", hash = "sha256:7c8ac5bc9726ccb1a1cce1af4ceb7589228db6c57ada3bfcd461075abe3a6a7b"}, + {file = "Cython-0.29.17-cp38-cp38-win_amd64.whl", hash = "sha256:8135cc7de72805833a118e7c8a255daddd35875d17ea21f6c356200b0fa4b732"}, + {file = "Cython-0.29.17-py2.py3-none-any.whl", hash = "sha256:20cdf3f918c46355128d7c7cb041872ba2863cc11313972c6e390bd3dad968ba"}, + {file = "Cython-0.29.17.tar.gz", hash = "sha256:6361588cb1d82875bcfbad83d7dd66c442099759f895cf547995f00601f9caf2"}, ] dataclasses = [ {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, @@ -2769,8 +2865,8 @@ defusedxml = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] deprecated = [ - {file = "Deprecated-1.2.11-py2.py3-none-any.whl", hash = "sha256:924b6921f822b64ec54f49be6700a126bab0640cfafca78f22c9d429ed590560"}, - {file = "Deprecated-1.2.11.tar.gz", hash = "sha256:471ec32b2755172046e28102cd46c481f21c6036a0ec027521eba8521aa4ef35"}, + {file = "Deprecated-1.2.12-py2.py3-none-any.whl", hash = "sha256:08452d69b6b5bc66e8330adde0a4f8642e969b9e1702904d137eeb29c8ffc771"}, + {file = "Deprecated-1.2.12.tar.gz", hash = "sha256:6d2de2de7931a968874481ef30208fd4e08da39177d61d3d4ebdf4366e7dbca1"}, ] entrypoints = [ {file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"}, @@ -2818,6 +2914,10 @@ flair = [ {file = "flair-0.7-py3-none-any.whl", hash = "sha256:42c7e8074f67eeac722d68f4d5a9ad602377a76f5c4a2a190b916645b9be6ff2"}, {file = "flair-0.7.tar.gz", hash = "sha256:50cfe5382b41ba88d9cd7096fb82d21d7f938b167fc7de2c8365bf53f3576ef4"}, ] +flake8 = [ + {file = "flake8-3.9.0-py2.py3-none-any.whl", hash = "sha256:12d05ab02614b6aee8df7c36b97d1a3b2372761222b19b58621355e82acddcff"}, + {file = "flake8-3.9.0.tar.gz", hash = "sha256:78873e372b12b093da7b5e5ed302e8ad9e988b38b063b61ad937f26ca58fc5f0"}, +] flatbuffers = [ {file = "flatbuffers-1.12-py2.py3-none-any.whl", hash = "sha256:9e9ef47fa92625c4721036e7c4124182668dc6021d9e7c73704edd395648deb9"}, {file = "flatbuffers-1.12.tar.gz", hash = "sha256:63bb9a722d5e373701913e226135b28a6f6ac200d5cc7b4d919fa38d73b44610"}, @@ -2843,38 +2943,32 @@ gdown = [ {file = "gdown-3.12.2.tar.gz", hash = "sha256:4b3a1301e57bfd8dce939bf25ef8fbb4b23967fd0f878eede328bdcc41386bac"}, ] gensim = [ - {file = "gensim-3.8.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:61eed1d6b5fbe6dda0586ea447ebc2dc7890a7f70c2ed953d5abc3fe3cfb94bb"}, - {file = "gensim-3.8.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3af62709369331c85552fd26caa21504baa64accc426dc094172f5c688750013"}, - {file = "gensim-3.8.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:8ff471921b3b10ffb3ae6cbb598dd9c07d9dc030dee5aa167e7682b549c42f87"}, - {file = "gensim-3.8.3-cp27-cp27m-win32.whl", hash = "sha256:440700e29b494bc2e1d52e14b69a821f46ab09ecf85cf36c8988f18e1d6c7a8b"}, - {file = "gensim-3.8.3-cp27-cp27m-win_amd64.whl", hash = "sha256:f8ea67bf8c47ee55cb1b32c97fa1474b7d6d22959dd8097c019a5d9c9df34f5f"}, - {file = "gensim-3.8.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7a90549dfc8ee3822fcad6da957de07d927e4e90ef42b3699543dee35ab2da13"}, - {file = "gensim-3.8.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7629b33cf35f672efdd5269381f7e301958ee2638f27dfc63b80c5bfeaa827d3"}, - {file = "gensim-3.8.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:6711b6d3a0007530ee7de7adc30a4c48a1d26ec6312ac50e1d1e0a1d54f9de5b"}, - {file = "gensim-3.8.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:ef2ddeceff482aee17c1e185f63bf027c8de8f595fdd9fd2d2503de96008f3b7"}, - {file = "gensim-3.8.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:41dcf6ecdc9acc657157967c791b8cbaba90ee6391f64efd28339b72f5e0c327"}, - {file = "gensim-3.8.3-cp35-cp35m-win32.whl", hash = "sha256:685a7657278161628821c8f873c5d7d2ffc0c28866648e39f76b450e4c7d5390"}, - {file = "gensim-3.8.3-cp35-cp35m-win_amd64.whl", hash = "sha256:b61a7c841a752c84b685674aa0d610289faad38795b325176481abe19b487e98"}, - {file = "gensim-3.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a61179df454a0d4b06a111c4ede0536f61c8121b4c0d0d02d23560a2fd4b3aff"}, - {file = "gensim-3.8.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:cc387d0d8bddbf3609ab95b3453296e4c9ff92c35e9799a17d86b1571d77a5fc"}, - {file = "gensim-3.8.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b36e6330471061cfd78aad751e24c6b4f56d575697af0fbab42655128927d296"}, - {file = "gensim-3.8.3-cp36-cp36m-win32.whl", hash = "sha256:1e3d66c2eec494376fc599701d9c2868549aed6e93e47177e39217f0188e2d88"}, - {file = "gensim-3.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:91fa62d61b21f1878f140b10520f9de4a26a52672fbe407edfc7e09ca2eff235"}, - {file = "gensim-3.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:637fc5969f3cef4b7c8fd3e78e31ef09565c5566d5ceabf076b4170eb6444a80"}, - {file = "gensim-3.8.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:22f45fd239cacd0e3715ac447a2c8a5eea02e730ec1f701c55b359e9298e63a8"}, - {file = "gensim-3.8.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d79370f78e9013b9d1e867c85ecc678d46a7ae0f01a8ca29e8f4291e5373b170"}, - {file = "gensim-3.8.3-cp37-cp37m-win32.whl", hash = "sha256:9c214b341f5304b906c79844e2787c13b46505df9dc70afca79a9a7dc0894478"}, - {file = "gensim-3.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fe98277a7b3b4987b40c928056bbaae1d0715022cf27bba89d05cd0d4fe51a84"}, - {file = "gensim-3.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a47903d104469a7a8b6f22ad5ef74681b19c4f4b71ff2c2893271b53161a43e4"}, - {file = "gensim-3.8.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:05bfc02e102a34c9c795095b688b1b4aaa2529c624821368c9c3ea6a16536f77"}, - {file = "gensim-3.8.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a8807ebf324dd11e1298a91a92d6e57c7bdabb91d0d5240bf1efa0c0eacd86f0"}, - {file = "gensim-3.8.3-cp38-cp38-win32.whl", hash = "sha256:90115d12ee545c21cc75521ef1bb3dd66aae8a378e9c2eb029c9f22df173c125"}, - {file = "gensim-3.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:4e34cf2e50f3eab3e303da46089ea4972567bf216e28f7535ada155770784ac8"}, - {file = "gensim-3.8.3.tar.gz", hash = "sha256:786adb0571f75114e9c5f7a31dd2e6eb39a9791f22c8757621545e2ded3ea367"}, + {file = "gensim-3.8.2-cp35-cp35m-macosx_10_7_intel.whl", hash = "sha256:ae3b493154073d059242fd4929cec050db77995b34621d3c9c7a622689cae341"}, + {file = "gensim-3.8.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:9d4407d0d866afa97c8a2c9d04ad0a6b996fe02f1f96144c0f929608bcdbff78"}, + {file = "gensim-3.8.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:27806c022289a76dbce29cd0e00090abb4a0ae117ff714ca0b963bd13de52d5b"}, + {file = "gensim-3.8.2-cp35-cp35m-win32.whl", hash = "sha256:3d1c1a94688c4b6107a261b0af0f43f13edef7263716348ffff790d207f4a629"}, + {file = "gensim-3.8.2-cp35-cp35m-win_amd64.whl", hash = "sha256:446476a017105a549a0eafba6e8ebb50d973775f1cf7fc1d23ba04e2c5056be4"}, + {file = "gensim-3.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1da1daed1d405c38541f4830981385fc4ae9ccb05cf01d4f49e184c4c0ccfe85"}, + {file = "gensim-3.8.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:806ea08d463931f4e44b2380bedf16325562bb047615de0e4bb95216074315d9"}, + {file = "gensim-3.8.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c32506dd2d112ef33721e862009f0d7aa1d83a9d8f006faedc532a4fa4c201fa"}, + {file = "gensim-3.8.2-cp36-cp36m-win32.whl", hash = "sha256:5be9320d09babf386909be1c799ebcef5fc3b8d1ba595635768e83bd753cbb52"}, + {file = "gensim-3.8.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0254577e162ae7fc99b7d47cdad121e2b120cb06fb4fdf88c2c7c67b0ac2af89"}, + {file = "gensim-3.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b0d0c4750adeb169744e5e6b60eb3425bc47b2e19ca77ae2aeae26ca03d6c6c8"}, + {file = "gensim-3.8.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:77bfbc0a424611f50d87e38ee92c514870f4a9eb2eb92efd9478d66f14a3dacc"}, + {file = "gensim-3.8.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7ddac73e8ad42f4522fb12a3b3c85192e28c67bb54dbc36ba7d53be8a7f8fed5"}, + {file = "gensim-3.8.2-cp37-cp37m-win32.whl", hash = "sha256:c8ae97aac860c57ffa444425a76566e1cf1d120daa2b3af6a748c2fe9edf48a5"}, + {file = "gensim-3.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5a7227c03a9ab48d80e306104a295f518e4049f21e29a51f41702bda247d5478"}, + {file = "gensim-3.8.2.tar.gz", hash = "sha256:46e3065e82e11d2c50c682aa17729292734a8388cb7301f0e3204052d2df2ff5"}, + {file = "gensim-3.8.2.win-amd64-py3.5.exe", hash = "sha256:48c6653dcc1a168209108d7658cae3b9b8aa05b212252bb5a696d6ba9b1da09c"}, + {file = "gensim-3.8.2.win-amd64-py3.6.exe", hash = "sha256:db22e1f6bfd093dc8c143e75ce4eb21a5c96568822d2447d952ae65c5be8240b"}, + {file = "gensim-3.8.2.win-amd64-py3.7.exe", hash = "sha256:5a114d3c1339255496c0be7b20fa0b5740fb2ccde0b56f4631e48fefe4be7c06"}, + {file = "gensim-3.8.2.win32-py3.5.exe", hash = "sha256:8a96813bab1043544c8d20806663c649195dcf13270ed6f336748ceb4ab90bd6"}, + {file = "gensim-3.8.2.win32-py3.6.exe", hash = "sha256:a9f0a27126126e466db0faccfe506559d50d0346c12d4b4d8d796d60bb8776a8"}, + {file = "gensim-3.8.2.win32-py3.7.exe", hash = "sha256:3234cbd52c0a4d548f385393040277fab03593358fee5673533e7ee6ed2f406c"}, ] google-auth = [ - {file = "google-auth-1.27.1.tar.gz", hash = "sha256:d8958af6968e4ecd599f82357ebcfeb126f826ed0656126ad68416f810f7531e"}, - {file = "google_auth-1.27.1-py2.py3-none-any.whl", hash = "sha256:63a5636d7eacfe6ef5b7e36e112b3149fa1c5b5ad77dd6df54910459bcd6b89f"}, + {file = "google-auth-1.28.0.tar.gz", hash = "sha256:9bd436d19ab047001a1340720d2b629eb96dd503258c524921ec2af3ee88a80e"}, + {file = "google_auth-1.28.0-py2.py3-none-any.whl", hash = "sha256:dcaba3aa9d4e0e96fd945bf25a86b6f878fcb05770b67adbeb50a63ca4d28a5e"}, ] google-auth-oauthlib = [ {file = "google-auth-oauthlib-0.4.3.tar.gz", hash = "sha256:54431535309cfab50897d9c181e8c2226268825aa6e42e930b05b99c5041a18c"}, @@ -2979,8 +3073,8 @@ idna-ssl = [ {file = "idna-ssl-1.1.0.tar.gz", hash = "sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.7.2-py3-none-any.whl", hash = "sha256:407d13f55dc6f2a844e62325d18ad7019a436c4bfcaee34cda35f2be6e7c3e34"}, - {file = "importlib_metadata-3.7.2.tar.gz", hash = "sha256:18d5ff601069f98d5d605b6a4b50c18a34811d655c55548adc833e687289acde"}, + {file = "importlib_metadata-3.7.3-py3-none-any.whl", hash = "sha256:b74159469b464a99cb8cc3e21973e4d96e05d3024d337313fedb618a6e86e6f4"}, + {file = "importlib_metadata-3.7.3.tar.gz", hash = "sha256:742add720a20d0467df2f444ae41704000f50e1234f46174b51f9c6031a1bd71"}, ] inflection = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, @@ -3010,6 +3104,10 @@ iso8601 = [ {file = "iso8601-0.1.14-py2.py3-none-any.whl", hash = "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004"}, {file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"}, ] +isort = [ + {file = "isort-5.7.0-py3-none-any.whl", hash = "sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc"}, + {file = "isort-5.7.0.tar.gz", hash = "sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e"}, +] janome = [ {file = "Janome-0.4.1-py2.py3-none-any.whl", hash = "sha256:a650e2684e80af72f869eff17566f31dd4444f5443c4771dca1ada60cea5c251"}, {file = "Janome-0.4.1.tar.gz", hash = "sha256:6c2c38d894014d57cb3151265c11146506ead3b3bc290898adc33711711612de"}, @@ -3036,12 +3134,12 @@ jupyter = [ {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"}, ] jupyter-client = [ - {file = "jupyter_client-6.1.11-py3-none-any.whl", hash = "sha256:5eaaa41df449167ebba5e1cf6ca9b31f7fd4f71625069836e2e4fee07fe3cb13"}, - {file = "jupyter_client-6.1.11.tar.gz", hash = "sha256:649ca3aca1e28f27d73ef15868a7c7f10d6e70f761514582accec3ca6bb13085"}, + {file = "jupyter_client-6.1.12-py3-none-any.whl", hash = "sha256:e053a2c44b6fa597feebe2b3ecb5eea3e03d1d91cc94351a52931ee1426aecfc"}, + {file = "jupyter_client-6.1.12.tar.gz", hash = "sha256:c4bca1d0846186ca8be97f4d2fa6d2bae889cce4892a167ffa1ba6bd1f73e782"}, ] jupyter-console = [ - {file = "jupyter_console-6.2.0-py3-none-any.whl", hash = "sha256:1d80c06b2d85bfb10bd5cc731b3db18e9023bc81ab00491d3ac31f206490aee3"}, - {file = "jupyter_console-6.2.0.tar.gz", hash = "sha256:7f6194f4f4692d292da3f501c7f343ccd5e36c6a1becf7b7515e23e66d6bf1e9"}, + {file = "jupyter_console-6.3.0-py3-none-any.whl", hash = "sha256:092283ba2c9b5ceb53f32d95891ecc59ed4bfeb69e36fe017db176213daa5b0e"}, + {file = "jupyter_console-6.3.0.tar.gz", hash = "sha256:947f66bbdeee2221b4fb3a6b78225d337b8f10832f14cecf7932183635abe1d9"}, ] jupyter-core = [ {file = "jupyter_core-4.7.1-py3-none-any.whl", hash = "sha256:8c6c0cac5c1b563622ad49321d5ec47017bd18b94facb381c6973a0486395f8e"}, @@ -3105,6 +3203,32 @@ langdetect = [ {file = "langdetect-1.0.8-py2-none-any.whl", hash = "sha256:f37495e63607865e47deed08d78f7f8e58172658216ff954b2f14671bcd87740"}, {file = "langdetect-1.0.8.tar.gz", hash = "sha256:363795ea005f1243c958e953245dac5d814fabdc025c9afa91588c5fa6b2fa83"}, ] +lazy-object-proxy = [ + {file = "lazy-object-proxy-1.5.2.tar.gz", hash = "sha256:5944a9b95e97de1980c65f03b79b356f30a43de48682b8bdd90aa5089f0ec1f4"}, + {file = "lazy_object_proxy-1.5.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e960e8be509e8d6d618300a6c189555c24efde63e85acaf0b14b2cd1ac743315"}, + {file = "lazy_object_proxy-1.5.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:522b7c94b524389f4a4094c4bf04c2b02228454ddd17c1a9b2801fac1d754871"}, + {file = "lazy_object_proxy-1.5.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:3782931963dc89e0e9a0ae4348b44762e868ea280e4f8c233b537852a8996ab9"}, + {file = "lazy_object_proxy-1.5.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:429c4d1862f3fc37cd56304d880f2eae5bd0da83bdef889f3bd66458aac49128"}, + {file = "lazy_object_proxy-1.5.2-cp35-cp35m-win32.whl", hash = "sha256:cd1bdace1a8762534e9a36c073cd54e97d517a17d69a17985961265be6d22847"}, + {file = "lazy_object_proxy-1.5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:ddbdcd10eb999d7ab292677f588b658372aadb9a52790f82484a37127a390108"}, + {file = "lazy_object_proxy-1.5.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ecb5dd5990cec6e7f5c9c1124a37cb2c710c6d69b0c1a5c4aa4b35eba0ada068"}, + {file = "lazy_object_proxy-1.5.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b6577f15d5516d7d209c1a8cde23062c0f10625f19e8dc9fb59268859778d7d7"}, + {file = "lazy_object_proxy-1.5.2-cp36-cp36m-win32.whl", hash = "sha256:c8fe2d6ff0ff583784039d0255ea7da076efd08507f2be6f68583b0da32e3afb"}, + {file = "lazy_object_proxy-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:fa5b2dee0e231fa4ad117be114251bdfe6afe39213bd629d43deb117b6a6c40a"}, + {file = "lazy_object_proxy-1.5.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1d33d6f789697f401b75ce08e73b1de567b947740f768376631079290118ad39"}, + {file = "lazy_object_proxy-1.5.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:57fb5c5504ddd45ed420b5b6461a78f58cbb0c1b0cbd9cd5a43ad30a4a3ee4d0"}, + {file = "lazy_object_proxy-1.5.2-cp37-cp37m-win32.whl", hash = "sha256:e7273c64bccfd9310e9601b8f4511d84730239516bada26a0c9846c9697617ef"}, + {file = "lazy_object_proxy-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f4e5e68b7af950ed7fdb594b3f19a0014a3ace0fedb86acb896e140ffb24302"}, + {file = "lazy_object_proxy-1.5.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cadfa2c2cf54d35d13dc8d231253b7985b97d629ab9ca6e7d672c35539d38163"}, + {file = "lazy_object_proxy-1.5.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e7428977763150b4cf83255625a80a23dfdc94d43be7791ce90799d446b4e26f"}, + {file = "lazy_object_proxy-1.5.2-cp38-cp38-win32.whl", hash = "sha256:2f2de8f8ac0be3e40d17730e0600619d35c78c13a099ea91ef7fb4ad944ce694"}, + {file = "lazy_object_proxy-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:38c3865bd220bd983fcaa9aa11462619e84a71233bafd9c880f7b1cb753ca7fa"}, + {file = "lazy_object_proxy-1.5.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:8a44e9901c0555f95ac401377032f6e6af66d8fc1fbfad77a7a8b1a826e0b93c"}, + {file = "lazy_object_proxy-1.5.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fa7fb7973c622b9e725bee1db569d2c2ee64d2f9a089201c5e8185d482c7352d"}, + {file = "lazy_object_proxy-1.5.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:71a1ef23f22fa8437974b2d60fedb947c99a957ad625f83f43fd3de70f77f458"}, + {file = "lazy_object_proxy-1.5.2-cp39-cp39-win32.whl", hash = "sha256:ef3f5e288aa57b73b034ce9c1f1ac753d968f9069cd0742d1d69c698a0167166"}, + {file = "lazy_object_proxy-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:37d9c34b96cca6787fe014aeb651217944a967a5b165e2cacb6b858d2997ab84"}, +] lunarcalendar = [ {file = "LunarCalendar-0.0.9-py2.py3-none-any.whl", hash = "sha256:5ef25883d73898b37edb54da9e0f04215aaa68b897fd12e9d4b79756ff91c8cb"}, {file = "LunarCalendar-0.0.9.tar.gz", hash = "sha256:681142f22fc353c3abca4b25699e3d1aa7083ad1c268dce36ba297eca04bed5a"}, @@ -3233,6 +3357,10 @@ matplotlib = [ {file = "matplotlib-3.3.4-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:cf3a7e54eff792f0815dbbe9b85df2f13d739289c93d346925554f71d484be78"}, {file = "matplotlib-3.3.4.tar.gz", hash = "sha256:3e477db76c22929e4c6876c44f88d790aacdf3c3f8f3a90cb1975c0bf37825b0"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] mistune = [ {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, @@ -3245,8 +3373,8 @@ mpld3 = [ {file = "mpld3-0.3.tar.gz", hash = "sha256:4d455884a211bf99b37ecc760759435c7bb6a5955de47d8daf4967e301878ab7"}, ] mplfinance = [ - {file = "mplfinance-0.12.7a7-py3-none-any.whl", hash = "sha256:08ac09b922c0e0482aadbb9a72f600415ad287db00f67227e042fd9a048e4d90"}, - {file = "mplfinance-0.12.7a7.tar.gz", hash = "sha256:a404e2a6b4c42edf06ac491e2a320b3dfa5d3435687b1e6df8c73ee8683b70f6"}, + {file = "mplfinance-0.12.7a10-py3-none-any.whl", hash = "sha256:aa4d9759a1befadfed190f9fc72ac8389d80fb61bc6f8ce6693d9c2627e88021"}, + {file = "mplfinance-0.12.7a10.tar.gz", hash = "sha256:f3745ad29ec834cd5505aa510f401f2c44b44328f92c781d093b3bb597641545"}, ] multidict = [ {file = "multidict-5.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f"}, @@ -3566,16 +3694,28 @@ pyasn1-modules = [ {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, ] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] pycparser = [ {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] +pyflakes = [ + {file = "pyflakes-2.3.0-py2.py3-none-any.whl", hash = "sha256:910208209dcea632721cb58363d0f72913d9e8cf64dc6f8ae2e02a3609aba40d"}, + {file = "pyflakes-2.3.0.tar.gz", hash = "sha256:e59fd8e750e588358f1b8885e5a4751203a0516e0ee6d34811089ac294c8806f"}, +] pygments = [ {file = "Pygments-2.8.1-py3-none-any.whl", hash = "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"}, {file = "Pygments-2.8.1.tar.gz", hash = "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94"}, ] +pylint = [ + {file = "pylint-2.7.2-py3-none-any.whl", hash = "sha256:d09b0b07ba06bcdff463958f53f23df25e740ecd81895f7d2699ec04bbd8dc3b"}, + {file = "pylint-2.7.2.tar.gz", hash = "sha256:0e21d3b80b96740909d77206d741aa3ce0b06b41be375d92e1f3244a274c1f8a"}, +] pymeeus = [ - {file = "PyMeeus-0.5.9.tar.gz", hash = "sha256:f6c23f47b71fe9b3225f2a6d36dc99743a7fcb7587e17653525883a48803eb1c"}, + {file = "PyMeeus-0.5.11.tar.gz", hash = "sha256:bb9d670818d8b0594317b48a7dadea02a0594e5344263bf2054e1a011c8fed55"}, ] pyobjc-core = [ {file = "pyobjc-core-7.1.tar.gz", hash = "sha256:a0616d5d816b4471f8f782c3a9a8923d2cc85014d88ad4f7fec694be9e6ea349"}, @@ -3598,7 +3738,7 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pyrsistent = [ - {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, + {file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"}, ] pysocks = [ {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, @@ -3733,8 +3873,8 @@ pyzmq = [ {file = "pyzmq-22.0.3.tar.gz", hash = "sha256:f7f63ce127980d40f3e6a5fdb87abf17ce1a7c2bd8bf2c7560e1bbce8ab1f92d"}, ] qtconsole = [ - {file = "qtconsole-5.0.2-py3-none-any.whl", hash = "sha256:0173486b9cd69e17df537fb4f1e0d62a88019f6661700a11fd7236fa89ed900b"}, - {file = "qtconsole-5.0.2.tar.gz", hash = "sha256:404994edfe33c201d6bd0c4bd501b00c16125071573c938533224992bea0b30f"}, + {file = "qtconsole-5.0.3-py3-none-any.whl", hash = "sha256:4a38053993ca2da058f76f8d75b3d8906efbf9183de516f92f222ac8e37d9614"}, + {file = "qtconsole-5.0.3.tar.gz", hash = "sha256:c091a35607d2a2432e004c4a112d241ce908086570cf68594176dd52ccaa212d"}, ] qtpy = [ {file = "QtPy-1.9.0-py2.py3-none-any.whl", hash = "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea"}, @@ -3745,64 +3885,67 @@ quandl = [ {file = "Quandl-3.6.1.tar.gz", hash = "sha256:84414e5f8e870a9c8a9392e9dc639d50e839c5f5e07737a09bb57dd8b14b264b"}, ] rapidfuzz = [ - {file = "rapidfuzz-1.2.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6271fa24301ad16fb0f4ff4ed0a9652cc10cef05090ebad2cdb80dcb5717f60c"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:36774b6ad89619298c2d32c402d19b0d47cebc76bee55bb49494af09d88c8f63"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d11ee8c493a94657207c487ad4cd9a77a1f91f935f508c2f5c6a8231e9d8fbfb"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:b5058d4b21338b5fac67cb75ae6ba7cf13b6e79601e9df94abff2feba0129b86"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:092ad4fb8ab1a89cee72fa4b25957dc472c2115b3fdac1b6876fda30a057db63"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-win32.whl", hash = "sha256:d2c14b4dafc42cac5f2bb1cf8b476ca7969cdb317f63cad9b23a77cc33c3b3b0"}, - {file = "rapidfuzz-1.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:fc5f44c00080a589f7b286f603bd825f054f8c4b98f5883047043855a5c602b1"}, - {file = "rapidfuzz-1.2.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:fbd4d71bcde22878aef88dbab3bb53846b40f6ffa871cce1ac3956dc0464fb21"}, - {file = "rapidfuzz-1.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a2b3686559cecf4e40ff6909d40dc2069e531d249bfca48d3d936806907c8d6f"}, - {file = "rapidfuzz-1.2.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:761648722889378ee09b01481eaced525315cb3a8c594b076151383bd10408e8"}, - {file = "rapidfuzz-1.2.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d09b97c8247c1191d942f064567c683827ea5e779ccd1273dfc97d43e1f9f2a0"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:08cce907aa30ae3d278b50c82b4647aa50195cd206237d5f48df9a0a932eb0eb"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2b167a66a914d50b73c1e4d8d5ca5e9809705b3f6f357adc0f5eaeec4a36a33a"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:edd1a9d9227c07a70644f7926e51dbcd02cf993b89efa0607e068de6d029f153"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:88ceee809357090d2842365856ff07763cc402366dcd9ec4000c430be3a9f6d6"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:2834340f3992c46f9285dc6f14fbe39b9692015127ebbce7d978a5e00e41bc3d"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-win32.whl", hash = "sha256:59ec1533d2fbc7fbdac71268b5578f94a945083a669bf5728f99fdddbb3572cb"}, - {file = "rapidfuzz-1.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:75540b8c81f06278b0da66cb079f0c6bc4baf3b7a0443cd67b45e0b55d329231"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bb26d9354e85bd069f9bb74690b91626fe28e5dd2e77ec3afcee707fd1f04972"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c86a4667821d907fba99e155cf9612e135110406f1c6d83770bca04801432ead"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:639aa7eb1a2a20e9027b79b4ebc5c147f0659206a5770930045abf5e7beea572"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:db42b90720983c47b982ff4d708f5e16c50a3d45fcc1faf3999828e9d6b6022e"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:8401d65889589a8258c54e459440a4b55dd96831bbcda6f8aeca91aa2c448687"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-win32.whl", hash = "sha256:d1d67322affee993a8f9bfd0f560737fe738aa1afcc76bda3979439a92b60f20"}, - {file = "rapidfuzz-1.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:96730be22c9c1e44a788b2476023ac4f103e3abf4f63153348e430cc5623ea5d"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3acb074c00e46716d7fe510fbbe6e47b4abe06441bbcee78eb5a089d2a7e28b3"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8e7d4638e6acff9a3acfe8907d52fe8f05ef9663b93abc9168c3354ca3bd03ce"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:753e4274f93c5c06a08dfd1e4a4993ef41f5e8175398964afec37b950cf666fe"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:7c577d167514d49822380b97cd902edd1525f30a05253bd3c4523144b47c50cf"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d2dd24ccd81537b15dadd6493cc5f4d2b5f9577f163768ce9eaab1bd2416c617"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-win32.whl", hash = "sha256:b3f9fcc8156f7309a74d17b81caa4b19e40c4986e42996e2ad070c49c0382913"}, - {file = "rapidfuzz-1.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e24700f9de6899395ed7f4e69c7c332e7120487dfc0673502b2b72cba97aa947"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9bf61eadf206504bab0315e589c3e481f899a212819f63316e5708c46cc78c2"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:08e903e8bc995eaa406980ece7e4fc732546b6190c2c6b0fd2eaea44a147c6cc"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ac1e48fb1b94c6c43515ac5f265af972fee8151bfb7acd72fe5c546d191db374"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:24cc98bfb0dfab34ee6967c1f2b98db8c9a6d33fe408d24120ba28141d35c6cc"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ad3adfd11adc9c43917936794d54d1012cba66bfa093c0bc2653de21a5788101"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-win32.whl", hash = "sha256:7a60c27ab966aac9ccae40fbcac2bc1782de26bdc3651bf9a7890ac4345180e5"}, - {file = "rapidfuzz-1.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:6e04685b421b0966c9e55de0a0c2d87c0f43d24fb6b52629291df60bb7f79b10"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d96278cef5de6ad6f5c85115a9f62d128a3e62c22fa0a2745a78e23136b135c2"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7464088b73510977fd54fb6edbd8376f8c95b1fdddc392878ff6016e69efc573"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6ab9df36090447bbc847ee7e2c63a2937dcbdd13ea343df12a8fcc4e2ac0d740"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:8a0b1bf371e6dabc972e790fd0ef47a392e3605cfa355280ac15ee3eef3b0ede"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:30db409ee47c17d4c98de6bc4da3292c7d70894644fdfb2fed76cd8e280c9a6b"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-win32.whl", hash = "sha256:17037ae5719712c8f73fd4a65686b80cfe05deabb9504e5ca7afe77dcdb389dd"}, - {file = "rapidfuzz-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:64ee48bd20dbb787b5f71b4c5d2c70a622ace0d38067a5a74f5f362ff212e42c"}, - {file = "rapidfuzz-1.2.1-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:21a5ac116dbc8760333f52118e0f37b6fecaaed82311a5098d45f0e9d8c81f94"}, - {file = "rapidfuzz-1.2.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:597ad46358034d0786bbfba1139fa10d3e91a6779e6e75133751a43fe4431304"}, - {file = "rapidfuzz-1.2.1-pp27-pypy_73-win32.whl", hash = "sha256:a4e688fca51936962ef7217bb811501019bd1c6012898b8097e2bff0a91a2a56"}, - {file = "rapidfuzz-1.2.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0060946f2d39ff0c43849cea181efaa750935dfb779d5d7216c843bda27b543f"}, - {file = "rapidfuzz-1.2.1-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:d5cc171ed54fc8d7eb24abc5e61c4a0c7e74e316677a0e092cf1cb4646df929c"}, - {file = "rapidfuzz-1.2.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:12ef8d6f7152815d38e270d029ee5de781e37f91b0dc27ba45afddd33a3dacd4"}, - {file = "rapidfuzz-1.2.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:19059b44be14a78359b7d955b26078b238b92f8c63e2c0a5e6abfde2823f32d1"}, - {file = "rapidfuzz-1.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bd689e852b52a4deae20dabc20997c91ac5fde7dca73c3ae464fd4046443970e"}, - {file = "rapidfuzz-1.2.1-pp37-pypy37_pp73-manylinux1_x86_64.whl", hash = "sha256:dc1fa130ce23c657333ba4eb2e3e59d35a0c1714d93b199400f464f473bf9958"}, - {file = "rapidfuzz-1.2.1-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:da32c521aa4c47d291ddcedad5301997127d8ffaf4126cb235e5891ecccf4752"}, - {file = "rapidfuzz-1.2.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:ec3b3e49791bfdfc8b71cbece63b9a0f2b25b960c950747dc18e48c2b698f78e"}, - {file = "rapidfuzz-1.2.1.tar.gz", hash = "sha256:e479212f8f6eaf6bbc9ac5418320a49ae09ad942d3bd437b9db7e0a37c56f819"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d49956421daad639040e44dc12b301eb3f105f2ca4a5e9b32ed6c9650f02789a"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d5a8f133fb85ea2ed882ab7053d69d0a60cc0c0a7e8bc30bb5e306066279508"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9059004a081a86f3fbdb44e3d36897264196883a339f740476d1869dd41e4068"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:c524cb3267a48ff826f54b70a396e0bc6eb5ba997f2900bc6eff242e43aaafb4"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:ec74086dd1e00f8beeeda14aab80657c7dd84a8c4a7ab67bddce1f2ad41dbe1f"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:b08e8f3dbfd718832dfc77ea87484a8b8942c4f3fafacfd92b1204679d97d8fd"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:3f07c9e13457620e32caa8192aa04e8bf8b99dab2d93a9679ef829c86e98fede"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-manylinux2014_s390x.whl", hash = "sha256:e61d8870134c3f419634387c9baa3997f4e5c4294fe620de39662562089212cf"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-win32.whl", hash = "sha256:aa19c9c1b53f6019de4d2451a62b2cba1dee49e53f58905c84215e17a4ba3fed"}, + {file = "rapidfuzz-1.3.0-cp35-cp35m-win_amd64.whl", hash = "sha256:3d2d91358994e2b8379dc529399521c2a3ec727bfdcea7552b0877be1ec54117"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:03d4fefc4a4ca0512040d0753d0be79d920d22e56cd2bc25f2ee6bdcd4176dc9"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:525634b52c0d9544b19105230fe0e09d2dce43901fa5f019a547d8667299f2b8"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c3679dad6789183219dea5ddb927bf62211dc1fdf5b6d17ad49971d2895f9518"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:6f18c4d9fc65caf6068e306acc40192ade6d9af88939eeda3617864b4d2e8abf"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:9aa106d30859a57a1447346cdeddeb7015748281f43f2054e3276551406c39c5"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:3efb9f3c0d1ea0ec82d38075306f7e721dd88fb9ec0684dd350d73d83df6ba53"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:ed0387466970882468535a4a49bc14336783c55035a7e5d0edb36d05e253b8fe"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:78b4e66dec10f9f3d7cc35e6924442b8c121bdaa8a0dbd70311561fd9ff87170"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-win32.whl", hash = "sha256:1cb927ea0904caad8f2923dfdfa0975c93fdc8528b882feda78cbfc373ffa229"}, + {file = "rapidfuzz-1.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ba61d15d0ac83800f7a283b4c188ab54ac8595b1181714cc06b5f04ef33542a"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:076943f5b318483c263584cec59763d1aac70ea0dab5f5653fde495cd1e6395f"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:d25d6f7d94b17a962526c2261cc8fc2e292c5a071db810aeb9d48771ae9ec3e6"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d282448a4121a947daa540fdf0e9a8808adcf81168cfca0da9786768f6209fbb"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:bdb9942565fb10bca30e707b8c96e6e5544bd4c604394fc92596355c34fef258"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:324f6b13274abdbed51d709d6a930cf1408c26a8013e279283f0131b5fc29ac0"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:aae04e463205b363f95ca6971d7f9e3ed39f65a5ef7fee35b01775bba1dde374"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:67a0af6e486bc706f9f64cbd024a0d8d8b63726df95bb7c7a155791391f19567"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:9931dad05f4d51cc4a610db3f33cc3631c4547412b4925380cca7f6f07041cb0"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:eeb6e1c0d63dc4909dfb7daa105c035ff6713189b5ea1c312f7e760f986296c0"}, + {file = "rapidfuzz-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f22193795ef02f9a6bf90e3898a81b927dfdb80c62c6cd3e59d87330a6d4bcf1"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a73a69108cc96fad0f57f374315107eef9e80f997da7483799a262616cc0ef31"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9d97ae27902ffc2efa87b272a79a7376ddea1639b969bf995f2b521c88c2d99e"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a2122c78ffcae47f562450928be439a5b94ddb5b0e0d8e365ee1d08e8fe6874f"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:b4e16aacf5969f0a24dc530d0aa610df105d8fa7dd2aa282a7db98a8039c1719"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1b52b7139b98d559bbd977bd28b7e68a8d75dc2345122ca8fcf938e7ff72b295"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:25edcf5a805479dd434155ea88e9e76e9b3677b670800d5e95e04556e1a4a0e0"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:92ee666f0cfa47e74e745e2bb794b43c6eeba2931c873a91b45b3439018cae77"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:4ab4513fbe47618dab0ffbdea7beb73695d730a424b8df719aee80e48f8d00ff"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-win32.whl", hash = "sha256:3db9d3ea27f0926a137f0e0169f5b29dd49b88fb0171ed7dfce224b890a86f11"}, + {file = "rapidfuzz-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:41b28235f68475a865a94b4c0bee3259f525aac523d182432b68f5cafa35d9a1"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7891ecf01052b69c0e0cc94695a506dd1374636292eca26e061a0c1dc3165f02"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:096b445dca7972161cdd1f856969414dde7cc9b09ff420005092d7b31139d41c"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:66c5579effe2a846117b4f499ab6910d164804c8fe31846a80981992d1b78e6e"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2997f73a0cb5abc3a31e8c740a908be426d71db38827486881728470cc60b2c5"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4fbbe7129df9ecd818f259136f598241206a6ac10b09763eafcf6fd1ca0fe83f"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:24a8af40f7fc41795892be937cf3480d5cd8ae1f62ef6a845e7258d05c9ab35c"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f02b615ad69279e6ed61a7ba072494cd05cfddde210472956139d3361f8f20d1"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:45d20908601158d06c65d9ed4a54585dc32bd49cadefc385374f77b9a4696368"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:0e3570ea068e0704f7b43d5228e97c45954dec370114071139fdd9cf731a1750"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:f027a7df163f5f1d13d9ea60bf06d8bc0730194a2d584c3185c3a77c1a145916"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-win32.whl", hash = "sha256:460bacd89c129cf1aefc56ae465f642c712aa9b620e74305040a1cf6975cc510"}, + {file = "rapidfuzz-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:5afa7539fb45b3c97fed67ca75a99ad7affce14561a3bd11e1c8d665b20ea8ab"}, + {file = "rapidfuzz-1.3.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5cadbd3f5df7e02dc11b819af860cb1a5365a49de515b76bf5dad62a3724ebaf"}, + {file = "rapidfuzz-1.3.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:7e2196346ae5a1a2ac79c780d63983df93c1dbbea8aed910c43ad13c67bddc35"}, + {file = "rapidfuzz-1.3.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:ac3bc9341d8f265eb65a66ec88f351851e89a0f22be916ed4e74590e347f159e"}, + {file = "rapidfuzz-1.3.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:3438c6db485dd5a3716a7f2e92a262b05db959f03712c4423b68a32453a5957d"}, + {file = "rapidfuzz-1.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ac6016f99dc36d490251c8b0910d7445921ca950ac204a4d299c0a298db8f0c"}, + {file = "rapidfuzz-1.3.0-pp37-pypy37_pp73-manylinux1_x86_64.whl", hash = "sha256:9573c989a78866269ced934a5a345ea44d05f4b69576d91c7e5b21771d19e030"}, + {file = "rapidfuzz-1.3.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:6f97fdca7a43ddb4258ddc2d6a8e960b0f5b369346d8bac02cc20b7b51721eb1"}, + {file = "rapidfuzz-1.3.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:c92b7e3148a90ac9f8740e4235c64cf5a02d15a4cfbd3aa580e62327e22d4d6a"}, + {file = "rapidfuzz-1.3.0.tar.gz", hash = "sha256:f6a95ed17d7750ca75f11751ab46365c58f37a5d846e2b21d072d7a0e77ffa72"}, ] regex = [ {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, @@ -3976,8 +4119,8 @@ smart-open = [ {file = "smart_open-4.2.0.tar.gz", hash = "sha256:d9f5a0f173ccb9bbae528db5a3804f57145815774f77ef755b9b0f3b4b2a9dcb"}, ] soupsieve = [ - {file = "soupsieve-2.2-py3-none-any.whl", hash = "sha256:d3a5ea5b350423f47d07639f74475afedad48cf41c0ad7a82ca13a3928af34f6"}, - {file = "soupsieve-2.2.tar.gz", hash = "sha256:407fa1e8eb3458d1b5614df51d9651a1180ea5fedf07feb46e45d7e25e6d6cdd"}, + {file = "soupsieve-2.2.1-py3-none-any.whl", hash = "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b"}, + {file = "soupsieve-2.2.1.tar.gz", hash = "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc"}, ] sqlitedict = [ {file = "sqlitedict-1.7.0.tar.gz", hash = "sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56"}, @@ -4037,8 +4180,8 @@ termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] terminado = [ - {file = "terminado-0.9.2-py3-none-any.whl", hash = "sha256:23a053e06b22711269563c8bb96b36a036a86be8b5353e85e804f89b84aaa23f"}, - {file = "terminado-0.9.2.tar.gz", hash = "sha256:89e6d94b19e4bc9dce0ffd908dfaf55cc78a9bf735934e915a4a96f65ac9704c"}, + {file = "terminado-0.9.3-py3-none-any.whl", hash = "sha256:430e876ec9d4d93a4fd8a49e82dcfae0c25f846540d0c5ca774b397533e237e8"}, + {file = "terminado-0.9.3.tar.gz", hash = "sha256:261c0b7825fecf629666e1820b484a5380f7e54d6b8bd889fa482e99dcf9bde4"}, ] testpath = [ {file = "testpath-0.4.4-py2.py3-none-any.whl", hash = "sha256:bfcf9411ef4bf3db7579063e0546938b1edda3d69f4e1fb8756991f5951f85d4"}, @@ -4187,8 +4330,8 @@ update-checker = [ {file = "update_checker-0.18.0.tar.gz", hash = "sha256:6a2d45bb4ac585884a6b03f9eade9161cedd9e8111545141e9aa9058932acb13"}, ] urllib3 = [ - {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"}, - {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"}, + {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, + {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, ] user-agent = [ {file = "user_agent-0.1.9.tar.gz", hash = "sha256:8f1ad46cc4aef9f99515ea1c74bb8cacc43e23074c335b2ba2db7735ebe9c0d5"}, diff --git a/pyproject.toml b/pyproject.toml index 84c831a6e37..20a292ec5cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,9 +40,16 @@ seaborn = "^0.11.0" scipy = "1.5.4" fredapi = "^0.4.3" screeninfo = "^0.6.7" +numpy = "~1.19.5" +pyrsistent = "~0.14.11" +regex = "~2020.11.13" +h5py = "~2.10.0" [tool.poetry.dev-dependencies] pytest = "^6.2.2" +pylint = "^2.7.2" +flake8 = "^3.9.0" +black = "^20.8b1" [tool.poetry.extras] prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "torch"] From 80ca26f2f3ace37a726a7a9331ee46c3c441c064 Mon Sep 17 00:00:00 2001 From: Aaron Cutright Date: Fri, 19 Mar 2021 21:15:10 -0400 Subject: [PATCH 11/19] Add python 3.8 instructions, workarounds for issue #226, #236 --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05d2045a00b..899ff16ce92 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,21 @@ This is a library for package management, and ensures a smoother experience than python terminal.py ``` +### Advanced User Install - Python 3.8 + +*Note that the `conda deactivate` -> `conda activate` in the middle is on purpose, this is sometimes required to avoid issues with poetry* + +``` +conda create -n gst python=3.8.8 +conda activate gst +conda install poetry +conda deactivate +conda activate gst +poetry install +conda install -c conda-forge fbprophet numpy=1.19.5 hdf5=1.10.5 +poetry install -E prediction +``` + ### Advanced User Install - Machine Learning If you are an advanced user and use other Python distributions, we have several requirements.txt documents that you can pick from to download project dependencies. @@ -145,10 +160,17 @@ Note: The libraries specified in the [requirements.txt](/requirements.txt) file ENABLE_PREDICT = os.getenv("GTFF_ENABLE_PREDICT") or True ``` -* Install optional ML features dependencies collection with poetry: +* Install optional ML features dependencies: ``` poetry install -E prediction ``` +*If you run into issues installing or `Cannot convert a symbolic Tensor...` at runtime, try this:* + +``` +conda install -c conda-forge fbprophet numpy=1.19.5 hdf5=1.10.5 +poetry install +poetry install -E prediction +``` *If you would like to set up a docker image:* @@ -157,10 +179,40 @@ poetry install -E prediction Note: The problem with docker is that it won't output matplotlib figures. -*Commands that may help you in case of an error:* -* `conda install -c conda-forge fbprophet -y` +*Commands that may help you in case of an error: + * `python -m pip install --upgrade pip` * `pip install pystan --upgrade` +* `poetry update --lock` + +### Other issues + +If you run into trouble with poetry and the advice above did not help, your best bet is to try + +1. `poetry update --lock` + +2. `conda deactivate` -> `conda activate gst`, then try again + +3. Delete the poetry cache, then try again + + | Platform | Location | + | -------- | ------------------------------- | + | Linux | "~/.cache/pypoetry" | + | Mac | "~/Library/Caches/pypoetry" | + | Windows | "%localappdata%/pypoetry/cache" | + +4. Track down the offensive package and purge it from your anaconda `` folder, then try again (removing through conda can sometimes leave locks behind) + + | Platform | Location | + | --------- | -------------------------------------------- | + | Linux/Mac | "~/anaconda3/envs" or "~/opt/anaconda3/envs" | + | Windows | "%userprofile%/anaconda3/envs" | + +5. Completely nuke your conda environment folder and make a new environment from scratch + +6. Reboot your computer and try again + +7. Submit a ticket on github ### API Keys From 93f6eb3ba363511d0c8d11817a1576162aed250a Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sat, 20 Mar 2021 09:21:15 +0000 Subject: [PATCH 12/19] Add examples to readme --- .../comparison_analysis/README.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/gamestonk_terminal/comparison_analysis/README.md b/gamestonk_terminal/comparison_analysis/README.md index a7fe87965cd..8306b075770 100644 --- a/gamestonk_terminal/comparison_analysis/README.md +++ b/gamestonk_terminal/comparison_analysis/README.md @@ -10,6 +10,12 @@ This menu aims to compare a pre-loaded stock with similar companies, and the usa * historical data comparison [Yahoo Finance] * [corr](#corr) * correlation between similar companies [Yahoo Finance] +* [income](#income) + * income financials comparison [Market Watch] +* [balance](#balance) + * balance financials comparison [Market Watch] +* [cashflow](#cashflow) + * cashflow financials comparison [Market Watch] ## get @@ -59,3 +65,53 @@ Historical price comparison between similar companies [Source: Yahoo Finance] * -t : type of candles: o-open, h-high, l-low, c-close, a-adjusted close. Default 'a'. ![corr](https://user-images.githubusercontent.com/25267873/110699596-efc41b80-81e6-11eb-924f-8739058aa54e.png) + + +## income + +```text +usage: income [-s L_SIMILAR] [-a L_ALSO] [-t 31-Dec-2020/2017] [-q] +``` + +Income financials comparison between similar companies [Source: Market Watch] + +* -s : similar companies to compare with. Default pre-loaded ones. +* -a : apart from loaded similar companies also compare with. +* -t : timeframe of earnings. Default: Last. +* -q : quarterly data instead of yearly. Default: False. + +Captura de ecrã 2021-03-20, às 09 10 02 + + +## balance + +```text +usage: balance [-s L_SIMILAR] [-a L_ALSO] [-t 31-Dec-2020/2017] [-q] +``` + +Balance financials comparison between similar companies [Source: Market Watch] + +* -s : similar companies to compare with. Default pre-loaded ones. +* -a : apart from loaded similar companies also compare with. +* -t : timeframe of earnings. Default: Last. +* -q : quarterly data instead of yearly. Default: False. + +Captura de ecrã 2021-03-20, às 09 10 53 + +## cashflow + +```text +usage: cashflow [-s L_SIMILAR] [-a L_ALSO] [-t 31-Dec-2020/2017] [-q] +``` + +Cashflow financials comparison between similar companies [Source: Market Watch] + +* -s : similar companies to compare with. Default pre-loaded ones. +* -a : apart from loaded similar companies also compare with. +* -t : timeframe of earnings. Default: Last. +* -q : quarterly data instead of yearly. Default: False. + +Captura de ecrã 2021-03-20, às 09 12 59 + + + From d9d319c95adb43d24084afb35dd6cc706489c746 Mon Sep 17 00:00:00 2001 From: didier Date: Sat, 20 Mar 2021 09:22:57 +0000 Subject: [PATCH 13/19] refactor cash to cashflow --- gamestonk_terminal/comparison_analysis/ca_controller.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py index 6c8158b1fe4..e158e504e05 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -30,7 +30,7 @@ class ComparisonAnalysisController: "corr", "income", "balance", - "cash", + "cashflow", ] def __init__( @@ -89,7 +89,7 @@ class ComparisonAnalysisController: print("") print(" income income financials comparison") print(" balance balance financials comparison") - print(" cash cash financials comparison") + print(" cashflow cashflow comparison") print("") return @@ -215,8 +215,8 @@ class ComparisonAnalysisController: """Process balance command""" mw_api.compare_balance(other_args, self.ticker, self.similar) - def call_cash(self, other_args: List[str]): - """Process cash command""" + def call_cashflow(self, other_args: List[str]): + """Process cashflow command""" mw_api.compare_cashflow(other_args, self.ticker, self.similar) From de738757c6e770153528d197628a432d0724ef72 Mon Sep 17 00:00:00 2001 From: didier Date: Sat, 20 Mar 2021 10:16:06 +0000 Subject: [PATCH 14/19] Improve ROADMAP --- ROADMAP.md | 54 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 8989040cbad..9a7c2ab08af 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # Roadmap 📍 -### Table of contents +## Table of contents * [Discovery](#Discovery) * [Behavioral Analysis](#Behavioral-Analysis) @@ -13,13 +13,17 @@ * [Comparison Analysis](#Comparison-Analysis) * [Exploratory Data Analysis](#Exploratory-Data-Analysis) * [Portfolio Analysis](#Portfolio-Analysis) +* [FRED](#FRED) +* [Options](#Options) * [Credit Analysis](#Credit-Analysis) * [Cryptocurrencies](#Cryptocurrencies) + +## Additional * [Backend](#Backend) * [Frontend](#Frontend) * [Developer Experience](#Developer-Experience) * [User Experience](#User-Experience) -* [Options](#Options) + --- ## Discovery @@ -40,6 +44,7 @@ ### Short term - [ ] Implement a better Twitter client (@aia) +- [x] Add FinBrain sentiment from news (@didier) - [PR #223](https://github.com/DidierRLopes/GamestonkTerminal/pull/223) ### Long term @@ -89,7 +94,8 @@ ### Short term -- [x] Add several exponential smoothing techniques [PR #132](https://github.com/DidierRLopes/GamestonkTerminal/pull/132) +- [x] Add several exponential smoothing techniques (@didier) - [PR #132](https://github.com/DidierRLopes/GamestonkTerminal/pull/132) +- [x] Allow backtesting (@didier) - [PR #169](https://github.com/DidierRLopes/GamestonkTerminal/pull/169) ### Long term @@ -111,7 +117,7 @@ ### Short term * [x] Add multi-ticker historical data comparison (@didier) - [PR #141](https://github.com/DidierRLopes/GamestonkTerminal/pull/141) -* [ ] Add multi-ticker financials comparison (@didier) +* [x] Add multi-ticker financials comparison (@didier) - [PR #237](https://github.com/DidierRLopes/GamestonkTerminal/pull/237) ### Long term @@ -132,8 +138,38 @@ ### Short term +- [x] Add robinhood (@jmaslek) - [PR #209](https://github.com/DidierRLopes/GamestonkTerminal/pull/209) +- [ ] Add Brokers (td, alpaca, webull, etc) (@jmaslek) +- [ ] Merge data from different brokers (@jmaslek) ### Long term +- [ ] Summaries / tear sheets (@jmaslek) +- [ ] Portfolio Optimization (@jmaslek) + + +--- + +## FRED + +### Short term + +- [x] Implement Economic data (gpd, unemployment rate, ...) (@jmaslek) - [PR #167](https://github.com/DidierRLopes/GamestonkTerminal/pull/167) +### Long term + + +--- + +## Options + +### Short term + +- [x] Add Volume graph (@lolrenx) - [PR #209](https://github.com/DidierRLopes/GamestonkTerminal/pull/209) +- [x] Add Open Interest graph (@lolrenx) - [PR #209](https://github.com/DidierRLopes/GamestonkTerminal/pull/209) + +### Long term + +- [ ] Add max pain graph (@lolrenx) + --- ## Credit Analysis @@ -209,13 +245,3 @@ --- -## Options - -### Short term - -- [ ] Add Volume graph (@lolrenx) -- [ ] Add Open Interest graph (@lolrenx) - -### Long term - -- [ ] Add max pain graph From 4eceb37bd692f0b1240ead040775454460ffb233 Mon Sep 17 00:00:00 2001 From: Prabhakar Chaganti Date: Sat, 20 Mar 2021 12:14:30 -0400 Subject: [PATCH 15/19] Added missing fredapi to requirements --- requirements-full.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-full.txt b/requirements-full.txt index 6da8fbfca0d..2122c6fa3c1 100644 --- a/requirements-full.txt +++ b/requirements-full.txt @@ -38,6 +38,7 @@ filelock==3.0.12; python_full_version >= "3.6.0" and python_version >= "3.6" finviz==1.3.4 flair==0.7; python_version >= "3.6" flatbuffers==1.12 +fredapi==0.4.3 ftfy==5.9; python_version >= "3.6" fundamentalanalysis==0.2.6 future==0.18.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6" From 71b68083b89f5a24716a0edf33d92b0993265ca7 Mon Sep 17 00:00:00 2001 From: Felixkruemel Date: Sat, 20 Mar 2021 17:27:30 +0100 Subject: [PATCH 16/19] Updated Roadmap for Prediction Techniques --- ROADMAP.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index a9f58a4ec46..cc9ca5476f4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -96,9 +96,12 @@ - [x] Add several exponential smoothing techniques (@didier) - [PR #132](https://github.com/DidierRLopes/GamestonkTerminal/pull/132) - [x] Allow backtesting (@didier) - [PR #169](https://github.com/DidierRLopes/GamestonkTerminal/pull/169) +- [ ] Add averaging around multiple predictions - [IS #240](https://github.com/DidierRLopes/GamestonkTerminal/issues/240) ### Long term +- [ ] Combine Sentiment Analysis with Chart data - [IS #240](https://github.com/DidierRLopes/GamestonkTerminal/issues/240) + --- ## Reports From a0af5e7575439bb7af21d0b85b1f0ba42041c91c Mon Sep 17 00:00:00 2001 From: Prabhakar Chaganti Date: Sat, 20 Mar 2021 15:40:52 -0400 Subject: [PATCH 17/19] Added FRED API env variable to instructions --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 899ff16ce92..f2615a4a072 100644 --- a/README.md +++ b/README.md @@ -225,10 +225,11 @@ These are the ones where a key is necessary: * Twitter: https://developer.twitter.com * Polygon: https://polygon.io * Financial Modeling Prep: https://financialmodelingprep.com/developer + * FRED: https://fred.stlouisfed.org/docs/api/api_key.html When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py). -Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY. +Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY. Example: ``` From 24eee2affbe519dcf1dc0948472382c43d12a960 Mon Sep 17 00:00:00 2001 From: Prabhakar Chaganti Date: Sat, 20 Mar 2021 17:32:10 -0400 Subject: [PATCH 18/19] Add fredapi to requirements-win --- requirements-win.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-win.txt b/requirements-win.txt index 5083766ee84..cdde68f6009 100644 --- a/requirements-win.txt +++ b/requirements-win.txt @@ -28,6 +28,7 @@ filelock==3.0.12; python_full_version >= "3.6.0" and python_version >= "3.6" finviz==1.3.4 flair==0.7; python_version >= "3.6" flatbuffers==1.12 +fredapi==0.4.3 ftfy==5.9; python_version >= "3.6" fundamentalanalysis==0.2.6 future==0.18.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6" From be2604e940705e5161b05053461735ed50c03348 Mon Sep 17 00:00:00 2001 From: Prabhakar Chaganti Date: Sat, 20 Mar 2021 20:56:59 -0400 Subject: [PATCH 19/19] Add materials industry to the econ data summary in papermill --- notebooks/templates/econ_data.ipynb | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/notebooks/templates/econ_data.ipynb b/notebooks/templates/econ_data.ipynb index e55acb77ab9..0be206e395a 100644 --- a/notebooks/templates/econ_data.ipynb +++ b/notebooks/templates/econ_data.ipynb @@ -322,6 +322,42 @@ "edh.draw_graph(\"XLF\", cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" ] }, + { + "cell_type": "markdown", + "id": "blistering-barnacles", + "metadata": {}, + "source": [ + "## Materials - 2 year trend with 20, 50 and 200 day SMA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "italian-portent", + "metadata": {}, + "outputs": [], + "source": [ + "edh.draw_graph(\"XLB\", cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" + ] + }, + { + "cell_type": "markdown", + "id": "material-science", + "metadata": {}, + "source": [ + "## Materials - 1 year trend with 20, 50 and 200 day SMA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bundle-enabler", + "metadata": {}, + "outputs": [], + "source": [ + "edh.draw_graph(\"XLB\", cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" + ] + }, { "cell_type": "code", "execution_count": null,