Although how you present your results is not a criterion in itself, it usually plays an important role on
how well your ideas are understood. A good report should convey efficiently the right information.
Aside correctness, this means:

Overall structure easy to follow --> follow the one we give you

Correct spelling and grammar: together, they ease the reading and the understanding

Clarity and concision; there is usually some elegance in simple yet efficient designs --> stick to the number of pages we indicate.
Do not make tables of content.

Use an appealing formatting, or rather, do not use an ugly one --> use latex for the report and one of its algorithmic package for the pseudo-code
(you can use the same one as the course's)

Regarding pseudo-code:

Provide a specification
for every pseudo-code function you write! We cannot credit code we do not understand

Code

The mark corresponding to the code are split into three main categories: correctness, language and style.
We consider that writing good-quality code (language and style) is as important as writing correct code.

We will implement some automatic testing for most projects. With time we have noticed a few misconceptions regarding those:

Misleading feedback from the automatic testing cannot constitue any form of excuse/pretext. It might indeed happen that the tests are wrong.
This usually (when it does) occurs at an early stage, when the testing scripts are not robust enough. Most of the time, however, the
bug does lie in the student code. Before reporting an issue, ensure you cannot reproduce the error. Otherwise, report it and we will
adapt as soon as possible.

The tests do not determine alone the mark you will get.

Not all tests are visible. We are encouraged you to develop your own tests. Thinking how to test a piece of a code is usually as formative as
writing it.

If automatic testing is set up, we will make no exception regarding the critical mistakes; reading the feedback
is enough to prevent such problems.

Advice

Commenting is an art (except it can be mastered, therefore it is more a skill than an art, but anyway, the point is that it is tricky).
Too many and the code become unreadable. Too few and the code is incomprehensible.

The trick is to write comments intented at someone who
knows the general context of the code (i.e. familiar with the concepts) but who has not written it. That's your classmates, colleagues, TA and ... you.
When you come back to your code six months later, you will wish you had taken the time to write some comments.

All auxiliary functions must be specified. As a good descriptive name, the specification allows readers to grasp what the function is intended to do.
However, specifications allow you to be more precise about the nature of inputs and output, and about their relationship. They also allow the programmer
to catch some mistakes, when they are well made and used.

Aside from specifications, every sizeable/tricky part of code should be commented upon. They should prevent two questions:

What is this whole block supposed to do?

What has the programmer written the code like that?

In other words, they make up for the lack of affordance of (some (part of)) code.

Here are a few references on the matter, if you want to dig it deeper: