18
\$\begingroup\$

Inspired by a question on StackOverflow I decided to code a GUI that is simple, efficent and can be used in other projects as well. I wanted to share this code since it probably is usefull to other people as well. You may want to share some practical hints how to make this code even better.

The code produces a table of frames and shows the information, I did gather for about 5 hours from wikipedia, in the final output. The frames are made clickable to make the usecase wider then without. I hope you enjoy this bit of code.

symbols = ['H','He','Li','Be','B','C','N','O','F','Ne',
           'Na','Mg','Al','Si','P','S','Cl','Ar','K', 'Ca',
           'Sc', 'Ti', 'V','Cr', 'Mn', 'Fe', 'Co', 'Ni',
           'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr',
           'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Tc', 'Ru',
           'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te',
           'I', 'Xe','Cs', 'Ba','La', 'Ce', 'Pr', 'Nd', 'Pm',
           'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm',
           'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir',
           'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn',
           'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am',
           'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Md', 'No', 'Lr',
           'Rf', 'Db', 'Sg', 'Bh','Hs', 'Mt', 'Ds', 'Rg', 'Cn',
           'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og']
keywords =['name','index','elementkategorie','gruppe','periode','block',
           'atommasse','aggregatzustand','dichte','elektronegativität']

values = [['Wasserstoff',1,'Nichtmetalle',1,1,'s',1.01,'gasförmig',0.08,2.2],#H
          ['Helium',2,'Edelgase',18,1,'s',4.00,'gasförmig',0.18,'n.A'],#He
          ['Lithium',3,'Alkalimetalle',1,2,'s',6.94,'fest',0.53,0.98],#Li
          ['Beryllium',4,'Erdalkalimetalle',2,2,'s',9.01,'fest',1.84,1.57],#Be
          ['Bor',5,'Halbmetalle',13,2,'p',10.81,'fest',2.46,2.04],#B
          ['Kohlenstoff',6,'Nichtmetalle',14,2,'p',12.01,'fest',2.26,2.55],#C
          ['Stickstoff',7,'Nichtmetalle',15,2,'p',14.00,'gasförmig',1.17,3.04],#N
          ['Sauerstoff',8,'Nichtmetalle',16,2,'p',15.99,'gasförmig',1.43,3.44],#O
          ['Fluor',9,'Halogene',17,2,'p',18.99,'gasförmig',1.70,3.98],#F
          ['Neon',10,'Edelgase',18,2,'p',20.17,'gasförmig',0.90,'n.A'],#Ne
      
          ['Natrium',11,'Alkalimetalle',1,3,'s',22.99,'fest',0.97,0.93],#Na
          ['Magnesium',12,'Erdalkalimetalle',2,3,'s',24.31,'fest',1.74,1.31],#Mg
          ['Aluminium',13,'Metalle',13,3,'p',26.98,'fest',2.69,1.61],#Al
          ['Silicium',14,'Halbmetalle',14,3,'p',28.08,'fest',2.34,1.90],#Si
          ['Phosphor',15,'Nichtmetalle',15,3,'p',30.97,'fest',2.4,2.19],#P
          ['Schwefel',16,'Nichtmetalle',16,3,'p',32.06,'fest',2.07,2.58],#S
          ['Chlor',17,'Halogene',17,3,'p',35.45,'gasförmig',3.22,3.16],#Cl
          ['Argon',18,'Edelgase',18,3,'p',39.95,'gasförmig',1.78,'n.A'],#Ar
          ['Kalium',19,'Alkalimetalle',1,4,'s',39.09,'fest',0.86,0.82],#K
          ['Calicium',20,'Erdalkalimetalle',2,4,'s',40.08,'fest',1.55,1.00],#Ca
         
          ['Scandium',21,'Übergangsmetalle',3,4,'d',44.96,'fest',2.99,1.36],#Sc
          ['Titan',22,'Übergangsmetalle',4,4,'d',47.87,'fest',4.5,1.54],#Ti
          ['Vandium',23,'Übergangsmetalle',5,4,'d',50.94,'fest',6.11,1.63],#V
          ['Chrom',24,'Übergangsmetalle',6,4,'d',51.99,'fest',7.14,1.66],#Cr
          ['Mangan',25,'Übergangsmetalle',7,4,'d',54.94,'fest',7.43,1.55],#Mn
          ['Eisen',26,'Übergangsmetalle',8,4,'d',55.85,'fest',7.87,1.83],#Fe
          ['Cobalt',27,'Übergangsmetalle',9,4,'d',58.93,'fest',8.90,1.88],#Co
          ['Nickel',28,'Übergangsmetalle',10,4,'d',58.69,'fest',8.90,1.91],#Ni
       
          ['Kupfer',29,'Übergangsmetalle',11,4,'d',63.54,'fest',8.92,1.90],#Cu
          ['Zink',30,'Übergangsmetalle',12,4,'d',65.38,'fest',7.14,1.65],#Zn
          ['Gallium',31,'Metalle',13,4,'p',69.72,'fest',5.90,1.81],#Ga
          ['Germanium',32,'Halbmetalle',14,4,'p',72.63,'fest',5.32,2.01],#Ge
          ['Arsen',33,'Halbmetalle',15,4,'p',74.92,'fest',5.73,2.18],#As
          ['Selen',34,'Halbmetalle',16,4,'p',78.97,'fest',4.82,2.55],#Se
          ['Brom',35,'Halogene',17,4,'p',79.90,'flüssig',3.12,2.96],#Br
          ['Krypton',36,'Edelgase',18,4,'p',83.80,'gasförmig',3.75,3.00],#Kr
         
          ['Rubidium',37,'Alkalimetalle',1,5,'s',85.47,'fest',1.53,0.82],#Rb
          ['Strontium',38,'Erdalkalimetalle',2,5,'s',87.62,'fest',2.63,0.95],#Sr
          ['Yttrium',39,'Übergangsmetalle',3,5,'d',88.91,'fest',4.47,1.22],#Y
          ['Zirconium',40,'Übergangsmetalle',4,5,'d',91.22,'fest',6.50,1.33],#Zr
          ['Niob',41,'Übergangsmetalle',5,5,'d',92.90,'fest',8.57,1.6],#Nb
          ['Molybdän',42,'Übergangsmetalle',6,5,'d',95.95,'fest',10.28,2.16],#Mo
          ['Technetium',43,'Übergangsmetalle',7,5,'d',98.90,'fest',11.5,1.9],#Tc
          ['Ruthenium',44,'Übergangsmetalle',8,5,'d',101.07,'fest',12.37,2.2],#Ru
         
          ['Rhodium',45,'Übergangsmetalle',9,5,'d',102.90,'fest',12.38,2.28],#Rh
          ['Palladium',46,'Übergangsmetalle',10,5,'d',106.42,'fest',11.99,2.20],#Pd
          ['Silber',47,'Übergangsmetalle',11,5,'d',107.87,'fest',10.49,1.93],#Ag
          ['cadmium',48,'Übergangsmetalle',12,5,'d',112.41,'fest',8.65,1.69],#Cd
          ['Indium',49,'Metalle',13,5,'p',114.82,'fest',7.31,1.78],#In
          ['Zinn',50,'Metalle',14,5,'p',118.71,'fest',5.77,1.96],#Sn
          ['Antimon',51,'Halbmetalle',15,5,'p',121.76,'fest',6.70,2.05],#Sb
          ['Tellur',52,'Halbmetalle',16,5,'p',127.60,'fest',6.24,2.10],#Te
      
          ['Iod',53,'Halogene',17,5,'p',126.90,'fest',4.94,2.66],#I
          ['Xenon',54,'Edelgase',18,5,'p',131.29,'gasförmig',5.90,2.6],#Xe
          ['Caesium',55,'Alkalimetalle',1,6,'s',132.91,'fest',1.90,0.79],#Cs
          ['Barium',56,'Erdalkalimetalle',2,6,'s',137.33,'fest',3.62,0.89],#Ba
          ['Lanthan',57,'Übergangsmetalle',3,6,'d',138.90,'fest',6.17,1.1],#La
          ['Cer',58,'Lanthanoide','La',6,'f',140.12,'fest',6.77,1.12],#Ce
          ['Praseodym',59,'Lanthanoide','La',6,'f',140.91,'fest',6.48,1.13],#Pr
          ['Neodym',60,'Lanthanoide','La',6,'f',144.24,'fest',7.00,1.14],#Nd
          ['Promethium',61,'Lanthanoide','La',6,'f',146.91,'fest',7.2,'n.A.'],#Pm
       
          ['Samarium',62,'Lanthanoide','La',6,'f',150.36,'fest',7.54,1.17],#Sm
          ['Europium',63,'Lanthanoide','La',6,'f',151.96,'fest',5.25,'n.A'],#Eu
          ['Gadolinium',64,'Lanthanoide','La',6,'f',157.25,'fest',7.89,1.20],#Gd
          ['Terbium',65,'Lanthanoide','La',6,'f',158.93,'fest',8.25,'n.A'],#Tb
          ['Dysprosium',66,'Lanthanoide','La',6,'f',162.50,'fest',8.56,1.22],#Dy
          ['Holmium',67,'Lanthanoide','La',6,'f',164.93,'fest',8.78,1.23],#Ho
          ['Erbium',68,'Lanthanoide','La',6,'f',167.26,'fest',9.05,1.24],#Er
          ['Thulium',69,'Lanthanoide','La',6,'f',168.93,'fest',9.32,1.25],#Tm
         
          ['Ytterbium',70,'Lanthanoide','La',6,'f',173.05,'fest',6.97,'n.A'],#Yb
          ['Lutetium',71,'Lanthanoide','La',6,'f',174.97,'fest',9.84,1.27],#Lu
          ['Hafnium',72,'Übergangsmetalle',4,6,'d',178.49,'fest',13.28,1.3],#Hf
          ['Tantal',73,'Übergangsmetalle',5,6,'d',180.95,'fest',16.65,1.5],#Ta
          ['Wolfram',74,'Übergangsmetalle',6,6,'d',183.84,'fest',19.25,2.36],#W
          ['Rhenium',75,'Übergangsmetalle',7,6,'d',186.21,'fest',21.00,1.9],#Re
          ['Osmium',76,'Übergangsmetalle',8,6,'d',190.23,'fest',22.59,2.2],#Os
          ['Irdium',77,'Übergangsmetalle',9,6,'d',192.22,'fest',22.56,2.2],#Ir

          ['Platin',78,'Übergangsmetalle',10,6,'d',195.08,'fest',21.45,2.2],#Pt
          ['Gold',79,'Übergangsmetalle',11,6,'d',196.97,'fest',19.32,2.54],#Au
          ['Quecksilber',80,'Übergangsmetalle',12,6,'d',200.59,'flüssig',13.55,2.00],#Hg
          ['Thalium',81,'Metalle',13,6,'p',204.38,'fest',11.85,1.62],#Tl
          ['Blei',82,'Metalle',14,6,'p',207.20,'fest',11.34,2.33],#Pb
          ['Bismut',83,'Metalle',15,6,'p',208.98,'fest',9.78,2.02],#Bi
          ['Polonium',84,'Metalle',16,6,'p',209.98,'fest',9.20,2.0],#Po
          ['Astat',85,'Halogene',17,6,'p',209.99,'fest','n.A',2.2],#At
          ['Radon',86,'Edelgase',18,6,'p',222.00,'gasförmig',9.73,'n.A'],#Rn

          ['Francium',87,'Alkalimetalle',1,7,'s',223.02,'fest','n.A',0.7],#Fr
          ['Radium',88,'Erdalkalimetalle',2,7,'s',226.03,'fest',5.5,0.9],#Ra
          ['Actinium',89,'Übergangsmetalle',3,7,'d',227.03,'fest',10.07,1.1],#Ac
          ['Thorium',90,'Actinoide','Ac',7,'f',232.04,'fest',11.72,1.3],#Th
          ['Protactinium',91,'Actinoide','Ac',7,'f',231.04,'fest',15.37,1.5],#Pa
          ['Uran',92,'Actinoide','Ac',7,'f',238.03,'fest',19.16,1.38],#U
          ['Neptunium',93,'Actinoide','Ac',7,'f',237.05,'fest',20.45,1.36],#Np
          ['Plutonium',94,'Actinoide','Ac',7,'f',244.06,'fest',19.82,1.28],#Pu
          ['Americium',95,'Actinoide','Ac',7,'f',243.06,'fest',13.67,1.3],#Am
          
          ['Curium',96,'Actinoide','Ac',7,'f',247.07,'fest',13.51,1.3],#Cm
          ['Berkelium',97,'Actinoide','Ac',7,'f',247,'fest',14.78,1.3],#Bk
          ['Californium',98,'Actinoide','Ac',7,'f',251,'fest',15.1,1.3],#Cf
          ['Einsteinium',99,'Actinoide','Ac',7,'f',252,'fest',8.84,'n.A'],#Es
          ['Fermium',100,'Actinoide','Ac',7,'f',257.10,'fest','n.A','n.A'],#Fm
          ['Medelevium',101,'Actinoide','Ac',7,'f',258,'fest','n.A','n.A'],#Md
          ['Nobelium',102,'Actinoide','Ac',7,'f',259,'fest','n.A.','n.A'],#No
          ['Lawrencium',103,'Actinoide','Ac',7,'f',266,'fest','n.A','n.A'],#Lr
          
          ['Rutherdordium',104,'Übergangsmetalle',4,7,'d',261.11,'fest',17.00,'n.A'],#Rf
          ['Dubnium',105,'Übergangsmetalle',5,7,'d',262.11,'n.A','n.A','n.A'],#Db
          ['Seaborgium',106,'Übergangsmetalle',6,7,'d',263.12,'n.A','n.A','n.A'],#Sg
          ['Bohrium',107,'Übergangsmetalle',7,7,'d',262.12,'n.A','n.A','n.A'],#Bh
          ['Hassium',108,'Übergangsmetalle',8,7,'d',265,'n.A','n.A','n.A'],#Hs
          ['Meitnerium',109,'Unbekannt',9,7,'d',268,'n.A','n.A','n.A'],#Mt
          ['Darmstadtium',110,'Unbekannt',10,7,'d',281,'n.A','n.A','n.A'],#Ds
          ['Roentgenium',111,'Unbekannt',11,7,'d',280,'n.A','n.A','n.A'],#Rg
          ['Copernicium',112,'Unbekannt',12,7,'d',277,'n.A','n.A','n.A'],#Cn

          ['Nihonium',113,'Unbekannt',13,7,'p',287,'n.A','n.A','n.A'],#Nh
          ['Flerovium',114,'Unbekannt',14,7,'p',289,'n.A','n.A','n.A'],#Fl
          ['Moscovium',115,'Unbekannt',15,7,'p',288,'n.A','n.A','n.A'],#Mc
          ['Livermorium',116,'Unbekannt',16,7,'p',293,'n.A','n.A','n.A'],#Lv
          ['Tenness',117,'Unbekannt',17,7,'p',292,'n.A','n.A','n.A'],#Ts
          ['Oganesson',118,'Unbekannt',18,7,'p',294,'fest',6.6,'n.A']#Og
          ]
kategorie_farben = {'Alkalimetalle' : '#fe6f61',
                    'Erdalkalimetalle':'#6791a7',
                    'Übergangsmetalle':'#83b8d0',
                    'Metalle':'#cae2ed',
                    'Halbmetalle':'#a7d6bc',
                    'Nichtmetalle':'#ffde66',
                    'Halogene':'#e9aa63',
                    'Edelgase':'#e29136',
                    'Unbekannt':'#cec0bf',
                    'Lanthanoide':'#696071',
                    'Actinoide':'#5b4c68'}
import tkinter as tk
root = tk.Tk()

class Element(tk.Frame):
    la_offset = 2;ac_offset=2;offset=2
    def __init__(self,master,symbol,**kwargs):
        tk.Frame.__init__(self,master,
                          relief = 'raised')
        self.kwargs = kwargs
        self.command= kwargs.pop('command', lambda:print('No command'))
        self.WIDTH,self.HEIGHT,self.BD = 100,100,3
        self.CMP = self.BD*2
        bg = kategorie_farben.get(kwargs.get('elementkategorie'))
        self.configure(width=self.WIDTH,height=self.HEIGHT,bd=self.BD,
                       bg=bg)
        self.grid_propagate(0)
        self.idx = tk.Label(self,text=kwargs.get('index'),bg=bg)
        self.u = tk.Label(self,text=kwargs.get('atommasse'),bg=bg)

        self.name = tk.Label(self,text=kwargs.get('name'),bg=bg)
        self.symb = tk.Label(self,text=symbol,font=('bold'),fg=self.get_fg(),bg=bg)
        
        self.e = tk.Label(self,text=kwargs.get('elektronegativität'),bg=bg)
        self.d = tk.Label(self,text=kwargs.get('dichte'),bg=bg)

        self.grid_columnconfigure(1, weight=2)
        self.grid_rowconfigure(1, weight=2)

        self.idx.grid(row=0,column=0,sticky='w')
        self.u.grid(row=0,column=2,sticky='e')
        
        mid_x = self.WIDTH/2-self.name.winfo_reqwidth()/2
        mid_y = self.HEIGHT/2-self.name.winfo_reqheight()/2
        offset= 15
        self.name.place(in_=self,x=mid_x-self.CMP,y=mid_y-self.CMP+offset)
        
        mid_x = self.WIDTH/2-self.symb.winfo_reqwidth()/2
        mid_y = self.HEIGHT/2-self.symb.winfo_reqheight()/2
        self.symb.place(in_=self,x=mid_x-self.CMP,y=mid_y-self.CMP-offset/2)
        
        self.e.grid(row=2,column=0,sticky='w')
        self.d.grid(row=2,column=2,sticky='e')

        r,c = kwargs.pop('periode'),kwargs.pop('gruppe')
        
        if c in ('La','Ac'):
            if c == 'La':
                c =Element.la_offset+Element.offset;Element.la_offset +=1
                r += self.offset
            if c == 'Ac':
                c =Element.ac_offset+Element.offset;Element.ac_offset +=1
                r += Element.offset
        
        self.grid(row=r,column=c,sticky='nswe')
        self.bind('<Enter>', self.in_active)
        self.bind('<Leave>', self.in_active)
        self.bind('<ButtonPress-1>', self.indicate)
        self.bind('<ButtonRelease-1>', self.execute)
        [child.bind('<ButtonPress-1>', self.indicate) for child in self.winfo_children()]
        [child.bind('<ButtonRelease-1>', self.execute) for child in self.winfo_children()]
    def in_active(self,event):
        if str(event.type) == 'Enter': self.flag = True
        if str(event.type) == 'Leave':
            self.flag = False;self.configure(relief='raised')
    def indicate(self,event):
        self.configure(relief='sunken')
    def execute(self,event):
        if self.flag: self.command();self.configure(relief='raised')
        else: self.configure(relief='raised')
    def get_fg(self):
        if self.kwargs.get('aggregatzustand') == 'fest': return 'black'
        if self.kwargs.get('aggregatzustand') == 'flüssig': return 'blue'
        if self.kwargs.get('aggregatzustand') == 'gasförmig': return 'red'
        if self.kwargs.get('aggregatzustand') == 'n.A': return 'grey'
def test():
    print('testing..')
        
for idx,symbol in enumerate(symbols):
    kwargs = {}
    for k,v in zip(keywords,values[idx]):
        kwargs.update({k:v})
    Element(root,symbol,command=test,**kwargs)
root.mainloop()

enter image description here

\$\endgroup\$
4
  • 2
    \$\begingroup\$ What is supposed to happen? Every time I click an element, this occurs: AttributeError: 'Element' object has no attribute 'flag'. \$\endgroup\$
    – FMc
    Dec 29, 2021 at 15:46
  • \$\begingroup\$ @FMc that's odd as soon as you enter a frame the attribute is set. By clicking on it only test is printed. I thought about calling the according wikipedia site or write info classes for each. Not sure what to do with it. \$\endgroup\$ Dec 29, 2021 at 15:50
  • 4
    \$\begingroup\$ Great python example and answers. However, this motivates me to create a javascript version. Also, I'd like to make a version where you can click somewhere to hide or show the actinides and lanthanides, to get a neater Periodic System. Perhaps great to fill a boring New Year weekend :-) \$\endgroup\$
    – Roland
    Dec 30, 2021 at 21:06
  • \$\begingroup\$ @Roland thanks for your advice and your kindness. I might as well will implement this in the code. Happy New Year! \$\endgroup\$ Jan 1 at 9:57

2 Answers 2

25
\$\begingroup\$

I hope you enjoy this bit of code.

I did!

Your symbols, keywords and values should have capitalised variable names since they're global constants. However, life would be easier if your symbols were integrated into your values, and keywords prepended with symbol. Even better: none of this actually belongs in your code, and should be cut out to a database file. JSON is easiest but there are others; for instance CSV would be higher-density (but has weaker typing).

You have not enough German in some parts, and too much German in others. Your localised data (e.g. Stickstoff) are fine. Schema (e.g. elementkategorie) and code (e.g. kategorie_farben) should not be localised and should be in English. Your floating-point rendering should use localised formats; in your case it will turn your decimal point into a comma.

Don't write n.A in your database; use None and convert that to a string on render.

Don't store root in the global namespace.

Don't leave **kwargs as a dictionary; instead make a simple @dataclass or named tuple.

Don't over-abbreviate variables like BD which should be BORDER. Likewise, over-abbreviated tk keyword arguments like bg have a full-form background which should be used instead.

Rather than strings like e, prefer constants in tk like tk.E.

Your if c in ('La','Ac'): is redundant and can be deleted.

Your flag, <Enter> and <Leave> aren't doing anything so in my suggested code I deleted them.

Refactor your get_fg to be a dictionary lookup.

Prefer the "has-a" pattern over the "is-a" pattern for your element frame class; in other words, instantiate a frame instead of inheriting one.

Consider adding a (German!) title to your window.

Factor out your creation of a middle-placed label for name and symbol to a function. Better yet: don't call place, and just represent your name and symbol labels as rows within the grid that span the width of the grid and are sticky to both east and west.

Consider resizing your chart to the window by use of a container frame and pack_configure.

You should name all of your widgets. If you don't, a name will be generated for you internally and this will make debugging more difficult.

Your element grid coordinate calculations are non-reentrant and can be performed only once per process run, since your offset variables are stored as statics. You should refactor this; the nicest way is an iterator function that keeps these offsets as locals and throws them away once all elements have been placed.

Rather than binding your mouse events to all children of your element frame, consider just calling a bindtags to pass all events from the child labels to the parent frame.

Typo: it's "rutherfordium".

I thought about calling the according wikipedia site

This is easy via webbrowser.

Suggested

elements.json

[
  {
    "symbol": "H",
    "name": "Wasserstoff",
    "number": 1,
    "category": "Nichtmetalle",
    "group": 1,
    "period": 1,
    "block": "s",
    "mass": 1.01,
    "phase": "gasförmig",
    "density": 0.08,
    "electronegativity": 2.2
  },
  {
    "symbol": "He",
    "name": "Helium",
    "number": 2,
    "category": "Edelgase",
    "group": 18,
    "period": 1,
    "block": "s",
    "mass": 4.0,
    "phase": "gasförmig",
    "density": 0.18,
    "electronegativity": null
  },
  {
    "symbol": "Li",
    "name": "Lithium",
    "number": 3,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 2,
    "block": "s",
    "mass": 6.94,
    "phase": "fest",
    "density": 0.53,
    "electronegativity": 0.98
  },
  {
    "symbol": "Be",
    "name": "Beryllium",
    "number": 4,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 2,
    "block": "s",
    "mass": 9.01,
    "phase": "fest",
    "density": 1.84,
    "electronegativity": 1.57
  },
  {
    "symbol": "B",
    "name": "Bor",
    "number": 5,
    "category": "Halbmetalle",
    "group": 13,
    "period": 2,
    "block": "p",
    "mass": 10.81,
    "phase": "fest",
    "density": 2.46,
    "electronegativity": 2.04
  },
  {
    "symbol": "C",
    "name": "Kohlenstoff",
    "number": 6,
    "category": "Nichtmetalle",
    "group": 14,
    "period": 2,
    "block": "p",
    "mass": 12.01,
    "phase": "fest",
    "density": 2.26,
    "electronegativity": 2.55
  },
  {
    "symbol": "N",
    "name": "Stickstoff",
    "number": 7,
    "category": "Nichtmetalle",
    "group": 15,
    "period": 2,
    "block": "p",
    "mass": 14.0,
    "phase": "gasförmig",
    "density": 1.17,
    "electronegativity": 3.04
  },
  {
    "symbol": "O",
    "name": "Sauerstoff",
    "number": 8,
    "category": "Nichtmetalle",
    "group": 16,
    "period": 2,
    "block": "p",
    "mass": 15.99,
    "phase": "gasförmig",
    "density": 1.43,
    "electronegativity": 3.44
  },
  {
    "symbol": "F",
    "name": "Fluor",
    "number": 9,
    "category": "Halogene",
    "group": 17,
    "period": 2,
    "block": "p",
    "mass": 18.99,
    "phase": "gasförmig",
    "density": 1.7,
    "electronegativity": 3.98
  },
  {
    "symbol": "Ne",
    "name": "Neon",
    "number": 10,
    "category": "Edelgase",
    "group": 18,
    "period": 2,
    "block": "p",
    "mass": 20.17,
    "phase": "gasförmig",
    "density": 0.9,
    "electronegativity": null
  },
  {
    "symbol": "Na",
    "name": "Natrium",
    "number": 11,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 3,
    "block": "s",
    "mass": 22.99,
    "phase": "fest",
    "density": 0.97,
    "electronegativity": 0.93
  },
  {
    "symbol": "Mg",
    "name": "Magnesium",
    "number": 12,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 3,
    "block": "s",
    "mass": 24.31,
    "phase": "fest",
    "density": 1.74,
    "electronegativity": 1.31
  },
  {
    "symbol": "Al",
    "name": "Aluminium",
    "number": 13,
    "category": "Metalle",
    "group": 13,
    "period": 3,
    "block": "p",
    "mass": 26.98,
    "phase": "fest",
    "density": 2.69,
    "electronegativity": 1.61
  },
  {
    "symbol": "Si",
    "name": "Silicium",
    "number": 14,
    "category": "Halbmetalle",
    "group": 14,
    "period": 3,
    "block": "p",
    "mass": 28.08,
    "phase": "fest",
    "density": 2.34,
    "electronegativity": 1.9
  },
  {
    "symbol": "P",
    "name": "Phosphor",
    "number": 15,
    "category": "Nichtmetalle",
    "group": 15,
    "period": 3,
    "block": "p",
    "mass": 30.97,
    "phase": "fest",
    "density": 2.4,
    "electronegativity": 2.19
  },
  {
    "symbol": "S",
    "name": "Schwefel",
    "number": 16,
    "category": "Nichtmetalle",
    "group": 16,
    "period": 3,
    "block": "p",
    "mass": 32.06,
    "phase": "fest",
    "density": 2.07,
    "electronegativity": 2.58
  },
  {
    "symbol": "Cl",
    "name": "Chlor",
    "number": 17,
    "category": "Halogene",
    "group": 17,
    "period": 3,
    "block": "p",
    "mass": 35.45,
    "phase": "gasförmig",
    "density": 3.22,
    "electronegativity": 3.16
  },
  {
    "symbol": "Ar",
    "name": "Argon",
    "number": 18,
    "category": "Edelgase",
    "group": 18,
    "period": 3,
    "block": "p",
    "mass": 39.95,
    "phase": "gasförmig",
    "density": 1.78,
    "electronegativity": null
  },
  {
    "symbol": "K",
    "name": "Kalium",
    "number": 19,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 4,
    "block": "s",
    "mass": 39.09,
    "phase": "fest",
    "density": 0.86,
    "electronegativity": 0.82
  },
  {
    "symbol": "Ca",
    "name": "Calicium",
    "number": 20,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 4,
    "block": "s",
    "mass": 40.08,
    "phase": "fest",
    "density": 1.55,
    "electronegativity": 1.0
  },
  {
    "symbol": "Sc",
    "name": "Scandium",
    "number": 21,
    "category": "Übergangsmetalle",
    "group": 3,
    "period": 4,
    "block": "d",
    "mass": 44.96,
    "phase": "fest",
    "density": 2.99,
    "electronegativity": 1.36
  },
  {
    "symbol": "Ti",
    "name": "Titan",
    "number": 22,
    "category": "Übergangsmetalle",
    "group": 4,
    "period": 4,
    "block": "d",
    "mass": 47.87,
    "phase": "fest",
    "density": 4.5,
    "electronegativity": 1.54
  },
  {
    "symbol": "V",
    "name": "Vandium",
    "number": 23,
    "category": "Übergangsmetalle",
    "group": 5,
    "period": 4,
    "block": "d",
    "mass": 50.94,
    "phase": "fest",
    "density": 6.11,
    "electronegativity": 1.63
  },
  {
    "symbol": "Cr",
    "name": "Chrom",
    "number": 24,
    "category": "Übergangsmetalle",
    "group": 6,
    "period": 4,
    "block": "d",
    "mass": 51.99,
    "phase": "fest",
    "density": 7.14,
    "electronegativity": 1.66
  },
  {
    "symbol": "Mn",
    "name": "Mangan",
    "number": 25,
    "category": "Übergangsmetalle",
    "group": 7,
    "period": 4,
    "block": "d",
    "mass": 54.94,
    "phase": "fest",
    "density": 7.43,
    "electronegativity": 1.55
  },
  {
    "symbol": "Fe",
    "name": "Eisen",
    "number": 26,
    "category": "Übergangsmetalle",
    "group": 8,
    "period": 4,
    "block": "d",
    "mass": 55.85,
    "phase": "fest",
    "density": 7.87,
    "electronegativity": 1.83
  },
  {
    "symbol": "Co",
    "name": "Cobalt",
    "number": 27,
    "category": "Übergangsmetalle",
    "group": 9,
    "period": 4,
    "block": "d",
    "mass": 58.93,
    "phase": "fest",
    "density": 8.9,
    "electronegativity": 1.88
  },
  {
    "symbol": "Ni",
    "name": "Nickel",
    "number": 28,
    "category": "Übergangsmetalle",
    "group": 10,
    "period": 4,
    "block": "d",
    "mass": 58.69,
    "phase": "fest",
    "density": 8.9,
    "electronegativity": 1.91
  },
  {
    "symbol": "Cu",
    "name": "Kupfer",
    "number": 29,
    "category": "Übergangsmetalle",
    "group": 11,
    "period": 4,
    "block": "d",
    "mass": 63.54,
    "phase": "fest",
    "density": 8.92,
    "electronegativity": 1.9
  },
  {
    "symbol": "Zn",
    "name": "Zink",
    "number": 30,
    "category": "Übergangsmetalle",
    "group": 12,
    "period": 4,
    "block": "d",
    "mass": 65.38,
    "phase": "fest",
    "density": 7.14,
    "electronegativity": 1.65
  },
  {
    "symbol": "Ga",
    "name": "Gallium",
    "number": 31,
    "category": "Metalle",
    "group": 13,
    "period": 4,
    "block": "p",
    "mass": 69.72,
    "phase": "fest",
    "density": 5.9,
    "electronegativity": 1.81
  },
  {
    "symbol": "Ge",
    "name": "Germanium",
    "number": 32,
    "category": "Halbmetalle",
    "group": 14,
    "period": 4,
    "block": "p",
    "mass": 72.63,
    "phase": "fest",
    "density": 5.32,
    "electronegativity": 2.01
  },
  {
    "symbol": "As",
    "name": "Arsen",
    "number": 33,
    "category": "Halbmetalle",
    "group": 15,
    "period": 4,
    "block": "p",
    "mass": 74.92,
    "phase": "fest",
    "density": 5.73,
    "electronegativity": 2.18
  },
  {
    "symbol": "Se",
    "name": "Selen",
    "number": 34,
    "category": "Halbmetalle",
    "group": 16,
    "period": 4,
    "block": "p",
    "mass": 78.97,
    "phase": "fest",
    "density": 4.82,
    "electronegativity": 2.55
  },
  {
    "symbol": "Br",
    "name": "Brom",
    "number": 35,
    "category": "Halogene",
    "group": 17,
    "period": 4,
    "block": "p",
    "mass": 79.9,
    "phase": "flüssig",
    "density": 3.12,
    "electronegativity": 2.96
  },
  {
    "symbol": "Kr",
    "name": "Krypton",
    "number": 36,
    "category": "Edelgase",
    "group": 18,
    "period": 4,
    "block": "p",
    "mass": 83.8,
    "phase": "gasförmig",
    "density": 3.75,
    "electronegativity": 3.0
  },
  {
    "symbol": "Rb",
    "name": "Rubidium",
    "number": 37,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 5,
    "block": "s",
    "mass": 85.47,
    "phase": "fest",
    "density": 1.53,
    "electronegativity": 0.82
  },
  {
    "symbol": "Sr",
    "name": "Strontium",
    "number": 38,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 5,
    "block": "s",
    "mass": 87.62,
    "phase": "fest",
    "density": 2.63,
    "electronegativity": 0.95
  },
  {
    "symbol": "Y",
    "name": "Yttrium",
    "number": 39,
    "category": "Übergangsmetalle",
    "group": 3,
    "period": 5,
    "block": "d",
    "mass": 88.91,
    "phase": "fest",
    "density": 4.47,
    "electronegativity": 1.22
  },
  {
    "symbol": "Zr",
    "name": "Zirconium",
    "number": 40,
    "category": "Übergangsmetalle",
    "group": 4,
    "period": 5,
    "block": "d",
    "mass": 91.22,
    "phase": "fest",
    "density": 6.5,
    "electronegativity": 1.33
  },
  {
    "symbol": "Nb",
    "name": "Niob",
    "number": 41,
    "category": "Übergangsmetalle",
    "group": 5,
    "period": 5,
    "block": "d",
    "mass": 92.9,
    "phase": "fest",
    "density": 8.57,
    "electronegativity": 1.6
  },
  {
    "symbol": "Mo",
    "name": "Molybdän",
    "number": 42,
    "category": "Übergangsmetalle",
    "group": 6,
    "period": 5,
    "block": "d",
    "mass": 95.95,
    "phase": "fest",
    "density": 10.28,
    "electronegativity": 2.16
  },
  {
    "symbol": "Tc",
    "name": "Technetium",
    "number": 43,
    "category": "Übergangsmetalle",
    "group": 7,
    "period": 5,
    "block": "d",
    "mass": 98.9,
    "phase": "fest",
    "density": 11.5,
    "electronegativity": 1.9
  },
  {
    "symbol": "Ru",
    "name": "Ruthenium",
    "number": 44,
    "category": "Übergangsmetalle",
    "group": 8,
    "period": 5,
    "block": "d",
    "mass": 101.07,
    "phase": "fest",
    "density": 12.37,
    "electronegativity": 2.2
  },
  {
    "symbol": "Rh",
    "name": "Rhodium",
    "number": 45,
    "category": "Übergangsmetalle",
    "group": 9,
    "period": 5,
    "block": "d",
    "mass": 102.9,
    "phase": "fest",
    "density": 12.38,
    "electronegativity": 2.28
  },
  {
    "symbol": "Pd",
    "name": "Palladium",
    "number": 46,
    "category": "Übergangsmetalle",
    "group": 10,
    "period": 5,
    "block": "d",
    "mass": 106.42,
    "phase": "fest",
    "density": 11.99,
    "electronegativity": 2.2
  },
  {
    "symbol": "Ag",
    "name": "Silber",
    "number": 47,
    "category": "Übergangsmetalle",
    "group": 11,
    "period": 5,
    "block": "d",
    "mass": 107.87,
    "phase": "fest",
    "density": 10.49,
    "electronegativity": 1.93
  },
  {
    "symbol": "Cd",
    "name": "cadmium",
    "number": 48,
    "category": "Übergangsmetalle",
    "group": 12,
    "period": 5,
    "block": "d",
    "mass": 112.41,
    "phase": "fest",
    "density": 8.65,
    "electronegativity": 1.69
  },
  {
    "symbol": "In",
    "name": "Indium",
    "number": 49,
    "category": "Metalle",
    "group": 13,
    "period": 5,
    "block": "p",
    "mass": 114.82,
    "phase": "fest",
    "density": 7.31,
    "electronegativity": 1.78
  },
  {
    "symbol": "Sn",
    "name": "Zinn",
    "number": 50,
    "category": "Metalle",
    "group": 14,
    "period": 5,
    "block": "p",
    "mass": 118.71,
    "phase": "fest",
    "density": 5.77,
    "electronegativity": 1.96
  },
  {
    "symbol": "Sb",
    "name": "Antimon",
    "number": 51,
    "category": "Halbmetalle",
    "group": 15,
    "period": 5,
    "block": "p",
    "mass": 121.76,
    "phase": "fest",
    "density": 6.7,
    "electronegativity": 2.05
  },
  {
    "symbol": "Te",
    "name": "Tellur",
    "number": 52,
    "category": "Halbmetalle",
    "group": 16,
    "period": 5,
    "block": "p",
    "mass": 127.6,
    "phase": "fest",
    "density": 6.24,
    "electronegativity": 2.1
  },
  {
    "symbol": "I",
    "name": "Iod",
    "number": 53,
    "category": "Halogene",
    "group": 17,
    "period": 5,
    "block": "p",
    "mass": 126.9,
    "phase": "fest",
    "density": 4.94,
    "electronegativity": 2.66
  },
  {
    "symbol": "Xe",
    "name": "Xenon",
    "number": 54,
    "category": "Edelgase",
    "group": 18,
    "period": 5,
    "block": "p",
    "mass": 131.29,
    "phase": "gasförmig",
    "density": 5.9,
    "electronegativity": 2.6
  },
  {
    "symbol": "Cs",
    "name": "Caesium",
    "number": 55,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 6,
    "block": "s",
    "mass": 132.91,
    "phase": "fest",
    "density": 1.9,
    "electronegativity": 0.79
  },
  {
    "symbol": "Ba",
    "name": "Barium",
    "number": 56,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 6,
    "block": "s",
    "mass": 137.33,
    "phase": "fest",
    "density": 3.62,
    "electronegativity": 0.89
  },
  {
    "symbol": "La",
    "name": "Lanthan",
    "number": 57,
    "category": "Übergangsmetalle",
    "group": 3,
    "period": 6,
    "block": "d",
    "mass": 138.9,
    "phase": "fest",
    "density": 6.17,
    "electronegativity": 1.1
  },
  {
    "symbol": "Ce",
    "name": "Cer",
    "number": 58,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 140.12,
    "phase": "fest",
    "density": 6.77,
    "electronegativity": 1.12
  },
  {
    "symbol": "Pr",
    "name": "Praseodym",
    "number": 59,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 140.91,
    "phase": "fest",
    "density": 6.48,
    "electronegativity": 1.13
  },
  {
    "symbol": "Nd",
    "name": "Neodym",
    "number": 60,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 144.24,
    "phase": "fest",
    "density": 7.0,
    "electronegativity": 1.14
  },
  {
    "symbol": "Pm",
    "name": "Promethium",
    "number": 61,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 146.91,
    "phase": "fest",
    "density": 7.2,
    "electronegativity": null
  },
  {
    "symbol": "Sm",
    "name": "Samarium",
    "number": 62,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 150.36,
    "phase": "fest",
    "density": 7.54,
    "electronegativity": 1.17
  },
  {
    "symbol": "Eu",
    "name": "Europium",
    "number": 63,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 151.96,
    "phase": "fest",
    "density": 5.25,
    "electronegativity": null
  },
  {
    "symbol": "Gd",
    "name": "Gadolinium",
    "number": 64,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 157.25,
    "phase": "fest",
    "density": 7.89,
    "electronegativity": 1.2
  },
  {
    "symbol": "Tb",
    "name": "Terbium",
    "number": 65,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 158.93,
    "phase": "fest",
    "density": 8.25,
    "electronegativity": null
  },
  {
    "symbol": "Dy",
    "name": "Dysprosium",
    "number": 66,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 162.5,
    "phase": "fest",
    "density": 8.56,
    "electronegativity": 1.22
  },
  {
    "symbol": "Ho",
    "name": "Holmium",
    "number": 67,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 164.93,
    "phase": "fest",
    "density": 8.78,
    "electronegativity": 1.23
  },
  {
    "symbol": "Er",
    "name": "Erbium",
    "number": 68,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 167.26,
    "phase": "fest",
    "density": 9.05,
    "electronegativity": 1.24
  },
  {
    "symbol": "Tm",
    "name": "Thulium",
    "number": 69,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 168.93,
    "phase": "fest",
    "density": 9.32,
    "electronegativity": 1.25
  },
  {
    "symbol": "Yb",
    "name": "Ytterbium",
    "number": 70,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 173.05,
    "phase": "fest",
    "density": 6.97,
    "electronegativity": null
  },
  {
    "symbol": "Lu",
    "name": "Lutetium",
    "number": 71,
    "category": "Lanthanoide",
    "group": "La",
    "period": 6,
    "block": "f",
    "mass": 174.97,
    "phase": "fest",
    "density": 9.84,
    "electronegativity": 1.27
  },
  {
    "symbol": "Hf",
    "name": "Hafnium",
    "number": 72,
    "category": "Übergangsmetalle",
    "group": 4,
    "period": 6,
    "block": "d",
    "mass": 178.49,
    "phase": "fest",
    "density": 13.28,
    "electronegativity": 1.3
  },
  {
    "symbol": "Ta",
    "name": "Tantal",
    "number": 73,
    "category": "Übergangsmetalle",
    "group": 5,
    "period": 6,
    "block": "d",
    "mass": 180.95,
    "phase": "fest",
    "density": 16.65,
    "electronegativity": 1.5
  },
  {
    "symbol": "W",
    "name": "Wolfram",
    "number": 74,
    "category": "Übergangsmetalle",
    "group": 6,
    "period": 6,
    "block": "d",
    "mass": 183.84,
    "phase": "fest",
    "density": 19.25,
    "electronegativity": 2.36
  },
  {
    "symbol": "Re",
    "name": "Rhenium",
    "number": 75,
    "category": "Übergangsmetalle",
    "group": 7,
    "period": 6,
    "block": "d",
    "mass": 186.21,
    "phase": "fest",
    "density": 21.0,
    "electronegativity": 1.9
  },
  {
    "symbol": "Os",
    "name": "Osmium",
    "number": 76,
    "category": "Übergangsmetalle",
    "group": 8,
    "period": 6,
    "block": "d",
    "mass": 190.23,
    "phase": "fest",
    "density": 22.59,
    "electronegativity": 2.2
  },
  {
    "symbol": "Ir",
    "name": "Irdium",
    "number": 77,
    "category": "Übergangsmetalle",
    "group": 9,
    "period": 6,
    "block": "d",
    "mass": 192.22,
    "phase": "fest",
    "density": 22.56,
    "electronegativity": 2.2
  },
  {
    "symbol": "Pt",
    "name": "Platin",
    "number": 78,
    "category": "Übergangsmetalle",
    "group": 10,
    "period": 6,
    "block": "d",
    "mass": 195.08,
    "phase": "fest",
    "density": 21.45,
    "electronegativity": 2.2
  },
  {
    "symbol": "Au",
    "name": "Gold",
    "number": 79,
    "category": "Übergangsmetalle",
    "group": 11,
    "period": 6,
    "block": "d",
    "mass": 196.97,
    "phase": "fest",
    "density": 19.32,
    "electronegativity": 2.54
  },
  {
    "symbol": "Hg",
    "name": "Quecksilber",
    "number": 80,
    "category": "Übergangsmetalle",
    "group": 12,
    "period": 6,
    "block": "d",
    "mass": 200.59,
    "phase": "flüssig",
    "density": 13.55,
    "electronegativity": 2.0
  },
  {
    "symbol": "Tl",
    "name": "Thalium",
    "number": 81,
    "category": "Metalle",
    "group": 13,
    "period": 6,
    "block": "p",
    "mass": 204.38,
    "phase": "fest",
    "density": 11.85,
    "electronegativity": 1.62
  },
  {
    "symbol": "Pb",
    "name": "Blei",
    "number": 82,
    "category": "Metalle",
    "group": 14,
    "period": 6,
    "block": "p",
    "mass": 207.2,
    "phase": "fest",
    "density": 11.34,
    "electronegativity": 2.33
  },
  {
    "symbol": "Bi",
    "name": "Bismut",
    "number": 83,
    "category": "Metalle",
    "group": 15,
    "period": 6,
    "block": "p",
    "mass": 208.98,
    "phase": "fest",
    "density": 9.78,
    "electronegativity": 2.02
  },
  {
    "symbol": "Po",
    "name": "Polonium",
    "number": 84,
    "category": "Metalle",
    "group": 16,
    "period": 6,
    "block": "p",
    "mass": 209.98,
    "phase": "fest",
    "density": 9.2,
    "electronegativity": 2.0
  },
  {
    "symbol": "At",
    "name": "Astat",
    "number": 85,
    "category": "Halogene",
    "group": 17,
    "period": 6,
    "block": "p",
    "mass": 209.99,
    "phase": "fest",
    "density": null,
    "electronegativity": 2.2
  },
  {
    "symbol": "Rn",
    "name": "Radon",
    "number": 86,
    "category": "Edelgase",
    "group": 18,
    "period": 6,
    "block": "p",
    "mass": 222.0,
    "phase": "gasförmig",
    "density": 9.73,
    "electronegativity": null
  },
  {
    "symbol": "Fr",
    "name": "Francium",
    "number": 87,
    "category": "Alkalimetalle",
    "group": 1,
    "period": 7,
    "block": "s",
    "mass": 223.02,
    "phase": "fest",
    "density": null,
    "electronegativity": 0.7
  },
  {
    "symbol": "Ra",
    "name": "Radium",
    "number": 88,
    "category": "Erdalkalimetalle",
    "group": 2,
    "period": 7,
    "block": "s",
    "mass": 226.03,
    "phase": "fest",
    "density": 5.5,
    "electronegativity": 0.9
  },
  {
    "symbol": "Ac",
    "name": "Actinium",
    "number": 89,
    "category": "Übergangsmetalle",
    "group": 3,
    "period": 7,
    "block": "d",
    "mass": 227.03,
    "phase": "fest",
    "density": 10.07,
    "electronegativity": 1.1
  },
  {
    "symbol": "Th",
    "name": "Thorium",
    "number": 90,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 232.04,
    "phase": "fest",
    "density": 11.72,
    "electronegativity": 1.3
  },
  {
    "symbol": "Pa",
    "name": "Protactinium",
    "number": 91,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 231.04,
    "phase": "fest",
    "density": 15.37,
    "electronegativity": 1.5
  },
  {
    "symbol": "U",
    "name": "Uran",
    "number": 92,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 238.03,
    "phase": "fest",
    "density": 19.16,
    "electronegativity": 1.38
  },
  {
    "symbol": "Np",
    "name": "Neptunium",
    "number": 93,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 237.05,
    "phase": "fest",
    "density": 20.45,
    "electronegativity": 1.36
  },
  {
    "symbol": "Pu",
    "name": "Plutonium",
    "number": 94,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 244.06,
    "phase": "fest",
    "density": 19.82,
    "electronegativity": 1.28
  },
  {
    "symbol": "Am",
    "name": "Americium",
    "number": 95,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 243.06,
    "phase": "fest",
    "density": 13.67,
    "electronegativity": 1.3
  },
  {
    "symbol": "Cm",
    "name": "Curium",
    "number": 96,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 247.07,
    "phase": "fest",
    "density": 13.51,
    "electronegativity": 1.3
  },
  {
    "symbol": "Bk",
    "name": "Berkelium",
    "number": 97,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 247,
    "phase": "fest",
    "density": 14.78,
    "electronegativity": 1.3
  },
  {
    "symbol": "Cf",
    "name": "Californium",
    "number": 98,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 251,
    "phase": "fest",
    "density": 15.1,
    "electronegativity": 1.3
  },
  {
    "symbol": "Es",
    "name": "Einsteinium",
    "number": 99,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 252,
    "phase": "fest",
    "density": 8.84,
    "electronegativity": null
  },
  {
    "symbol": "Fm",
    "name": "Fermium",
    "number": 100,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 257.1,
    "phase": "fest",
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Md",
    "name": "Medelevium",
    "number": 101,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 258,
    "phase": "fest",
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "No",
    "name": "Nobelium",
    "number": 102,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 259,
    "phase": "fest",
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Lr",
    "name": "Lawrencium",
    "number": 103,
    "category": "Actinoide",
    "group": "Ac",
    "period": 7,
    "block": "f",
    "mass": 266,
    "phase": "fest",
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Rf",
    "name": "Rutherfordium",
    "number": 104,
    "category": "Übergangsmetalle",
    "group": 4,
    "period": 7,
    "block": "d",
    "mass": 261.11,
    "phase": "fest",
    "density": 17.0,
    "electronegativity": null
  },
  {
    "symbol": "Db",
    "name": "Dubnium",
    "number": 105,
    "category": "Übergangsmetalle",
    "group": 5,
    "period": 7,
    "block": "d",
    "mass": 262.11,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Sg",
    "name": "Seaborgium",
    "number": 106,
    "category": "Übergangsmetalle",
    "group": 6,
    "period": 7,
    "block": "d",
    "mass": 263.12,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Bh",
    "name": "Bohrium",
    "number": 107,
    "category": "Übergangsmetalle",
    "group": 7,
    "period": 7,
    "block": "d",
    "mass": 262.12,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Hs",
    "name": "Hassium",
    "number": 108,
    "category": "Übergangsmetalle",
    "group": 8,
    "period": 7,
    "block": "d",
    "mass": 265,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Mt",
    "name": "Meitnerium",
    "number": 109,
    "category": "Unbekannt",
    "group": 9,
    "period": 7,
    "block": "d",
    "mass": 268,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Ds",
    "name": "Darmstadtium",
    "number": 110,
    "category": "Unbekannt",
    "group": 10,
    "period": 7,
    "block": "d",
    "mass": 281,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Rg",
    "name": "Roentgenium",
    "number": 111,
    "category": "Unbekannt",
    "group": 11,
    "period": 7,
    "block": "d",
    "mass": 280,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Cn",
    "name": "Copernicium",
    "number": 112,
    "category": "Unbekannt",
    "group": 12,
    "period": 7,
    "block": "d",
    "mass": 277,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Nh",
    "name": "Nihonium",
    "number": 113,
    "category": "Unbekannt",
    "group": 13,
    "period": 7,
    "block": "p",
    "mass": 287,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Fl",
    "name": "Flerovium",
    "number": 114,
    "category": "Unbekannt",
    "group": 14,
    "period": 7,
    "block": "p",
    "mass": 289,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Mc",
    "name": "Moscovium",
    "number": 115,
    "category": "Unbekannt",
    "group": 15,
    "period": 7,
    "block": "p",
    "mass": 288,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Lv",
    "name": "Livermorium",
    "number": 116,
    "category": "Unbekannt",
    "group": 16,
    "period": 7,
    "block": "p",
    "mass": 293,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Ts",
    "name": "Tenness",
    "number": 117,
    "category": "Unbekannt",
    "group": 17,
    "period": 7,
    "block": "p",
    "mass": 292,
    "phase": null,
    "density": null,
    "electronegativity": null
  },
  {
    "symbol": "Og",
    "name": "Oganesson",
    "number": 118,
    "category": "Unbekannt",
    "group": 18,
    "period": 7,
    "block": "p",
    "mass": 294,
    "phase": "fest",
    "density": 6.6,
    "electronegativity": null
  }
]

Python

import json
import tkinter as tk
import webbrowser
from locale import setlocale, LC_ALL, format_string
from typing import Optional, Union, Iterable, Iterator, NamedTuple


class Element(NamedTuple):
    symbol: str
    name: str
    number: int
    category: str
    group: Union[str, int]
    period: int
    block: str
    mass: float
    phase: Optional[str]
    density: Optional[float]
    electronegativity: Optional[float]


class PlacedElement(NamedTuple):
    row: int
    column: int
    element: Element


def format_float(s: Optional[float]) -> str:
    if s is None:
        return 'n.A'
    return format_string('%.2f', s)


def place_elements(elements: Iterable[Element]) -> Iterator[PlacedElement]:
    OFFSET = 2
    la_offset = 2
    ac_offset = 2

    for element in elements:
        period, group_name = element.period, element.group

        if group_name == 'La':
            group = la_offset + OFFSET
            la_offset += 1
            period += OFFSET
        elif group_name == 'Ac':
            group = ac_offset + OFFSET
            ac_offset += 1
            period += OFFSET
        else:
            group = group_name

        yield PlacedElement(row=period - 1, column=group - 1, element=element)


def load_json(filename: str = 'elements.json') -> Iterator[Element]:
    with open(filename, encoding='utf-8') as f:
        for element_dict in json.load(f):
            yield Element(**element_dict)


class ElementButton:
    BORDER = 3

    CATEGORY_COLORS = {
        'Alkalimetalle': '#fe6f61',
        'Erdalkalimetalle': '#6791a7',
        'Übergangsmetalle': '#83b8d0',
        'Metalle': '#cae2ed',
        'Halbmetalle': '#a7d6bc',
        'Nichtmetalle': '#ffde66',
        'Halogene': '#e9aa63',
        'Edelgase': '#e29136',
        'Unbekannt': '#cec0bf',
        'Lanthanoide': '#696071',
        'Actinoide': '#5b4c68',
    }

    PHASE_COLORS = {
        'fest': 'black',
        'flüssig': 'blue',
        'gasförmig': 'red',
        None:  'grey',
    }

    def __init__(self, parent: tk.Widget, placed_element: PlacedElement) -> None:
        self.element = placed_element.element
        self.background = self.CATEGORY_COLORS[self.element.category]
        self.frame = frame = tk.Frame(
            parent, relief=tk.RAISED,
            name=f'frame_{self.element.symbol}',
            background=self.background,
            border=self.BORDER,
        )
        self.frame.grid_columnconfigure(1, weight=2)
        self.frame.grid(row=placed_element.row, column=placed_element.column, sticky=tk.EW)

        self.populate()

        frame.bind('<ButtonPress-1>', self.press)
        frame.bind('<ButtonRelease-1>', self.release)
        for child in frame.winfo_children():
            child.bindtags((frame,))

    def populate(self) -> None:
        prefix = f'label_{self.element.symbol}_'

        tk.Label(
            self.frame, name=prefix + 'number',
            text=self.element.number, background=self.background,
        ).grid(row=0, column=0, sticky=tk.NW)

        tk.Label(
            self.frame, name=prefix + 'mass',
            text=format_float(self.element.mass), background=self.background,
        ).grid(row=0, column=2, sticky=tk.NE)

        tk.Label(
            self.frame, name=prefix + 'name',
            text=self.element.name, background=self.background,
        ).grid(row=1, column=0, sticky=tk.EW, columnspan=3)

        tk.Label(
            self.frame, name=prefix + 'symbol',
            text=self.element.symbol, font='bold', background=self.background,
            foreground=self.PHASE_COLORS[self.element.phase],
        ).grid(row=2, column=0, sticky=tk.EW, columnspan=3)

        tk.Label(
            self.frame, name=prefix + 'electronegativity',
            text=format_float(self.element.electronegativity), background=self.background,
        ).grid(row=3, column=0, sticky=tk.SW)

        tk.Label(
            self.frame, name=prefix + 'density',
            text=format_float(self.element.density), background=self.background,
        ).grid(row=3, column=2, sticky=tk.SE)

    def press(self, event: tk.Event) -> None:
        self.frame.configure(relief='sunken')

    def release(self, event: tk.Event) -> None:
        self.frame.configure(relief='raised')
        webbrowser.open(
            url=f'https://de.wikipedia.org/wiki/{self.element.name}',
            new=2,
        )


def main() -> None:
    setlocale(LC_ALL, 'de-DE.UTF-8')

    root = tk.Tk()
    root.title('Periodensystem der Elemente')

    frame = tk.Frame(root, name='grid_container')
    frame.pack_configure(fill=tk.BOTH)

    elements = tuple(place_elements(load_json()))
    for element in elements:
        ElementButton(frame, element)

    columns = {elm.column for elm in elements}
    for x in columns:
        frame.grid_columnconfigure(index=x, weight=1)

    root.mainloop()


if __name__ == '__main__':
    main()

screenshot

\$\endgroup\$
4
  • 5
    \$\begingroup\$ First of all, thanks a lot for reviewing my code. It will take me some time to understand your changes since I never worked with JSON or the local modul, neither I was aware that something like local exists. This looks awsome and I am sure, I will learn a lot here. Thank you very much! \$\endgroup\$ Dec 29, 2021 at 18:20
  • \$\begingroup\$ Hi, what is the advantage of using class Element(NamedTuple) instead of namedtuple from collections? \$\endgroup\$ Dec 31, 2021 at 7:28
  • 2
    \$\begingroup\$ @3DspatialUser What's the difference between namedtuple and NamedTuple? \$\endgroup\$
    – Peilonrayz
    Dec 31, 2021 at 10:21
  • 1
    \$\begingroup\$ O wow sorry I should should use google as a search machine instead of you, but thanks for your answer! \$\endgroup\$ Dec 31, 2021 at 10:39
23
\$\begingroup\$

Don't optimize the wrong thing

You have an excellent review already, so I'll comment on a narrow topic: cramped code layout. For example:

def execute(self,event):
    if self.flag: self.command();self.configure(relief='raised')
    else: self.configure(relief='raised')

As a species, software engineers are often optimizers. And the problem with optimization is its seductiveness. The thing being optimized (speed, memory, or lines of code) can start to seem independently important -- a legitimate goal in its own right. It almost never is.

Code is read or quickly scanned orders of magnitude more frequently than it is typed. The real enemy in coding is complexity, confusion, and bugs -- not whether you have to type a few extra spaces and newline characters. Do yourself a favor and type the code in a way that optimizes for readability rather than lines of code:

def execute(self, event):
    if self.flag:
        self.command()
        self.configure(relief='raised')
    else:
        self.configure(relief='raised')

And notice what happens when we do that. By enhancing the visibility of the logical structure, we see that the code is needlessly repetitive and verbose. So we edit further, ending up with a version that is more compact than the cramped version we started with:

def execute(self, event):
    if self.flag:
        self.command()
    self.configure(relief='raised')
\$\endgroup\$
2
  • \$\begingroup\$ I could not agree more. I suspect this fun question would have gotten more reviews if the code were easier to read for exactly the reasons you elucidate here. \$\endgroup\$
    – chicks
    Jan 3 at 19:10
  • \$\begingroup\$ @chicks Agree, the point is valid. I catch myself struggling between "is it good enough?" and "am I next year also be able to understand what I did there?". I started recently with __doc__ strings and also try to implement dataclasses like in the accepted answer. \$\endgroup\$ Jan 8 at 18:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.