In today's final lecture, I will talk about how your project will be graded
Slight Disappointment
Proposals
Not one student suggested some kind of ranking of something software
engineering or Informatics related. Eg.
Ranking git repositories by average size of commit
Ranking git repositories by amount of profanity
Average response rates for issues
Rankings
Proposals
A few students have struggled with how to “combine rankings”
As if there must be a single ranking
I did not specify this
I only said that there had to be a ranking
Which should be read as “at least one ranking”
Honours Project
Proposals
I forgot to mention that some of you have quite ambitious projects. You
can make a start to them here and then possibly self-propose completing
the project for your honours project next year. The proposal will be in
January so you'll know by then if you want to continue with what you have.
Grading
Software Engineering
The bigger picture answer to the question of what you will
be graded upon, is your ability to demonstrate your software engineering
skills
Perhaps, ideally, I'd like to simply grade you on your software engineering skills
There are two reasons this is not the case:
It's infeasible for me to accurately judge your software engineering ability
unless you demonstrate it in some way
There will likely be times in the future when demonstrating an
ability is more important than attaining it
Grading
Engineering vs Producing
Even directly grading your ability to engineer software is
a little unsatisfying
What commonly matters is your ability to produce software
Often, the best way to achieve success in any software project
is to avoid developing code
The lesson is: in general try to avoid writing software
Unfortunately, for this project you have to demonstrate an
an ability to engineer software
Of course if you manage to do something like the above, that is
still impressive and credit worthy
Just make sure you get the credit it is due,
by writing about it in your report
Proposals
Cooking
Cooking is way more popular than I expected
Approximately 8-10 proposals were for some form of recipe collection site
To re-iterate, there is a slight risk here that you demonstrate
more of an ability to curate a database than to engineer software
You may find the above WYSIWYG editor helpful for your needs,
but be careful as you will likely end up storing the whole thing
as unstructured data
Recipes
Front-end To a Database
@app.route('/')
def show_entries():
cur = g.db.execute('select id, title, text from entries order by id desc')
entries = [dict(id=row[0], title=row[1], text=row[2]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
Recipes
Front-end To a Database
@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g.db.execute('insert into entries (title, text) values (?, ?)',
[request.form['title'], request.form['text']])
g.db.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
When we display an entry, we give it an upvote button
Recipes
Add Rankings
@app.route('/upvote', methods=['POST'])
def upvote_entry():
# Perform a query to get the current number of upvotes:
upvotes = cur.fetchall....
g.db.execute('update entries set upvotes=? where id=? values (?, ?, ?)',
[upvotes+1, request.form['recipe-id']])
...
To upvote we simply execute a database update statement
Recipes
Add Rankings
def show_entries():
cur = g.db.execute('select id, title, text from entries order by upvotes desc')
When we display entries, order by upvotes
Grading
Demonstrate Software Engineering
Recall that the main goal is to demonstrate your ability to
engineer good software
Third-party libraries for your back-end should generally
be installed on the server and not commited to your repository
Front-end, usually Javascript, often need to be stored in the
repository to be made available for the client
Not always the case, eg. public mirrors of common
Javascript libraries, such as JQuery exist
Source Code Control
Proposals: Commit messages
Do not feel limited to single line commit messages
If you perform a git commit, without the -m,
it will open up an editor and you can type in as much
as you like
Normally I suggest that if you write more than one paragraph and you are quite
possibly recording something that you maybe wish to record elsewhere
But many of you seem to be sticking religiously to single sentence
commits messages as if there were some kind of limit
Documentation
Developer Documentation
Many large projects require extensive documentation
Web sites on the other hand, hopefully, do not require
user documentation separate from the web site itself
The documentation you write, is for other developers
This means, anything someone would need to take over development from you
The only means that you can individually reduce your “bus factor”
Documentation
Developer Documentation
This includes:
Compilation instructions
Running Instructions
Testing Instructions
Debugging instructions
Deployment instruction if appropriate
A starting point to help the developer orientate themselves
Eg. “The main logic of the web application is in 'blah.code'
routes the requests to specific functions”
Eg. “If you wish to change only the look of the website
the CSS files are found in ...”
Documentation
Automation
Anything that can be automated, should be automated
Rather than have long lists of commands developers need to input
provide a script to do them all
If that script may need to be parameterised, so be it:
Either with script command-line arguments (in bash these are accessible with $1, $2 ...)
Or editing the script in which case the variables to edit
should be clearly marked at the top
Documentation
Automation
Edit the script
$INSTALL_DIR=""
$PATH_TO_DEPX=""
if [ "${INSTALL_DIR}" == '' ]; then
echo "You need to set the installation directory."
exit 1;
fi
...
Documentation
Source Code Comments
Repeating the advice from earlier:
Generally you are not writing what the code does
but why it does it
Generally held view that “code should be self-documenting”:
That's fine, I agree, but often it is non-obvious how to make it self-documenting
It may even be impossible, for example if works around a feature of an external library
Documentation
Do I need a comment?
// Choose a delay from the exponential distribution given the rate
dice = generator.nextDouble();
delay = 1.0 - (1.0/rate * Math.log(dice));
System.out.println (delay);
// Choose a delay from the exponential distribution given the rate
dice = generator.nextDouble();
delay = 1.0 - (1.0/rate * Math.log(dice));
System.out.println (delay);
// The X library indexes from 1, when we created our database we start the
// unique identifiers off at 0. Arguably we should change that and we
// would not need the "+ 1" here, but we need to think about where else we
// use the unique identifiers as indices first
Third_party.some_method(entries, index + 1);
Testing
Unnecessary Qualification
English has a habit of unnecessary qualification, eg.
People in glass houses should not throw stones
How about everyone refrain from stone throwing?
Testing
Unnecessary Qualification
English has a habit of unnecessary qualification, eg.
People using a dynamically typed language should comprehensively test their source code
How about everyone comprehensively test their source code?
However, reading your proposals:
Testing
Proposals
Testing
Proposals
Testing
Proposals
Dynamically typed languages have become much more popular in the last 10-20 years
At least in part this is because an increased emphasis on testing has reduced the benefits of static typing
So I can turn my sentence around:
“People who do not comprehensively test should use a statically typed language”
This is not an unnecessary qualification because I'm not suggesting that everyone should use a statically typed language
Testing
Proposals Disappointment
Very few proposals mentioned anything about testing
Even fewer asked anything about testing
I'm aware that testing seems like an extra chore
Think of it as reducing the amount of manual work you do
Testing
Choreness
I believe testing is seen as so laborious because your first
exposure is to testing is of unit testing micro-methods
When your method returns the maximum integer in a list, I can see
why you do not appreciate any great need to test
Testing
Large Programs
Parts of a large program often interact with each other in much
more complex ways
Tests under these circumstances are much more fruitful, you are
making sure that changes to one part of the program do not adversely
affect some other part
Testing
Simple Example
You have some database for storing the persistant state of your web application
You have some schema, some tables with columns
Suppose you wish to add some new functionality:
This requires that you make a change to the database schema
Perhaps you have to add a column
How can you be sure that your change of the schema has not broken some functionality?
Testing
Simple Example
You have three possible strategies:
Make the change and re-run your comprehensive test suite
Fix anything that was broken and repeat
Make the change and manually test out all functionality, preferably in different circumstances
boring, repetitive, error-prone and time-consuming
Make the change in a way that is very unlikely to break existing functionality, such as adding a new table
Do this often enough and it is an excellent way to make an unmaintainable mess
Recipes Example
Original schema:
drop table if exists entries;
create table entries (
id integer primary key autoincrement,
title text not null,
text text not null
);
Testing
Recipes Example
Which we update with ‘upvotes’
drop table if exists entries;
create table entries (
id integer primary key autoincrement,
title text not null,
text text not null,
upvotes integer
);
Testing
Recipes Example
Our original code to add to the database is now wrong
@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g.db.execute('insert into entries (title, text) values (?, ?)',
[request.form['title'], request.form['text']])
g.db.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
When you have several operations on the same tables you have to re-check
all of the operations that were previously working
Testing
Automate Test Database Creation
Create some test databases
But make sure you write some code to automatically create them
A common error is to use your application to create some test databases
But this means if you update the database schema you will have to re-use your application to create them again with the new schema
Much better if you only have to update a line or two in code to automatically create them
Maintainable Code
Software is generally deployed in an ever changing environment:
The requirements change because the world has changed
New laws
New competing/complimentary products
New hardware
New uses
For this reason software must be frequently updated/fixed/modified/enhanced
This is difficult if your software is not maintainable
Maintainable Code
Code Structure
Generally have you got a nice separation of concerns
You have some processing of the data, could you use that outwith your application?
Often the solution involving the least amount of code is the best
This does not mean using fewer characters, but fewer constructs
A common error is over-using classes
Maintainable Code
Idiomatic Code
You have chosen your language(s) of choice
You should use it appropriately, this is, admittedly, a little vaguely defined
Maintainable Code
Idiomatic Code
For example, suppose you are using Python (popular in the proposals):
Not using getters and setters (Python has ‘properties’ for this purpose)
Using iterators, see below:
Using with syntax
More generally, do not use Strings and Integers for
all kinds of values that could have more specific and appropriate types
for x in xs:
...
better than:
for i in range(length(xs)):
x = xs[i]
Maintainable Code
Automate Everything
The best way to make sure that someone else can maintain your code
is to automate as much as possible
If you have a single command to compile and run your web application
they can at least run it simply
If you have a single command to run your entire test suite, they
can easily modify code and examine the effects
Your Report
As discussed last week
This is your opportunity to enhance the demonstration of
your software engineering abilities
This includes how readable it is
If cannot understand it, you will not receive much credit for it,
nor whatever you are trying to convey
This is a common situation, if you cannot describe what
you have done and why, you likely will not receive much
credit for it, whatever form credit may take
Early Submission
Early submission deadline: Thursday 11th December at 4pm
If you submit after the early submission deadline the highest grade you can achieve is 90
Interactions
Use of source code control
Documentation, including source comments
Testing
Maintainable code
Your report
Early submission
Interactions
For example testing is a special case of automate everything
under maintainable code
Documentation is a special case of readable code under
maintainable code
Summary
How easily could someone else continue develop of your application?
If the answer is, “not easily” then you are failing
Use your report to demonstrate that you are not failing
Or that you have at least learnt how not to fail
Note: I've not said much about actually producing some cool/good product
If you produce something good but in a way that is entirely unsustainable
you likely won't recieve a very high mark
Similarly some proposals are of quite questionable value, but done
in a very principled manner could well achieve a very high mark
Summary
I do not wish to scare you
Relax, if you spend enough
time on it you will almost certainly get at the very least a reasonable mark