Best Python code snippet using robotframework-pageobjects_python
scrapers.py
Source:scrapers.py  
...37        return soup38    # @params (row) - html TR, (column) - which column holds the data, (get_text) - return the html element, or the actual text39    # @descrip - for HTML tables, return the cell of the table40    # @returns str - either BS4obj or the actual text41    def get_table_cell(self, row, column, get_text: bool) -> str:42        table_cells = row.find_all('td')43        if get_text:44            return table_cells[column].get_text()45        return table_cells[column]46 # =========================================================== #47 #                 Bloomberg scraper                            #48 # ============================================================ #49class Bloomberg(Scaper):50    # @params (None)51    # @descrip - scrapes bloomberg sectors and populates the sectors dict for future use.52    # @returns None53    def __init__(self, firefox_instance=None):54        self.sectors = {}55        soup = super().get_data('https://www.bloomberg.com/markets/sectors', firefox_instance)56        table_rows = soup.find_all(57            'div', class_='sector-data-table__sector-row')58        for row in table_rows:59            sector_name = row.contents[1].get_text().strip().lower()60            sector_performance = row.contents[3].get_text().strip()61            sector_performance = sector_performance[:(62                len(sector_performance) - 1)]63            if (util.isValidFloat(sector_performance)):64                self.sectors[sector_name] = float(sector_performance)65        return66 # =========================================================== #67 #                 Finviz scraper                               #68 # ============================================================ #69class FinViz(Scaper):70    # @params (path, firefox_instance) - URL or file path of the resource, firefox_instance -> an instance of the firefox browser (FireFox class)71    # @descrip - scrapes Finviz and populates a BS4 Obj72    # @returns None73    def __init__(self, path: str, firefox_instance=None):74        self.base = super()75        self.soup = self.base.get_data(path, firefox_instance)76        self.news = []  # List of News Events77        self.table = None78        return79    # @params (Upper_threshold) - Only find tickers that have at this value and below,  (Lower_threshold) - Only find tickers that have at this value and above80    # @descrip - scrapes single webpage for tickers81    # @returns list - list of tickers that met the parameter criteria82    def get_tickers(self, upper_threshold: float, lower_threhold: float) -> list:83        tickers = []84        self.table = self.soup.find('table', attrs={85                                    'bgcolor': '#d3d3d3', 'border': '0', 'cellpadding': '3', 'cellspacing': '1', 'width': '100%'})86        if self.table == None:87            return tickers88        table_rows = self.table.find_all('tr')89        for row in table_rows:90            change = self.base.get_table_cell(row, 9, True)91            change = change.replace('%', '').replace('-', '')92            if (util.isValidFloat(change)):93                if (lower_threhold <= float(change) <= upper_threshold):94                    tickers.append(self.base.get_table_cell(row, 1, True))95        return tickers96    # @params (None)97    # @descrip - find last row id of the web page. Finviz will give you the same last id for subsquent pages.98    # @returns int - value of last row item on finviz99    def get_last_finviz_row_id(self) -> int:100        if self.table == None:101            return 0102        table_rows = self.table.find_all('tr')103        for row in table_rows:104            last_id = self.base.get_table_cell(row, 0, True)105            if (util.isValidInt(last_id)):106                last_id = int(last_id)107        return last_id108    # @params (None)109    # @descrip - finds the date of the last news article and checks to see if it was in the date ranges specified in utils. Also stores off news events.110    # @returns bool - true if we find a news article, false if not and stores off link,title and date into news field111    def has_finviz_news(self) -> bool:112        table = self.soup.find('table', id='news-table')113        if table == None:114            return False115        table_rows = table.find_all('tr')116        for index, row in enumerate(table_rows):117            news_date = self.base.get_table_cell(row, 0, True)118            news_date = unicodedata.normalize(119                'NFKD', news_date).strip()  # Drop Ending Bytes120            news_date = util.string_to_date(news_date)121            if (news_date != None):122                if index < 10:123                    for date in util.get_date_ranges():124                        if (news_date == date):125                            return True126                model = News_Event()127                title = self.base.get_table_cell(row, 1, False)128                title = title.find('a', href=True)129                model.data['date_of_article'] = news_date130                model.data['title_of_article'] = title.get_text()131                model.data['link'] = title['href']132                model.data['source'] = 'Finviz'133                self.news.append(model)134        return False135 # =========================================================== #136 #                 SEC Edgar Files scraper                     #137 # ============================================================ #138class SEC_Edgar(Scaper):139    # @params (ticker) - ticker => company we want to gather info on.140    # @descrip - Set ups required fields for class use. if we can find info from the ticker, then try to find it from the CIK number.141    # @returns None142    def __init__(self, ticker: str) -> None:143        self.base = super()144        self.ticker = ticker145        self.cik = None146        self.cik_dict = {}147        self.soup = None148        self.is_valid = True149        self.links_s8 = []150        self.links_425 = []151        self.links_s3 = []152        self.links_8k = []153        self.links_f3 = []154        self.links_f6 = []155        self.links_f4 = []156        self.late_filings = 0157        self.ct_orders = 0158        self.ipo_date = datetime.today().date()159        self.is_adr = False160        self.base_data = self.base.get_data(161            'https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=' + self.ticker + '&type=&dateb=&owner=exclude&start=0&count=100')162        with open('./data_operations/utils/cik_ticker.json') as f:163            self.cik_dict = json.load(f)164        if self.base_data.find('h1', text="No matching Ticker Symbol."):165            self.is_valid = False166            return167        cik = self.base_data.find('span', class_='companyName')168        cik = cik.find('a').get_text()169        self.cik = cik.split(' ')[0]170        return171    # @params (inc) - inc => determines which "page" we are on since SEC maxium display count is 100.172    # @descrip - Makes the request, and scrapes the given page.173    # @returns bool - true if we have data, false if we at the end of line.174    def load_data(self, inc: int) -> bool:175        self.soup = self.base.get_data('https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=' +176                                       self.ticker + '&type=&dateb=&owner=exclude&start=' + str(inc) + '&count=100')177        table = self.soup.find('table', class_='tableFile2')178        if table == None:179            return False180        rows = table.find_all('tr')181        if len(rows) >= 2:182            return True183        return False184    # @params (location_code, sic_code) - loc_code => the state in which the company is registerd (a SEC code) / sic_code => the sector in which the company is registered (SEC code)185    # @descrip - loads the company search by SIC code, and cross references by location code186    # @returns list - a list of CIK codes of companies in the same state, and same sector.187    def get_sic_data(self, location_code: str, sic_code: str) -> list:188        inc = 0189        comps = []190        sic_html = self.base.get_data('https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&SIC=' +191                                      sic_code + '&owner=exclude&match=&start=' + str(inc) + '&count=100&hidefilings=0')192        while not sic_html.find('div', class_='noCompanyMatch'):193            table = sic_html.find('table', class_='tableFile2')194            rows = table.find_all('tr')195            for index, row in enumerate(rows):196                if index == 0:  # Skip header TR row197                    continue198                comp_state_code = self.base.get_table_cell(row, 2, True)199                if location_code == comp_state_code:200                    comps.append(self.base.get_table_cell(row, 0, True))201            inc = inc + 100202            sic_html = self.base.get_data('https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&SIC=' +203                                          sic_code + '&owner=exclude&match=&start=' + str(inc) + '&count=100&hidefilings=0')204        return comps205    # @params (None)206    # @descrip - iterates through list of CIKs and converts to a ticker str207    # @returns list - a list of ticker str's of companies in the same state and same sector.208    def get_related_companies(self) -> list:209        # if related co not in CIK file, maybe they merged?210        related_cos = []211        links = self.base_data.find('p', class_='identInfo')212        links = links.find_all('a', href=True)213        sic_code = links[0].get_text()214        location_code = links[1].get_text()215        company_ciks = self.get_sic_data(location_code, sic_code)216        for cik in company_ciks:217            for cik_item in self.cik_dict:218                if str(self.cik_dict[cik_item]['cik_str']) in cik and cik != self.cik:219                    related_cos.append(self.cik_dict[cik_item]['ticker'])220                    break221        return related_cos222    # @params (ticker) - ticker of competeing company223    # @descrip - Takes a specified ticker and collects the past 5 days price action for it224    # @returns list - a list of peer_performance models for each day we have data225    def make_arr_peer_performance_model(self, ticker: str) -> list:226        sleep(1)  # Yfinance rate limiting227        peer_list = []228        symbol = yfinance.Ticker(ticker)229        data = symbol.history(period='5d')230        for index, row in data.iterrows():231            try:232                peer_model = Peer_Performance()233                peer_model.data['ticker'] = ticker234                peer_model.data['date'] = index.date()235                peer_model.data['open'] = row.Open236                peer_model.data['high'] = row.High237                peer_model.data['low'] = row.Low238                peer_model.data['close'] = row.Close239                peer_model.data['volume'] = row.Volume240                peer_model.data['percent_change'] = peer_model.to_percent(241                    row.Open, row.Close)242                peer_list.append(peer_model)243            except:244                # Not valid ticker or whatever. Dont add the model.245                pass246        return peer_list247    # @params (None)248    # @descrip - Iterates through the filings page by page and pulls out the forms we are looking for. Only for american listed companies which have different reporting requirments.249    # @returns None250    def parse_sec_filings(self) -> None:251        inc = 0252        s1_found = False253        while self.load_data(inc):254            table = self.soup.find('table', class_='tableFile2')255            rows = table.find_all('tr')256            if self.is_adr:257                self.parse_sec_foreign_filings(table)258            else:259                for index, row in enumerate(rows):260                    if index == 0:  # Skip header row261                        continue262                    form_id = self.base.get_table_cell(row, 0, True)263                    if form_id == '6-K' or form_id == 'F-1' or form_id == 'F-3' or form_id == 'F-6' or form_id == 'F-3ASR' or form_id == '20-F':264                        # Safe to say this is a ADR265                        self.is_adr = True266                        self.parse_sec_foreign_filings(table)267                        break268                    elif form_id == 'NT 10-K' or form_id == 'NT 10-Q' or form_id == 'NT 10-D' or form_id == 'NT 11-k':269                        self.late_filings += 1270                    elif form_id == 'S-8':271                        link = self.base.get_table_cell(row, 1, False)272                        link = link.find('a', href=True)273                        self.links_s8.append(274                            'https://www.sec.gov' + link['href'])275                    elif form_id == 'S-3' or form_id == 'S-3ASR':276                        link = self.base.get_table_cell(row, 1, False)277                        link = link.find('a', href=True)278                        self.links_s3.append(279                            'https://www.sec.gov' + link['href'])280                    elif form_id == 'CT ORDER':281                        self.ct_orders += 1282                    elif form_id == '8-K':283                        link = self.base.get_table_cell(row, 1, False)284                        link = link.find('a', href=True)285                        self.links_8k.append(286                            'https://www.sec.gov' + link['href'])287                    elif form_id == 'S-1':288                        s1_found = True289                        self.ipo_date = self.base.get_table_cell(row, 3, True)290                    elif form_id == '425':291                        link = self.base.get_table_cell(row, 1, False)292                        link = link.find('a', href=True)293                        self.links_425.append(294                            'https://www.sec.gov' + link['href'])295            if not s1_found:296                last_parsed_date = self.base.get_table_cell(297                    rows[(len(rows) - 1)], 3, True)298                if util.string_to_date(last_parsed_date) != None:299                    if self.ipo_date > util.string_to_date(last_parsed_date):300                        self.ipo_date = util.string_to_date(last_parsed_date)301            inc += 100302        return303    # @params (None)304    # @descrip - Iterates through the filings page by page and pulls out the forms we are looking for. Only for foreign listed companies which have different reporting requirments.305    # @returns None306    def parse_sec_foreign_filings(self, sec_table) -> None:307        # 6K can contain just too much disorganized information. Skipping for now.308        rows = sec_table.find_all('tr')309        # Since Foreign issuers dont have to file a S-1, just find the first entry310        last_parsed_date = self.base.get_table_cell(311            rows[(len(rows) - 1)], 3, True)312        if util.string_to_date(last_parsed_date) != None:313            if self.ipo_date > util.string_to_date(last_parsed_date):314                self.ipo_date = util.string_to_date(last_parsed_date)315        for index, row in enumerate(rows):316            last_parsed_date = None317            if index == 0:  # Skip header row318                continue319            form_id = self.base.get_table_cell(row, 0, True)320            if form_id == 'NT 11-k' or form_id == 'NT 20-F' or form_id == 'NT 10-D':321                self.late_filings += 1322            elif form_id == 'F-4':323                link = self.base.get_table_cell(row, 1, False)324                link = link.find('a', href=True)325                self.links_f4.append('https://www.sec.gov' + link['href'])326            elif form_id == 'F-3' or form_id == 'F-3ASR':327                link = self.base.get_table_cell(row, 1, False)328                link = link.find('a', href=True)329                self.links_f3.append('https://www.sec.gov' + link['href'])330            elif form_id == 'CT ORDER':331                self.ct_orders += 1332            elif form_id == 'S-8':333                link = self.base.get_table_cell(row, 1, False)334                link = link.find('a', href=True)335                self.links_s8.append('https://www.sec.gov' + link['href'])336            elif form_id == 'S-3' or form_id == 'S-3ASR':337                link = self.base.get_table_cell(row, 1, False)338                link = link.find('a', href=True)339                self.links_s3.append('https://www.sec.gov' + link['href'])340            elif form_id == 'F-6':341                link = self.base.get_table_cell(row, 1, False)342                link = link.find('a', href=True)343                self.links_f6.append('https://www.sec.gov' + link['href'])344            elif form_id == '425':345                link = self.base.get_table_cell(row, 1, False)346                link = link.find('a', href=True)347                self.links_425.append('https://www.sec.gov' + link['href'])348        return349    # @params (None)350    # @descrip - iterate though our forms we want, and scrapes each page trying to find the necessary information.351    # @returns SEC model with all information352    def make_sec_model(self) -> SEC:353        self.parse_sec_filings()354        model = SEC()355        model.data['date_of_ipo'] = self.ipo_date356        model.data['late_filings'] = self.late_filings357        model.data['ct_orders'] = self.ct_orders358        model.data['is_adr'] = self.is_adr359        # ====================== American Company =========================360        for link in self.links_s3:361            offering_model = self.make_secondary_offering_model(link)362            if offering_model.data['date'] != None:363                model.data['secondary_offerings'].append(offering_model)364        for link in self.links_8k:365            info_model = self.make_company_info_model(link)366            model.data['company_info'].append(info_model)367        # ======================== Foreign Company ===========================368        for link in self.links_f3:369            offering_model = self.make_secondary_offering_model(link)370            if offering_model.data['date'] != None:371                model.data['secondary_offerings'].append(offering_model)372        for link in self.links_f4:373            offering_model = self.make_secondary_offering_model(link)374            if offering_model.data['date'] != None:375                model.data['secondary_offerings'].append(offering_model)376        for link in self.links_f6:377            offering_model = self.make_secondary_offering_model(link)378            if offering_model.data['date'] != None:379                model.data['secondary_offerings'].append(offering_model)380        # ======================== Applies to both ======================381        for link in self.links_s8:382            stock_prog_model = self.make_stock_program_model(link)383            if stock_prog_model.data['date'] != None:384                model.data['stock_program'].append(stock_prog_model)385        for link in self.links_425:386            merger_model = self.make_merger_model(link)387            same_mergering_co = False388            for mergering_co in model.data['mergers']:389                if merger_model.data['merging_with_cik'] == None or merger_model.data['merging_with_cik'] == mergering_co.data['merging_with_cik']:390                    same_mergering_co = True391                    break392            if not same_mergering_co:393                model.data['mergers'].append(merger_model)394        return model395    # @params (link) - a link to form index page (Not the actual form)396    # @descrip - navigates to the form and tries to find the table that specifies how many shares were issued.397    # @returns SEC_Secondary_Offering Model398    def make_secondary_offering_model(self, link: str) -> SEC_Secondary_Offering:399        model = SEC_Secondary_Offering()400        model.data['link'] = link401        try:402            issued_shares = None403            model.data['is_asr'] = False404            data = self.base.get_data(link)405            # Get date from info header406            submission_date = data.find('div', text='Filing Date')407            submission_date = submission_date.find_next_sibling('div')408            model.data['date'] = submission_date.get_text()409            # parse main table for form type and link to actual submission410            table = data.find('table', class_='tableFile')411            rows = table.find_all('tr')412            form_type = self.base.get_table_cell(rows[1], 3, True)413            form = self.base.get_table_cell(rows[1], 2, False)414            form = form.find('a', href=True)415            form = 'https://www.sec.gov' + form['href']416            if form_type == 'S-3ASR':417                model.data['is_asr'] = True418            if path.splitext(form)[1] == '.txt':419                # Currently, we dont parse text files.420                # Usually means its from over 15 years ago.421                # Null Date so we dont append422                model.data['date'] = None423                return model424            # Parse the actual submission form for information425            data = self.base.get_data(form)426            stock_offering_table_rows = None427            tables = data.find_all('table')428            for table in tables:429                try:430                    rows = table.find_all('tr')431                    title_cell = self.base.get_table_cell(rows[2], 0, True)432                    title_cell = title_cell.lstrip()433                    if 'Title of ' in title_cell:434                        stock_offering_table_rows = rows435                        break436                except:437                    # Who the eff knows what table this is, but pass438                    continue439            # If its a standard table, try to get where we initially think the issued shares should be then clean it up440            issued_shares = self.base.get_table_cell(441                stock_offering_table_rows[3], 2, True)442            issued_shares = unicodedata.normalize('NFKD', issued_shares)443            issued_shares = issued_shares.split(' America')[0].replace(444                ',', '').replace('shares', '').strip()445            if util.isValidInt(issued_shares):446                model.data['additional_shares_issued'] = int(issued_shares)447                return model448            # Although Common Stock is in the table twice, we are not breaking. So our "issued shares" is the last occurance of title "common stock"449            for row in stock_offering_table_rows:450                row_title = self.base.get_table_cell(451                    row, 0, True).split(',')[0].split('(')[0].strip()452                if row_title.lower() == 'common stock':453                    issued_shares = self.base.get_table_cell(row, 2, True).split(454                        ' Amercia')[0].replace(',', '').split(' shares')[0].split('(')[0]455            # if we parsed the wrong row, oh well, null it out456            model.data['additional_shares_issued'] = int(457                issued_shares) if util.isValidInt(issued_shares) else None458            return model459        except:460            # if we blow up just add the link for future reference461            return model462    # @params (link) - a link to form index page (Not the actual form)463    # @descrip - Checks the blue info boxes for the companies that received notification from letters. We are assuming that because the companies have been notified that a merger is taking place. Other options are: Merger failed, Company bought a product from another company etc.464    # @returns SEC_Merger Model465    def make_merger_model(self, link: str) -> SEC_Merger:466        model = SEC_Merger()467        merging_cik = None468        merging_name = None469        try:470            data = self.base.get_data(link)471            # Get date from info header472            submission_date = data.find('div', text='Filing Date')473            submission_date = submission_date.find_next_sibling(474                'div').get_text()475            model.data['date'] = submission_date476            companies = data.find_all('span', class_='companyName')477            for company in companies:478                cik = company.find('a').get_text()479                cik = cik.split(' ')[0]480                if self.cik in cik:481                    continue482                merging_cik = cik483                merging_name = company.get_text().split(' (')[0]484            model.data['merging_with_company'] = merging_name485            model.data['merging_with_cik'] = merging_cik486            model.data['date'] = submission_date487        except:488            # Dont append to our main model because our cik is null489            model.data['merging_with_cik'] = None490        finally:491            return model492    # @params (link) - a link to form index page (Not the actual form)493    # @descrip - Looks at the header information to find the different sections that the 8-k is reporting on. For more detail, we will have to use the link to view the 8-k ourselves.494    # @returns SEC_Company_Info495    def make_company_info_model(self, link: str) -> SEC_Company_Info:496        model = SEC_Company_Info()497        model.data['link'] = link498        try:499            data = self.base.get_data(link)500            table = data.find('table', class_='tableFile')501            rows = table.find_all('tr')502            submission_date = data.find('div', text='Filing Date')503            submission_date = submission_date.find_next_sibling(504                'div').get_text()505            item_group = data.find('div', text='Items').parent506            item_group = item_group.find('div', class_='info')507            item_group = item_group.get_text(separator='|').split('|')508            for item in item_group:509                item_details = item.split(': ')510                item_num = item_details[0].split('Item ')[1]511                model.data['item_list'][item_num] = item_details[1]512            model.data['date'] = submission_date513            form_link = self.base.get_table_cell(rows[1], 2, False)514            form_link = form_link.find('a', href=True)515            model.data['link'] = 'https://www.sec.gov' + form_link['href']516        except:517            # Just save off the link518            pass519        finally:520            return model521    # @params (link) - a link to form index page (Not the actual form)522    # @descrip - navigates to the form and tries to find the table that specifies how many shares were issued for employee benefits. Although they are issuing more shares, it means the employees are invested in the co.523    # @returns SEC_Employee_Stock524    def make_stock_program_model(self, link: str) -> SEC_Employee_Stock:525        model = SEC_Employee_Stock()526        model.data['link'] = link527        try:528            issued_shares = None529            data = self.base.get_data(link)530            # Get date from info header531            submission_date = data.find('div', text='Filing Date')532            submission_date = submission_date.find_next_sibling('div')533            model.data['date'] = submission_date.get_text()534            # parse main table for form type and link to actual submission535            table = data.find('table', class_='tableFile')536            rows = table.find_all('tr')537            form = self.base.get_table_cell(rows[1], 2, False)538            form = form.find('a', href=True)539            form = 'https://www.sec.gov' + form['href']540            if path.splitext(form)[1] == '.txt':541                # Currently, we dont parse text files.542                # Usually means its from over 15 years ago.543                # Null Date so we dont append544                model.data['date'] = None545                return model546            # Parse the actual submission form for information547            data = self.base.get_data(form)548            stock_offering_table_rows = None549            tables = data.find_all('table')550            for table in tables:551                try:552                    rows = table.find_all('tr')553                    title_cell = self.base.get_table_cell(rows[2], 0, True)554                    title_cell = title_cell.lstrip()555                    if 'Title of ' in title_cell:556                        stock_offering_table_rows = rows557                        break558                except:559                    # Who the eff knows what table this is, but pass560                    continue561            # If its a standard table, try to get where we initial think the issued shares should be then clean it up562            issued_shares = self.base.get_table_cell(563                stock_offering_table_rows[3], 2, True)564            issued_shares = unicodedata.normalize('NFKD', issued_shares)565            issued_shares = issued_shares.split(' America')[0].replace(566                ',', '').replace('shares', '').strip()567            if util.isValidInt(issued_shares):568                model.data['additional_shares_issued'] = int(issued_shares)569                return model570            # Although Common Stock is in the table twice, we are not breaking. So our "issued shares" is the last occurance of title "common stock"571            for row in stock_offering_table_rows:572                row_title = self.base.get_table_cell(573                    row, 0, True).split(',')[0].split('(')[0].strip()574                if row_title.lower() == 'common stock':575                    issued_shares = self.base.get_table_cell(row, 2, True).split(576                        ' America')[0].replace(',', '').split(' shares')[0].split('(')[0]577            # if we parsed the wrong row, oh well, null it out578            model.data['additional_shares_issued'] = int(579                issued_shares) if util.isValidInt(issued_shares) else None580        except:581            # if we blow up just add the link for future reference582            pass583        finally:584            return model585 # =========================================================== #586 #                 TD Ameritrade scraper                        #587 # ============================================================ #588class TDAmeritrade(Scaper):589    # @params (ticker) - symbol to find, (index) = is the ticker a indice?...test_cell_editors.py
Source:test_cell_editors.py  
...39#     def test_editing_does_not_update_source_on_noneditable_table(self, bokeh_model_page):40#         self.table.editable = False41#         page = bokeh_model_page(self.table)42#         # Click row 1 (which triggers the selection callback)43#         cell = get_table_cell(page.driver, 1, 1)44#         cell.click()45#         results = page.results46#         assert results['values'] == self.values47#         # Now double click, enter the text new value and <enter>48#         cell = get_table_cell(page.driver, 1, 1)49#         # TODO50#         # Click row 2 (which triggers callback again so we can inspect the data)51#         cell = get_table_cell(page.driver, 2, 1)52#         cell.click()53#         results = page.results54#         assert results['values'] == self.values55#         assert page.has_no_console_errors()56#     def test_editing_updates_source(self, bokeh_model_page):57#         page = bokeh_model_page(self.table)58#         # Click row 1 (which triggers the selection callback)59#         cell = get_table_cell(page.driver, 1, 1)60#         cell.click()61#         results = page.results62#         assert results['values'] == self.values63#         # Now double click, enter the text new value and <enter>64#         cell = get_table_cell(page.driver, 1, 1)65#         # TODO66#         # Click row 2 (which triggers callback again so we can inspect the data)67#         cell = get_table_cell(page.driver, 2, 1)68#         cell.click()69#         results = page.results70#         assert results['values'] == [False, False]71#         assert page.has_no_console_errors()72class Test_IntEditor(Test_CellEditor_Base):73    values = [1, 2]74    editor = IntEditor75    def test_editing_does_not_update_source_on_noneditable_table(self, bokeh_model_page):76        self.table.editable = False77        page = bokeh_model_page(self.table)78        # Click row 1 (which triggers the selection callback)79        cell = get_table_cell(page.driver, 1, 1)80        cell.click()81        results = page.results82        assert results['values'] == self.values83        # Now double click, enter the text new value and <enter>84        cell = get_table_cell(page.driver, 1, 1)85        enter_text_in_cell(page.driver, cell, "33")86        # Click row 2 (which triggers callback again so we can inspect the data)87        cell = get_table_cell(page.driver, 2, 1)88        cell.click()89        results = page.results90        assert results['values'] == self.values91        assert page.has_no_console_errors()92    @pytest.mark.parametrize('bad', ["1.1", "text"])93    def test_editing_does_not_update_source_on_bad_values(self, bad, bokeh_model_page):94        self.table.editable = False95        page = bokeh_model_page(self.table)96        # Click row 1 (which triggers the selection callback)97        cell = get_table_cell(page.driver, 1, 1)98        cell.click()99        results = page.results100        assert results['values'] == self.values101        # Now double click, enter the text new value and <enter>102        cell = get_table_cell(page.driver, 1, 1)103        enter_text_in_cell(page.driver, cell, bad)104        # Click row 2 (which triggers callback again so we can inspect the data)105        cell = get_table_cell(page.driver, 2, 1)106        cell.click()107        results = page.results108        assert results['values'] == self.values109        assert page.has_no_console_errors()110    def test_editing_updates_source(self, bokeh_model_page):111        page = bokeh_model_page(self.table)112        # Click row 1 (which triggers the selection callback)113        cell = get_table_cell(page.driver, 1, 1)114        cell.click()115        results = page.results116        assert results['values'] == self.values117        # Now double click, enter the text new value and <enter>118        cell = get_table_cell(page.driver, 1, 1)119        enter_text_in_cell(page.driver, cell, "33")120        # Click row 2 (which triggers callback again so we can inspect the data)121        cell = get_table_cell(page.driver, 2, 1)122        cell.click()123        results = page.results124        assert results['values'] == [33, 2]125        assert page.has_no_console_errors()126class Test_NumberEditor(Test_CellEditor_Base):127    values = [1.1, 2.2]128    editor = NumberEditor129    def test_editing_does_not_update_source_on_noneditable_table(self, bokeh_model_page):130        self.table.editable = False131        page = bokeh_model_page(self.table)132        # Click row 1 (which triggers the selection callback)133        cell = get_table_cell(page.driver, 1, 1)134        cell.click()135        results = page.results136        assert results['values'] == self.values137        # Now double click, enter the text new value and <enter>138        cell = get_table_cell(page.driver, 1, 1)139        enter_text_in_cell(page.driver, cell, "33.5")140        # Click row 2 (which triggers callback again so we can inspect the data)141        cell = get_table_cell(page.driver, 2, 1)142        cell.click()143        results = page.results144        assert results['values'] == self.values145        assert page.has_no_console_errors()146    @pytest.mark.parametrize('bad', ["text"])147    def test_editing_does_not_update_source_on_bad_values(self, bad, bokeh_model_page):148        self.table.editable = False149        page = bokeh_model_page(self.table)150        # Click row 1 (which triggers the selection callback)151        cell = get_table_cell(page.driver, 1, 1)152        cell.click()153        results = page.results154        assert results['values'] == self.values155        # Now double click, enter the text new value and <enter>156        cell = get_table_cell(page.driver, 1, 1)157        enter_text_in_cell(page.driver, cell, bad)158        # Click row 2 (which triggers callback again so we can inspect the data)159        cell = get_table_cell(page.driver, 2, 1)160        cell.click()161        results = page.results162        assert results['values'] == self.values163        assert page.has_no_console_errors()164    def test_editing_updates_source(self, bokeh_model_page):165        page = bokeh_model_page(self.table)166        # Click row 1 (which triggers the selection callback)167        cell = get_table_cell(page.driver, 1, 1)168        cell.click()169        results = page.results170        assert results['values'] == self.values171        # Now double click, enter the text new value and <enter>172        cell = get_table_cell(page.driver, 1, 1)173        enter_text_in_cell(page.driver, cell, "33.5")174        # Click row 2 (which triggers callback again so we can inspect the data)175        cell = get_table_cell(page.driver, 2, 1)176        cell.click()177        results = page.results178        assert results['values'] == [33.5, 2.2]179        assert page.has_no_console_errors()180class Test_StringEditor(Test_CellEditor_Base):181    values = ["foo", "bar"]182    editor = StringEditor183    def test_editing_does_not_update_source_on_noneditable_table(self, bokeh_model_page):184        self.table.editable = False185        page = bokeh_model_page(self.table)186        # Click row 1 (which triggers the selection callback)187        cell = get_table_cell(page.driver, 1, 1)188        cell.click()189        results = page.results190        assert results['values'] == self.values191        # Now double click, enter the text new value and <enter>192        cell = get_table_cell(page.driver, 1, 1)193        enter_text_in_cell(page.driver, cell, "baz")194        # Click row 2 (which triggers callback again so we can inspect the data)195        cell = get_table_cell(page.driver, 2, 1)196        cell.click()197        results = page.results198        assert results['values'] == self.values199        assert page.has_no_console_errors()200    @pytest.mark.parametrize('bad', ["1", "1.1", "-1"])201    def test_editing_does_not_update_source_on_bad_values(self, bad, bokeh_model_page):202        self.table.editable = False203        page = bokeh_model_page(self.table)204        # Click row 1 (which triggers the selection callback)205        cell = get_table_cell(page.driver, 1, 1)206        cell.click()207        results = page.results208        assert results['values'] == self.values209        # Now double click, enter the text new value and <enter>210        cell = get_table_cell(page.driver, 1, 1)211        enter_text_in_cell(page.driver, cell, bad)212        # Click row 2 (which triggers callback again so we can inspect the data)213        cell = get_table_cell(page.driver, 2, 1)214        cell.click()215        results = page.results216        assert results['values'] == self.values217        assert page.has_no_console_errors()218    def test_editing_updates_source(self, bokeh_model_page):219        page = bokeh_model_page(self.table)220        # Click row 1 (which triggers the selection callback)221        cell = get_table_cell(page.driver, 1, 1)222        cell.click()223        results = page.results224        assert results['values'] == self.values225        # Now double click, enter the text new value and <enter>226        cell = get_table_cell(page.driver, 1, 1)227        enter_text_in_cell(page.driver, cell, "baz")228        # Click row 2 (which triggers callback again so we can inspect the data)229        cell = get_table_cell(page.driver, 2, 1)230        cell.click()231        results = page.results232        assert results['values'] == ["baz", "bar"]233        assert page.has_no_console_errors()234    def test_editing_updates_source_with_click_enter(self, bokeh_model_page):235        page = bokeh_model_page(self.table)236        # Click row 1 (which triggers the selection callback)237        cell = get_table_cell(page.driver, 1, 1)238        cell.click()239        results = page.results240        assert results['values'] == self.values241        # Now double click, enter the text new value and <enter>242        cell = get_table_cell(page.driver, 1, 1)243        enter_text_in_cell_with_click_enter(page.driver, cell, "baz")244        # Click row 2 (which triggers callback again so we can inspect the data)245        cell = get_table_cell(page.driver, 2, 1)246        cell.click()247        results = page.results248        assert results['values'] == ["baz", "bar"]249        assert page.has_no_console_errors()250# XXX (bev) PercentEditor is currently completely broken251# class Test_PercentEditor(Test_CellEditor_Base):252#     values = [0.1, 0.2]253#     editor = PercentEditor254#     def test_editing_does_not_update_source_on_noneditable_table(self, bokeh_model_page):255#         self.table.editable = False256#         page = bokeh_model_page(self.table)257#         # Click row 1 (which triggers the selection callback)258#         cell = get_table_cell(page.driver, 1, 1)259#         cell.click()260#         results = page.results261#         assert results['values'] == self.values262#         # Now double click, enter the text 33 and <enter>263#         cell = get_table_cell(page.driver, 1, 1)264#         enter_text_in_cell(page.driver, cell, "0.5")265#         # Click row 2 (which triggers callback again so we can inspect the data)266#         cell = get_table_cell(page.driver, 2, 1)267#         cell.click()268#         results = page.results269#         assert results['values'] == self.values270#         assert page.has_no_console_errors()271#     @pytest.mark.parametrize('bad', ["-1", "-0.5", "1.1", "2", "text"])272#     def test_editing_does_not_update_source_on_bad_values(self, bad, bokeh_model_page):273#         self.table.editable = False274#         page = bokeh_model_page(self.table)275#         # Click row 1 (which triggers the selection callback)276#         cell = get_table_cell(page.driver, 1, 1)277#         cell.click()278#         results = page.results279#         assert results['values'] == self.values280#         # Now double click, enter the text new value and <enter>281#         cell = get_table_cell(page.driver, 1, 1)282#         enter_text_in_cell(page.driver, cell, bad)283#         # Click row 2 (which triggers callback again so we can inspect the data)284#         cell = get_table_cell(page.driver, 2, 1)285#         cell.click()286#         results = page.results287#         assert results['values'] == self.values288#         assert page.has_no_console_errors()289#     def test_editing_updates_source(self, bokeh_model_page):290#         page = bokeh_model_page(self.table)291#         # click row 1 (which triggers the selection callback)292#         cell = get_table_cell(page.driver, 1, 1)293#         cell.click()294#         results = page.results295#         assert results['values'] == self.values296#         # now double click, enter the text 33 and <enter>297#         cell = get_table_cell(page.driver, 1, 1)298#         enter_text_in_cell(page.driver, cell, "0.5")299#         # click row 2 (which triggers callback again so we can inspect the data)300#         cell = get_table_cell(page.driver, 2, 1)301#         cell.click()302#         results = page.results303#         assert results['values'] == [0.5, 0.2]...api.py
Source:api.py  
1import sys2def get_table_cell(value):3    if isinstance(value, float):4        s = str(round(value, 3))5    else:6        s = value7    return s + (12-len(s)) * ' '8class Solver:9    def __init__(self, coefficients, is_max, restrictions):10        self.table = []11        self.basis = []12        self.is_max = is_max13        self.basis_indexes = []14        self.resolution_column = -115        self.coefficients = coefficients16        self.restrictions_number = len(restrictions)17        max_length = 018        for i in restrictions:19            max_length = max(max_length, len(i)) - 120        self.width = max_length + self.restrictions_number21        self.height = self.restrictions_number+122        for i in range(self.restrictions_number):23            row = []24            for j in range(self.width):25                if j < len(restrictions[i])-1:26                    row.append(restrictions[i][j])27                else:28                    if i == j - max_length:29                        row.append(1.0)30                    else:31                        row.append(0.0)32            row.append(restrictions[i][len(restrictions[i])-1])33            self.table.append(row)34        row = []35        for coefficient in coefficients:36            row.append(-coefficient)37        for i in range(self.height):38            row.append(0.0)39        self.table.append(row)40        self.select_basis()41    def select_basis(self):42        self.basis = ['' for _ in range(self.height-1)]43        self.basis_indexes = [0 for _ in range(self.height-1)]44        for i in range(self.width):45            counter = 046            index = -147            for j in range(self.height):48                if self.table[j][i] != 0:49                    counter += 150                    index = j51            if counter == 1:52                if i < self.width - self.restrictions_number:53                    self.basis[index] = 'x' + str(i+1)54                else:55                    self.basis[index] = 'y' + str(i - self.width + self.restrictions_number + 1)56                self.basis_indexes[index] = i57    def solve(self):58        while not self.is_over():59            self.count_bi()60            self.print(False)61            self.append()62            self.select_basis()63        self.print(True)64        print()65        variables = [None for _ in range(len(self.coefficients))]66        for i in range(self.height-1):67            var = self.table[i][self.width] / self.table[i][self.basis_indexes[i]]68            print(f'{self.basis[i]}={round(var, 3)}')69            if self.basis[i][0] == 'x':70                variables[int(self.basis[i][1:])-1] = var71        success = variables.count(None) == 072        if success:73            print('f(', end='')74            print('; '.join(list(map(str, variables))), end='')75            res = 076            for i in range(len(variables)):77                res += variables[i] * self.coefficients[i]78            print(') =', res)79    def count_bi(self):80        self.resolution_column = self.get_resolution_column_index()81        for i in range(self.height-1):82            self.table[i].append(self.table[i][self.width] / self.table[i][self.resolution_column])83    def is_over(self):84        f = (lambda x: x < 0) if self.is_max else (lambda x: x > 0)85        for i in range(self.width+1):86            if f(self.table[self.height-1][i]):87                return False88        return True89    def append(self):90        best = float('inf')91        h_index = -192        for i in range(self.height-1):93            if 0 < self.table[i][self.width + 1] < best:94                best = self.table[i][self.width+1]95                h_index = i96        new_table = [[] for _ in range(self.height)]97        for i in range(self.width+1):98            new_table[h_index].append(self.table[h_index][i])99        for i in range(self.height):100            if i != h_index:101                coef = -(self.table[i][self.resolution_column] / self.table[h_index][self.resolution_column])102                for j in range(self.width+1):103                    new_table[i].append(self.table[i][j] + self.table[h_index][j] * coef)104        self.table = new_table105    def get_resolution_column_index(self):106        index = -1107        f = (lambda x, y: x < y) if self.is_max else (lambda x, y: x > y)108        best = (1 if self.is_max else -1) * sys.maxsize109        for i in range(self.width + 1):110            if f(self.table[self.height - 1][i], best):111                best = self.table[self.height - 1][i]112                index = i113        return index114    def print(self, end):115        print(get_table_cell('ÐазиÑ'), end='')116        for i in range(self.width):117            if i < self.width - self.restrictions_number:118                print(get_table_cell('x' + str(i+1)), end='')119            else:120                print(get_table_cell('y' + str(i - self.width + self.restrictions_number + 1)), end='')121        print(get_table_cell('bi'), end='')122        print(get_table_cell('bi/ÑазÑ. ÑÑ.'))123        for i in range(len(self.basis)):124            print(get_table_cell(self.basis[i]), end='')125            for j in range(self.width+(1 if end else 2)):126                print(get_table_cell(self.table[i][j]), end='')127            print()128        print(get_table_cell('f(x)'), end='')129        for i in range(self.width+1):130            print(get_table_cell(self.table[len(self.table)-1][i]), end='')131        print()132        if not end:...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
