Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialnicolaspeterson
8,569 Pointsraise ValueError, amount_due in try block, except ValueError as err…
I’m struggling with these three parts of the video, which I must have watched 20 times… Why do we raise (and not except) a ValueError in our original function? Why do we need to move the amount_due expression into the try block? How the heck does ValueError as err even work? I can clearly see how this affects the final output, but I can’t wrap my head around the individual components. I’ve tried looking at other answers here but no luck. Best answer will be given a green tick :)
1 Answer
Chris Freeman
Treehouse Moderator 68,441 PointsHey nicolaspeterson, good questions all.
Let’s first review the basic concepts of errors. When an unexpected event occurs, an error is “raised”. This raising may be done by internal code (like when int()
sees an error) or explicitly by a coder using the raise
command. The error says the program can not continue.
In general, all errors will cause a program to halt unless the error is “handled”. Handling an error means being prepared that an error might happen by wrapping code in a try/except
block. Theexcept
statement lists the exceptions that will be handled locally, all other errors are passed along (possibly ending the program if not handled somewhere else.)
Why do we raise (and not except) a ValueError in our original function?
“Raise” is the process of halting execution, flagging the error, and returning control to the point where this code was called. Since the split_check
function doesn’t have control over the arguments passed in, there isn’t a viable option to put in an except
block to handle the situation. So a raise
is used to notify the calling code.
Why do we need to move the amount_due expression into the try block?
By placing the amount_due
expression in a try
block, any error raised during the execution of this statement (and all others within the try
block) will be evaluated by the matching except
statement. Either the int(input…))
or the amount_due
statements could raise a ValueError
.
How the heck does ValueError as err even work?
The error that is raised has an associated error object. This error object is an instance of the corresponding error class:
>>> ValueError
<class 'ValueError'>
>>> ValueError("hello")
ValueError('hello',)
>>> type(ValueError("hello"))
<class 'ValueError'>
The basic except
statement only matches the type of the error object. It does not provide and access to the matched error object. By using the as
refinement, the provided label “err” may be used to reference the error object directly. This then allows using the err
reference in a str
context which will return the “Oh no…” string.
Post back if you need more help. Good luck!!!
nicolaspeterson
8,569 Pointsnicolaspeterson
8,569 PointsThis is fantastic, thank you so much! When you put it like this, it makes a lot more sense.