questions about Exceptions?

S

skanemupp

is there a general philosophy as to when to use exceptions and when
not to?

like here:
def Calc():
global nbr
try:
print eval(nbr)
except:
print "Not computable"
nbr = ""

i have a calculator and nbr is a string that contains '0123456789+-*/'

if the string ends on +-*/ it will throw an exception(unexpected EOF).

i could easily prevent the exceptions here with an if-statement, is
that preferrable and why?


also when u throw exceptions should u catch the speicfic one? i guess
only if u want it to do soemthing special since catching only only
one exception logicall would abort the program if another one is
thrown?
 
C

cokofreedom

In general you should only catch the exceptions you want to catch,
therefore avoiding the issue of catching "unexpected" ones, for
instances the programming unexpectandly closing.

Well, exception handling is expensive (when it catches one) so it
really is up to you. If you are using eval and know it might "EOF"
then you should probably look to handle that. The main IF statement
style I can think of (checking the end of the string) wouldn't be much
of an improvement.

Currently I would be very worried about seeing that code as it breaks
a number of "conventions". However it depends on the importance of the
code to wherever or not you should change this. (Global variable, the
use of Eval, the CATCH ALL except and the setting of a global variable
at the end.)

I've seen a good few (simple and advanced) calculator examples using
python on the NET, it might be worth looking at some to see their
style of coding a calculator to help your own.
 
S

skanemupp

In general you should only catch the exceptions you want to catch,
therefore avoiding the issue of catching "unexpected" ones, for
instances the programming unexpectandly closing.

Well, exception handling is expensive (when it catches one) so it
really is up to you. If you are using eval and know it might "EOF"
then you should probably look to handle that. The main IF statement
style I can think of (checking the end of the string) wouldn't be much
of an improvement.

Currently I would be very worried about seeing that code as it breaks
a number of "conventions". However it depends on the importance of the
code to wherever or not you should change this. (Global variable, the
use of Eval, the CATCH ALL except and the setting of a global variable
at the end.)

I've seen a good few (simple and advanced) calculator examples using
python on the NET, it might be worth looking at some to see their
style of coding a calculator to help your own.


i know about the GLOBAL stuff, i might rewrite the program using
classes later so i can avoid this. i am mainly playin with tkinter for
now.

i was thinking the same check with if at the beginning and end of the
string so there isnt a */ but also if someone uses /// or soemthing
like that in the middle it crashes so it is hard to cover every case,
esp since **5 means ^5.
is the use of if also expensive?
 
S

skanemupp

here is the whole code:

from __future__ import division
import Tkinter
from Tkinter import *

mygui = Tkinter.Tk()
mygui.title("Calculator")

w = Label(mygui, text="Answer: ")
w.place(relx=0.15, rely=0.1, anchor=CENTER)

nbr = ""

def Disp(nstr):
global nbr
nbr=nbr+nstr
print "You need to seek help!",nbr

def Calc():
global nbr
try:
print eval(nbr)
#a = Label(mygui, text=eval(nbr))
#a.place(relx=0.4, rely=0.1, anchor=CENTER)
except:
print "Not computable"
nbr = ""

def Erase():
global nbr
nbr = ""


b = Button(mygui, text="1",command=lambda n='1':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.2, anchor=CENTER)
b = Button(mygui, text="2",command=lambda n='2':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.2, anchor=CENTER)
b = Button(mygui, text="3",command=lambda n='3':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.2, anchor=CENTER)
b = Button(mygui, text="+",command=lambda n='+':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.2, anchor=CENTER)
b = Button(mygui, text="4",command=lambda n='4':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.3, anchor=CENTER)
b = Button(mygui, text="5",command=lambda n='5':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.3, anchor=CENTER)
b = Button(mygui, text="6",command=lambda n='6':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.3, anchor=CENTER)
b = Button(mygui, text="-",command=lambda n='-':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.3, anchor=CENTER)
b = Button(mygui, text="7",command=lambda n='7':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.4, anchor=CENTER)
b = Button(mygui, text="8",command=lambda n='8':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.4, anchor=CENTER)
b = Button(mygui, text="9",command=lambda n='9':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.4, anchor=CENTER)
b = Button(mygui, text="*",command=lambda n='*':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.4, anchor=CENTER)
b = Button(mygui, text="0",command=lambda n='0':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.5, anchor=CENTER)
b = Button(mygui, text="C",command=Erase, width=2, height=1)
b.place(relx=0.2, rely=0.5, anchor=CENTER)
b = Button(mygui, text="^.5",command=lambda n='**.5':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.5, anchor=CENTER)
b = Button(mygui, text="/",command=lambda n='/':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.5, anchor=CENTER)
b = Button(mygui, text="=",command=Calc, width=2, height=1)
b.place(relx=0.2, rely=0.7, anchor=CENTER)

mygui.mainloop()
 
C

cokofreedom

def Calc():
global nbr
try:
print eval(nbr)
#a = Label(mygui, text=eval(nbr))
#a.place(relx=0.4, rely=0.1, anchor=CENTER)
except:
print "Not computable"
nbr = ""

def Erase():
global nbr
nbr = ""

Seems to me you could be better off passing a parameter and a return
statement of None (or your parameter cleaned) for those functions,
which should work. Given an input, Eval it and then return None. That
way you wouldn't need the Erase...
 
S

skanemupp

Seems to me you could be better off passing a parameter and a return
statement of None (or your parameter cleaned) for those functions,
which should work. Given an input, Eval it and then return None. That
way you wouldn't need the Erase...

the erase() id alwys need if u wanna abort whilst u wrote something.
 
C

cokofreedom

the erase() id alwys need if u wanna abort whilst u wrote something.

But if it is meant to only evaluate once you've pressed the enter key
(I take it?) you shouldn't need that. And if you are to abort while
evaluating it will not do that.
 
S

skanemupp

But if it is meant to only evaluate once you've pressed the enter key
(I take it?) you shouldn't need that. And if you are to abort while
evaluating it will not do that.


CHANGED IT NOW TO A MUCH BETTER SOLUTION(will see if i can make a
better solution with the buttons, hate big blocks of similarlooking
code):


from __future__ import division
import Tkinter
from Tkinter import *

mygui = Tkinter.Tk()
mygui.title("Calculator")

l = Label(mygui, text="Answer: ")
l.place(relx=0.15, rely=0.2, anchor=CENTER)

e = Entry(mygui)
e.place(relx=0.4, rely=0.1, anchor=CENTER)

def Disp(nstr):
e.insert(END, nstr)

def Calc():
expr=e.get()
try:
b = Label(mygui, text=eval(expr))
b.place(relx=0.4, rely=0.2, anchor=CENTER)
except:
b = Label(mygui, text="Not computable")
b.place(relx=0.4, rely=0.2, anchor=CENTER)

def Erase():
e.delete(0,END)

b = Button(mygui, text="1",command=lambda n='1':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.4, anchor=CENTER)
b = Button(mygui, text="2",command=lambda n='2':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.4, anchor=CENTER)
b = Button(mygui, text="3",command=lambda n='3':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.4, anchor=CENTER)
b = Button(mygui, text="+",command=lambda n='+':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.4, anchor=CENTER)
b = Button(mygui, text="4",command=lambda n='4':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.5, anchor=CENTER)
b = Button(mygui, text="5",command=lambda n='5':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.5, anchor=CENTER)
b = Button(mygui, text="6",command=lambda n='6':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.5, anchor=CENTER)
b = Button(mygui, text="-",command=lambda n='-':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.5, anchor=CENTER)
b = Button(mygui, text="7",command=lambda n='7':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.6, anchor=CENTER)
b = Button(mygui, text="8",command=lambda n='8':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.6, anchor=CENTER)
b = Button(mygui, text="9",command=lambda n='9':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.6, anchor=CENTER)
b = Button(mygui, text="*",command=lambda n='*':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.6, anchor=CENTER)
b = Button(mygui, text="0",command=lambda n='0':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.7, anchor=CENTER)
b = Button(mygui, text="C",command=Erase, width=2, height=1)
b.place(relx=0.2, rely=0.7, anchor=CENTER)
b = Button(mygui, text="^",command=lambda n='**':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.7, anchor=CENTER)
b = Button(mygui, text="/",command=lambda n='/':Disp(n), width=2,
height=1)
b.place(relx=0.4, rely=0.7, anchor=CENTER)
b = Button(mygui, text=".",command=lambda n='.':Disp(n), width=2,
height=1)
b.place(relx=0.1, rely=0.8, anchor=CENTER)
b = Button(mygui, text="(",command=lambda n='(':Disp(n), width=2,
height=1)
b.place(relx=0.2, rely=0.8, anchor=CENTER)
b = Button(mygui, text=")",command=lambda n=')':Disp(n), width=2,
height=1)
b.place(relx=0.3, rely=0.8, anchor=CENTER)
b = Button(mygui, text="=",command=Calc, width=2, height=1)
b.place(relx=0.4, rely=0.8, anchor=CENTER)

mygui.mainloop()
 
S

skanemupp

from __future__ import division
import Tkinter
from Tkinter import *

mygui = Tkinter.Tk()
mygui.title("Calculator")

l = Label(mygui, text="Answer: ")
l.place(relx=0.15, rely=0.2, anchor=CENTER)

e = Entry(mygui)
e.place(relx=0.4, rely=0.1, anchor=CENTER)

def Disp(nstr):
e.insert(END, nstr)

def Calc():
expr=e.get()
try:
b = Label(mygui, text=eval(expr))
b.place(relx=0.4, rely=0.2, anchor=CENTER)
except:
b = Label(mygui, text="Not computable")
b.place(relx=0.4, rely=0.2, anchor=CENTER)

def Erase():
e.delete(0,END)


x = 0.1
y = 0.4
for char in '123+456-789*0^./()':
b = Button(mygui, text=char,command=lambda n=char:Disp(n),
width=2, height=1)
b.place(relx=x, rely=y, anchor=CENTER)
x=x+0.1
if x==0.5:
x=0.1
y=y+0.1

b = Button(mygui, text="C",command=Erase, width=2, height=1)
b.place(relx=0.3, rely=0.8, anchor=CENTER)
b = Button(mygui, text="=",command=Calc, width=2, height=1)
b.place(relx=0.4, rely=0.8, anchor=CENTER)

mygui.mainloop()
 
S

skanemupp

Seems to me you could be better off passing a parameter and a return
statement of None (or your parameter cleaned) for those functions,
which should work. Given an input, Eval it and then return None. That
way you wouldn't need the Erase...

i never really got what u meant by this?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top