<bijan.parsia, christos.kotselidis@manchester.ac.uk>
(bug reports welcome!)
i % 3 == 0
and i % 5 == 0
_ % _ == 0
pattern!print
a lotFIZZ = 'Fizz'
BUZZ = 'Buzz'
This lecture was derived from the excellent blog post FizzBuzz In Too Much Detail by Tom Dalling.
Tom uses Ruby and goes a couple of steps further. Worth a read!
Intellectual property is any articulable, tangible production of a mind whose physical realisations are restricted by law (in production, distribution, etc.)
Name | Establishment | Enforcement |
---|---|---|
Copyright | Automatic, immediate | Civil and Criminal |
Patent | Application; exposure before application destroys it | Mostly civil |
Trademark | Application and vigorous defense | Mostly civil |
Trade Secret | Automatic (by not telling people) and NDAs | Mostly civil |
Copyright is a licensable monopoly of tangible expression of an idea with respect to reproduction, derivation, display, distribution, and the like.
A patent is a licensable monopoly of the use or sale of a "non-obvious" invention (of a process, machine, design (sometimes), mechanism, procedure, etc.
A trade secret is an invention which is not disclosed
Our discussion will be adequate if it has as much clearness as the subject-matter admits of, for precision is not to be sought for alike in all discussions, any more than in all the products of the crafts...for it is the mark of an educated [person] to look for precision in each class of things just so far as the nature of the subject admits...
— Aristotle, Nicomachaen Ethics, Book 1, 3
We demand rigidly defined areas of doubt and uncertainty!
— Douglas Adams, The Hitchhiker's Guide to the Galaxy
A defect in a software system is a quality level (for some quality) that is not acceptable.
What counts as a defect is often determined late in the game!
If your program crashes then it
If your program crashes, and the cause is in your code, then it
(Does QA hate you? — scroll for the cartoons as well as the wisdom.)
This is a logical, not temporal, order.
The penalty for failing to define the problem is that you can waste a lot of time solving the wrong problem. This is a double-barreled penalty because you also don't solve the right problem.
—McConnell, 3.3
We're going to look at your rainfalls before discussing it in detail.
We're going to do a code review!
You're going to work in 2-person teams!
To the lab! Material in the usual place.
The rainfall problem is still a challenge!
rainfall.py
?average_rainfall(input_list)
doctest
Design a program called rainfall that consumes a list of numbers representing daily rainfall amounts as entered by a user. The list may contain the number -999 indicating the end of the data of interest. Produce the average of the non-negative values in the list up to the first -999 (if it shows up). There may be negative numbers other than -999 in the list.
def average_rainfall(input_list):
""">>> average_rainfall(<<FIRST TEST INPUT>>)
<<FIRST EXPECTED RESULT>>
"""
# Here is where your code should go
return "Your computed average as a integer" #<-- change this!
$ python 1setup.py
Your computed average as a integer
$ python -m doctest 1setup.py
**********************************************************************
File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/1setup.py", line 2, in 1setup.average_rainfall
Failed example:
average_rainfall(<<FIRST TEST INPUT>>)
Exception raised:
Traceback (most recent call last):
File "//anaconda/lib/python3.5/doctest.py", line 1320, in __run
compileflags, 1), test.globs)
File "<doctest 1setup.average_rainfall[0]>", line 1
average_rainfall(<<FIRST TEST INPUT>>)
^
SyntaxError: invalid syntax
**********************************************************************
1 items had failures:
1 of 1 in 1setup.average_rainfall
***Test Failed*** 1 failures.
doctest
subprocess
etc.average_rainfall(input_list)
'2 3 4 67 -999'
==> [2, 3, 4, 67, -999]
average_rainfall
v 2def average_rainfall(input_list):
""">>> average_rainfall([2,3,4,67, -999])
19.0
"""
# Here is where your code should go
return "Your computed average as a integer" #<-- change this!
$ python 1setup.py
Your computed average as a integer
$ python -m doctest 2firstfull.py
**********************************************************************
File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/2firstfull.py", line 2, in 2firstfull.average_rainfall
Failed example:
average_rainfall([2,3,4,67, -999])
Expected:
19.0
Got:
'Your computed average as a integer'
**********************************************************************
1 items had failures:
1 of 1 in 2firstfull.average_rainfall
***Test Failed*** 1 failures.
def average_rainfall(input_list):
""">>> average_rainfall([2,3,4,67, -999])
19.0
"""
# Here is where your code should go
return sum(input_list)/len(input_list)
def average_rainfall(input_list):
""">>> average_rainfall([2,3,4,67, -999])
19.0
>>> average_rainfall([2,3,4,67])
19.0
"""
# Here is where your code should go
return sum(input_list)/len(input_list)
$ python -m doctest 4firstimpl2.py
**********************************************************************
File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/4firstimpl2.py", line 2, in 4firstimpl2.average_rainfall
Failed example:
average_rainfall([2,3,4,67, -999])
Expected:
19.0
Got:
-184.6
**********************************************************************
1 items had failures:
1 of 2 in 4firstimpl2.average_rainfall
***Test Failed*** 1 failures.
def average_rainfall(input_list):
""">>> average_rainfall([2,3,4,67, -999])
19.0
>>> average_rainfall([2,3,4,67])
19.0
"""
# Here is where your code should go
return sum(input_list[:-1])/len(input_list[:-1])
def average_rainfall(input_list):
""">>> average_rainfall([2, 3, 4, 67, -999])
19.0
>>> average_rainfall([2, 3, 4, 67])
19.0
"""
rainfall_sum = 0
count = 0
for i in input_list:
if i == -999:
break
else:
rainfall_sum += i
count += 1
# Here is where your code should go
return rainfall_sum/count
$ python -m doctest 5secondimpl.py
**********************************************************************
File "/Users/bparsia/Documents/2018/Teaching/COMP61511/labs/lab1/followup/5secondimpl.py", line 2, in 5secondimpl.average_rainfall
Failed example:
average_rainfall([2,3,4,67, -999])
Expected:
19.0
Got:
19.0
**********************************************************************
1 items had failures:
1 of 2 in 5secondimpl.average_rainfall
***Test Failed*** 1 failures.
Whaaaaaaaaaaaaaaaaaat?!
There was a bug in our tests
def average_rainfall(input_list):
""">>> average_rainfall([2, 3, 4, 67, -999])
19.0
vs.def average_rainfall(input_list):
""" >>> average_rainfall([2, 3, 4, 67, -999])
19.0
Earlier tests failed for two reasons!
$ python -m doctest 6secondimpl2.py
$
$ python -m doctest -v 6secondimpl2.py
Trying:
average_rainfall([2,3,4,67, -999])
Expecting:
19.0
ok
Trying:
average_rainfall([2,3,4,67])
Expecting:
19.0
ok
1 items had no tests:
6secondimpl2
1 items passed all tests:
2 tests in 6secondimpl2.average_rainfall
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
[-999]
)[-999, 1]
the same as [-999]
?[]
and [-999]
?[-999]
and [-999, 0]
[-1 0 10]
[-1 -2 -3 -999 1]
the same as []
?QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers. Orders a sfdeljknesv.
— Bill Sempf (@sempf) September 23, 2014
McConnell: 22.2 Recommended Approach to Developer Testing
miniwc
from the specWhat were the challenges you encountered?
What challenges were inherent to the problem?
What challenges were environmental?
There seems to be a miniwc.py: 0.5/0.5 points.
There seems to be a doctest_miniwc.py and test files: 0.5/0.5 points.
Prohibited libraries have been used: 0/1 points. Formatting was correct: 1/1 points.
The script passed 35.7% of miniwc simple tests: 2/5 points.
The script passed 0.0% of miniwc binary tests: 0/1 points.
The script passed 0.0% of miniwc unicode tests: 0/1 points.
Penalties: none.
Total marks: 4.0/10.0
wc
miniwc.py
(now called wc.py
)miniwc.py