hello welcome back to lesson number
eight
this lesson is about defensive
programming so so far we've looked at
many tools to build your program to
write code and develop functions and
code and packages and all kinds of
things
but now we need to look a bit about how
to make that code more reliable
now writing code is very well and easy
but writing code that is robust and
reliable in under most circumstances is
a lot more difficult and the aster the
assert statement
is an incredibly useful tool
in your library
for dealing with this
assert is a statement that means we
state it like so there are no brackets
it is
not a function we say assert
and then
we say give an expression that evaluates
to true or false so we could have x less
than
10
then comma
and then we can put a string and this
string will be the error that appears
x
must be greater than 10
and we'll just add in or
equal
to
n string
right so at the moment we're getting a
name error because we haven't defined x
yet so let's define x let's make x4 now
if we run the assert nothing happens
because x is less than 10 so
let's set x equal to 12
and run it again
you can see we're triggering an
assertion error
it's saying x must be greater than or
equal to 10. in other words this is a
way of raising an error specifically
under a certain condition it's like an
if statement and a raise error statement
or rolled into one and they're very
useful
where would you use this you might ask
well
a quite common location would be in some
kind of function so
let's have a um
we could have a function that does the
fizz buzz
algorithm
if i haven't mentioned it so far
fizzbuzz takes a number of some kind
and says is that number divisible by 3
if so say fizz if it's divisible by five
then buzz if it's divisible by three and
five if is buzz
and if it's divisible
by neither then just return the number
so we can say if number
visible by three
and
number
divisible by
five
return
fizz
ah no fizz buzz
else if
number divisible by
three
return
fizz
else if
number
little by five
return buzz
else
return number
there we go this is our function we've
got fizzbuzz
there's butts let's see there we go we
can get fizz buzz returned
1011 get the number back fine this all
works fine however what happens if we do
this
we get an error because
type error not all arguments converted
during string formatting which isn't all
that helpful
so what we can do is add an assert
statement we can assert
type of number
is equal to int
fizzbuzz
only
takes
integer
arguments
there we go so now
if somebody was to call fizzbuzz
with a non-integer value we get an
assertion error and a much more helpful
argument
we can even add
assertions to the end
so we can say
assert
number
well we can assert type
number
in
so rather than saying equal to we can
say in
int
or
string
now what we're saying
is we get an assertion error here but if
for some reason
something is returned that is neither an
int nor a string it will be picked up by
this assertion now you might be
wondering oh but we're obviously not
going to get that because we're tacking
the type here and we're returning things
here
yes that's true
however
one thing that often happens in code is
that people will go away
and the code will be edited by them
later on or by somebody else
functionality will change to add in some
kind of new feature
and so suddenly these assertions at the
beginning at the end are required
because things are changing in the body
of the code
this is a very common occurrence
especially when extending functionality
so that's how assertion types work but
as you can imagine changing things in
the body of the code people might change
the assertions
to make
to work with what they currently do
but a much better way of testing whether
your function behaves
as it should do
is with a test
so what is a test our test is just
another function really we have tests we
have test
fizz
buzz uh
multiples
three
so what this test is gonna do
is it's going to run
for i in
for item
in and let's have a list of multiples of
3 so 3
5 7
3
6 9 12
and then we'll go up to some other large
number like
333
and
-3
so for each of those we're going to
assert
that fizzbuzz
of item
is equal to
fizz
there we go so now if we run this test
it passes nothing happens because our
function
will return fizz for all of those values
and that's what a test is
we basically build some kind of test
where we expect to see one result
we run our function to make sure it
returns that result
and then we throw an error if it doesn't
and this is what's known as a test
as you can imagine writing tests for
your code is incredibly useful
in fact most major code boxes will have
a suite of tests
a suite which is often many many
tests long
it's not uncommon
uh for
projects like pioneer pdl to have
test libraries that have hundreds of
tests
in fact i think it has almost upwards of
300 tests
because tests can ensure that your code
behaves exactly as it is needed to
once you have a lot of things going on
in your code if it's longer than a few
hundred lines then that means that
you've got a load of behavior that your
code does when you want to change it and
add new behavior you want to make sure
that you haven't broken the old behavior
you want to make sure that you haven't
inadvertently changed something
somewhere else in the code
and the best way to do that is to have a
series of tests that run through your
code and basically check that the
functionality is there
that means that when you start working
on it you can run a test to make sure
that nothing's been broken by anyone
else then you can do your edits then you
can run the tests again to make sure
that you have maintained the
functionality that you wanted to
and we can show that with this fizz buzz
calculator because we've got fizzbuzz
multiples of three we could do
another one for multiples of five
where we say
uh
5
10
r but we could put 15 15 obviously won't
work because it's multiple of three and
a multiple of five so skip that twenty
twenty five
five five five
minus five
and then say that this should be
buzz
so you might be wondering okay well how
are we going to
ah we've got an assertion error what's
going on it means that one of our
numbers is not returning the correct
result
so we can do this let's say add a thing
saying
um
we're going to add an f string
which is a formatted string i would
recommend
looking this up
this is just saying which item went
wrong
so 555 this means that 505 is probably
also divisible by three so let's change
it to 55.
there we go now it's passing
okay so we've got two tests for our
function
what if we wanted to expand the fizzbuzz
function if we wanted to expand and make
it fizzbuzz bang
fizzbuzz bang is an extension of
fizzbuzz
whereby we go up to multiples of seven
become bang
or we could even say fizzbuzz what if we
did fizzbuzz but with characters as well
so there is this other extension to the
game where you say fizzbuzz
for every
character that matches the numbers so
for example 13 isn't divisible by 3 or 5
but you would say fizz because it's got
a 3 in it
suddenly things get more complicated
suddenly things are getting a lot harder
to program and thus a lot harder to make
sure that everything works in every
scenario and that's where tests come in
finally
i should talk about how
so far we've been writing tests
after we've written the function this
isn't that uncommon
this is quite a standard way of doing
things however it has been shown time
and again that the best way
to write
functions is to write the tests first
and we write the test first that's
called test driven development we define
tests
beforehand
and then
use that to think about exactly what we
think should happen
take it for this fizz buzz for example
imagine we hadn't written fizz buzz yet
we write fiz bars multiples of five so
we have these assert statements these
have to be true then we could do
this bars multiples of five
and three
and then say
all of these have to be true
so what else is a multiple of five and a
multiple of three
okay well there's some some easy ones
and then let's say
minus 15
what do we think zero should be should
zero be a multiple of five and three
oh
ah
assertion error 15 so we've got a
problem
you see we've written our code 15
should return fizzbuzz ah but we didn't
write it properly did we
so we should have done fizz buzz here
rather than just buzz
there we go let's try it again
there we go they're all passing so zero
is also a multiple of five and three
this forces us to think about exactly
what we would do or what we want the
code to do in that scenario if we write
the test first we can say okay well 15
30 60 -15 they should all be fine
but zero should zero be fizzbuzz should
zero be zero technically it's divisible
but do we include it should it be
counted this is what test driven
development leads us to think it forces
you to outline the specification in
advance and it's a very powerful tool
alright
have a go at the exercises and see how
you do
you