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!!