1
from tkinter import *

app=Tk()
app.title("progress")
app.geometry("800x500+365+120")

q={'weigh':100,'goal':75,'now':86} #or 'now':93

def bar():
    first=int(q['weigh'])
    achieve=int(q['goal'])
    today=int(q['now'])

    def num(n):
        for z in range(0,n):
            y=(first-achieve)*(z/100)
            if (first-today)==y:
                return z
            if today<achieve:
                z=100
                return z
    rate=int(num(101)/10)
    for _ in range(1,rate+1):
        Entry(app,bg="blue",width=4).pack(side=LEFT)
    for _ in range(rate,10):
        Entry(app,width=4).pack(side=LEFT)

Button(app,text="OK",command=bar).pack()
app.mainloop()
TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'

I make progress bar. But this does not work only when q['now'] is 86 or 93. Why does this Error occur and how can I solve it?

R_Dax
  • 706
  • 3
  • 10
  • 25
  • Is there the possibility of `num` not returning anything? If so your error might come from `num(101)/10`. Also please post the full error traceback – TheLizzard May 26 '21 at 11:03
  • What should be returned after the for loop inside `num()`? – acw1668 May 26 '21 at 11:04
  • @TheLizzard Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\KMS\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__ return self.func(*args) File "c:\Users\KMS\Desktop\aaaa.py", line 24, in bar rate=int(num(101)/10) TypeError: unsupported operand type(s) for /: 'NoneType' and 'int' – Kim minseong May 26 '21 at 15:06
  • @hyem_msg So it is as I guessed. `num(101)` doesn't return anything because the if statements aren't satisfied. So the function automatically returns `None` which you are trying to divide by `10`. That raises the error – TheLizzard May 26 '21 at 15:15
  • @TheLizzard all number except 86,93 works well. then I want to use 86 and 93, what should I do? – Kim minseong May 26 '21 at 15:38
  • @hyem_msg I have no idea how your program works but it seems to me like those if statements have broken logic. Try rewriting that part of your code. – TheLizzard May 26 '21 at 15:55
  • It is because you are comparing float number (`y`) and integer number (`first-today`). When I print the values when `z` is 56, I get `14.000000000000002` for `y` and `14` for `first-today`. Your code should expect they are equal, but the result is not. Use `y=round((first-achieve)*(z/100), 2)`. – acw1668 May 26 '21 at 15:56
  • @acw1668 WOW! Thanks to you, I solve this error! Thank you very much! Everything you do will be fine! – Kim minseong May 26 '21 at 16:29

1 Answers1

0

this is normal problem:

The normal function is returned None. so this mean in your for loop in num(n) function the if you made isn't true so the functions doesn't return z it's returned as normal function which is None. so if you want to check that append else and print out if the if statements doesn't true. like this :

    def num(n):
        for z in range(0,n):
            y=(first-achieve)*(z/100)
            if (first-today)==y:
                return z
            if today<achieve:
                z=100
                return z
            else:
                print('The if statements is not true so the function now returned None')

so if you want to return the z in all statements in else append return z so when you call the function every where and every time it's will return int do:

    def num(n):
        for z in range(0,n):
            y=(first-achieve)*(z/100)
            if (first-today)==y:
                return z
            if today<achieve:
                z=100
                return z
            else:
                return z 
                # if you want to give a message error to user do this:
                # from tkinter import messagebox
                # messagebox.showerror('Error', 'the function dosen't returned int')

the final code:

from tkinter import *
import tkinter

app=Tk()
app.title("progress")
app.geometry("800x500+365+120")

q={'weigh':100,'goal':75,'now':86} #or 'now':93

def bar():
    first=int(q['weigh'])
    achieve=int(q['goal'])
    today=int(q['now'])

    def num(n):
        for z in range(0,n):
            y=(first-achieve)*(z/100)
            if (first-today)==y:
                return z
            if today<achieve:
                z=100
                return z
            else:
                return z 
                # if you want to give a message error to user do this:
                # from tkinter import messagebox
                # messagebox.showerror('Error', 'the function dosen't returned int')
                
    print(num(101))
    rate=int(num(101)/10)
    for _ in range(1,rate+1):
        Entry(app,bg="blue",width=4).pack(side=LEFT)
    for _ in range(rate,10):
        Entry(app,width=4).pack(side=LEFT)

Button(app,text="OK",command=bar).pack()
app.mainloop()

Hope this works.

Shihab
  • 94
  • 10