Explore all Selenium open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Selenium

scrapy

1.8.2

playwright

v1.21.1

selenium

Selenium 4.1.0

rrweb

rrweb@1.1.3; rrweb-player@0.7.14; rrweb-snapshot@1.1.14

nightwatch

v2.1.0

Popular Libraries in Selenium

scrapy

by scrapy doticonpythondoticon

star image 42899 doticonNOASSERTION

Scrapy, a fast high-level web crawling & scraping framework for Python.

playwright

by microsoft doticontypescriptdoticon

star image 36789 doticonApache-2.0

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.

selenium

by SeleniumHQ doticonjavadoticon

star image 23180 doticonApache-2.0

A browser automation framework and ecosystem.

awesome-python-login-model

by Kr1s77 doticonpythondoticon

star image 13481 doticonNOASSERTION

😮python模拟登陆一些大型网站,还有一些简单的爬虫,希望对你们有所帮助❤️,如果喜欢记得给个star哦🌟

chromeless

by prisma-archive doticontypescriptdoticon

star image 13250 doticonMIT

🖥 Chrome automation made simple. Runs locally or headless on AWS Lambda.

InstaPy

by timgrossmann doticonpythondoticon

star image 13182 doticonGPL-3.0

📷 Instagram Bot - Tool for automated Instagram interactions

rrweb

by rrweb-io doticontypescriptdoticon

star image 11468 doticonMIT

record and replay the web

nightwatch

by nightwatchjs doticonjavascriptdoticon

star image 11057 doticonMIT

End-to-end testing framework written in Node.js and using the W3C Webdriver API

Auto.js

by hyb1996 doticonjavadoticon

star image 10414 doticonMPL-2.0

A UiAutomator on android, does not need root access(安卓平台上的JavaScript自动化工具)

Trending New libraries in Selenium

autoscraper

by alirezamika doticonpythondoticon

star image 3565 doticonMIT

A Smart, Automatic, Fast and Lightweight Web Scraper for Python

playwright-dotnet

by microsoft doticonjavascriptdoticon

star image 1421 doticonMIT

.NET version of the Playwright testing and automation library.

Web-Fuzzing-Box

by gh0stkey doticonhtmldoticon

star image 917 doticon

Web Fuzzing Box - Web 模糊测试字典与一些Payloads,主要包含:弱口令暴力破解、目录以及文件枚举、Web漏洞...字典运用于实战案例:https://gh0st.cn/archives/2019-11-11/1

playwright-sharp

by microsoft doticoncsharpdoticon

star image 684 doticonMIT

.NET version of the Playwright testing and automation library.

V2RayCloudSpider

by QIN2DIM doticonpythondoticon

star image 553 doticonMIT

采集免费、优质的机场订阅链接;科学上网,从娃娃抓起!

DrissionPage

by g1879 doticonpythondoticon

star image 539 doticonBSD-3-Clause

A module that integrates selenium and requests session, encapsulates common page operations, can achieve seamless switching between the two modes.

playwright-go

by mxschmitt doticonjavascriptdoticon

star image 531 doticonMIT

Playwright for Go a browser automation library to control Chromium, Firefox and WebKit with a single API.

Insomniac

by alexal1 doticonpythondoticon

star image 505 doticonMIT

Instagram bot for automated Instagram interaction using Android device via ADB

equal-access

by IBMa doticonjavascriptdoticon

star image 489 doticonApache-2.0

IBM Equal Access Accessibility Checker contains tools to automate accessibility checking from a browser or in a continuous development/build environment

Top Authors in Selenium

1

LambdaTest

43 Libraries

star icon247

2

browserstack

37 Libraries

star icon657

3

osandadeshan

32 Libraries

star icon95

4

PacktPublishing

31 Libraries

star icon471

5

sridharbandi

17 Libraries

star icon58

6

katalon-studio

17 Libraries

star icon553

7

appium

13 Libraries

star icon2463

8

pytest-dev

12 Libraries

star icon1803

9

testingbot

12 Libraries

star icon48

10

applitools

10 Libraries

star icon78

1

43 Libraries

star icon247

2

37 Libraries

star icon657

3

32 Libraries

star icon95

4

31 Libraries

star icon471

5

17 Libraries

star icon58

6

17 Libraries

star icon553

7

13 Libraries

star icon2463

8

12 Libraries

star icon1803

9

12 Libraries

star icon48

10

10 Libraries

star icon78

Trending Kits in Selenium

No Trending Kits are available at this moment for Selenium

Trending Discussions on Selenium

Selenium-chromedriver: Cannot construct KeyEvent from non-typeable key

Python Selenium AWS Lambda Change WebGL Vendor/Renderer For Undetectable Headless Scraper

How To Set ChromeOptions (or goog:ChromeOptions) for Selenium::Chrome in Perl

DeprecationWarning: executable_path has been deprecated, please pass in a Service object

How can I send Dynamic website content to scrapy with the html content generated by selenium browser?

Python/Selenium web scrap how to find hidden src value from a links?

Efficient code for custom color formatting in tkinter python

Unable to build and deploy Rails 6.0.4.1 app on heroku - Throws gyp verb cli error

Log4j 1: How to mitigate the vulnerability in log4j without updating version to 2.15.0

TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options' error using firefox_options as arguments in Selenium Python

QUESTION

Selenium-chromedriver: Cannot construct KeyEvent from non-typeable key

Asked 2022-Mar-25 at 12:17

I updated my Chrome and Chromedriver to the latest version yesterday, and since then I get the following error messages when running my Cucumber features:

1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3        (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4      #0 0x55e9ce6a4093 <unknown>
5      #1 0x55e9ce16a648 <unknown>
6      #2 0x55e9ce1a9866 <unknown>
7      #3 0x55e9ce1cbd29 <unknown>
8      .....
9

I try to fill a text field with Capybara's fill_in method. While debugging I noticed that Capybara has problems especially with the symbols @ and \. Every other character can be written into the text field without any problems.

The code that triggers the error looks like this

1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3        (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4      #0 0x55e9ce6a4093 <unknown>
5      #1 0x55e9ce16a648 <unknown>
6      #2 0x55e9ce1a9866 <unknown>
7      #3 0x55e9ce1cbd29 <unknown>
8      .....
9def sign_in(user)
10  visit new_sign_in_path
11  fill_in 'Email', with: user.email
12  fill_in 'Password', with: user.password
13  click_button 'Sign in'
14end
15

user.email contains a string like "example1@mail.com".

I work with Rails 6.1.3.1, Cucumber 5.3.0, Chromedriver 98.0.4758.48, capybara 3.35.3

The error only occurs on features that are tagged with @javascript

Do you have any ideas what causes this error or how to fix it?

ANSWER

Answered 2022-Feb-03 at 08:25

It seems something has changed in the new version of ChromeDriver and it is no longer possible to send some special chars directly using send_keys method.

In this link you will see how it is solved (in C#) --> Selenium - SendKeys("@") write an "à"

And regarding python implementation, check this out --> https://www.geeksforgeeks.org/special-keys-in-selenium-python/

Specifically, my implementation was (using MAC):

1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3        (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4      #0 0x55e9ce6a4093 <unknown>
5      #1 0x55e9ce16a648 <unknown>
6      #2 0x55e9ce1a9866 <unknown>
7      #3 0x55e9ce1cbd29 <unknown>
8      .....
9def sign_in(user)
10  visit new_sign_in_path
11  fill_in 'Email', with: user.email
12  fill_in 'Password', with: user.password
13  click_button 'Sign in'
14end
15driver.find_element('.email-input', 'user@mail.com')
16

Now I had to change it by:

1....
2unknown error: Cannot construct KeyEvent from non-typeable key
3        (Session info: chrome=98.0.4758.80) (Selenium::WebDriver::Error::UnknownError)
4      #0 0x55e9ce6a4093 <unknown>
5      #1 0x55e9ce16a648 <unknown>
6      #2 0x55e9ce1a9866 <unknown>
7      #3 0x55e9ce1cbd29 <unknown>
8      .....
9def sign_in(user)
10  visit new_sign_in_path
11  fill_in 'Email', with: user.email
12  fill_in 'Password', with: user.password
13  click_button 'Sign in'
14end
15driver.find_element('.email-input', 'user@mail.com')
16from selenium.webdriver.common.keys import Keys
17from selenium.webdriver.common.action_chains import ActionChains
18
19emailParts = 'user@mail.com'.split('@')
20emailElement = driver.find_element('.email-input')
21
22emailElement.send_keys(emailParts[0])
23action = ActionChains(driver)
24action.key_down(Keys.ALT).send_keys('2').key_up(Keys.ALT).perform()
25emailElement.send_keys(emailParts[1])
26

Source https://stackoverflow.com/questions/70967207

QUESTION

Python Selenium AWS Lambda Change WebGL Vendor/Renderer For Undetectable Headless Scraper

Asked 2022-Mar-21 at 20:19
Concept:

Using AWS Lambda functions with Python and Selenium, I want to create a undetectable headless chrome scraper by passing a headless chrome test. I check the undetectability of my headless scraper by opening up the test and taking a screenshot. I ran this test on a Local IDE and on a Lambda server.


Implementation:

I will be using a python library called selenium-stealth and will follow their basic configuration:

1stealth(driver,
2        languages=["en-US", "en"],
3        vendor="Google Inc.",
4        platform="Win32",
5        webgl_vendor="Intel Inc.",
6        renderer="Intel Iris OpenGL Engine",
7        fix_hairline=True,
8        )
9

I implemented this configuration on a Local IDE as well as an AWS Lambda Server to compare the results.


Local IDE:

Found below are the test results running on a local IDE: enter image description here


Lambda Server:

When I run this on a Lambda server, both the WebGL Vendor and Renderer are blank. as shown below:

enter image description here

I even tried to manually change the WebGL Vendor/Renderer using the following JavaScript command:

1stealth(driver,
2        languages=["en-US", "en"],
3        vendor="Google Inc.",
4        platform="Win32",
5        webgl_vendor="Intel Inc.",
6        renderer="Intel Iris OpenGL Engine",
7        fix_hairline=True,
8        )
9driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {"source": "WebGLRenderingContext.prototype.getParameter = function(parameter) {if (parameter === 37445) {return 'VENDOR_INPUT';}if (parameter === 37446) {return 'RENDERER_INPUT';}return getParameter(parameter);};"})
10

Then I thought maybe that it could be something wrong with the parameter number. I configured the command execution without the if statement, but the same thing happened: It worked on my Local IDE but had no effect on an AWS Lambda Server.

Simply Put:

Is it possible to add Vendor/Renderer on AWS Lambda? In my efforts, it seems that there is no possible way. I made sure to submit this issue on the selenium-stealth GitHub Repository.

ANSWER

Answered 2021-Dec-18 at 02:01
WebGL

WebGL is a cross-platform, open web standard for a low-level 3D graphics API based on OpenGL ES, exposed to ECMAScript via the HTML5 Canvas element. WebGL at it's core is a Shader-based API using GLSL, with constructs that are semantically similar to those of the underlying OpenGL ES API. It follows the OpenGL ES specification, with some exceptions for the out of memory-managed languages such as JavaScript. WebGL 1.0 exposes the OpenGL ES 2.0 feature set; WebGL 2.0 exposes the OpenGL ES 3.0 API.

Now, with the availability of Selenium Stealth building of Undetectable Scraper using Selenium driven ChromeDriver initiated Browsing Context have become much more easier.


selenium-stealth

selenium-stealth is a python package selenium-stealth to prevent detection. This programme tries to make python selenium more stealthy. However, as of now selenium-stealth only support Selenium Chrome.

  • Code Block:

1stealth(driver,
2        languages=["en-US", "en"],
3        vendor="Google Inc.",
4        platform="Win32",
5        webgl_vendor="Intel Inc.",
6        renderer="Intel Iris OpenGL Engine",
7        fix_hairline=True,
8        )
9driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {"source": "WebGLRenderingContext.prototype.getParameter = function(parameter) {if (parameter === 37445) {return 'VENDOR_INPUT';}if (parameter === 37446) {return 'RENDERER_INPUT';}return getParameter(parameter);};"})
10from selenium import webdriver
11from selenium.webdriver.chrome.options import Options
12from selenium.webdriver.chrome.service import Service
13from selenium_stealth import stealth
14
15options = Options()
16options.add_argument("start-maximized")
17options.add_experimental_option("excludeSwitches", ["enable-automation"])
18options.add_experimental_option('useAutomationExtension', False)
19s = Service('C:\\BrowserDrivers\\chromedriver.exe')
20driver = webdriver.Chrome(service=s, options=options)
21
22# Selenium Stealth settings
23stealth(driver,
24      languages=["en-US", "en"],
25      vendor="Google Inc.",
26      platform="Win32",
27      webgl_vendor="Intel Inc.",
28      renderer="Intel Iris OpenGL Engine",
29      fix_hairline=True,
30  )
31
32driver.get("https://bot.sannysoft.com/")
33
  • Browser Screenshot:

  • bot_sannysoft

    You can find a detailed relevant discussion in Can a website detect when you are using Selenium with chromedriver?


    Changing WebGL Vendor/Renderer in AWS Lambda

    AWS Lambda enables us to deliver compressed WebGL websites to end users. When requested webpage objects are compressed, the transfer size is reduced, leading to faster downloads, lower cloud storage fees, and lower data transfer fees. Improved load times also directly influence the viewer experience and retention, which helps in improving website conversion and discoverability. Using WebGL, websites are more immersive while still being accessible via a browser URL. Through this technique AWS Lambda to automatically compress the objects uploaded to S3.

    product-page-diagram_Lambda-RealTimeFileProcessing.a59577de4b6471674a540b878b0b684e0249a18c

    Background on compression and WebGL

    HTTP compression is a capability that can be built into web servers and web clients to improve transfer speed and bandwidth utilization. This capability is negotiated between the server and the client using an HTTP header which may indicate that a resource being transferred, cached, or otherwise referenced is compressed. AWS Lambda on the server-side supports Content-Encoding header.

    On the client-side, most browsers today support brotli and gzip compression through HTTP headers (Accept-Encoding: deflate, br, gzip) and can handle server response headers. This means browsers will automatically download and decompress content from a web server at the client-side, before rendering webpages to the viewer.


    Conclusion

    Due to this constraint you may not be able to change the WebGL Vendor/Renderer in AWS Lambda, else it may directly affect the process of rendering webpages to the viewers and can stand out to be a bottleneck in UX.


    tl; dr

    You can find a couple of relevant detailed discussion in:

    Source https://stackoverflow.com/questions/70265306

    QUESTION

    How To Set ChromeOptions (or goog:ChromeOptions) for Selenium::Chrome in Perl

    Asked 2022-Mar-18 at 09:33

    In Python, I could easily change the browser "navigator.webdriver" property to false, when using the local chromedriver with my local Chrome browser.

    1from selenium import webdriver
    2
    3options = webdriver.ChromeOptions()
    4options.add_argument("--disable-blink-features=AutomationControlled")
    5driver = webdriver.Chrome(chrome_options=options)
    6driver.get([some url])
    7

    After the above, in the Chrome browser console, navigator.webdriver would show "false".

    But I do not know how to translate the above to Perl. The following code would still leave the navigator.webdriver as "true". So how do I implement the Python code above in Perl? Is it possible (ideally without using the remote stand-alone selenium server)?

    1from selenium import webdriver
    2
    3options = webdriver.ChromeOptions()
    4options.add_argument("--disable-blink-features=AutomationControlled")
    5driver = webdriver.Chrome(chrome_options=options)
    6driver.get([some url])
    7use strict;
    8use warnings;
    9use Selenium::Chrome;
    10my $driver = Selenium::Chrome->new(
    11   custom_args => '--disable-blink-features=AutomationControlled' );
    12$driver->get([some url]);
    13

    Any help would be greatly appreciated!

    ANSWER

    Answered 2022-Mar-18 at 09:33

    Need to use extra_capabilities with goog:chromeOptions

    1from selenium import webdriver
    2
    3options = webdriver.ChromeOptions()
    4options.add_argument("--disable-blink-features=AutomationControlled")
    5driver = webdriver.Chrome(chrome_options=options)
    6driver.get([some url])
    7use strict;
    8use warnings;
    9use Selenium::Chrome;
    10my $driver = Selenium::Chrome->new(
    11   custom_args => '--disable-blink-features=AutomationControlled' );
    12$driver->get([some url]);
    13my $drv = Selenium::Chrome->new(
    14     'extra_capabilities' => {
    15         'goog:chromeOptions' => {
    16             prefs => { ... },
    17             args => [ 
    18                 'window-position=960,10', 'window-size=950,1180', # etc   
    19                 'disable-blink-features=AutomationControlled'
    20             ]
    21         }
    22     }
    23);
    24

    (I don't know how disable-blink-features relates to that "navigator.webdriver")

    For the list of attributes available in the constructor, along with the extra_capabilities, see Selenium::Remote::Driver, from which Selenium::Chrome inherits.

    For Chrome-specific capabilities see "Recognized capabilities" in chromedriver, and more generally see Selenium documentation and W3C WebDriver standard.


    Specifically

    Source https://stackoverflow.com/questions/71518438

    QUESTION

    DeprecationWarning: executable_path has been deprecated, please pass in a Service object

    Asked 2022-Feb-14 at 12:45

    I started a selenium tutorial today and have run into this error when trying to run the code. I've tried other methods but ultimately get the same error. I'm on MacOS using VSC.

    My Code:

    1from selenium import webdriver
    2
    3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
    4driver = webdriver.Chrome(PATH)
    5driver.get("https://www.google.com")
    6
    7

    I've also tried inserting C: in front of /Users. Can anyone guide me on why this is happening/how to fix it?

    ANSWER

    Answered 2021-Nov-10 at 19:03

    This error message...

    1from selenium import webdriver
    2
    3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
    4driver = webdriver.Chrome(PATH)
    5driver.get("https://www.google.com")
    6
    7DeprecationWarning: executable_path has been deprecated, please pass in a Service object
    8

    ...implies that the key executable_path will be deprecated in the upcoming releases.

    This change is inline with the Selenium 4.0 Beta 1 changelog which mentions:

    Deprecate all but Options and Service arguments in driver instantiation. (#9125,#9128)


    Solution

    Once the key executable_path is deprecated you have to use an instance of the Service() class as follows:

    1from selenium import webdriver
    2
    3PATH = '/Users/blutch/Documents/Chrom Web Driver\chromedriver.exe'
    4driver = webdriver.Chrome(PATH)
    5driver.get("https://www.google.com")
    6
    7DeprecationWarning: executable_path has been deprecated, please pass in a Service object
    8from selenium import webdriver
    9from selenium.webdriver.chrome.service import Service
    10
    11s = Service('C:/Users/.../chromedriver.exe')
    12driver = webdriver.Chrome(service=s)
    13

    Source https://stackoverflow.com/questions/69918148

    QUESTION

    How can I send Dynamic website content to scrapy with the html content generated by selenium browser?

    Asked 2022-Jan-20 at 15:35

    I am working on certain stock-related projects where I have had a task to scrape all data on a daily basis for the last 5 years. i.e from 2016 to date. I particularly thought of using selenium because I can use crawler and bot to scrape the data based on the date. So I used the use of button click with selenium and now I want the same data that is displayed by the selenium browser to be fed by scrappy. This is the website I am working on right now. I have written the following code inside scrappy spider.

    1class FloorSheetSpider(scrapy.Spider):
    2    name = "nepse"
    3
    4    def start_requests(self):
    5
    6        driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    7        
    8     
    9        floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
    10
    11        for date in floorsheet_dates:
    12            driver.get(
    13                "https://merolagani.com/Floorsheet.aspx")
    14
    15            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    16                                ).send_keys(date)
    17            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    18            total_length = driver.find_element(By.XPATH,
    19                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    20            z = int((total_length.split()[-1]).replace(']', ''))    
    21            for data in range(z, z + 1):
    22                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    23                self.url = driver.page_source
    24                yield Request(url=self.url, callback=self.parse)
    25
    26               
    27    def parse(self, response, **kwargs):
    28        for value in response.xpath('//tbody/tr'):
    29            print(value.css('td::text').extract()[1])
    30            print("ok"*200)
    31

    Update: Error after answer is

    1class FloorSheetSpider(scrapy.Spider):
    2    name = "nepse"
    3
    4    def start_requests(self):
    5
    6        driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    7        
    8     
    9        floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
    10
    11        for date in floorsheet_dates:
    12            driver.get(
    13                "https://merolagani.com/Floorsheet.aspx")
    14
    15            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    16                                ).send_keys(date)
    17            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    18            total_length = driver.find_element(By.XPATH,
    19                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    20            z = int((total_length.split()[-1]).replace(']', ''))    
    21            for data in range(z, z + 1):
    22                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    23                self.url = driver.page_source
    24                yield Request(url=self.url, callback=self.parse)
    25
    26               
    27    def parse(self, response, **kwargs):
    28        for value in response.xpath('//tbody/tr'):
    29            print(value.css('td::text').extract()[1])
    30            print("ok"*200)
    312022-01-14 14:11:36 [twisted] CRITICAL: 
    32Traceback (most recent call last):
    33  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
    34    result = current_context.run(gen.send, result)
    35  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
    36    start_requests = iter(self.spider.start_requests())
    37TypeError: 'NoneType' object is not iterable
    38

    I want to send current web html content to scrapy feeder but I am getting unusal error for past 2 days any help or suggestions will be very much appreciated.

    ANSWER

    Answered 2022-Jan-14 at 09:30

    The 2 solutions are not very different. Solution #2 fits better to your question, but choose whatever you prefer.

    Solution 1 - create a response with the html's body from the driver and scraping it right away (you can also pass it as an argument to a function):

    1class FloorSheetSpider(scrapy.Spider):
    2    name = "nepse"
    3
    4    def start_requests(self):
    5
    6        driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    7        
    8     
    9        floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
    10
    11        for date in floorsheet_dates:
    12            driver.get(
    13                "https://merolagani.com/Floorsheet.aspx")
    14
    15            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    16                                ).send_keys(date)
    17            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    18            total_length = driver.find_element(By.XPATH,
    19                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    20            z = int((total_length.split()[-1]).replace(']', ''))    
    21            for data in range(z, z + 1):
    22                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    23                self.url = driver.page_source
    24                yield Request(url=self.url, callback=self.parse)
    25
    26               
    27    def parse(self, response, **kwargs):
    28        for value in response.xpath('//tbody/tr'):
    29            print(value.css('td::text').extract()[1])
    30            print("ok"*200)
    312022-01-14 14:11:36 [twisted] CRITICAL: 
    32Traceback (most recent call last):
    33  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
    34    result = current_context.run(gen.send, result)
    35  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
    36    start_requests = iter(self.spider.start_requests())
    37TypeError: 'NoneType' object is not iterable
    38import scrapy
    39from selenium import webdriver
    40from selenium.webdriver.common.by import By
    41from scrapy.http import HtmlResponse
    42
    43
    44class FloorSheetSpider(scrapy.Spider):
    45    name = "nepse"
    46
    47    def start_requests(self):
    48
    49        # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    50        driver = webdriver.Chrome()
    51
    52        floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
    53
    54        for date in floorsheet_dates:
    55            driver.get(
    56                "https://merolagani.com/Floorsheet.aspx")
    57
    58            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    59                                ).send_keys(date)
    60            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    61            total_length = driver.find_element(By.XPATH,
    62                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    63            z = int((total_length.split()[-1]).replace(']', ''))
    64            for data in range(1, z + 1):
    65                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    66                self.body = driver.page_source
    67
    68                response = HtmlResponse(url=driver.current_url, body=self.body, encoding='utf-8')
    69                for value in response.xpath('//tbody/tr'):
    70                    print(value.css('td::text').extract()[1])
    71                    print("ok"*200)
    72
    73        # return an empty requests list
    74        return []
    75

    Solution 2 - with super simple downloader middleware:

    (You might have a delay here in parse method so be patient).

    1class FloorSheetSpider(scrapy.Spider):
    2    name = "nepse"
    3
    4    def start_requests(self):
    5
    6        driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    7        
    8     
    9        floorsheet_dates = ['01/03/2016','01/04/2016', up to till date '01/10/2022']
    10
    11        for date in floorsheet_dates:
    12            driver.get(
    13                "https://merolagani.com/Floorsheet.aspx")
    14
    15            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    16                                ).send_keys(date)
    17            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    18            total_length = driver.find_element(By.XPATH,
    19                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    20            z = int((total_length.split()[-1]).replace(']', ''))    
    21            for data in range(z, z + 1):
    22                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    23                self.url = driver.page_source
    24                yield Request(url=self.url, callback=self.parse)
    25
    26               
    27    def parse(self, response, **kwargs):
    28        for value in response.xpath('//tbody/tr'):
    29            print(value.css('td::text').extract()[1])
    30            print("ok"*200)
    312022-01-14 14:11:36 [twisted] CRITICAL: 
    32Traceback (most recent call last):
    33  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/twisted/internet/defer.py", line 1661, in _inlineCallbacks
    34    result = current_context.run(gen.send, result)
    35  File "/home/navaraj/PycharmProjects/first_scrapy/env/lib/python3.8/site-packages/scrapy/crawler.py", line 88, in crawl
    36    start_requests = iter(self.spider.start_requests())
    37TypeError: 'NoneType' object is not iterable
    38import scrapy
    39from selenium import webdriver
    40from selenium.webdriver.common.by import By
    41from scrapy.http import HtmlResponse
    42
    43
    44class FloorSheetSpider(scrapy.Spider):
    45    name = "nepse"
    46
    47    def start_requests(self):
    48
    49        # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    50        driver = webdriver.Chrome()
    51
    52        floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
    53
    54        for date in floorsheet_dates:
    55            driver.get(
    56                "https://merolagani.com/Floorsheet.aspx")
    57
    58            driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    59                                ).send_keys(date)
    60            driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    61            total_length = driver.find_element(By.XPATH,
    62                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    63            z = int((total_length.split()[-1]).replace(']', ''))
    64            for data in range(1, z + 1):
    65                driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    66                self.body = driver.page_source
    67
    68                response = HtmlResponse(url=driver.current_url, body=self.body, encoding='utf-8')
    69                for value in response.xpath('//tbody/tr'):
    70                    print(value.css('td::text').extract()[1])
    71                    print("ok"*200)
    72
    73        # return an empty requests list
    74        return []
    75import scrapy
    76from scrapy import Request
    77from scrapy.http import HtmlResponse
    78from selenium import webdriver
    79from selenium.webdriver.common.by import By
    80
    81
    82class SeleniumMiddleware(object):
    83    def process_request(self, request, spider):
    84        url = spider.driver.current_url
    85        body = spider.driver.page_source
    86        return HtmlResponse(url=url, body=body, encoding='utf-8', request=request)
    87
    88
    89class FloorSheetSpider(scrapy.Spider):
    90    name = "nepse"
    91
    92    custom_settings = {
    93        'DOWNLOADER_MIDDLEWARES': {
    94            'tempbuffer.spiders.yetanotherspider.SeleniumMiddleware': 543,
    95            # 'projects_name.path.to.your.pipeline': 543
    96        }
    97    }
    98    driver = webdriver.Chrome()
    99
    100    def start_requests(self):
    101
    102        # driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    103
    104
    105        floorsheet_dates = ['01/03/2016','01/04/2016']#, up to till date '01/10/2022']
    106
    107        for date in floorsheet_dates:
    108            self.driver.get(
    109                "https://merolagani.com/Floorsheet.aspx")
    110
    111            self.driver.find_element(By.XPATH, "//input[@name='ctl00$ContentPlaceHolder1$txtFloorsheetDateFilter']"
    112                                ).send_keys(date)
    113            self.driver.find_element(By.XPATH, "(//a[@title='Search'])[3]").click()
    114            total_length = self.driver.find_element(By.XPATH,
    115                                               "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text
    116            z = int((total_length.split()[-1]).replace(']', ''))
    117            for data in range(1, z + 1):
    118                self.driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
    119                self.body = self.driver.page_source
    120                self.url = self.driver.current_url
    121
    122                yield Request(url=self.url, callback=self.parse, dont_filter=True)
    123
    124    def parse(self, response, **kwargs):
    125        print('test ok')
    126        for value in response.xpath('//tbody/tr'):
    127            print(value.css('td::text').extract()[1])
    128            print("ok"*200)
    129

    Notice that I've used chrome so change it back to firefox like in your original code.

    Source https://stackoverflow.com/questions/70651053

    QUESTION

    Python/Selenium web scrap how to find hidden src value from a links?

    Asked 2022-Jan-16 at 02:28

    Scrapping links should be a simple feat, usually just grabbing the src value of the a tag.

    I recently came across this website (https://sunteccity.com.sg/promotions) where the href value of a tags of each item cannot be found, but the redirection still works. I'm trying to figure out a way to grab the items and their corresponding links. My typical python selenium code looks something as such

    1all_items = bot.find_elements_by_class_name('thumb-img')
    2for promo in all_items:
    3    a = promo.find_elements_by_tag_name("a")
    4    print("a[0]: ", a[0].get_attribute("href"))
    5

    However, I can't seem to retrieve any href, onclick attributes, and I'm wondering if this is even possible. I noticed that I couldn't do a right-click, open link in new tab as well.

    Are there any ways around getting the links of all these items?

    Edit: Are there any ways to retrieve all the links of the items on the pages?

    i.e.

    1all_items = bot.find_elements_by_class_name('thumb-img')
    2for promo in all_items:
    3    a = promo.find_elements_by_tag_name("a")
    4    print("a[0]: ", a[0].get_attribute("href"))
    5https://sunteccity.com.sg/promotions/724
    6https://sunteccity.com.sg/promotions/731
    7https://sunteccity.com.sg/promotions/751
    8https://sunteccity.com.sg/promotions/752
    9https://sunteccity.com.sg/promotions/754
    10https://sunteccity.com.sg/promotions/280
    11...
    12

    Edit: Adding an image of one such anchor tag for better clarity: enter image description here

    ANSWER

    Answered 2022-Jan-15 at 19:47

    You are using a wrong locator. It brings you a lot of irrelevant elements.
    Instead of find_elements_by_class_name('thumb-img') please try find_elements_by_css_selector('.collections-page .thumb-img') so your code will be

    1all_items = bot.find_elements_by_class_name('thumb-img')
    2for promo in all_items:
    3    a = promo.find_elements_by_tag_name("a")
    4    print("a[0]: ", a[0].get_attribute("href"))
    5https://sunteccity.com.sg/promotions/724
    6https://sunteccity.com.sg/promotions/731
    7https://sunteccity.com.sg/promotions/751
    8https://sunteccity.com.sg/promotions/752
    9https://sunteccity.com.sg/promotions/754
    10https://sunteccity.com.sg/promotions/280
    11...
    12all_items = bot.find_elements_by_css_selector('.collections-page .thumb-img')
    13for promo in all_items:
    14    a = promo.find_elements_by_tag_name("a")
    15    print("a[0]: ", a[0].get_attribute("href"))
    16

    You can also get the desired links directly by .collections-page .thumb-img a locator so that your code could be:

    1all_items = bot.find_elements_by_class_name('thumb-img')
    2for promo in all_items:
    3    a = promo.find_elements_by_tag_name("a")
    4    print("a[0]: ", a[0].get_attribute("href"))
    5https://sunteccity.com.sg/promotions/724
    6https://sunteccity.com.sg/promotions/731
    7https://sunteccity.com.sg/promotions/751
    8https://sunteccity.com.sg/promotions/752
    9https://sunteccity.com.sg/promotions/754
    10https://sunteccity.com.sg/promotions/280
    11...
    12all_items = bot.find_elements_by_css_selector('.collections-page .thumb-img')
    13for promo in all_items:
    14    a = promo.find_elements_by_tag_name("a")
    15    print("a[0]: ", a[0].get_attribute("href"))
    16links = bot.find_elements_by_css_selector('.collections-page .thumb-img a')
    17for link in links:
    18    print(link.get_attribute("href"))
    19

    Source https://stackoverflow.com/questions/70721360

    QUESTION

    Efficient code for custom color formatting in tkinter python

    Asked 2022-Jan-11 at 14:31

    [Editing this question completely] Thank you , for those who helped in building the Periodic Table successfully . As I completed it , I tried to link it with another of my project E-Search , which acts like Google and fetches answers , except that it will fetch me the data of the Periodic Table .

    But , I got a problem - not with the searching but with the layout . I'm trying to layout the x-scrollbar in my canvas which will display results regarding the search . However , it is not properly done . Can anyone please help ?

    Below here is my code :

    1import tkinter as tk
    2import PT
    3
    4root = tk.Tk()
    5root.attributes('-fullscreen', True)
    6root.config(bg='black')
    7
    8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
    9
    10elementals = PT.the_element_list
    11
    12search = tk.StringVar()
    13
    14search_entry = tk.Entry(root, textvariable=search)
    15search_entry.place(relx=0.3, rely=0.3)
    16
    17
    18def search_engine():
    19
    20    results = 0
    21    var1 = 0
    22
    23    texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
    24
    25    scroll = tk.Scrollbar(root, orient="horizontal")
    26    scroll.place(relx=0.05, rely=0.44, width=1000)
    27
    28    grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
    29    grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
    30
    31
    32    for i in elementals:
    33        if search.get() in i or search.get() in str(i):
    34            canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
    35            canvas1.place(relx=0.02+results*0.18, rely=0.1)
    36            results += 1
    37            for x in range(10):
    38                tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
    39                var1 += 1
    40            var1 = 0
    41
    42    scroll.config(command=grand_canvas.xview)
    43        
    44    tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
    45
    46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
    47
    48root.mainloop()
    49
    50

    And my Periodic Table Project , from where I extract data [Please name the file of this project as PT.py , then the code given above will work] .

    1import tkinter as tk
    2import PT
    3
    4root = tk.Tk()
    5root.attributes('-fullscreen', True)
    6root.config(bg='black')
    7
    8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
    9
    10elementals = PT.the_element_list
    11
    12search = tk.StringVar()
    13
    14search_entry = tk.Entry(root, textvariable=search)
    15search_entry.place(relx=0.3, rely=0.3)
    16
    17
    18def search_engine():
    19
    20    results = 0
    21    var1 = 0
    22
    23    texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
    24
    25    scroll = tk.Scrollbar(root, orient="horizontal")
    26    scroll.place(relx=0.05, rely=0.44, width=1000)
    27
    28    grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
    29    grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
    30
    31
    32    for i in elementals:
    33        if search.get() in i or search.get() in str(i):
    34            canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
    35            canvas1.place(relx=0.02+results*0.18, rely=0.1)
    36            results += 1
    37            for x in range(10):
    38                tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
    39                var1 += 1
    40            var1 = 0
    41
    42    scroll.config(command=grand_canvas.xview)
    43        
    44    tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
    45
    46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
    47
    48root.mainloop()
    49
    50import tkinter as tk
    51from functools import partial
    52
    53
    54the_element_list = [['Hydrogen',1,'Non Metal',1,1,'s',1.01,'Gaseous',0.08,2.2],#H
    55                    ['Helium',2,'Noble Gas',18,1,'s',4.00,'Gaseous',0.18,'Unavailable'],#He
    56
    57                    ['Lithium',3,'Alkaline Metal',1,2,'s',6.94,'Solid',0.53,0.98],#Li
    58                    ['Beryllium',4,'Alkaline Earth Metal',2,2,'s',9.01,'Solid',1.84,1.57],#Be
    59                    ['Boron',5,'Metalloid',13,2,'p',10.81,'Solid',2.46,2.04],#B
    60                    ['Carbon',6,'Non Metal',14,2,'p',12.01,'Solid',2.26,2.55],#C
    61                    ['Nitrogen',7,'Non Metal',15,2,'p',14.00,'Gaseous',1.17,3.04],#N
    62                    ['Oxygen',8,'Non Metal',16,2,'p',15.99,'Gaseous',1.43,3.44],#O
    63                    ['Fluorine',9,'Halogen',17,2,'p',18.99,'Gaseous',1.70,3.98],#F
    64                    ['Neon',10,'Noble Gas',18,2,'p',20.17,'Gaseous',0.90,'Unavailable'],#Ne
    65                
    66                    ['Sodium',11,'Alkaline Metal',1,3,'s',22.99,'Solid',0.97,0.93],#Na
    67                    ['Magnesium',12,'Alkaline Earth Metal',2,3,'s',24.31,'Solid',1.74,1.31],#Mg
    68                    ['Aluminium',13,'Metal',13,3,'p',26.98,'Solid',2.69,1.61],#Al
    69                    ['Silicon',14,'Metalloid',14,3,'p',28.08,'Solid',2.34,1.90],#Si
    70                    ['Phosphorus',15,'Non Metal',15,3,'p',30.97,'Solid',2.4,2.19],#P
    71                    ['Sulphur',16,'Non Metal',16,3,'p',32.06,'Solid',2.07,2.58],#S
    72                    ['Chlorine',17,'Halogen',17,3,'p',35.45,'Gaseous',3.22,3.16],#Cl
    73                    ['Argon',18,'Noble Gas',18,3,'p',39.95,'Gaseous',1.78,'Unavailable'],#Ar
    74
    75                    ['Potassium',19,'Alkaline Metal',1,4,'s',39.09,'Solid',0.86,0.82],#K
    76                    ['Calicium',20,'Alkaline Earth Metal',2,4,'s',40.08,'Solid',1.55,1.00],#Ca                   
    77                    ['Scandium',21,'Transition Metal',3,4,'d',44.96,'Solid',2.99,1.36],#Sc
    78                    ['Titanium',22,'Transition Metal',4,4,'d',47.87,'Solid',4.5,1.54],#Ti
    79                    ['Vanadium',23,'Transition Metal',5,4,'d',50.94,'Solid',6.11,1.63],#V
    80                    ['Chromium',24,'Transition Metal',6,4,'d',51.99,'Solid',7.14,1.66],#Cr
    81                    ['Manganese',25,'Transition Metal',7,4,'d',54.94,'Solid',7.43,1.55],#Mn
    82                    ['Iron',26,'Transition Metal',8,4,'d',55.85,'Solid',7.87,1.83],#Fe
    83                    ['Cobalt',27,'Transition Metal',9,4,'d',58.93,'Solid',8.90,1.88],#Co
    84                    ['Nickel',28,'Transition Metal',10,4,'d',58.69,'Solid',8.90,1.91],#Ni                
    85                    ['Copper',29,'Transition Metal',11,4,'d',63.54,'Solid',8.92,1.90],#Cu
    86                    ['Zinc',30,'Transition Metal',12,4,'d',65.38,'Solid',7.14,1.65],#Zn
    87                    ['Gallium',31,'Metal',13,4,'p',69.72,'Solid',5.90,1.81],#Ga
    88                    ['Germanium',32,'Metalloid',14,4,'p',72.63,'Solid',5.32,2.01],#Ge
    89                    ['Arsenic',33,'Metalloid',15,4,'p',74.92,'Solid',5.73,2.18],#As
    90                    ['Selenium',34,'Metalloid',16,4,'p',78.97,'Solid',4.82,2.55],#Se
    91                    ['Bromine',35,'Halogen',17,4,'p',79.90,'Liquid',3.12,2.96],#Br
    92                    ['Krypton',36,'Noble Gas',18,4,'p',83.80,'Gaseous',3.75,3.00],#Kr
    93                    
    94                    ['Rubidium',37,'Alkaline Metal',1,5,'s',85.47,'Solid',1.53,0.82],#Rb
    95                    ['Strontium',38,'Alkaline Earth Metal',2,5,'s',87.62,'Solid',2.63,0.95],#Sr
    96                    ['Yttrium',39,'Transition Metal',3,5,'d',88.91,'Solid',4.47,1.22],#Y
    97                    ['Zirconium',40,'Transition Metal',4,5,'d',91.22,'Solid',6.50,1.33],#Zr
    98                    ['Niobium',41,'Transition Metal',5,5,'d',92.90,'Solid',8.57,1.6],#Nb
    99                    ['Molybednium',42,'Transition Metal',6,5,'d',95.95,'Solid',10.28,2.16],#Mo
    100                    ['Technetium',43,'Transition Metal',7,5,'d',98.90,'Solid',11.5,1.9],#Tc
    101                    ['Ruthenium',44,'Transition Metal',8,5,'d',101.07,'Solid',12.37,2.2],#Ru                    
    102                    ['Rhodium',45,'Transition Metal',9,5,'d',102.90,'Solid',12.38,2.28],#Rh
    103                    ['Palladium',46,'Transition Metal',10,5,'d',106.42,'Solid',11.99,2.20],#Pd
    104                    ['ilver',47,'Transition Metal',11,5,'d',107.87,'Solid',10.49,1.93],#Ag
    105                    ['Cadmium',48,'Transition Metal',12,5,'d',112.41,'Solid',8.65,1.69],#Cd
    106                    ['Indium',49,'Metal',13,5,'p',114.82,'Solid',7.31,1.78],#In
    107                    ['Tin',50,'Metal',14,5,'p',118.71,'Solid',5.77,1.96],#Sn
    108                    ['Antimony',51,'Metalloid',15,5,'p',121.76,'Solid',6.70,2.05],#Sb
    109                    ['Tellurium',52,'Metalloid',16,5,'p',127.60,'Solid',6.24,2.10],#Te                
    110                    ['Iodine',53,'Halogen',17,5,'p',126.90,'Solid',4.94,2.66],#I
    111                    ['Xenon',54,'Noble Gas',18,5,'p',131.29,'Gaseous',5.90,2.6],#Xe
    112
    113                    ['Caesium',55,'Alkaline Metal',1,6,'s',132.91,'Solid',1.90,0.79],#Cs
    114                    ['Barium',56,'Alkaline Earth Metal',2,6,'s',137.33,'Solid',3.62,0.89],#Ba
    115
    116                    ['Lanthanum',57,'Transition Metal',3,6,'d',138.90,'Solid',6.17,1.1],#La
    117                    ['Cerium',58,'Lanthanide','La',6,'f',140.12,'Solid',6.77,1.12],#Ce
    118                    ['Praseodymium',59,'Lanthanide','La',6,'f',140.91,'Solid',6.48,1.13],#Pr
    119                    ['Neodymium',60,'Lanthanide','La',6,'f',144.24,'Solid',7.00,1.14],#Nd
    120                    ['Promethium',61,'Lanthanide','La',6,'f',146.91,'Solid',7.2,'Unavailable.'],#Pm               
    121                    ['Samarium',62,'Lanthanide','La',6,'f',150.36,'Solid',7.54,1.17],#Sm
    122                    ['Europium',63,'Lanthanide','La',6,'f',151.96,'Solid',5.25,'Unavailable'],#Eu
    123                    ['Gadolinium',64,'Lanthanide','La',6,'f',157.25,'Solid',7.89,1.20],#Gd
    124                    ['Terbium',65,'Lanthanide','La',6,'f',158.93,'Solid',8.25,'Unavailable'],#Tb
    125                    ['Dysprosium',66,'Lanthanide','La',6,'f',162.50,'Solid',8.56,1.22],#Dy
    126                    ['Holmium',67,'Lanthanide','La',6,'f',164.93,'Solid',8.78,1.23],#Ho
    127                    ['Erbium',68,'Lanthanide','La',6,'f',167.26,'Solid',9.05,1.24],#Er
    128                    ['Thulium',69,'Lanthanide','La',6,'f',168.93,'Solid',9.32,1.25],#Tm                    
    129                    ['Ytterbium',70,'Lanthanide','La',6,'f',173.05,'Solid',6.97,'Unavailable'],#Yb
    130                    ['Lutetium',71,'Lanthanide','La',6,'f',174.97,'Solid',9.84,1.27],#Lu
    131
    132                    ['Hafnium',72,'Transition Metal',4,6,'d',178.49,'Solid',13.28,1.3],#Hf
    133                    ['Tantalum',73,'Transition Metal',5,6,'d',180.95,'Solid',16.65,1.5],#Ta
    134                    ['Tungsten',74,'Transition Metal',6,6,'d',183.84,'Solid',19.25,2.36],#W
    135                    ['Rhenium',75,'Transition Metal',7,6,'d',186.21,'Solid',21.00,1.9],#Re
    136                    ['Osmium',76,'Transition Metal',8,6,'d',190.23,'Solid',22.59,2.2],#Os
    137                    ['Irdium',77,'Transition Metal',9,6,'d',192.22,'Solid',22.56,2.2],#Ir
    138                    ['Platinum',78,'Transition Metal',10,6,'d',195.08,'Solid',21.45,2.2],#Pt
    139                    ['Gold',79,'Transition Metal',11,6,'d',196.97,'Solid',19.32,2.54],#Au
    140                    ['Mercury',80,'Transition Metal',12,6,'d',200.59,'Liquid',13.55,2.00],#Hg
    141                    ['Thalium',81,'Metal',13,6,'p',204.38,'Solid',11.85,1.62],#Tl
    142                    ['Lead',82,'Metal',14,6,'p',207.20,'Solid',11.34,2.33],#Pb
    143                    ['Bismuth',83,'Metal',15,6,'p',208.98,'Solid',9.78,2.02],#Bi
    144                    ['Polonium',84,'Metal',16,6,'p',209.98,'Solid',9.20,2.0],#Po
    145                    ['Astatine',85,'Halogen',17,6,'p',209.99,'Solid','Unavailable',2.2],#At
    146                    ['Radon',86,'Noble Gas',18,6,'p',222.00,'Gaseous',9.73,'Unavailable'],#Rn
    147
    148                    ['Francium',87,'Alkaline Metal',1,7,'s',223.02,'Solid','Unavailable',0.7],#Fr
    149                    ['Radium',88,'Alkaline Earth Metal',2,7,'s',226.03,'Solid',5.5,0.9],#Ra
    150
    151                    ['Actinium',89,'Transition Metal',3,7,'d',227.03,'Solid',10.07,1.1],#Ac
    152                    ['Thorium',90,'Actinide','Ac',7,'f',232.04,'Solid',11.72,1.3],#Th
    153                    ['Protactinium',91,'Actinide','Ac',7,'f',231.04,'Solid',15.37,1.5],#Pa
    154                    ['Uranium',92,'Actinide','Ac',7,'f',238.03,'Solid',19.16,1.38],#U
    155                    ['Neptunium',93,'Actinide','Ac',7,'f',237.05,'Solid',20.45,1.36],#Np
    156                    ['Plutonium',94,'Actinide','Ac',7,'f',244.06,'Solid',19.82,1.28],#Pu
    157                    ['Americium',95,'Actinide','Ac',7,'f',243.06,'Solid',13.67,1.3],#Am                    
    158                    ['Curium',96,'Actinide','Ac',7,'f',247.07,'Solid',13.51,1.3],#Cm
    159                    ['Berkelium',97,'Actinide','Ac',7,'f',247,'Solid',14.78,1.3],#Bk
    160                    ['Californium',98,'Actinide','Ac',7,'f',251,'Solid',15.1,1.3],#Cf
    161                    ['Einsteinium',99,'Actinide','Ac',7,'f',252,'Solid',8.84,'Unavailable'],#Es
    162                    ['Fermium',100,'Actinide','Ac',7,'f',257.10,'Solid','Unavailable','Unavailable'],#Fm
    163                    ['Medelevium',101,'Actinide','Ac',7,'f',258,'Solid','Unavailable','Unavailable'],#Md
    164                    ['Nobelium',102,'Actinide','Ac',7,'f',259,'Solid','Unavailable.','Unavailable'],#No
    165                    ['Lawrencium',103,'Actinide','Ac',7,'f',266,'Solid','Unavailable','Unavailable'],#Lr
    166                    
    167                    ['Rutherfordium',104,'Transition Metal',4,7,'d',261.11,'Solid',17.00,'Unavailable'],#Rf
    168                    ['Dubnium',105,'Transition Metal',5,7,'d',262.11,'Unavailable','Unavailable','Unavailable'],#Db
    169                    ['Seaborgium',106,'Transition Metal',6,7,'d',263.12,'Unavailable','Unavailable','Unavailable'],#Sg
    170                    ['Bohrium',107,'Transition Metal',7,7,'d',262.12,'Unavailable','Unavailable','Unavailable'],#Bh
    171                    ['Hassium',108,'Transition Metal',8,7,'d',265,'Unavailable','Unavailable','Unavailable'],#Hs
    172                    ['Meitnerium',109,'Unknown',9,7,'d',268,'Unavailable','Unavailable','Unavailable'],#Mt
    173                    ['Darmstadtium',110,'Unknown',10,7,'d',281,'Unavailable','Unavailable','Unavailable'],#Ds
    174                    ['Roentgenium',111,'Unknown',11,7,'d',280,'Unavailable','Unavailable','Unavailable'],#Rg
    175                    ['Copernicium',112,'Unknown',12,7,'d',277,'Unavailable','Unavailable','Unavailable'],#Cn
    176                    ['Nihonium',113,'Unknown',13,7,'p',287,'Unavailable','Unavailable','Unavailable'],#Nh
    177                    ['Flerovium',114,'Unknown',14,7,'p',289,'Unavailable','Unavailable','Unavailable'],#Fl
    178                    ['Moscovium',115,'Unknown',15,7,'p',288,'Unavailable','Unavailable','Unavailable'],#Mc
    179                    ['Livermorium',116,'Unknown',16,7,'p',293,'Unavailable','Unavailable','Unavailable'],#Lv
    180                    ['Tennessine',117,'Unknown',17,7,'p',292,'Unavailable','Unavailable','Unavailable'],#Ts
    181                    ['Oganesson',118,'Unknown',18,7,'p',294,'Solid',6.6,'Unavailable']]#Og
    182
    183
    184if __name__ == '__main__': # Listing the information of elements 
    185
    186    group_no_of_elements = [1] ; period_no_of_elements = [1] ; atomic_mass_of_elements = [1.01] ; block_of_elements = ['s'] ; name_of_elements = ['Hydrogen'] ; atomic_number_of_elements = [1] ; type_of_elements = ['Non Metal'] ; state_of_elements = ['Gaseous'] ; density_of_elements = [0.08] ; electronegativity_of_elements = [2.2]
    187
    188    group_no_of_elements_sec = [] ; period_no_of_elements_sec = [] ; atomic_mass_of_elements_sec = [] ; block_of_elements_sec = [] ; name_of_elements_sec = [] ; atomic_number_of_elements_sec = [] ; type_of_elements_sec = [] ; state_of_elements_sec = [] ; density_of_elements_sec = [] ; electronegativity_of_elements_sec = []
    189
    190
    191    def add_to_list(a,b,c):
    192
    193        for i in range(a,b):
    194            if c == ' ':
    195                atomic_number_of_elements.append(" ")
    196                name_of_elements.append(" ")
    197                atomic_mass_of_elements.append(" ")
    198                block_of_elements.append(" ")
    199                group_no_of_elements.append(" ")
    200                period_no_of_elements.append(" ")
    201                type_of_elements.append(" ")
    202                state_of_elements.append(" ")
    203                density_of_elements.append(" ")
    204                electronegativity_of_elements.append(" ")
    205
    206            elif c == 1:
    207                name_of_elements.append(the_element_list[i][0])
    208                atomic_number_of_elements.append(the_element_list[i][1])
    209                type_of_elements.append(the_element_list[i][2])
    210                group_no_of_elements.append(the_element_list[i][3])
    211                period_no_of_elements.append(the_element_list[i][4])
    212                block_of_elements.append(the_element_list[i][5])
    213                atomic_mass_of_elements.append(the_element_list[i][6])
    214                state_of_elements.append(the_element_list[i][7])
    215                density_of_elements.append(the_element_list[i][8])
    216                electronegativity_of_elements.append(the_element_list[i][9])
    217
    218            elif c == 2:
    219                name_of_elements_sec.append(the_element_list[i][0])
    220                atomic_number_of_elements_sec.append(the_element_list[i][1])
    221                type_of_elements_sec.append(the_element_list[i][2])
    222                group_no_of_elements_sec.append(the_element_list[i][3])
    223                period_no_of_elements_sec.append(the_element_list[i][4])
    224                block_of_elements_sec.append(the_element_list[i][5])
    225                atomic_mass_of_elements_sec.append(the_element_list[i][6])
    226                state_of_elements_sec.append(the_element_list[i][7])
    227                density_of_elements_sec.append(the_element_list[i][8])
    228                electronegativity_of_elements_sec.append(the_element_list[i][9])
    229
    230
    231    add_to_list(0,16,' ')
    232    add_to_list(1,4,1)
    233    add_to_list(0,10,' ')
    234    add_to_list(4,12,1)
    235    add_to_list(0,10,' ')
    236    add_to_list(12,56,1)
    237    add_to_list(0,1,' ')
    238    add_to_list(71,88,1)
    239    add_to_list(0,1,' ')
    240    add_to_list(103,118,1)
    241    add_to_list(56,71,2)
    242    add_to_list(88,103,2)
    243
    244
    245if __name__ == '__main__': # Variables -- Toplevel Window's Names 
    246
    247    tk_window = []
    248    for i in range(0,126):
    249        tk_window.append(i)
    250
    251    tk_window_2 = []
    252    for i in range(0,30):
    253        tk_window_2.append(i)
    254
    255
    256if __name__ == '__main__': # Variables -- Symbols of elements in the Periodic Table 
    257
    258    period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
    259    period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
    260    period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
    261    period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
    262    period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
    263    period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
    264    period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
    265
    266    period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
    267    period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
    268
    269    # Making a list of main elements and secondary elements
    270    main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
    271    sec  = period_6a + period_7a
    272
    273
    274if __name__ == '__main__': # Variables -- Colours for each group of simliar elements in the Periodic Table 
    275
    276    # Colors for each group
    277    non_m_col   = '#feab90'
    278    alk_m_col   = '#ffe0b2'
    279    alk_ea_col  = '#fecc81'
    280    trans_m_col = '#d2c4e8'
    281    halogen_col = '#a4d7a7'
    282    metals_col  = '#feab90'
    283    noble_g_col = '#fefffe'
    284    act_col     = '#b2e5fd'
    285    rare_m_col  = '#e7ee9a'
    286    plain_but_col = 'grey' 
    287
    288
    289if __name__ == '__main__': # Using tkinter to display a Periodic Table of Elements
    290
    291    root = tk.Tk()
    292    root.attributes('-fullscreen', True)
    293    root.config(bg='purple')
    294
    295    tk.Label(root, text="Periodic Table of Elements", bg='purple', fg='white', font=['Bookman Old Style', 40, 'bold', 'underline']).place(relx=0.15, rely=0.02)
    296
    297
    298    if __name__ == '__main__': # Frames for the Periodic Table
    299
    300        # Frame for the entire table
    301        period_tab = tk.Frame(root, bg='grey', highlightbackground='black', highlightthickness=20)
    302        period_tab.pack(side=tk.BOTTOM, pady=(0,50))
    303
    304        # Frame for the main elements only
    305        main_elem = tk.Frame(period_tab)
    306        main_elem.pack(padx=20, pady=20)
    307
    308        # Frame for the secondary elements only
    309        sec_elem = tk.Frame(period_tab)
    310        sec_elem.pack(pady=20, padx=20)
    311
    312
    313    if __name__ == '__main__': # Function which creates a window of info for each element
    314
    315        def PT(window, name, symbol, atom_no, atom_mass, block, group, period, type, state, density, electronegativity):
    316            if atom_no == ' ':
    317                pass
    318            else:
    319                window = tk.Toplevel(root)
    320                window.geometry('400x400')
    321                window.config(bg='black')
    322
    323                tk.Label(window, text=name, bg='black', fg='white').place(relx=0.3, rely=0.1)
    324
    325                tk.Label(window, text=f"Symbol : {symbol}", bg='black', fg='white').place(relx=0.05, rely=0.3)
    326                tk.Label(window, text=f"Atomic Number : {atom_no}", bg='black', fg='white').place(relx=0.05, rely=0.35)
    327                tk.Label(window, text=f"Atomic Mass : {atom_mass}", bg='black', fg='white').place(relx=0.05, rely=0.4)
    328                tk.Label(window, text=f"Block : {block}", bg='black', fg='white').place(relx=0.05, rely=0.45)
    329                tk.Label(window, text=f"Group Number : {group}", bg='black', fg='white').place(relx=0.05, rely=0.5)
    330                tk.Label(window, text=f"Period Number : {period}", bg='black', fg='white').place(relx=0.05, rely=0.55)
    331                tk.Label(window, text=f"Type of element : {type}", bg='black', fg='white').place(relx=0.05, rely=0.6)
    332                tk.Label(window, text=f"State of element : {state}", bg='black', fg='white').place(relx=0.05, rely=0.65)
    333                tk.Label(window, text=f"Density : {density}", bg='black', fg='white').place(relx=0.05, rely=0.7)
    334                tk.Label(window, text=f"Electronegativity : {electronegativity}", bg='black', fg='white').place(relx=0.05, rely=0.75)
    335
    336
    337    if __name__ == '__main__': # Creating buttons for each element in the Periodic Table
    338
    339        # Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
    340        buttons = []
    341        for i in range(7):
    342            temp = []
    343            for j in range(18):
    344                but = tk.Button(main_elem,text=main[18*i+j],width=8,bg='#f0f0f0', command=partial(PT, tk_window[18*i+j], name_of_elements[18*i+j], main[18*i+j], atomic_number_of_elements[18*i+j], atomic_mass_of_elements[18*i+j], block_of_elements[18*i+j], group_no_of_elements[18*i+j], period_no_of_elements[18*i+j], type_of_elements[18*i+j], state_of_elements[18*i+j], density_of_elements[18*i+j], electronegativity_of_elements[18*i+j]))
    345                but.grid(row=i,column=j)
    346                temp.append(but)
    347            buttons.append(temp)
    348
    349        # Creating a 2x15 table of buttons for secondary elements
    350        for i in range(2):
    351            for j in range(15):
    352                if i == 0: # If row 1 then different color
    353                    tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=rare_m_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
    354                else:
    355                    tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=act_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
    356
    357
    358    if __name__ == '__main__': # Setting colours for each button
    359
    360        # Manually pick out main elements from the table
    361        non_metals     = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
    362        alk_metals     = [row[0] for row in buttons[1:]]
    363        alk_ea_metals  = [row[1] for row in buttons[1:]]
    364        halogens       = [row[16] for row in buttons[1:]]
    365        noble_gases    = [row[-1] for row in buttons[:]]
    366        transition_met = [buttons[x][3:12] for x in range(3,7)]
    367        metals         = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
    368        rare_metals    = [row[2] for row in buttons[3:6]]
    369        actinoid       = buttons[-1][2]
    370        plain_but      = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
    371
    372        # Change colors for those main element buttons
    373        actinoid['bg'] = act_col
    374        for i in alk_metals:
    375            i['bg'] = alk_m_col
    376        for i in alk_ea_metals: 
    377            i['bg'] = alk_ea_col
    378        for i in halogens:      
    379            i['bg'] = halogen_col
    380        for i in noble_gases:   
    381            i['bg'] = noble_g_col
    382        for i in rare_metals:   
    383            i['bg'] = rare_m_col
    384
    385        for i in transition_met:
    386            for j in i:
    387                j['bg'] = trans_m_col
    388
    389        for i in plain_but:
    390            for j in i:
    391                j['bg'] = plain_but_col
    392
    393        for i in non_metals:
    394            if isinstance(i,list):
    395                for j in i:
    396                    j.config(bg=non_m_col)
    397            else:
    398                i.config(bg=non_m_col)
    399
    400        for i in metals:
    401            if isinstance(i,list):
    402                for j in i:
    403                    j.config(bg=metals_col)
    404            else:
    405                i.config(bg=metals_col)
    406        
    407        for i in plain_but:
    408            for j in i:
    409                j['relief'] = 'flat'
    410
    411
    412    if __name__ == '__main__': # Creating a frame for categorizing elements on basis of their colours 
    413        legends_frame = tk.Canvas(root, bg='black', width=200, height=250)
    414
    415        tk.Label(legends_frame, text='Categories', bg='black', fg='white', font=['Bookman Old Style', 10, 'underline']).place(relx=0.25, rely=0.03)
    416
    417        labels = ['Actinides', 'Alkali Metals', 'Alkali Earth Metals', 'Halogens', 'Lanthanides', 'Metalloids', 'Noble Gases',  'Non Metals', 'Transition Metals']
    418        colours = [act_col, alk_m_col, alk_ea_col, halogen_col, rare_m_col, metals_col, noble_g_col, non_m_col, trans_m_col]
    419
    420        for i in range(0,9):
    421            tk.Label(legends_frame, text=labels[i], bg='black', fg=colours[i]).place(relx=0.4, rely=0.16+i*0.09)
    422            tk.Canvas(legends_frame, bg=colours[i], width=32, height=12, borderwidth=0).place(relx=0.1, rely=0.16+i*0.09)
    423
    424        legends_frame.place(relx=0.8, rely=0.05)
    425
    426
    427    tk.Button(root,text='EXIT',command=root.destroy).place(x=10, y=10)
    428
    429    root.mainloop()
    430

    Further Notes : If anyone could suggest me some tips through which I can write better codes , I would be grateful to him/her .

    ANSWER

    Answered 2021-Dec-29 at 20:33

    I rewrote your code with some better ways to create table. My idea was to pick out the buttons that fell onto a range of type and then loop through those buttons and change its color to those type.

    1import tkinter as tk
    2import PT
    3
    4root = tk.Tk()
    5root.attributes('-fullscreen', True)
    6root.config(bg='black')
    7
    8tk.Button(root, text='EXIT', command=root.destroy).place(x=0, y=0)
    9
    10elementals = PT.the_element_list
    11
    12search = tk.StringVar()
    13
    14search_entry = tk.Entry(root, textvariable=search)
    15search_entry.place(relx=0.3, rely=0.3)
    16
    17
    18def search_engine():
    19
    20    results = 0
    21    var1 = 0
    22
    23    texts = ["Name : ", "Atomic No. : ", "Atomic Mass : ", "Block : ", "Group No. : ", "Period No. : ", "Type : ", "State : ", "Density : ", "Electronegativity : "]
    24
    25    scroll = tk.Scrollbar(root, orient="horizontal")
    26    scroll.place(relx=0.05, rely=0.44, width=1000)
    27
    28    grand_canvas = tk.Canvas(root, bg='black', xscrollcommand=scroll.set)
    29    grand_canvas.pack(fill="x", padx=20, pady=(0,40), side=tk.BOTTOM)
    30
    31
    32    for i in elementals:
    33        if search.get() in i or search.get() in str(i):
    34            canvas1 = tk.Canvas(grand_canvas, bg='black', width=200, height=200)
    35            canvas1.place(relx=0.02+results*0.18, rely=0.1)
    36            results += 1
    37            for x in range(10):
    38                tk.Label(canvas1, text=f"{texts[x]}{i[x]}", bg='black', fg='white').place(relx=0.05, rely=0.08+var1*0.08)
    39                var1 += 1
    40            var1 = 0
    41
    42    scroll.config(command=grand_canvas.xview)
    43        
    44    tk.Label(root, text=f"Number of resuts : {results}", bg='black', fg='white').place(relx=0.7, rely=0.3)
    45
    46tk.Button(root, text='Search', command=search_engine).place(relx=0.5, rely=0.3)
    47
    48root.mainloop()
    49
    50import tkinter as tk
    51from functools import partial
    52
    53
    54the_element_list = [['Hydrogen',1,'Non Metal',1,1,'s',1.01,'Gaseous',0.08,2.2],#H
    55                    ['Helium',2,'Noble Gas',18,1,'s',4.00,'Gaseous',0.18,'Unavailable'],#He
    56
    57                    ['Lithium',3,'Alkaline Metal',1,2,'s',6.94,'Solid',0.53,0.98],#Li
    58                    ['Beryllium',4,'Alkaline Earth Metal',2,2,'s',9.01,'Solid',1.84,1.57],#Be
    59                    ['Boron',5,'Metalloid',13,2,'p',10.81,'Solid',2.46,2.04],#B
    60                    ['Carbon',6,'Non Metal',14,2,'p',12.01,'Solid',2.26,2.55],#C
    61                    ['Nitrogen',7,'Non Metal',15,2,'p',14.00,'Gaseous',1.17,3.04],#N
    62                    ['Oxygen',8,'Non Metal',16,2,'p',15.99,'Gaseous',1.43,3.44],#O
    63                    ['Fluorine',9,'Halogen',17,2,'p',18.99,'Gaseous',1.70,3.98],#F
    64                    ['Neon',10,'Noble Gas',18,2,'p',20.17,'Gaseous',0.90,'Unavailable'],#Ne
    65                
    66                    ['Sodium',11,'Alkaline Metal',1,3,'s',22.99,'Solid',0.97,0.93],#Na
    67                    ['Magnesium',12,'Alkaline Earth Metal',2,3,'s',24.31,'Solid',1.74,1.31],#Mg
    68                    ['Aluminium',13,'Metal',13,3,'p',26.98,'Solid',2.69,1.61],#Al
    69                    ['Silicon',14,'Metalloid',14,3,'p',28.08,'Solid',2.34,1.90],#Si
    70                    ['Phosphorus',15,'Non Metal',15,3,'p',30.97,'Solid',2.4,2.19],#P
    71                    ['Sulphur',16,'Non Metal',16,3,'p',32.06,'Solid',2.07,2.58],#S
    72                    ['Chlorine',17,'Halogen',17,3,'p',35.45,'Gaseous',3.22,3.16],#Cl
    73                    ['Argon',18,'Noble Gas',18,3,'p',39.95,'Gaseous',1.78,'Unavailable'],#Ar
    74
    75                    ['Potassium',19,'Alkaline Metal',1,4,'s',39.09,'Solid',0.86,0.82],#K
    76                    ['Calicium',20,'Alkaline Earth Metal',2,4,'s',40.08,'Solid',1.55,1.00],#Ca                   
    77                    ['Scandium',21,'Transition Metal',3,4,'d',44.96,'Solid',2.99,1.36],#Sc
    78                    ['Titanium',22,'Transition Metal',4,4,'d',47.87,'Solid',4.5,1.54],#Ti
    79                    ['Vanadium',23,'Transition Metal',5,4,'d',50.94,'Solid',6.11,1.63],#V
    80                    ['Chromium',24,'Transition Metal',6,4,'d',51.99,'Solid',7.14,1.66],#Cr
    81                    ['Manganese',25,'Transition Metal',7,4,'d',54.94,'Solid',7.43,1.55],#Mn
    82                    ['Iron',26,'Transition Metal',8,4,'d',55.85,'Solid',7.87,1.83],#Fe
    83                    ['Cobalt',27,'Transition Metal',9,4,'d',58.93,'Solid',8.90,1.88],#Co
    84                    ['Nickel',28,'Transition Metal',10,4,'d',58.69,'Solid',8.90,1.91],#Ni                
    85                    ['Copper',29,'Transition Metal',11,4,'d',63.54,'Solid',8.92,1.90],#Cu
    86                    ['Zinc',30,'Transition Metal',12,4,'d',65.38,'Solid',7.14,1.65],#Zn
    87                    ['Gallium',31,'Metal',13,4,'p',69.72,'Solid',5.90,1.81],#Ga
    88                    ['Germanium',32,'Metalloid',14,4,'p',72.63,'Solid',5.32,2.01],#Ge
    89                    ['Arsenic',33,'Metalloid',15,4,'p',74.92,'Solid',5.73,2.18],#As
    90                    ['Selenium',34,'Metalloid',16,4,'p',78.97,'Solid',4.82,2.55],#Se
    91                    ['Bromine',35,'Halogen',17,4,'p',79.90,'Liquid',3.12,2.96],#Br
    92                    ['Krypton',36,'Noble Gas',18,4,'p',83.80,'Gaseous',3.75,3.00],#Kr
    93                    
    94                    ['Rubidium',37,'Alkaline Metal',1,5,'s',85.47,'Solid',1.53,0.82],#Rb
    95                    ['Strontium',38,'Alkaline Earth Metal',2,5,'s',87.62,'Solid',2.63,0.95],#Sr
    96                    ['Yttrium',39,'Transition Metal',3,5,'d',88.91,'Solid',4.47,1.22],#Y
    97                    ['Zirconium',40,'Transition Metal',4,5,'d',91.22,'Solid',6.50,1.33],#Zr
    98                    ['Niobium',41,'Transition Metal',5,5,'d',92.90,'Solid',8.57,1.6],#Nb
    99                    ['Molybednium',42,'Transition Metal',6,5,'d',95.95,'Solid',10.28,2.16],#Mo
    100                    ['Technetium',43,'Transition Metal',7,5,'d',98.90,'Solid',11.5,1.9],#Tc
    101                    ['Ruthenium',44,'Transition Metal',8,5,'d',101.07,'Solid',12.37,2.2],#Ru                    
    102                    ['Rhodium',45,'Transition Metal',9,5,'d',102.90,'Solid',12.38,2.28],#Rh
    103                    ['Palladium',46,'Transition Metal',10,5,'d',106.42,'Solid',11.99,2.20],#Pd
    104                    ['ilver',47,'Transition Metal',11,5,'d',107.87,'Solid',10.49,1.93],#Ag
    105                    ['Cadmium',48,'Transition Metal',12,5,'d',112.41,'Solid',8.65,1.69],#Cd
    106                    ['Indium',49,'Metal',13,5,'p',114.82,'Solid',7.31,1.78],#In
    107                    ['Tin',50,'Metal',14,5,'p',118.71,'Solid',5.77,1.96],#Sn
    108                    ['Antimony',51,'Metalloid',15,5,'p',121.76,'Solid',6.70,2.05],#Sb
    109                    ['Tellurium',52,'Metalloid',16,5,'p',127.60,'Solid',6.24,2.10],#Te                
    110                    ['Iodine',53,'Halogen',17,5,'p',126.90,'Solid',4.94,2.66],#I
    111                    ['Xenon',54,'Noble Gas',18,5,'p',131.29,'Gaseous',5.90,2.6],#Xe
    112
    113                    ['Caesium',55,'Alkaline Metal',1,6,'s',132.91,'Solid',1.90,0.79],#Cs
    114                    ['Barium',56,'Alkaline Earth Metal',2,6,'s',137.33,'Solid',3.62,0.89],#Ba
    115
    116                    ['Lanthanum',57,'Transition Metal',3,6,'d',138.90,'Solid',6.17,1.1],#La
    117                    ['Cerium',58,'Lanthanide','La',6,'f',140.12,'Solid',6.77,1.12],#Ce
    118                    ['Praseodymium',59,'Lanthanide','La',6,'f',140.91,'Solid',6.48,1.13],#Pr
    119                    ['Neodymium',60,'Lanthanide','La',6,'f',144.24,'Solid',7.00,1.14],#Nd
    120                    ['Promethium',61,'Lanthanide','La',6,'f',146.91,'Solid',7.2,'Unavailable.'],#Pm               
    121                    ['Samarium',62,'Lanthanide','La',6,'f',150.36,'Solid',7.54,1.17],#Sm
    122                    ['Europium',63,'Lanthanide','La',6,'f',151.96,'Solid',5.25,'Unavailable'],#Eu
    123                    ['Gadolinium',64,'Lanthanide','La',6,'f',157.25,'Solid',7.89,1.20],#Gd
    124                    ['Terbium',65,'Lanthanide','La',6,'f',158.93,'Solid',8.25,'Unavailable'],#Tb
    125                    ['Dysprosium',66,'Lanthanide','La',6,'f',162.50,'Solid',8.56,1.22],#Dy
    126                    ['Holmium',67,'Lanthanide','La',6,'f',164.93,'Solid',8.78,1.23],#Ho
    127                    ['Erbium',68,'Lanthanide','La',6,'f',167.26,'Solid',9.05,1.24],#Er
    128                    ['Thulium',69,'Lanthanide','La',6,'f',168.93,'Solid',9.32,1.25],#Tm                    
    129                    ['Ytterbium',70,'Lanthanide','La',6,'f',173.05,'Solid',6.97,'Unavailable'],#Yb
    130                    ['Lutetium',71,'Lanthanide','La',6,'f',174.97,'Solid',9.84,1.27],#Lu
    131
    132                    ['Hafnium',72,'Transition Metal',4,6,'d',178.49,'Solid',13.28,1.3],#Hf
    133                    ['Tantalum',73,'Transition Metal',5,6,'d',180.95,'Solid',16.65,1.5],#Ta
    134                    ['Tungsten',74,'Transition Metal',6,6,'d',183.84,'Solid',19.25,2.36],#W
    135                    ['Rhenium',75,'Transition Metal',7,6,'d',186.21,'Solid',21.00,1.9],#Re
    136                    ['Osmium',76,'Transition Metal',8,6,'d',190.23,'Solid',22.59,2.2],#Os
    137                    ['Irdium',77,'Transition Metal',9,6,'d',192.22,'Solid',22.56,2.2],#Ir
    138                    ['Platinum',78,'Transition Metal',10,6,'d',195.08,'Solid',21.45,2.2],#Pt
    139                    ['Gold',79,'Transition Metal',11,6,'d',196.97,'Solid',19.32,2.54],#Au
    140                    ['Mercury',80,'Transition Metal',12,6,'d',200.59,'Liquid',13.55,2.00],#Hg
    141                    ['Thalium',81,'Metal',13,6,'p',204.38,'Solid',11.85,1.62],#Tl
    142                    ['Lead',82,'Metal',14,6,'p',207.20,'Solid',11.34,2.33],#Pb
    143                    ['Bismuth',83,'Metal',15,6,'p',208.98,'Solid',9.78,2.02],#Bi
    144                    ['Polonium',84,'Metal',16,6,'p',209.98,'Solid',9.20,2.0],#Po
    145                    ['Astatine',85,'Halogen',17,6,'p',209.99,'Solid','Unavailable',2.2],#At
    146                    ['Radon',86,'Noble Gas',18,6,'p',222.00,'Gaseous',9.73,'Unavailable'],#Rn
    147
    148                    ['Francium',87,'Alkaline Metal',1,7,'s',223.02,'Solid','Unavailable',0.7],#Fr
    149                    ['Radium',88,'Alkaline Earth Metal',2,7,'s',226.03,'Solid',5.5,0.9],#Ra
    150
    151                    ['Actinium',89,'Transition Metal',3,7,'d',227.03,'Solid',10.07,1.1],#Ac
    152                    ['Thorium',90,'Actinide','Ac',7,'f',232.04,'Solid',11.72,1.3],#Th
    153                    ['Protactinium',91,'Actinide','Ac',7,'f',231.04,'Solid',15.37,1.5],#Pa
    154                    ['Uranium',92,'Actinide','Ac',7,'f',238.03,'Solid',19.16,1.38],#U
    155                    ['Neptunium',93,'Actinide','Ac',7,'f',237.05,'Solid',20.45,1.36],#Np
    156                    ['Plutonium',94,'Actinide','Ac',7,'f',244.06,'Solid',19.82,1.28],#Pu
    157                    ['Americium',95,'Actinide','Ac',7,'f',243.06,'Solid',13.67,1.3],#Am                    
    158                    ['Curium',96,'Actinide','Ac',7,'f',247.07,'Solid',13.51,1.3],#Cm
    159                    ['Berkelium',97,'Actinide','Ac',7,'f',247,'Solid',14.78,1.3],#Bk
    160                    ['Californium',98,'Actinide','Ac',7,'f',251,'Solid',15.1,1.3],#Cf
    161                    ['Einsteinium',99,'Actinide','Ac',7,'f',252,'Solid',8.84,'Unavailable'],#Es
    162                    ['Fermium',100,'Actinide','Ac',7,'f',257.10,'Solid','Unavailable','Unavailable'],#Fm
    163                    ['Medelevium',101,'Actinide','Ac',7,'f',258,'Solid','Unavailable','Unavailable'],#Md
    164                    ['Nobelium',102,'Actinide','Ac',7,'f',259,'Solid','Unavailable.','Unavailable'],#No
    165                    ['Lawrencium',103,'Actinide','Ac',7,'f',266,'Solid','Unavailable','Unavailable'],#Lr
    166                    
    167                    ['Rutherfordium',104,'Transition Metal',4,7,'d',261.11,'Solid',17.00,'Unavailable'],#Rf
    168                    ['Dubnium',105,'Transition Metal',5,7,'d',262.11,'Unavailable','Unavailable','Unavailable'],#Db
    169                    ['Seaborgium',106,'Transition Metal',6,7,'d',263.12,'Unavailable','Unavailable','Unavailable'],#Sg
    170                    ['Bohrium',107,'Transition Metal',7,7,'d',262.12,'Unavailable','Unavailable','Unavailable'],#Bh
    171                    ['Hassium',108,'Transition Metal',8,7,'d',265,'Unavailable','Unavailable','Unavailable'],#Hs
    172                    ['Meitnerium',109,'Unknown',9,7,'d',268,'Unavailable','Unavailable','Unavailable'],#Mt
    173                    ['Darmstadtium',110,'Unknown',10,7,'d',281,'Unavailable','Unavailable','Unavailable'],#Ds
    174                    ['Roentgenium',111,'Unknown',11,7,'d',280,'Unavailable','Unavailable','Unavailable'],#Rg
    175                    ['Copernicium',112,'Unknown',12,7,'d',277,'Unavailable','Unavailable','Unavailable'],#Cn
    176                    ['Nihonium',113,'Unknown',13,7,'p',287,'Unavailable','Unavailable','Unavailable'],#Nh
    177                    ['Flerovium',114,'Unknown',14,7,'p',289,'Unavailable','Unavailable','Unavailable'],#Fl
    178                    ['Moscovium',115,'Unknown',15,7,'p',288,'Unavailable','Unavailable','Unavailable'],#Mc
    179                    ['Livermorium',116,'Unknown',16,7,'p',293,'Unavailable','Unavailable','Unavailable'],#Lv
    180                    ['Tennessine',117,'Unknown',17,7,'p',292,'Unavailable','Unavailable','Unavailable'],#Ts
    181                    ['Oganesson',118,'Unknown',18,7,'p',294,'Solid',6.6,'Unavailable']]#Og
    182
    183
    184if __name__ == '__main__': # Listing the information of elements 
    185
    186    group_no_of_elements = [1] ; period_no_of_elements = [1] ; atomic_mass_of_elements = [1.01] ; block_of_elements = ['s'] ; name_of_elements = ['Hydrogen'] ; atomic_number_of_elements = [1] ; type_of_elements = ['Non Metal'] ; state_of_elements = ['Gaseous'] ; density_of_elements = [0.08] ; electronegativity_of_elements = [2.2]
    187
    188    group_no_of_elements_sec = [] ; period_no_of_elements_sec = [] ; atomic_mass_of_elements_sec = [] ; block_of_elements_sec = [] ; name_of_elements_sec = [] ; atomic_number_of_elements_sec = [] ; type_of_elements_sec = [] ; state_of_elements_sec = [] ; density_of_elements_sec = [] ; electronegativity_of_elements_sec = []
    189
    190
    191    def add_to_list(a,b,c):
    192
    193        for i in range(a,b):
    194            if c == ' ':
    195                atomic_number_of_elements.append(" ")
    196                name_of_elements.append(" ")
    197                atomic_mass_of_elements.append(" ")
    198                block_of_elements.append(" ")
    199                group_no_of_elements.append(" ")
    200                period_no_of_elements.append(" ")
    201                type_of_elements.append(" ")
    202                state_of_elements.append(" ")
    203                density_of_elements.append(" ")
    204                electronegativity_of_elements.append(" ")
    205
    206            elif c == 1:
    207                name_of_elements.append(the_element_list[i][0])
    208                atomic_number_of_elements.append(the_element_list[i][1])
    209                type_of_elements.append(the_element_list[i][2])
    210                group_no_of_elements.append(the_element_list[i][3])
    211                period_no_of_elements.append(the_element_list[i][4])
    212                block_of_elements.append(the_element_list[i][5])
    213                atomic_mass_of_elements.append(the_element_list[i][6])
    214                state_of_elements.append(the_element_list[i][7])
    215                density_of_elements.append(the_element_list[i][8])
    216                electronegativity_of_elements.append(the_element_list[i][9])
    217
    218            elif c == 2:
    219                name_of_elements_sec.append(the_element_list[i][0])
    220                atomic_number_of_elements_sec.append(the_element_list[i][1])
    221                type_of_elements_sec.append(the_element_list[i][2])
    222                group_no_of_elements_sec.append(the_element_list[i][3])
    223                period_no_of_elements_sec.append(the_element_list[i][4])
    224                block_of_elements_sec.append(the_element_list[i][5])
    225                atomic_mass_of_elements_sec.append(the_element_list[i][6])
    226                state_of_elements_sec.append(the_element_list[i][7])
    227                density_of_elements_sec.append(the_element_list[i][8])
    228                electronegativity_of_elements_sec.append(the_element_list[i][9])
    229
    230
    231    add_to_list(0,16,' ')
    232    add_to_list(1,4,1)
    233    add_to_list(0,10,' ')
    234    add_to_list(4,12,1)
    235    add_to_list(0,10,' ')
    236    add_to_list(12,56,1)
    237    add_to_list(0,1,' ')
    238    add_to_list(71,88,1)
    239    add_to_list(0,1,' ')
    240    add_to_list(103,118,1)
    241    add_to_list(56,71,2)
    242    add_to_list(88,103,2)
    243
    244
    245if __name__ == '__main__': # Variables -- Toplevel Window's Names 
    246
    247    tk_window = []
    248    for i in range(0,126):
    249        tk_window.append(i)
    250
    251    tk_window_2 = []
    252    for i in range(0,30):
    253        tk_window_2.append(i)
    254
    255
    256if __name__ == '__main__': # Variables -- Symbols of elements in the Periodic Table 
    257
    258    period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
    259    period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
    260    period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
    261    period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
    262    period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
    263    period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
    264    period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
    265
    266    period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
    267    period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
    268
    269    # Making a list of main elements and secondary elements
    270    main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
    271    sec  = period_6a + period_7a
    272
    273
    274if __name__ == '__main__': # Variables -- Colours for each group of simliar elements in the Periodic Table 
    275
    276    # Colors for each group
    277    non_m_col   = '#feab90'
    278    alk_m_col   = '#ffe0b2'
    279    alk_ea_col  = '#fecc81'
    280    trans_m_col = '#d2c4e8'
    281    halogen_col = '#a4d7a7'
    282    metals_col  = '#feab90'
    283    noble_g_col = '#fefffe'
    284    act_col     = '#b2e5fd'
    285    rare_m_col  = '#e7ee9a'
    286    plain_but_col = 'grey' 
    287
    288
    289if __name__ == '__main__': # Using tkinter to display a Periodic Table of Elements
    290
    291    root = tk.Tk()
    292    root.attributes('-fullscreen', True)
    293    root.config(bg='purple')
    294
    295    tk.Label(root, text="Periodic Table of Elements", bg='purple', fg='white', font=['Bookman Old Style', 40, 'bold', 'underline']).place(relx=0.15, rely=0.02)
    296
    297
    298    if __name__ == '__main__': # Frames for the Periodic Table
    299
    300        # Frame for the entire table
    301        period_tab = tk.Frame(root, bg='grey', highlightbackground='black', highlightthickness=20)
    302        period_tab.pack(side=tk.BOTTOM, pady=(0,50))
    303
    304        # Frame for the main elements only
    305        main_elem = tk.Frame(period_tab)
    306        main_elem.pack(padx=20, pady=20)
    307
    308        # Frame for the secondary elements only
    309        sec_elem = tk.Frame(period_tab)
    310        sec_elem.pack(pady=20, padx=20)
    311
    312
    313    if __name__ == '__main__': # Function which creates a window of info for each element
    314
    315        def PT(window, name, symbol, atom_no, atom_mass, block, group, period, type, state, density, electronegativity):
    316            if atom_no == ' ':
    317                pass
    318            else:
    319                window = tk.Toplevel(root)
    320                window.geometry('400x400')
    321                window.config(bg='black')
    322
    323                tk.Label(window, text=name, bg='black', fg='white').place(relx=0.3, rely=0.1)
    324
    325                tk.Label(window, text=f"Symbol : {symbol}", bg='black', fg='white').place(relx=0.05, rely=0.3)
    326                tk.Label(window, text=f"Atomic Number : {atom_no}", bg='black', fg='white').place(relx=0.05, rely=0.35)
    327                tk.Label(window, text=f"Atomic Mass : {atom_mass}", bg='black', fg='white').place(relx=0.05, rely=0.4)
    328                tk.Label(window, text=f"Block : {block}", bg='black', fg='white').place(relx=0.05, rely=0.45)
    329                tk.Label(window, text=f"Group Number : {group}", bg='black', fg='white').place(relx=0.05, rely=0.5)
    330                tk.Label(window, text=f"Period Number : {period}", bg='black', fg='white').place(relx=0.05, rely=0.55)
    331                tk.Label(window, text=f"Type of element : {type}", bg='black', fg='white').place(relx=0.05, rely=0.6)
    332                tk.Label(window, text=f"State of element : {state}", bg='black', fg='white').place(relx=0.05, rely=0.65)
    333                tk.Label(window, text=f"Density : {density}", bg='black', fg='white').place(relx=0.05, rely=0.7)
    334                tk.Label(window, text=f"Electronegativity : {electronegativity}", bg='black', fg='white').place(relx=0.05, rely=0.75)
    335
    336
    337    if __name__ == '__main__': # Creating buttons for each element in the Periodic Table
    338
    339        # Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
    340        buttons = []
    341        for i in range(7):
    342            temp = []
    343            for j in range(18):
    344                but = tk.Button(main_elem,text=main[18*i+j],width=8,bg='#f0f0f0', command=partial(PT, tk_window[18*i+j], name_of_elements[18*i+j], main[18*i+j], atomic_number_of_elements[18*i+j], atomic_mass_of_elements[18*i+j], block_of_elements[18*i+j], group_no_of_elements[18*i+j], period_no_of_elements[18*i+j], type_of_elements[18*i+j], state_of_elements[18*i+j], density_of_elements[18*i+j], electronegativity_of_elements[18*i+j]))
    345                but.grid(row=i,column=j)
    346                temp.append(but)
    347            buttons.append(temp)
    348
    349        # Creating a 2x15 table of buttons for secondary elements
    350        for i in range(2):
    351            for j in range(15):
    352                if i == 0: # If row 1 then different color
    353                    tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=rare_m_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
    354                else:
    355                    tk.Button(sec_elem,text=sec[15*i+j],width=8,bg=act_col, command=partial(PT, tk_window_2[15*i+j], name_of_elements_sec[15*i+j], sec[15*i+j], atomic_number_of_elements_sec[15*i+j], atomic_mass_of_elements_sec[15*i+j], block_of_elements_sec[15*i+j], group_no_of_elements_sec[15*i+j], period_no_of_elements_sec[15*i+j], type_of_elements_sec[15*i+j], state_of_elements_sec[15*i+j], density_of_elements_sec[15*i+j], electronegativity_of_elements_sec[15*i+j])).grid(row=i,column=j)
    356
    357
    358    if __name__ == '__main__': # Setting colours for each button
    359
    360        # Manually pick out main elements from the table
    361        non_metals     = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
    362        alk_metals     = [row[0] for row in buttons[1:]]
    363        alk_ea_metals  = [row[1] for row in buttons[1:]]
    364        halogens       = [row[16] for row in buttons[1:]]
    365        noble_gases    = [row[-1] for row in buttons[:]]
    366        transition_met = [buttons[x][3:12] for x in range(3,7)]
    367        metals         = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
    368        rare_metals    = [row[2] for row in buttons[3:6]]
    369        actinoid       = buttons[-1][2]
    370        plain_but      = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
    371
    372        # Change colors for those main element buttons
    373        actinoid['bg'] = act_col
    374        for i in alk_metals:
    375            i['bg'] = alk_m_col
    376        for i in alk_ea_metals: 
    377            i['bg'] = alk_ea_col
    378        for i in halogens:      
    379            i['bg'] = halogen_col
    380        for i in noble_gases:   
    381            i['bg'] = noble_g_col
    382        for i in rare_metals:   
    383            i['bg'] = rare_m_col
    384
    385        for i in transition_met:
    386            for j in i:
    387                j['bg'] = trans_m_col
    388
    389        for i in plain_but:
    390            for j in i:
    391                j['bg'] = plain_but_col
    392
    393        for i in non_metals:
    394            if isinstance(i,list):
    395                for j in i:
    396                    j.config(bg=non_m_col)
    397            else:
    398                i.config(bg=non_m_col)
    399
    400        for i in metals:
    401            if isinstance(i,list):
    402                for j in i:
    403                    j.config(bg=metals_col)
    404            else:
    405                i.config(bg=metals_col)
    406        
    407        for i in plain_but:
    408            for j in i:
    409                j['relief'] = 'flat'
    410
    411
    412    if __name__ == '__main__': # Creating a frame for categorizing elements on basis of their colours 
    413        legends_frame = tk.Canvas(root, bg='black', width=200, height=250)
    414
    415        tk.Label(legends_frame, text='Categories', bg='black', fg='white', font=['Bookman Old Style', 10, 'underline']).place(relx=0.25, rely=0.03)
    416
    417        labels = ['Actinides', 'Alkali Metals', 'Alkali Earth Metals', 'Halogens', 'Lanthanides', 'Metalloids', 'Noble Gases',  'Non Metals', 'Transition Metals']
    418        colours = [act_col, alk_m_col, alk_ea_col, halogen_col, rare_m_col, metals_col, noble_g_col, non_m_col, trans_m_col]
    419
    420        for i in range(0,9):
    421            tk.Label(legends_frame, text=labels[i], bg='black', fg=colours[i]).place(relx=0.4, rely=0.16+i*0.09)
    422            tk.Canvas(legends_frame, bg=colours[i], width=32, height=12, borderwidth=0).place(relx=0.1, rely=0.16+i*0.09)
    423
    424        legends_frame.place(relx=0.8, rely=0.05)
    425
    426
    427    tk.Button(root,text='EXIT',command=root.destroy).place(x=10, y=10)
    428
    429    root.mainloop()
    430from tkinter import *
    431
    432period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
    433period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
    434period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
    435period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
    436period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
    437period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
    438period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
    439
    440period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
    441period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
    442
    443# Making a list of main elements and secondary elements
    444main = period_1 + period_2 + period_3 + period_4 + period_5 + period_6 + period_7
    445sec  = period_6a + period_7a
    446
    447# Colors for each group
    448non_m_col   = '#feab90'
    449alk_m_col   = '#ffe0b2'
    450alk_ea_col  = '#fecc81'
    451trans_m_col = '#d2c4e8'
    452halogen_col = '#a4d7a7'
    453metals_col  = '#feab90'
    454noble_g_col = '#fefffe'
    455act_col     = '#b2e5fd'
    456rare_m_col  = '#e7ee9a' 
    457
    458root = Tk()
    459
    460# Frame for the entire table
    461period_tab = Frame(root)
    462period_tab.pack()
    463
    464# Frame for the main elements only
    465main_elem = Frame(period_tab)
    466main_elem.pack()
    467
    468# Frame for the secondary elements only
    469sec_elem = Frame(period_tab)
    470sec_elem.pack(pady=10)
    471
    472# Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
    473buttons = []
    474for i in range(7):
    475    temp = []
    476    for j in range(18):
    477        but = Button(main_elem,text=main[18*i+j],width=10,bg='#f0f0f0')
    478        but.grid(row=i,column=j)
    479        temp.append(but)
    480    buttons.append(temp)
    481
    482# Creating a 2x15 table of buttons for secondary elements
    483for i in range(2):
    484    for j in range(15):
    485        text = sec[15*i+j]
    486        if i == 0: # If row 1 then different color
    487            Button(sec_elem,text=text,width=10,bg=rare_m_col).grid(row=i,column=j)
    488        else:
    489            Button(sec_elem,text=text,width=10,bg=act_col).grid(row=i,column=j)
    490            
    491# Manually pick out main elements from the table
    492non_metals     = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
    493alk_metals     = [row[0] for row in buttons[1:]]
    494alk_ea_metals  = [row[1] for row in buttons[1:]]
    495halogens       = [row[16] for row in buttons[1:]]
    496noble_gases    = [row[-1] for row in buttons[:]]
    497transition_met = [buttons[x][3:12] for x in range(3,7)]
    498metals         = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
    499rare_metals    = [row[2] for row in buttons[3:6]]
    500actinoid       = buttons[-1][2]
    501plain_but      = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
    502
    503# Change colors for those main element buttons
    504actinoid['bg'] = act_col
    505for i in alk_metals:    i['bg'] = alk_m_col
    506for i in alk_ea_metals: i['bg'] = alk_ea_col
    507for i in halogens:      i['bg'] = halogen_col
    508for i in noble_gases:   i['bg'] = noble_g_col
    509for i in rare_metals:   i['bg'] = rare_m_col
    510
    511for i in transition_met:
    512    for j in i:
    513        j['bg'] = trans_m_col
    514
    515for i in non_metals:
    516    if isinstance(i,list):
    517        for j in i:
    518            j.config(bg=non_m_col)
    519    else:
    520        i.config(bg=non_m_col)
    521
    522for i in metals:
    523    if isinstance(i,list):
    524        for j in i:
    525            j.config(bg=metals_col)
    526    else:
    527        i.config(bg=metals_col)
    528 
    529for i in plain_but:
    530    for j in i:
    531        j['relief'] = 'flat'
    532
    533Button(root,text='EXIT',command=root.destroy).pack(pady=10)
    534
    535root.mainloop()
    536

    I've commented the code to make it more understandable. The slicing part might seem a bit complicated because python list does not support 2D slicing. One way is to create a numpy array and store the coordinates onto it and then retrieve the respective button object based on coordinate, might be longer code but it would make the slicing more easier and understandable as numpy supports 2D slicing.

    Final output of the GUI: ss

    Edit: Here is a more advanced and not so complicated periodic table

    Source https://stackoverflow.com/questions/70506629

    QUESTION

    Unable to build and deploy Rails 6.0.4.1 app on heroku - Throws gyp verb cli error

    Asked 2022-Jan-02 at 10:07

    Hi i was deploying a branch on heroku and threw up this error. I also tried deploying a branch which worked perfectly, but that is also showing the same error.

    local yarn verion : 1.22.17 local node version : v12.22.7 Please help !!!

    Tried building without yarn.lock and package-lock same thing.

    This is how it starts Heroku deployment build log through CLI

    1yarn install v1.22.17
    2remote:        warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
    3remote:        [1/5] Validating package.json...
    4remote:        [2/5] Resolving packages...
    5remote:        [3/5] Fetching packages...
    6remote:        [4/5] Linking dependencies...
    7remote:        warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
    8remote:        warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
    9remote:        [5/5] Building fresh packages...
    10remote:        error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
    11remote:        Exit code: 1
    12remote:        Command: node scripts/build.js
    13remote:        Arguments: 
    14remote:        Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    15remote:        Output:
    16remote:        Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
    17remote:        gyp info it worked if it ends with ok
    18remote:        gyp verb cli [
    19remote:        gyp verb cli   '/tmp/build_df192222/bin/node',
    20remote:        gyp verb cli   '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
    21remote:        gyp verb cli   'rebuild',
    22

    . . . . . `

    1yarn install v1.22.17
    2remote:        warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
    3remote:        [1/5] Validating package.json...
    4remote:        [2/5] Resolving packages...
    5remote:        [3/5] Fetching packages...
    6remote:        [4/5] Linking dependencies...
    7remote:        warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
    8remote:        warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
    9remote:        [5/5] Building fresh packages...
    10remote:        error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
    11remote:        Exit code: 1
    12remote:        Command: node scripts/build.js
    13remote:        Arguments: 
    14remote:        Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    15remote:        Output:
    16remote:        Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
    17remote:        gyp info it worked if it ends with ok
    18remote:        gyp verb cli [
    19remote:        gyp verb cli   '/tmp/build_df192222/bin/node',
    20remote:        gyp verb cli   '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
    21remote:        gyp verb cli   'rebuild',
    22remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
    23remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    24remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    25remote:              |                                      ^~~~~~~~~~~
    26remote:              |                                      remove_cv
    27remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    28remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    29remote:              |                                      ^~~~~~~~~~~
    30remote:              |                                      remove_cv
    31remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
    32remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    33remote:              |                                                  ^
    34remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
    35remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    36remote:              |                                                               ^~~~~~~
    37remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
    38remote:        ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    39remote:          284 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    40remote:              |                                                                                                  ^~~~~~~~~~~~
    41remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
    42remote:        ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    43remote:          320 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    44remote:              |                                                                                                  ^~~~~~~~~~~~
    45remote:        In file included from ../../../../../nan/nan.h:58,
    46remote:                         from ../src/binding.cpp:1:
    47remote:        ../src/binding.cpp: At global scope:
    48remote:        /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
    49remote:          821 |       (node::addon_register_func) (regfunc),                          \
    50remote:              |                                           ^
    51remote:        /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
    52remote:          855 |   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
    53remote:              |   ^~~~~~~~~~~~~
    54remote:        ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
    55remote:          358 | NODE_MODULE(binding, RegisterModule);
    56remote:              | ^~~~~~~~~~~
    57remote:        make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
    58remote:        make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
    59remote:        gyp ERR! build error 
    60remote:        gyp ERR! stack Error: `make` failed with exit code: 2
    61remote:        gyp ERR! stack     at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
    62remote:        gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
    63remote:        gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
    64remote:        gyp ERR! System Linux 4.4.0-1097-aws
    65remote:        gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
    66remote:        gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    67remote:        gyp ERR! node -v v16.13.1
    68remote:        gyp ERR! node-gyp -v v3.8.0
    69remote:        gyp ERR! not ok 
    70remote:        Build failed with error code: 1
    71remote: 
    72remote:  !
    73remote:  !     Precompiling assets failed.
    74remote:  !
    75remote:  !     Push rejected, failed to compile Ruby app.
    76remote: 
    77remote:  !     Push failed
    78

    Though it is a Rails app I added node in engines to package.json.

    1yarn install v1.22.17
    2remote:        warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
    3remote:        [1/5] Validating package.json...
    4remote:        [2/5] Resolving packages...
    5remote:        [3/5] Fetching packages...
    6remote:        [4/5] Linking dependencies...
    7remote:        warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
    8remote:        warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
    9remote:        [5/5] Building fresh packages...
    10remote:        error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
    11remote:        Exit code: 1
    12remote:        Command: node scripts/build.js
    13remote:        Arguments: 
    14remote:        Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    15remote:        Output:
    16remote:        Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
    17remote:        gyp info it worked if it ends with ok
    18remote:        gyp verb cli [
    19remote:        gyp verb cli   '/tmp/build_df192222/bin/node',
    20remote:        gyp verb cli   '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
    21remote:        gyp verb cli   'rebuild',
    22remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
    23remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    24remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    25remote:              |                                      ^~~~~~~~~~~
    26remote:              |                                      remove_cv
    27remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    28remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    29remote:              |                                      ^~~~~~~~~~~
    30remote:              |                                      remove_cv
    31remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
    32remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    33remote:              |                                                  ^
    34remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
    35remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    36remote:              |                                                               ^~~~~~~
    37remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
    38remote:        ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    39remote:          284 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    40remote:              |                                                                                                  ^~~~~~~~~~~~
    41remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
    42remote:        ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    43remote:          320 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    44remote:              |                                                                                                  ^~~~~~~~~~~~
    45remote:        In file included from ../../../../../nan/nan.h:58,
    46remote:                         from ../src/binding.cpp:1:
    47remote:        ../src/binding.cpp: At global scope:
    48remote:        /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
    49remote:          821 |       (node::addon_register_func) (regfunc),                          \
    50remote:              |                                           ^
    51remote:        /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
    52remote:          855 |   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
    53remote:              |   ^~~~~~~~~~~~~
    54remote:        ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
    55remote:          358 | NODE_MODULE(binding, RegisterModule);
    56remote:              | ^~~~~~~~~~~
    57remote:        make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
    58remote:        make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
    59remote:        gyp ERR! build error 
    60remote:        gyp ERR! stack Error: `make` failed with exit code: 2
    61remote:        gyp ERR! stack     at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
    62remote:        gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
    63remote:        gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
    64remote:        gyp ERR! System Linux 4.4.0-1097-aws
    65remote:        gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
    66remote:        gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    67remote:        gyp ERR! node -v v16.13.1
    68remote:        gyp ERR! node-gyp -v v3.8.0
    69remote:        gyp ERR! not ok 
    70remote:        Build failed with error code: 1
    71remote: 
    72remote:  !
    73remote:  !     Precompiling assets failed.
    74remote:  !
    75remote:  !     Push rejected, failed to compile Ruby app.
    76remote: 
    77remote:  !     Push failed
    78{
    79  "name": "travel_empire",
    80  "private": true,
    81  "dependencies": {
    82    "@fortawesome/fontawesome-free": "^5.15.4",
    83    "@popperjs/core": "^2.10.2",
    84    "@rails/actioncable": "^6.0.0",
    85    "@rails/activestorage": "^6.0.0",
    86    "@rails/ujs": "^6.0.0",
    87    "@rails/webpacker": "4.3.0",
    88    "bootstrap": "4.3.1",
    89    "bootstrap-icons": "^1.5.0",
    90    "easy-autocomplete": "^1.3.5",
    91    "jquery": "^3.6.0",
    92    "jquery-ui-dist": "^1.12.1",
    93    "js-autocomplete": "^1.0.4",
    94    "node-sass": "^7.0.0",
    95    "popper.js": "^1.16.1",
    96    "turbolinks": "^5.2.0"
    97  },
    98  "version": "0.1.0",
    99  "devDependencies": {
    100    "webpack-dev-server": "^4.6.0"
    101  },
    102  "engines": {
    103    "node": "16.x"
    104  }
    105}
    106

    Gemfile

    1yarn install v1.22.17
    2remote:        warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
    3remote:        [1/5] Validating package.json...
    4remote:        [2/5] Resolving packages...
    5remote:        [3/5] Fetching packages...
    6remote:        [4/5] Linking dependencies...
    7remote:        warning " > webpack-dev-server@4.6.0" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
    8remote:        warning "webpack-dev-server > webpack-dev-middleware@5.2.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
    9remote:        [5/5] Building fresh packages...
    10remote:        error /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass: Command failed.
    11remote:        Exit code: 1
    12remote:        Command: node scripts/build.js
    13remote:        Arguments: 
    14remote:        Directory: /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    15remote:        Output:
    16remote:        Building: /tmp/build_df192222/bin/node /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
    17remote:        gyp info it worked if it ends with ok
    18remote:        gyp verb cli [
    19remote:        gyp verb cli   '/tmp/build_df192222/bin/node',
    20remote:        gyp verb cli   '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js',
    21remote:        gyp verb cli   'rebuild',
    22remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h: In function ‘void v8::internal::PerformCastCheck(T*)’:
    23remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    24remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    25remote:              |                                      ^~~~~~~~~~~
    26remote:              |                                      remove_cv
    27remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: ‘remove_cv_t’ is not a member of ‘std’; did you mean ‘remove_cv’?
    28remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    29remote:              |                                      ^~~~~~~~~~~
    30remote:              |                                      remove_cv
    31remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:50: error: template argument 2 is invalid
    32remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    33remote:              |                                                  ^
    34remote:        /app/.node-gyp/16.13.1/include/node/v8-internal.h:492:63: error: ‘::Perform’ has not been declared
    35remote:          492 |             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
    36remote:              |                                                               ^~~~~~~
    37remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render(Nan::NAN_METHOD_ARGS_TYPE)’:
    38remote:        ../src/binding.cpp:284:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    39remote:          284 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    40remote:              |                                                                                                  ^~~~~~~~~~~~
    41remote:        ../src/binding.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE render_file(Nan::NAN_METHOD_ARGS_TYPE)’:
    42remote:        ../src/binding.cpp:320:98: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
    43remote:          320 |     int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
    44remote:              |                                                                                                  ^~~~~~~~~~~~
    45remote:        In file included from ../../../../../nan/nan.h:58,
    46remote:                         from ../src/binding.cpp:1:
    47remote:        ../src/binding.cpp: At global scope:
    48remote:        /app/.node-gyp/16.13.1/include/node/node.h:821:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
    49remote:          821 |       (node::addon_register_func) (regfunc),                          \
    50remote:              |                                           ^
    51remote:        /app/.node-gyp/16.13.1/include/node/node.h:855:3: note: in expansion of macro ‘NODE_MODULE_X’
    52remote:          855 |   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
    53remote:              |   ^~~~~~~~~~~~~
    54remote:        ../src/binding.cpp:358:1: note: in expansion of macro ‘NODE_MODULE’
    55remote:          358 | NODE_MODULE(binding, RegisterModule);
    56remote:              | ^~~~~~~~~~~
    57remote:        make: *** [binding.target.mk:133: Release/obj.target/binding/src/binding.o] Error 1
    58remote:        make: Leaving directory '/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass/build'
    59remote:        gyp ERR! build error 
    60remote:        gyp ERR! stack Error: `make` failed with exit code: 2
    61remote:        gyp ERR! stack     at ChildProcess.onExit (/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
    62remote:        gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
    63remote:        gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
    64remote:        gyp ERR! System Linux 4.4.0-1097-aws
    65remote:        gyp ERR! command "/tmp/build_df192222/bin/node" "/tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
    66remote:        gyp ERR! cwd /tmp/build_df192222/node_modules/@rails/webpacker/node_modules/node-sass
    67remote:        gyp ERR! node -v v16.13.1
    68remote:        gyp ERR! node-gyp -v v3.8.0
    69remote:        gyp ERR! not ok 
    70remote:        Build failed with error code: 1
    71remote: 
    72remote:  !
    73remote:  !     Precompiling assets failed.
    74remote:  !
    75remote:  !     Push rejected, failed to compile Ruby app.
    76remote: 
    77remote:  !     Push failed
    78{
    79  "name": "travel_empire",
    80  "private": true,
    81  "dependencies": {
    82    "@fortawesome/fontawesome-free": "^5.15.4",
    83    "@popperjs/core": "^2.10.2",
    84    "@rails/actioncable": "^6.0.0",
    85    "@rails/activestorage": "^6.0.0",
    86    "@rails/ujs": "^6.0.0",
    87    "@rails/webpacker": "4.3.0",
    88    "bootstrap": "4.3.1",
    89    "bootstrap-icons": "^1.5.0",
    90    "easy-autocomplete": "^1.3.5",
    91    "jquery": "^3.6.0",
    92    "jquery-ui-dist": "^1.12.1",
    93    "js-autocomplete": "^1.0.4",
    94    "node-sass": "^7.0.0",
    95    "popper.js": "^1.16.1",
    96    "turbolinks": "^5.2.0"
    97  },
    98  "version": "0.1.0",
    99  "devDependencies": {
    100    "webpack-dev-server": "^4.6.0"
    101  },
    102  "engines": {
    103    "node": "16.x"
    104  }
    105}
    106source 'https://rubygems.org'
    107git_source(:github) { |repo| "https://github.com/#{repo}.git" }
    108
    109ruby '2.7.3'
    110
    111# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
    112gem 'rails', '~> 6.0.3', '>= 6.0.3.7'
    113
    114gem 'mongoid', git: 'https://github.com/mongodb/mongoid.git'
    115
    116
    117# Use Puma as the app server
    118gem 'puma', '~> 4.1'
    119# Use SCSS for stylesheets
    120gem 'sass-rails', '>= 6'
    121# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
    122gem 'webpacker', '~> 4.0'
    123# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
    124gem 'turbolinks', '~> 5'
    125# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
    126gem 'jbuilder', '~> 2.7'
    127# Use Redis adapter to run Action Cable in production
    128# gem 'redis', '~> 4.0'
    129# Use Active Model has_secure_password
    130
    131
    132# Use Active Storage variant
    133# gem 'image_processing', '~> 1.2'
    134
    135
    136gem 'axlsx'
    137gem 'caxlsx_rails'
    138
    139
    140#Bootstrap for UI
    141gem 'bootstrap', '~> 5.1.0'
    142gem 'bootstrap-timepicker-rails', '~> 0.1.3'
    143gem 'bootstrap-select-rails', '~> 1.6', '>= 1.6.3'
    144#JQuery Rails
    145gem 'jquery-rails'
    146
    147 gem 'rails_12factor', group: :production
    148# Reduces boot times through caching; required in config/boot.rb
    149gem 'bootsnap', '>= 1.4.2', require: false
    150
    151group :development, :test do
    152  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
    153  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
    154end
    155
    156group :development do
    157  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
    158  gem 'web-console', '>= 3.3.0'
    159  gem 'listen', '~> 3.2'
    160  gem 'pry'
    161  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
    162  gem 'spring'
    163  gem 'spring-watcher-listen', '~> 2.0.0'
    164end
    165
    166group :test do
    167  # Adds support for Capybara system testing and selenium driver
    168  gem 'capybara', '>= 2.15'
    169  gem 'selenium-webdriver'
    170  # Easy installation and use of web drivers to run system tests with browsers
    171  gem 'webdrivers'
    172  gem 'cucumber-rails', require: false
    173  gem 'database_cleaner'
    174end
    175
    176# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
    177gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
    178
    179#HTTParty for RESTful API calls
    180gem 'httparty'
    181
    182
    183#Paperclip for storing files
    184gem 'paperclip'
    185gem "mongoid-paperclip", :require => "mongoid_paperclip"
    186
    187gem "letter_opener", :group => :development
    188

    ANSWER

    Answered 2021-Dec-18 at 14:32

    I had a similar problem but resolved by following steps.

    1. Run the following command. heroku buildpacks:add heroku/nodejs --index 1
    2. Update node version from 16.x to 12.16.2 in package.json.

    Source https://stackoverflow.com/questions/70401055

    QUESTION

    Log4j 1: How to mitigate the vulnerability in log4j without updating version to 2.15.0

    Asked 2021-Dec-22 at 02:45

    I am using log4j 1.2.16. I am using this with maven selenium testng java project. I am looking for a solution without upgrading the version of log4j.

    1<dependency>
    2    <groupId>log4j</groupId>
    3    <artifactId>log4j</artifactId>
    4    <version>1.2.16</version>
    5</dependency>
    6

    ANSWER

    Answered 2021-Dec-16 at 15:08

    Since you're using log4j 1, the specific vulnerability is not present there. However, note the following from http://slf4j.org/log4shell.html:

    Is log4j 1.x vulnerable? Given that log4j version 1.x is still very widely deployed, perhaps 10 times more widely than log4j 2.x, we have been receiving a steady stream of questions regarding the vulnerability of log4j version 1.x.

    As log4j 1.x does NOT offer a JNDI look up mechanism at the message level, it does NOT suffer from CVE-2021-44228.

    However, log4j 1.x comes with JMSAppender which will perform a JNDI lookup if enabled in log4j's configuration file, i.e. log4j.properties or log4j.xml.

    An attacker who ALREADY has write access the log4j configuration file will need to add JMSAppender into the configuration poisoned with malicious connection parameters. Note that prior legitimate usage of JMSAppender is irrelevant to the ability of the attacker to mount a successful attack.

    Also note that poisoning the configuration file is not enough. The attacker also needs to force log4j to reload its configuration file with the poisoned parameters. Given that log4j 1.x does not offer automatic reloading, the poisoned configuration file will typically only become effective at application restart.

    Nevertheless, while not easy, such an attack is not impossible. Thus it makes some sense to make job of the attacker even harder by removing JMSAppender altogether from log4j-1.2.17.jar.

    In the absence of a new log4j 1.x release, you can remove JMSAppender from the log4j-1.2.17.jar artifact yourself. Here is the command:

    1<dependency>
    2    <groupId>log4j</groupId>
    3    <artifactId>log4j</artifactId>
    4    <version>1.2.16</version>
    5</dependency>
    6zip -d log4j-1.2.17.jar org/apache/log4j/net/JMSAppender.class
    7

    If you do not have access to 'zip', you can also use the 'jar' command.

    1<dependency>
    2    <groupId>log4j</groupId>
    3    <artifactId>log4j</artifactId>
    4    <version>1.2.16</version>
    5</dependency>
    6zip -d log4j-1.2.17.jar org/apache/log4j/net/JMSAppender.class
    7#assuming log4j-1.2.17.jar exists in current directory
    8mkdir tmp
    9cd tmp
    10jar xvf ../log4j-1.2.17.jar
    11rm org/apache/log4j/net/JMSAppender.class
    12jar cvf ../log4j-1.2.17-patched.jar .
    13

    It goes without saying that once log4j-1.2.17.jar is patched, you would need to deploy it.

    Source https://stackoverflow.com/questions/70332054

    QUESTION

    TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options' error using firefox_options as arguments in Selenium Python

    Asked 2021-Dec-12 at 22:00

    I'm trying to create a script which downloads a file from a website and for this I want to change the download filepath. When I try to do this with the Firefox options it gives me this error:

    1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
    2

    Code:

    1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
    2from selenium import webdriver
    3from selenium import webdriver
    4from selenium.webdriver.common.by import By
    5from selenium.webdriver.firefox.options import Options
    6from selenium.webdriver.common.keys import Keys
    7import time
    8
    9options = Options()
    10
    11options.add_argument("download.default_directory=C:\\Music")
    12browser = webdriver.Firefox(firefox_options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
    13browser.get('https://duckduckgo.com/')
    14

    ANSWER

    Answered 2021-Dec-12 at 21:50

    The browser option parameter firefox_options was deprecated in Selenium 3.8.0

    • Browser option parameters are now standardized across drivers as options. firefox_options, chrome_options, and ie_options are now deprecated

    Instead you have to use options as follows:

    1TypeError: WebDriver.__init__() got an unexpected keyword argument 'firefox_options'
    2from selenium import webdriver
    3from selenium import webdriver
    4from selenium.webdriver.common.by import By
    5from selenium.webdriver.firefox.options import Options
    6from selenium.webdriver.common.keys import Keys
    7import time
    8
    9options = Options()
    10
    11options.add_argument("download.default_directory=C:\\Music")
    12browser = webdriver.Firefox(firefox_options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
    13browser.get('https://duckduckgo.com/')
    14from selenium.webdriver.firefox.options import Options
    15
    16options = Options()
    17options.add_argument("download.default_directory=C:\\Music")
    18browser = webdriver.Firefox(options=options, executable_path=r'C:\\selenium\\geckodriver.exe')
    19

    Source https://stackoverflow.com/questions/70326002

    Community Discussions contain sources that include Stack Exchange Network

    Tutorials and Learning Resources in Selenium

    Tutorials and Learning Resources are not available at this moment for Selenium

    Share this Page

    share link

    Get latest updates on Selenium