when using 'raise' for a user defined exception, it does not work under the 'try' - exception

need your kind help!
I have defined a new Exception called 'UnderAge' (just checking if a person is under an age limit).
The strange thing is that when i use 'raise UnderAge as e....' it does not work under the 'try' segment.
only the exception is working.
Here is the code :
class UnderAge(Exception):
def __init__(self, name, age):
self._name = name
self._age = age
def __str__(self):
return "the age %s is under 18 yo" % self._age
def get_age(self):
return self._age
def send_invitation(name, age):
try:
if int(age) < 18:
raise UnderAge(name, age)
else:
print("You should send an invitation to " + name)
except UnderAge as e:
print("Age must be above 18 but now age is %s." % e.get_age())
def main():
send_invitation("miri", 16)
if __name__ == "__main__":
main()
-----When running it i only get :
C:\Python\Python38-32\python.exe "C:/Users/mikie/Documents/Pyton Programs/Next.py Course/Targil_3.3.2a.py"
Age must be above 18 but now age is 16.
Process finished with exit code 0
----- i should see also an output indicating the UnderAge and its relevant str which i have changed.
Please help me guys:-)
thanks,
Mike

false alarm - this is a normal behaviour of the raise.
It should pop the customized exception only if there is no exception defined in the code after the 'try'.
Also, the string which overrides the__str__ can be called by e.str.

Related

Calling Private Methods Recursively

I am writing a code that has a class Fraction with attributes Numerator and Denominator. The Output should display the fraction in a simplified form. For e.g. 20/100 should be display as 1/5.
I have tried the below code but getting a Type Error as below:
TypeError: unsupported operand type(s) for /: 'int' and 'NoneType'
class fraction:
def get_data(self):
self.__num=int(input("Enter the Nr:"))
self.__deno=int(input("Enter the Dr:"))
if (self.__deno==0):
print("Fraction not possible")
exit()
def display_data(self):
self.__simplify()
print(self.__num,"/",self.__deno)
def __simplify(self):
print("The simplified fraction is")
common_divisor=self.__GCD(self.__num,self.__deno)
self.__num=(self.__num)/(common_divisor)
self.__deno=(self.__deno)/(common_divisor)
def __GCD(self,a,b):
if (b==0):
return a
else:
self.__GCD(b,a%b)
f=fraction()
f.get_data()
f.display_data()
I have no clue how to solve this Error. Please help me as i am new to Python and want to build strong basics.
The problem is in this function definition:
def __GCD(self,a,b):
if (b==0):
return a
else:
self.__GCD(b,a%b)
There's no return statement on the else clause. (Also, the else clause can be implicit instead of explicit.) Instead try:
def __GCD(self, a, b):
if b == 0:
return a
return self.__GCD(b, a % b)

how can i make the input work with my parameters?

I have started a python class and my book does not seem to help me.
My professor has a program that bombards my code with different inputs and if any of the inputs do not work then my code is "wrong". I have done many days worth of editing and am at a complete loss. I have the code working if someone puts and input of an actual number. But where my code fails the test is if input is "miles_to_laps(26)" it errors out.
I have tried changing the input to int(input()) but that does not fix the issue. I've gone through changing variables and even changing the input method but still am at a loss. I have already tried contacting my teacher but 6 days of no response and 3 days of being late i feel like I'm just going no where.
user_miles = int(input())
def miles_to_laps(user_miles):
x = user_miles
y = 4
x2 = x * y
result = print('%0.2f' % float(x2))
return result
miles_to_laps(user_miles)
my code works for real number inputs but my professor is wanting inputs like
miles_to_laps(26) and miles_to_laps(13) to create the same outputs.
For the wierd input functionality you can try:
import re
def parse_function_text(s):
try:
return re.search("miles_to_laps\((.+)\)", s)[1]
except TypeError:
return None
def accept_input(user_input):
desugar = parse_function_text(user_input)
if desugar is not None:
user_input = desugar
try:
return float(user_input)
except ValueError:
raise ValueError("Cannot process input %s" % user_input)
assert accept_input("miles_to_laps(3.5)") == 3.5
I'm trying to keep all the pedantism aside, but what kind of CS/programming teaching is that?
Areas of concern:
separate user input from rest of code
separate output formatting from function output
the code inside miles_to_laps is excessive
Now here is the code to try:
LAPS_PER_MILE = 4
# the only calculation, "pure" function
def miles_to_laps(miles):
return LAPS_PER_MILE * miles
# sorting out valid vs invalid input, "interface"
def accept_input(user_input):
try:
return float(user_input)
except ValueError:
raise ValueError("Cannot process input %s" % user_input)
if __name__ == "__main__":
# running the program
laps = miles_to_laps(accept_input(input()))
print ('%0.2f' % laps)
Hope this is not too overwhelming.
Update: second attempt
MILE = 1609.34 # meters per mile
LAP = 400 # track lap
LAPS_PER_MILE = MILE/LAP
def miles_to_laps(miles):
return LAPS_PER_MILE * miles
def laps_coerced(laps):
return '%0.2f' % laps
def accept_input(user_input):
try:
return float(user_input)
except ValueError:
raise ValueError("Cannot process input %s" % user_input)
def main(user_input_str):
miles = accept_input(user_input_str)
laps = miles_to_laps(miles)
print (laps_coerced(laps))
if __name__ == "__main__":
main(input())

How to skip one condition if that is not needed in Python 3.7?

I have written a code using if, try/except clause. I want to use "try" to check whether the parameters are correct and if those are correct the "print" function will run.
If the parameters are not right then the error message will be printed and the print section will not run.
The problem is when I am correct input it is running but when I am giving wrong input, after printing the error message I am getting NameError, saying "room1" is not defined. I understood why it is happening but I am confused how to get the correct output without getting an error.
My code is:
class Hotel:
def __init__(self,room,catagory):
if type(room) != int:
raise TypeError()
if type(catagory) != str:
raise TypeError()
self.room = room
self.catagory = catagory
self.catagories = {"A":"Elite","B":"Economy","C":"Regular"}
self.rooms = ["0","1","2","3","4","5"]
def getRoom(self):
return self.room
def getCatagory(self):
return self.catagories.get(self.catagory)
def __str__(self):
return "%s and %s"%(self.rooms[self.room],self.catagories.get(self.catagory))
try:
room1 = Hotel(a,"A")
except:
print("there's an error")
print (room1)
Your print should be in the try segment of your code as it will always execute whether there is an error or not.
class Hotel:
def __init__(self,room,catagory):
if type(room) != int:
raise TypeError()
if type(catagory) != str:
raise TypeError()
self.room = room
self.catagory = catagory
self.catagories = {"A":"Elite","B":"Economy","C":"Regular"}
self.rooms = ["0","1","2","3","4","5"]
def getRoom(self):
return self.room
def getCatagory(self):
return self.catagories.get(self.catagory)
def __str__(self):
return "%s and %s"%(self.rooms[self.room],self.catagories.get(self.catagory))
Initialization
try:
room1 = Hotel(a,"A")
print (room1)
except:
print("there's an error")

binary output for python def function

New:
I am now working on a calculator for the terminal. I'm having the same error as before. but this time its telling me this: <function div at 0x7faf88c9e488>
code is at : https://github.com/mishiki1002/Solo-Calculater/blob/master/Solo-Main.py
Solved:
I have been programming in python for Year and a half. I have played around with the def function and variables. My current programming project is a RPG Fantasy type game. I am currently still at the begging and i am wondering what kind of output this is and why i am getting it. I believe it is some kind of binary bit.
<function showInstructions at 0x7fa8933162f0>
when i compile my code through my terminal using python main.py that is what i get. This is my full source code for the game. Please leave any comments and or suggestions for my programming. Also please tell me if my code is sloppy. I try and document all i can so its easier for me and programmers around me to read it.
Sincerely Josh
!/usr/bin/python3
#We will import this so that we have a random in counter chance for the game.
#this will all so prove use full when we have attacks sequences and Loot drops
from random import randint
class Character:
def __init__(self):
#This is the name that you have made for your character
self.name = ' '
#Amount of health for you character
self.health = 100
#Max amount of health for your character
self.health_max = 9999
#Damage class to define the attack methods needed to Battle?
def do_damage(self, enemy):
#Defining a varible called damage. Stating that the minimum damage can be 0. And No less than that, for either
damage = min(
# Stating that the minimum damage can be 0. And No less than that, for either character
max(radint(0, self.health)) - randint(0, enemy.health), 0), (enemy.health)
#Actual Damage System
enemy.health = enemy.health - damage
#Printing the product to the user/gamer
if damamge ==0: "%s evades %s's attack." % (enemy.name , self.name)
#If you land a hit
else: print("%s hurts %s!" % (self.name, enemy.name))
#printing your enemys health so you know how much left un-till 0
return enemy.health <= 0
class Enemy(Character):
def __init__(self, player):
#Since we declared that the enemy is a character it takes a characters paramaters
Character.__init__(self)
#It needs a name Like a Goblin
self.name = 'a Goblin'
#And it needs health
self.health = randint(1, 15 + player.health)
class Player(Character):
#Now we are delcaring a Side characters role
def __init__(self, player):
Character.__init__(self)
#when you check out the menu to see how your characters are doing you will see a meesage saying Normal and
#the amount of health they have
self.state = 'Normal'
#Now we set their health
self.health = 100
#Max Health
self.health_max = 9999
#Start Menu will be here
def showInstructions():
print("Sound_Soul")
print("----------")
print("Commmands:")
print(" 'go [direction]'")
print("The Cardinal Directions:")
print(" north")
print(" east")
print(" south")
print(" west")
print (showInstructions)
You are getting that because you are using only function name showInstructions instead of a call to the function like so showInstructions().
Edit:
One more thing: you don't need to also use print when calling your function as you already have print statements within your function. This causes "None" to be printed below your intended text because the function indeed return None by default.

trap exceptions comprehensively in Jython

This is my attempt so far to trap all exceptions in Jython code. The most difficult thing, I find, is trapping exceptions when you override a method from a Java class: with the "vigil" decorator below (which also tests whether the EDT/Event Despatch Thread status is correct) you can find out the first line where the code is thrown... so you can identify the method itself. But not the line.
Furthermore, tracing stack frames back through Python and Java stacks is completely beyond me. Obviously there seem to be these layers and layers of "proxy" classes, a no doubt inevitable part of Jython mechanics. It'd be great if someone much cleverer than me were to take an interest in this question!
NB this is an example of how to use the "vigil" decorator:
class ColumnCellRenderer( javax.swing.table.DefaultTableCellRenderer ):
#vigil( True ) # means a check is done that the thread is the EDT, as well as intercepting Python Exceptions and Java Throwables...
def getTableCellRendererComponent( self, table, value, isSelected, hasFocus, row, column):
super_comp = self.super__getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column)
super_comp.foreground = java.awt.Color.black
super_comp.font = main_frame_self.m_plain_font
...
... and these are three functions I use in an attempt to trap stuff...
def custom_hook(type_of_e, e, tb ):
"""
Method to catch Python-style BaseExceptions, using the command sys.excepthook = custom_hook.
The first thing this method needs to do in Jython is to determine whether this is a Java
java.lang.Throwable or not. If it is this JThrowable
must be handled by the code which caters for B{uncaught Java Throwables}.
"""
try:
if 'tb' not in locals():
tb = None
logger.error("Python custom_hook called...\ntype of e: %s\ne: %s\ntb: %s" % ( unicode( type_of_e ), unicode( e ),
unicode( tb ) ))
msg = ''.join( traceback.format_exception(type_of_e, e, tb ))
logger.error( "traceback:\n" + msg )
except BaseException, e:
logger.error( "exception in Python custom_hook!:\n%s" % e )
raise e
sys.excepthook = custom_hook
class JavaUncaughtExceptHandler( java.lang.Thread.UncaughtExceptionHandler ):
"""
java.lang.Class to catch any Java Throwables thrown by the app.
"""
def uncaughtException( self, thread, throwable ):
try:
'''
NB getting the Java stack trace like this seems to produce a very different trace
from throwable.printStackTrace()... why?
'''
# we want a single log message
exception_msg = "\n*** uncaught Java Exception being logged in %s:\n" % __file__
baos = java.io.ByteArrayOutputStream()
ps = java.io.PrintStream(baos)
throwable.printStackTrace( ps )
# remove multiple lines from Java stack trace message
java_stack_trace_lines = unicode( baos.toString( "ISO-8859-1" )).splitlines()
java_stack_trace_lines = filter( None, java_stack_trace_lines )
normalised_java_stack_trace = '\n'.join( java_stack_trace_lines )
exception_msg += normalised_java_stack_trace + '\n'
python_traceback_string = traceback.format_exc()
exception_msg += "Python traceback:\n%s" % python_traceback_string
logger.error( exception_msg )
except (BaseException, java.lang.Throwable ), e:
logger.error( "*** exception in Java exception handler:\ntype %s\n%s" % ( type( e ), unicode( e ) ) )
raise e
# NB printStackTrace causes the custom_hook to be invoked... (but doesn't print anything)
java.lang.Thread.setDefaultUncaughtExceptionHandler( JavaUncaughtExceptHandler() )
def vigil( *args ):
"""
Decorator with two functions.
1. to check that a method is being run in the EDT or a non-EDT thread;
2. to catch any Java Throwables which otherwise would not be properly caught and documented: in particular,
with normal Java error-trapping in Jython it seems impossible to determine the line number at which an
Exception was thrown. This at least records the line at which a Java java.lang.Throwable
was thrown.
"""
if len( args ) != 1:
raise Exception( "vigil: wrong number of args (should be 1, value: None/True/False): %s" % str( args ))
req_edt = args[ 0 ]
if req_edt and type( req_edt ) is not bool:
raise Exception( "vigil: edt_status is wrong type: %s, type %s" % ( req_edt, type( req_edt )) )
def real_decorator( function ):
if not hasattr( function, '__call__' ):
raise Exception( "vigil: function %s does not have __call__ attr, type %s"
% ( function, type( function )) )
# NB info about decorator location can't be got when wrapper called, so record it at this point
penultimate_frame = traceback.extract_stack()[ -2 ]
decorator_file = penultimate_frame[ 0 ]
decorator_line_no = penultimate_frame[ 1 ]
def wrapper( *args, **kvargs ):
try:
# TODO is it possible to get the Python and/or Java stack trace at this point?
if req_edt and javax.swing.SwingUtilities.isEventDispatchThread() != req_edt:
logger.error( "*** vigil: wrong EDT value, should be %s\nfile %s, line no %s, function: %s\n" %
( "EDT" if req_edt else "non-EDT", decorator_file, decorator_line_no, function ))
return function( *args, **kvargs )
except ( BaseException, java.lang.Throwable ), e:
''' NB All sorts of problems if a vigil-protected function throws an exception:
1) just raising e means you get a very short stack trace...
2) if you list the stack trace elements here you get a line (seemingly inside the function where the
exception occurred) but often the wrong line!
3) Python/Java stack frames: how the hell does it all work???
4) want a single error message to be logged
'''
msg = "*** exception %s caught by vigil in file %s\nin function starting line %d" % ( e, decorator_file, decorator_line_no )
logger.error( msg )
frame = inspect.currentframe()
# the following doesn't seem to work... why not?
python_stack_trace = traceback.format_stack(frame)
python_stack_string = "Python stack trace:\n"
for el in python_stack_trace[ : -1 ]:
python_stack_string += el
logger.error( python_stack_string )
if isinstance( e, java.lang.Throwable ):
# NB problems with this stack trace: although it appears to show the
# correct Java calling pathway, it seems that the line number of every file and method
# is always shown as being the last line, wherever the exception was actually raised.
# Possibly try and get hold of the actual Pyxxx objects ... (?)
java_stack_trace = e.stackTrace
java_stack_string = "Java stack trace:\n"
for el in java_stack_trace:
java_stack_string += " %s\n" % unicode( el )
logger.error( java_stack_string )
raise e
return wrapper
return real_decorator
PS it is of course possible to top-and-tail every overridden Java method with try ... except... but where's the fun in that? Seriously, even doing that I'm unable to find the line at which the exception is thrown...
Here's an example of a decorator used in the socket module in Jython to map Java exceptions to Python exceptions. I didn't read your vigil decorator too closely since it's doing a lot of work, but I'm putting it here in case it might help:
def raises_java_exception(method_or_function):
"""Maps java socket exceptions to the equivalent python exception.
Also sets _last_error on socket objects so as to support SO_ERROR.
"""
#wraps(method_or_function)
def handle_exception(*args, **kwargs):
is_socket = len(args) > 0 and isinstance(args[0], _realsocket)
try:
try:
return method_or_function(*args, **kwargs)
except java.lang.Exception, jlx:
raise _map_exception(jlx)
except error, e:
if is_socket:
args[0]._last_error = e[0]
raise
else:
if is_socket:
args[0]._last_error = 0
return handle_exception
Mostly what we are seeing here is that we are dispatching on whether it is a Java exception (java.lang.Exception) or not. I suppose this could be generalized to java.lang.Throwable, although it's unclear what can be done in the case of java.lang.Error in any event. Certainly nothing corresponding to socket errors!
The above decorator in turn uses the _map_exception function to unwrap the Java exception. It's quite application specific here as you can see:
def _map_exception(java_exception):
if isinstance(java_exception, NettyChannelException):
java_exception = java_exception.cause # unwrap
if isinstance(java_exception, SSLException) or isinstance(java_exception, CertificateException):
cause = java_exception.cause
if cause:
msg = "%s (%s)" % (java_exception.message, cause)
else:
msg = java_exception.message
py_exception = SSLError(SSL_ERROR_SSL, msg)
else:
mapped_exception = _exception_map.get(java_exception.__class__)
if mapped_exception:
py_exception = mapped_exception(java_exception)
else:
py_exception = error(-1, 'Unmapped exception: %s' % java_exception)
py_exception.java_exception = java_exception
return _add_exception_attrs(py_exception)
There is some clunkiness in the code, and I'm sure room for improvement, but overall it certainly makes any decorated code much easier to follow. Example:
#raises_java_exception
def gethostname():
return str(InetAddress.getLocalHost().getHostName())
Jim Baker's answer is interesting... but what I wanted is sthg comprehensive which documents the maximum possible amount of stack trace info when an exception of any kind is raised. CPython not being multi-thread, its stack trace doesn't have to cope with Runnables. I'm not enough of a Jython/Python expert to know whether you can always get the whole stack in "pure Python" code (i.e. no use of Java classes).
But one of the things I wanted to get was the activity which had led up to the running of a Runnable in Jython. And the activity which had led up to the Runnable having run that Runnable, etc., right back to the very first thread. My solution below, taking inspiration from Jim's answer but also from doublep's comment, creates a new Jython class, TraceableRunnable, which will store the list of stack traces on creation.
When an exception, either Java or Python style, is raised, this logs everything right back to the start of the run (if you systematically use TraceableRunnable instead of Runnable).
Each run() code of a TraceableRunner subclass also has to do this call at some point:
self.record_thread()
... hopefully this is not too irksome an imposition...
(NB in a truly "grown up" implementation you'd want to check that this call had been made... I'm sure that this could be done by some suitably sophisticated Pythonic technique, failing which by unit testing or something. Also you might want to require a call at the very end of the run() code to delete this dictionary entry...)
This is the catching and logging code:
class TraceableRunnable( java.lang.Runnable ):
thread_to_tr_dic = {}
def __init__( self ):
# no need to call super's __init__: Runnable is a Java *interface*
caller_thread = java.lang.Thread.currentThread()
self.frame_stack_list = []
if hasattr( caller_thread, 'frame_stack_list' ):
self.frame_stack_list = copy.deepcopy( caller_thread.frame_stack_list )
self.frame_stack_list.append( traceback.extract_stack() )
def record_thread( self ):
TraceableRunnable.thread_to_tr_dic[ java.lang.Thread.currentThread() ] = self
class EDTException( Exception ):
pass
def vigil( *args ):
"""
Decorator with two functions.
1. to check that a method is being run in the EDT or a non-EDT thread
2. to catch any exceptions
"""
if len( args ) != 1:
raise Exception( "vigil: wrong number of args (should be 1, value: None/True/False): %s" % str( args ))
req_edt = args[ 0 ]
if req_edt and type( req_edt ) is not bool:
raise Exception( "vigil: edt_status is wrong type: %s, type %s" % ( req_edt, type( req_edt )) )
def process_exception( exc, python = True ):
tb_obj = sys.exc_info()[ 2 ]
msg = "Exception thrown message %s\nfamily %s, type: %s\n" % ( str( exc ), "Python" if python else "Java", type( exc ))
msg += "traceback object part:\n"
ex_tb = traceback.extract_tb( tb_obj )
# first is frame in vigil
ex_tb = ex_tb[ 1 : ]
if not ex_tb:
msg += " none\n"
else:
tb_strings = traceback.format_list( ex_tb )
for tb_string in tb_strings:
msg += tb_string
curr_thread = java.lang.Thread.currentThread()
if curr_thread in TraceableRunnable.thread_to_tr_dic:
runnable = TraceableRunnable.thread_to_tr_dic[ curr_thread ]
# duck-typing, obviously... although redundant test, as only TraceableRunnables should be in the dictionary...
if hasattr( runnable, 'frame_stack_list' ):
msg += "\nOLDER STACKS:\n"
for frame_stack in runnable.frame_stack_list:
msg += "\nframe stack id: %d\n" % id( frame_stack )
frame_stack = frame_stack[ : -1 ]
if not frame_stack:
msg += " no frames\n"
else:
# most recent call first: reverse array...
stack_strings = traceback.format_list( reversed( frame_stack ))
for stack_string in stack_strings:
msg += stack_string
logger.error( msg )
def real_decorator( function ):
if not hasattr( function, '__call__' ):
raise Exception( "vigil: function %s does not have __call__ attr, type %s"
% ( function, type( function )) )
# NB info about decorator location can't be got when wrapper called, so record it at this point
penultimate_frame = traceback.extract_stack()[ -2 ]
decorator_file = penultimate_frame[ 0 ]
decorator_line_no = penultimate_frame[ 1 ]
def wrapper( *args, **kvargs ):
try:
if req_edt is not None and javax.swing.SwingUtilities.isEventDispatchThread() != req_edt:
msg = \
"vigil: wrong EDT value, should be %s\nfile %s\nline no %s, function: %s" % \
( "EDT" if req_edt else "non-EDT", decorator_file, decorator_line_no, function )
raise EDTException( msg )
return function( *args, **kvargs )
except BaseException, e:
# we cannot know how calling code will want to deal with an EDTException
if type( e ) is EDTException:
raise e
process_exception( e )
except java.lang.Throwable, t:
process_exception( t, False )
return wrapper
return real_decorator
Would welcome improvements from proper programmers...!