0

enter image description here

I cannot able to solve the proper percentage function to properly work on my calculator. Please help.

this kind of error I get each time I run the percentage button

File "f:\Visial Studio\Calculator.py", line 53, in <lambda>
Button(root,text="%", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show(percentage)).place(x=290,y=100)
File "f:\Visial Studio\Calculator.py", line 19, in show
equation+=value
TypeError: can only concatenate str (not "function") to str
PS F:\Visial Studio> & 
C:/Users/*******/AppData/Local/Microsoft/WindowsApps/python3.10.exe "f:/Visial 
Studio/Calculator.py"
File "f:\Visial Studio\Calculator.py", line 28
equation=(value*value)/100))   #(a*b)/100

#===========Code===============================

import tkinter
from tkinter import *
from unittest import result
import math

root=Tk() 
root.title("Basic Calculator") 
root.geometry("570x600+100+200") 
root. resizable(False,False) 
root.configure(bg="#17161b")

#===========Formula===============================

equation=""

def show(value):
    global equation
    equation+=value
    label_result.config(text=equation)

def clear():
    global equation
    equation=""
    label_result.config(text=equation)

this is the place where I found the issues

def percentage():
    global equation
    equation=(value*value)/100))   #(a*b)/100

def calculate():
    global equation
    result=""
    if equation !="":
        try:
            result=eval(equation) 
        except:
            result="error"
            equation=""
        label_result.config(text=result)

#==========Label======================================================

label_result= Label(root,width=25,height=2,text="",font=("arial",30)) 
label_result.pack() 

#==========Buttons======================================================

Button(root,text="C", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#3697f5",command=lambda: clear()).place(x=10,y=100) 
Button(root,text="/", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("/")).place(x=150,y=100) 
Button(root,text="%", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show(percentage)).place(x=290,y=100) 
Button(root,text="x", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("*")).place(x=430,y=100)

Button(root,text="7", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("7")).place(x=10,y=200) 
Button(root,text="8", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("8")).place(x=150,y=200) 
Button(root,text="9", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("9")).place(x=290,y=200) 
Button(root,text="-", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("-")).place(x=430,y=200)

Button(root,text="4", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("4")).place(x=10,y=300) 
Button(root,text="5", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("5")).place(x=150,y=300) 
Button(root,text="6", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("6")).place(x=290,y=300) 
Button(root,text="+", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("+")).place(x=430,y=300)

Button(root,text="1", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("1")).place(x=10,y=400) 
Button(root,text="2", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("2")).place(x=150,y=400) 
Button(root,text="3", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("3")).place(x=290,y=400) 
Button(root,text="0", width=11, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show("0")).place(x=10,y=500)

Button(root,text=".", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show(".")).place(x=290,y=500) 
Button(root,text="=", width=5, height=3, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#fe9037",command=lambda: calculate()).place(x=430,y=400) 


root.mainloop()
  • 1
    hi ahmed, welcome to stackoverflow. dont be discouraged, you can see on you error log says `line 19, in show equation+=value TypeError: can only concatenate str (not "function") to str`. do notice that your `equation` value is a string (empty string) while on your button you have `show(percentage)` of which in this case the percentage is a function passed as is and have no return value. perhaps you need to rethink the flow of your calculator. there are too many items to fix. – Bagus Tesa Mar 01 '22 at 07:24
  • Welcome ahmed! As you are new to Stack Overflow, it might be helpful for you to read [how-to-ask](https://stackoverflow.com/help/how-to-ask), it will help you make sure you can provide all and only the necessary details required to solve the question. Thanks! :) – typedecker Mar 01 '22 at 08:34

1 Answers1

0

The problem is in this line of your code -:

Button(root,text="%", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show(percentage)).place(x=290,y=100)

The show function you call, concatenates the given argument to the string named equation. But, if the given argument is not a string, then the concatenation is not possible.

In this line the argument passed, is a function, i.e. the percentage function you previously defined, it thus, is not able to concatenate a function with a string, so it throws an error indicating that.

TypeError: can only concatenate str (not "function") to str

If what is intended, is to append the value returned by the percentage function, than all you have to do is call the percentage function using another set of round brackets and then convert the return value to a string using the str function and pass it into show like so -:

Button(root,text="%", width=5, height=1, font=("arial",30,"bold"), 
bd=1,fg="#fff",bg="#2a2d36",command=lambda: show(str(percentage()))).place(x=290,y=100)

But, also note that it seems like the percentage function is not properly designed, as it is changing the value of the global variable equation to integer(int) type instead. While, for all other functions the value of equation is a string, which it technically is supposed to be, as you are using the value of equation as the label text.


EDIT: Also as mentioned by @acw1668, there were two extra round brackets at the end of the line that sets the value of the variable equation, that would have thrown an error, removing it is also part of redesigning the percentage function.


Redesigning the percentage function further to account for the above changes like so -:

def percentage():
    global equation
    return (value*value)/100   #(a*b)/100 #RETURN THE INT VALUE INSTEAD TO BE CONVERTED INTO STRING IN THE LAMBDA CALL FROM ABOVE.

should fix the problem.


NOTE: Also note, it seems like many of your functions may need redesigning similar to percentage function, as you are updating the value of equation string in the show function as well as in all the other functions you are calling(atleast those provided in the OP).

Also, I would suggest having a look at this, which is a better way to define widgets, than to place them in the same line where the constructor is called, eventhough here no reference is being saved of the object, but the current way of dealing with widgets can lead to an Attribute Error in some cases.

Further, dealing with global variables can sometimes be a little tricky, and/or might not give the results as required, so it is suggested to put such functions that relate to each other within a class and make use of a class's inner attributes using self. It would also allow you to make multiple instances of the same class, which would not work with normally defined functions that modify global variables.

typedecker
  • 1,351
  • 2
  • 13
  • 25
  • 1
    Do you notice that there are extra `))` at the line `return (value*value)/100))`? Also `value` is undefined in OP code. – acw1668 Mar 01 '22 at 08:46
  • Yes, thanks I did not notice it before :), I edited it to include the information. – typedecker Mar 01 '22 at 08:49