Python Forum

Full Version: ZeroDivisionError: float division by zero
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
in line 132, I always get a ZeroDivisionError. Does anybody have a hint to solve the issue??
Actually, I want to show a popup-window, if the user doesn't select an item of the listbox, as soon as the button below is pressing..

from tkinter import*
import tkinter as tk
from tkinter import messagebox as mb
import math


l = 9.92                         # Länge
b = 10.5                         # Breite
h = 2.34                         # Höhe
V = l*b*h                        # Volumen
A = l*b                          # Nutzfläche = Deckenfläche : 104.16m²
A_f = 30.45                      # Fensterfläche                       
A_w = 2*(l*h)+2*(h*b) - A_f      # Wandfläche insgesamt: 65.12m²
V = l*b*h                        # Volumen des Raumes: 243.73m³
AV = A/V                         # Verhältnis Fläche zu Volumen: 0.43m²

# Constants for the geometry of the main window
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 300
APP_TITLE = "Simple Applikation"
 
# Variables
b = 0
items_for_listbox = ["Musik","Sprache","Vortrag","Spr.+Vor.","Sport"]

def Abs_Materialen(x):
    for n in range (x):
        if x == 1: 
            Abs_Wand = Wand*(0.03+ 0.03+ 0.03+ 0.04+ 0.05+ 0.06)/6
            return(Abs_Wand)
        if x == 2:   
            Abs_Wand = Wand*(0.11+ 0.22+ 0.34+ 0.35+ 0.51+ 0.43)/6
            return(Abs_Wand)
        if x == 3:   
            Abs_Wand = Wand*(0.02+ 0.02+ 0.03+ 0.03+ 0.04+ 0.06)/6
            return(Abs_Wand)
        if x == 4:   
            Abs_Wand = Wand*(0.03+ 0.03+ 0.02+ 0.04+ 0.05+ 0.05)/6
            return(Abs_Wand)
        if x == 11: 
            Abs_Boden = Boden*(0.04+ 0.04+ 0.05+ 0.06+ 0.06+ 0.06)/6
            return(Abs_Boden)
        if x == 12:   
            Abs_Boden = Boden*(0.20+ 0.15+ 0.10+ 0.09+ 0.06+ 0.10)/6
            return(Abs_Boden)
        if x == 13:   
            Abs_Boden = Boden*(0.15+ 0.08+ 0.07+ 0.06+ 0.06+ 0.06)/6
            return(Abs_Boden)
        if x == 14:   
            Abs_Boden = Boden*(0.02+ 0.04+ 0.07+ 0.19+ 0.29+ 0.35)/6
            return(Abs_Boden)       
        if x == 10: 
            Abs_Fenster = Fenster*(0.28+ 0.20+ 0.11+ 0.06+ 0.03+ 0.02)/6
            return(Abs_Fenster)     

        
def Abs_Objekte(x):
    for n in range (x):
        if x == 1: 
            Abs_MP = MP*(0.15+ 0.25+ 0.55+ 0.80+ 0.90+ 0.90)/6
            return(Abs_MP)
        if x == 2:   
            Abs_WP = WP*(0.05+ 0.10+ 0.15+ 0.35+ 0.45+ 0.60)/6
            return(Abs_WP)
        if x == 3:   
            Abs_Stuhl = Stuhl*(0.05+ 0.15+ 0.20+ 0.10+ 0.03+ 0.03)/6
            return(Abs_Stuhl) 

# Eingabe der Flächen in m²:
Boden = 100
Decke = 100
Wand    = 180
Fenster = 80

WP = 18 # Weibliche Person
MP = 19 # Männliche Person

Stuhl = WP + MP

Abs_Fläche =  Abs_Materialen(4)+ Abs_Materialen(11) +Abs_Objekte(1) + Abs_Objekte(2)+ Abs_Objekte(3)
Abs_Fläche



#------------------------ popup -----------------------------------

def popupmsg(msg):
    popup= tk.Tk()
    popup.wm_title("!")
    popup.iconbitmap("C:/Users/PC/Desktop/Icons/attention.ico")
    label = ttk.Label(popup, text=msg, font=NORM_FONT).pack(side="top", fill="x", pady=10)
    B1 = ttk.Button(popup, text="Okay", command = popup.destroy).pack()
    popup.mainloop()

# -----------------------------calculating -------------------------

def select(event):
    global b
    #a = int(mylistbox.get(tk.ANCHOR))
    a = mylistbox.get(tk.ANCHOR)
    b = curselection(a) 
    selected_var.set(b)
    
def curselection(a):
    
    if a=="Musik":
        T_soll_A1 = 0.45*math.log10(V)+0.07                
        return (T_soll_A1)
                
    elif a=="Sprache":
        T_soll_A2 = 0.37*math.log10(V)-0.14             
        return (T_soll_A2)
                
    elif a=="Vortrag":
        T_soll_A3 = 0.32*math.log10(V)-0.17               
        return (T_soll_A3)
                
    elif a=="Spr.+Vor.":    
        T_soll_A4 = 0.26*math.log10(V)-0.14           
        return (T_soll_A4)
        
    elif a=="Sport":    
        T_soll_A5 = 0.75*math.log10(V)-1              
        return (T_soll_A5)
    
    
def calculate():
    global b
    if mylistbox.get(ACTIVE):
        Abs_Fl_ges = 0.163 * V / b # gemäß Sabinesche Formel:T_soll = (0163*V)/A_abs
        Absorber = Abs_Fl_ges - Abs_Fläche
        result_var.set(Absorber)  
    elif b==0:
        tk.messagebox.showinfo("No selection")
              
# GUI
# App window
app_win = tk.Tk()
app_win.title(APP_TITLE) 
app_win.wm_geometry("%dx%d+%d+%d" % (APP_WIDTH, APP_HEIGHT, APP_XPOS, APP_YPOS))
 
# Main container embeded in the app window
# Container for all of the app widgets
main_frame = tk.Frame(app_win)
main_frame.pack(expand=tk.YES, fill=tk.BOTH)
 
# Label to show your listbox selection
selected_var = tk.StringVar()
tk.Label(main_frame, textvariable=selected_var, font=('times', 12, 'bold')
    ).pack(expand=tk.YES)
selected_var.set("No selection")
 
# Label to show your calculated result
result_var = tk.StringVar()
tk.Label(main_frame, textvariable=result_var, font=('times', 12, 'bold')
    ).pack(expand=tk.YES)
result_var.set("No result")
 
# Container for the listbox & scrollbar (embeded in the main frame)
listbox_frame = tk.Frame(main_frame)
listbox_frame.pack(expand=tk.YES)
     
mylistbox = tk.Listbox(listbox_frame, height=5, width=10, font=('times',18))
mylistbox.bind('<<ListboxSelect>>', select)
mylistbox.grid(row=0, column=0)
mylistbox.insert(tk.END, *items_for_listbox)
  
scroll = tk.Scrollbar(listbox_frame, orient=tk.VERTICAL) # the allignment of the scrollbar
mylistbox["yscrollcommand"] = scroll.set # link the list with the scroll
scroll["command"] = mylistbox.yview # link the scroll with the scroll
scroll.grid(row=0, column=1, sticky=tk.N+tk.S) #sticky=N+S+E)
 
# Button to launch a calculation
button=tk.Button(main_frame, text="Fläche der Absorber",
    command=calculate).pack(expand=tk.YES)
    
app_win.mainloop()
At line 25 you set b = 0. You can't divide by zero, thus
Error:
ZeroDivisionError


The only solution is to have b equal a non-zero.
Ok thanks, and how can I show up the messagebox in function calculate? The popup-window doesn't appear...
There was more then one error.
A cleaned up version of your code:

Haven't tested much.
import math
from tkinter import (
    Tk,
    ttk,
    messagebox,
    StringVar,
    Label,
    Listbox,
    Scrollbar,
    Button,
    Frame,
    ACTIVE,
    ANCHOR,
    BOTH,
    END,
    YES,
    N,
    S,
    VERTICAL,
)

length = 9.92  # Länge
width = 10.5  # Breite
height = 2.34  # Höhe
A = length * width  # Nutzfläche = Deckenfläche : 104.16m²
A_f = 30.45  # Fensterfläche
A_w = (
    2 * (length * height) + 2 * (height * width) - A_f
)  # Wandfläche insgesamt: 65.12m²
V = length * width * height  # Volumen des Raumes: 243.73m³
AV = A / V  # Verhältnis Fläche zu Volumen: 0.43m²

# Constants for the geometry of the main window
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 300
APP_TITLE = "Simple Applikation"
NORM_FONT = ("Arial", 16)
# Variables
items_for_listbox = ["Musik", "Sprache", "Vortrag", "Spr.+Vor.", "Sport"]


def abs_materialen(x):
    for n in range(x):
        if x == 1:
            return Wand * (0.03 + 0.03 + 0.03 + 0.04 + 0.05 + 0.06) / 6
        if x == 2:
            return Wand * (0.11 + 0.22 + 0.34 + 0.35 + 0.51 + 0.43) / 6
        if x == 3:
            return Wand * (0.02 + 0.02 + 0.03 + 0.03 + 0.04 + 0.06) / 6
        if x == 4:
            return Wand * (0.03 + 0.03 + 0.02 + 0.04 + 0.05 + 0.05) / 6
        if x == 11:
            return Boden * (0.04 + 0.04 + 0.05 + 0.06 + 0.06 + 0.06) / 6
        if x == 12:
            return Boden * (0.20 + 0.15 + 0.10 + 0.09 + 0.06 + 0.10) / 6
        if x == 13:
            return Boden * (0.15 + 0.08 + 0.07 + 0.06 + 0.06 + 0.06) / 6
        if x == 14:
            return Boden * (0.02 + 0.04 + 0.07 + 0.19 + 0.29 + 0.35) / 6
        if x == 10:
            return Fenster * (0.28 + 0.20 + 0.11 + 0.06 + 0.03 + 0.02) / 6


def abs_objekte(x):
    for n in range(x):
        if x == 1:
            return MP * (0.15 + 0.25 + 0.55 + 0.80 + 0.90 + 0.90) / 6
        if x == 2:
            return WP * (0.05 + 0.10 + 0.15 + 0.35 + 0.45 + 0.60) / 6
        if x == 3:
            return Stuhl * (0.05 + 0.15 + 0.20 + 0.10 + 0.03 + 0.03) / 6


Boden = 100
Decke = 100
Wand = 180
Fenster = 80

WP = 18  # Weibliche Person
MP = 19  # Männliche Person

Stuhl = WP + MP

abs_flaeche = (
    abs_materialen(4)
    + abs_materialen(11)
    + abs_objekte(1)
    + abs_objekte(2)
    + abs_objekte(3)
)


# ------------------------ popup -----------------------------------


def popupmsg(msg):
    popup = Tk()
    popup.wm_title("!")
    popup.iconbitmap("C:/Users/PC/Desktop/Icons/attention.ico")
    ttk.Label(popup, text=msg, font=NORM_FONT).pack(side="top", fill="x", pady=10)
    ttk.Button(popup, text="Okay", command=popup.destroy).pack()
    popup.mainloop()


# -----------------------------calculating -------------------------


# noinspection PyUnusedLocal
def select(event):
    global width
    # a = int(mylistbox.get(tk.ANCHOR))
    a = mylistbox.get(ANCHOR)
    width = curselection(a)
    selected_var.set(width)


def curselection(a):
    if a == "Musik":
        return 0.45 * math.log10(V) + 0.07

    elif a == "Sprache":
        return 0.37 * math.log10(V) - 0.14

    elif a == "Vortrag":
        return 0.32 * math.log10(V) - 0.17

    elif a == "Spr.+Vor.":
        return 0.26 * math.log10(V) - 0.14

    elif a == "Sport":
        return 0.75 * math.log10(V) - 1


def calculate():
    global width
    if mylistbox.get(ACTIVE):
        abs_fl_ges = (
            0.163 * V / width
        )  # gemäß Sabinesche Formel:T_soll = (0163*V)/A_abs
        absorber = abs_fl_ges - abs_flaeche
        result_var.set(absorber)
    elif width == 0:
        messagebox.showinfo("No selection")


# GUI
# App window
app_win = Tk()
app_win.title(APP_TITLE)
app_win.wm_geometry("%dx%d+%d+%d" % (APP_WIDTH, APP_HEIGHT, APP_XPOS, APP_YPOS))

# Main container embeded in the app window
# Container for all of the app widgets
main_frame = Frame(app_win)
main_frame.pack(expand=YES, fill=BOTH)

# Label to show your listbox selection
selected_var = StringVar()
Label(main_frame, textvariable=selected_var, font=("times", 12, "bold")).pack(
    expand=YES
)
selected_var.set("No selection")

# Label to show your calculated result
result_var = StringVar()
Label(main_frame, textvariable=result_var, font=("times", 12, "bold")).pack(expand=YES)
result_var.set("No result")

# Container for the listbox & scrollbar (embeded in the main frame)
listbox_frame = Frame(main_frame)
listbox_frame.pack(expand=YES)

mylistbox = Listbox(listbox_frame, height=5, width=10, font=("times", 18))
mylistbox.bind("<<ListboxSelect>>", select)
mylistbox.grid(row=0, column=0)
mylistbox.insert(END, *items_for_listbox)

scroll = Scrollbar(listbox_frame, orient=VERTICAL)  # the allignment of the scrollbar
mylistbox["yscrollcommand"] = scroll.set  # link the list with the scroll
scroll["command"] = mylistbox.yview  # link the scroll with the scroll
scroll.grid(row=0, column=1, sticky=N + S)  # sticky=N+S+E)

# Button to launch a calculation
button = Button(main_frame, text="Fläche der Absorber", command=calculate).pack(
    expand=YES
)

app_win.mainloop()

Hey,

thanks for quick respond! Unfortunately it doesn't work yet, the messagebox still doesn't appear yet...

I've got now that b is already existed,so thanks for the advice!! But your solution, to replace b with width, is not correct, because width cannot be changed. It has to stay this way.

I need a global variable, which has no relation to the others. For example z or something like that.
Calling mylistbox.get(ACTIVE) seems to return always the last object you added. In this case it was "Sport".
I think you have to refactor the code. It could be done with one class. There seems also to be an disambiguity between the first selection and the selection by mice.

Maybe I can look after work to investigate.
All objects like length, with, etc. should be live inside the class.
Ok, I'll wait for your solution. In the meantime, I'try to find a way to solve the problem, but I think this is waste of time. hahaha...

This is the latest version of the code,including your improvements:
import math
from tkinter import (
    Tk,
    ttk,
    messagebox,
    StringVar,
    Label,
    Listbox,
    Scrollbar,
    Button,
    Frame,
    ACTIVE,
    ANCHOR,
    BOTH,
    END,
    YES,
    N,
    S,
    VERTICAL,
)

l = 9.92                         # Länge
b = 10.5                         # Breite
h = 2.34                         # Höhe
A = l*b                          # Nutzfläche = Deckenfläche : 104.16m²
A_f = 30.45                      # Fensterfläche                       
A_w = 2*(l*h)+2*(h*b) - A_f      # Wandfläche insgesamt: 65.12m²
V = l*b*h                        # Volumen des Raumes: 243.73m³
AV = A/V                         # Verhältnis Fläche zu Volumen: 0.43m²

# Constants for the geometry of the main window
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 300
APP_TITLE = "Simple Applikation"
 
# Variables
z = 1
items_for_listbox = ["Musik","Sprache","Vortrag","Spr.+Vor.","Sport"]

def Abs_Materialen(x):
    for n in range (x):
        if x == 1: 
            Abs_Wand = Wand*(0.03+ 0.03+ 0.03+ 0.04+ 0.05+ 0.06)/6
            return(Abs_Wand)
        if x == 2:   
            Abs_Wand = Wand*(0.11+ 0.22+ 0.34+ 0.35+ 0.51+ 0.43)/6
            return(Abs_Wand)
        if x == 3:   
            Abs_Wand = Wand*(0.02+ 0.02+ 0.03+ 0.03+ 0.04+ 0.06)/6
            return(Abs_Wand)
        if x == 4:   
            Abs_Wand = Wand*(0.03+ 0.03+ 0.02+ 0.04+ 0.05+ 0.05)/6
            return(Abs_Wand)
        if x == 11: 
            Abs_Boden = Boden*(0.04+ 0.04+ 0.05+ 0.06+ 0.06+ 0.06)/6
            return(Abs_Boden)
        if x == 12:   
            Abs_Boden = Boden*(0.20+ 0.15+ 0.10+ 0.09+ 0.06+ 0.10)/6
            return(Abs_Boden)
        if x == 13:   
            Abs_Boden = Boden*(0.15+ 0.08+ 0.07+ 0.06+ 0.06+ 0.06)/6
            return(Abs_Boden)
        if x == 14:   
            Abs_Boden = Boden*(0.02+ 0.04+ 0.07+ 0.19+ 0.29+ 0.35)/6
            return(Abs_Boden)       
        if x == 10: 
            Abs_Fenster = Fenster*(0.28+ 0.20+ 0.11+ 0.06+ 0.03+ 0.02)/6
            return(Abs_Fenster)     

        
def Abs_Objekte(x):
    for n in range (x):
        if x == 1: 
            Abs_MP = MP*(0.15+ 0.25+ 0.55+ 0.80+ 0.90+ 0.90)/6
            return(Abs_MP)
        if x == 2:   
            Abs_WP = WP*(0.05+ 0.10+ 0.15+ 0.35+ 0.45+ 0.60)/6
            return(Abs_WP)
        if x == 3:   
            Abs_Stuhl = Stuhl*(0.05+ 0.15+ 0.20+ 0.10+ 0.03+ 0.03)/6
            return(Abs_Stuhl) 

# Eingabe der Flächen in m²:
Boden = 100
Decke = 100
Wand    = 180
Fenster = 80

WP = 18 # Weibliche Person
MP = 19 # Männliche Person

Stuhl = WP + MP

Abs_Fläche =  Abs_Materialen(4)+ Abs_Materialen(11) +Abs_Objekte(1) + Abs_Objekte(2)+ Abs_Objekte(3)
Abs_Fläche



#------------------------ popup -----------------------------------

def popupmsg(msg):
    popup= Tk()
    popup.wm_title("!")
    popup.iconbitmap("C:/Users/PC/Desktop/Icons/attention.ico")
    ttk.Label(popup, text=msg, font=NORM_FONT).pack(side="top", fill="x", pady=10)
    ttk.Button(popup, text="Okay", command = popup.destroy).pack()
    popup.mainloop()

# -----------------------------calculating -------------------------

def select(event):
    global z
    #a = int(mylistbox.get(tk.ANCHOR))
    a = mylistbox.get(ANCHOR)
    z = curselection(a) 
    selected_var.set(z)
    
def curselection(a):
    
    if a=="Musik":
        T_soll_A1 = 0.45*math.log10(V)+0.07                
        return (T_soll_A1)
                
    elif a=="Sprache":
        T_soll_A2 = 0.37*math.log10(V)-0.14             
        return (T_soll_A2)
                
    elif a=="Vortrag":
        T_soll_A3 = 0.32*math.log10(V)-0.17               
        return (T_soll_A3)
                
    elif a=="Spr.+Vor.":    
        T_soll_A4 = 0.26*math.log10(V)-0.14           
        return (T_soll_A4)
        
    elif a=="Sport":    
        T_soll_A5 = 0.75*math.log10(V)-1              
        return (T_soll_A5)
    
    
def calculate():
    global z
    if mylistbox.get(ACTIVE):
        Abs_Fl_ges = 0.163 * V / z # gemäß Sabinesche Formel:T_soll = (0163*V)/A_abs
        Absorber = Abs_Fl_ges - Abs_Fläche
        result_var.set(Absorber)  
    elif z == 0:
        messagebox.showinfo("No selection")
              
# GUI
# App window
app_win = Tk()
app_win.title(APP_TITLE) 
app_win.wm_geometry("%dx%d+%d+%d" % (APP_WIDTH, APP_HEIGHT, APP_XPOS, APP_YPOS))
 
# Main container embeded in the app window
# Container for all of the app widgets
main_frame = Frame(app_win)
main_frame.pack(expand=YES, fill=BOTH)
 
# Label to show your listbox selection
selected_var = StringVar()
Label(main_frame, textvariable=selected_var, font=('times', 12, 'bold')).pack(expand=YES)
selected_var.set("No selection")
 
# Label to show your calculated result
result_var = StringVar()
Label(main_frame, textvariable=result_var, font=('times', 12, 'bold')).pack(expand=YES)
result_var.set("No result")
 
# Container for the listbox & scrollbar (embeded in the main frame)
listbox_frame = Frame(main_frame)
listbox_frame.pack(expand=YES)
     
mylistbox = Listbox(listbox_frame, height=5, width=10, font=('times',18))
mylistbox.bind('<<ListboxSelect>>', select)
mylistbox.grid(row=0, column=0)
mylistbox.insert(END, *items_for_listbox)
  
scroll = Scrollbar(listbox_frame, orient=VERTICAL) # the allignment of the scrollbar
mylistbox["yscrollcommand"] = scroll.set # link the list with the scroll
scroll["command"] = mylistbox.yview # link the scroll with the scroll
scroll.grid(row=0, column=1, sticky=N+S) #sticky=N+S+E)
 
# Button to launch a calculation
button=Button(main_frame, text="Fläche der Absorber",
    command=calculate).pack(expand=YES)
    
app_win.mainloop()
You should split the GUI from code for calculation. Then you can test it better.
First comes the calculation:

Example:
class RoomSound:
    def __init__(self, length, width, height, area_window):
        self.length = length
        self.width = width
        self.height = height
        self.area_window = area_window

    @property
    def area(self):
        """
        Area in m²
        """
        return self.length * self.width

    @property
    def volume(self):
        """
        Volume in m³
        """
        return self.length * self.width * self.height

    @property
    def area_volume_ratio(self):
        return self.area / self.volume

    @property
    def area_room(self):
        """
        Area of room in m²
        """
        return 2 * self.length * self.height + 2 * self.height * self.width - self.area_window

    @property
    def reverberation(self):
        """
        Reverberation with sabine equation 
        """
        return 0.163 * self.area_volume_ratio


if __name__ == "__main__":
    length = 9.92  # Länge
    width = 10.5  # Breite
    height = 2.34  # Höhe
    A_f = 30.45  # Fensterfläche
    room1 = RoomSound(length, width, height, A_f)
    print(room1.area, room1.volume, room1.reverberation)
The parameters could expressed in dicts for example:
Instead of using indicies, you could use for example the name: "Stuhl"

objekte = {
    "Stuhl": 3.4533333333333336,
    "MP": 0.5916666666666667,
    "WP": 0.2833333333333334,
}

print(objekte["Stuhl"])
Or with the different sounds:
sounds = {
    "Musik": {"factor": 0.45, "offset": 0.07},
    "Sprache": {"factor": 0.37, "offset": -0.14},
    "Vortrag": {"factor": 0.32, "offset": -0.17},
    "Spr.+Vor.": {"factor": 0.26, "offset": -0.17},
    "Sport": {"factor": 0.75, "offset": -1},
}


def get_level(sound_type, V):
    sound = sounds[sound_type]
    return sound["factor"] * math.log10(V) + sound["offset"]


print(get_level("Musik", 20))
To get for example all type of sounds, use the keys:

print("Sounds:", list(sounds.keys()))
This would make the creation of the Listbox more dynamic.
Ok thanks!! Now I'll try your examples in the next days and I let you know whether it works or not :)