-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.Rmd
226 lines (123 loc) · 11.4 KB
/
index.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
---
title: "DHSC Coding Principles"
author: "DHSC Office of the Chief Analyst"
site: bookdown::bookdown_site
documentclass: book
output:
#bookdown::pdf_book: default
bookdown::gitbook:
config:
download: null
toc:
collapse: section
scroll_highlight: yes
after: |
<li><a href="https://github.com/DataS-DHSC/coding_principles_book" target="blank">Coding Principles Book on GitHub</a></li>
mathjax: default
---
# Disclaimer {-}
This is an unapproved draft and does not represent the views of the DHSC.
## Aknowledgements {-}
These principles were inspired by the MOJ [Coding Principles and Standards](https://moj-analytical-services.github.io/our-coding-standards/web/) and developed further by a group at DHSC to produce a version targeted at DHSC Analysts.
# Introduction {-}
These principles are designed with the aim of improving coding standards and consistency within the department.
Adoption of these principles should improve quality, facilitate collaboration and enable effective QA of code. The principles are not language specific. This is to maximise uptake and provide a uniform set of values across languages.
The principles are designed to be achievable by all DHSC analysts producing code. Each Principle is flexible and has multiple levels:
* **Must** - You aren't finished until your code has met this standard.
* **Should** - Do this unless you are ready to justify not doing so.
* **Could** - Things you can do to improve your code beyond the base standard.
# Overview {-}
**1) [Use Version Control]**
<!-- Define -->
(ref:versioncontrol-intro) Version control your code so you and your collaborators can track changes over time, trace back errors, and retrieve old versions. Version control will help you make changes and improvements to your code with confidence.
(ref:versioncontrol-must) Use [version control](#what_is_vc) and follow guidance on coding in the open.
(ref:versioncontrol-should) Use standard tools ([Git](#git) & [GitHub](#github)) to help you version control code.
(ref:versioncontrol-could) With your team, agree and design a version control [workflow](#workflow_vc). Use ([Git](#git) & [GitHub](#github)) collaboratively and [effectively](#effective_vc).
<!-- Print -->
(ref:versioncontrol-intro)
**2) [Write Easy to Read Code]**
<!-- Define -->
(ref:easytoread-intro) Keep your code easy to read. Using a consistent style and sensible names will make it easier to collaborate and quality assure work. It will also help you spot errors.
(ref:easytoread-must) Follow the [DHSC adopted style](#style_guides) for your language, use [meaningful names](#meaningful_names) and avoid [overlaps](#dont_overlap).
(ref:easytoread-should) Use a [linter](https://en.wikipedia.org/wiki/Lint_%28software%29) or code formatter to ensure that your code conforms to the style guide.
(ref:easytoread-could) Review your code with colleagues to make ensure your names and style promote understanding.
<!-- Print -->
(ref:easytoread-intro)
**3) [Correct, Clear, Fast & Concise - In That Order]**
<!-- Define -->
(ref:correctclearconcise-intro) Write code with your colleagues priorities in mind. They need your code to work correctly, and they will have to understand and check it before they can benefit from it being fast or concise.
(ref:correctclearconcise-must) Ensure that your code is [correct](#ccfc_correct) and that it is [clear](#ccfc_clear) how it functions.
(ref:correctclearconcise-should) Make your code [fast](#ccfc_fast) and [concise](#ccfc_concise), where possible _without_ sacrificing correctness, clarity or excessive resource! Record choices made to achieve this balance.
(ref:correctclearconcise-could) Use profiling tools to understand resource usage and [refactor](https://en.wikipedia.org/wiki/Code_refactoring) to improve clarity and performance.
<!-- Print -->
(ref:correctclearconcise-intro)
**4) [Write Flexible Code]**
<!-- Define -->
(ref:flexiblecode-intro) Write flexible code where it will save time later. Good code is often adapted and repurposed. However, don't try to solve every problem upfront, or try and cover edge cases you may never encounter. Find a balance and focus on making your code easy to change.
(ref:flexiblecode-must) [Break up](#breakup) your code into chunks, with a clear [structure](#structure) and [don't repeat yourself](#dry).
(ref:flexiblecode-should) Think about, and document the way your code might break with different inputs. Include [input validation](#input_validation) to catch mistakes earlier in your code and make it easier to repurpose.
(ref:flexiblecode-could) Implement and test thorough [error handling](#error_handling). Consider writing and sharing general purposes 'tool' code, especially if you solve a problem someone else might have.
<!-- Print -->
(ref:flexiblecode-intro)
**5) [Comment Effectively]**
<!-- Define -->
(ref:comments-intro) Comment your code so that it's function is clear. Well targeted comments make it less likely that avoidable mistakes are made when using or updating your code. Colleagues and your future self will thank you.
(ref:comments-must) Write and maintain accurate comments as you code.
(ref:comments-should) Think carefully about _why_ you are leaving comments, what to capture, and what belongs elsewhere (in documentation).
(ref:comments-could) Review old code you have written - are the comments helpful? What would you include next time?
<!-- Print -->
(ref:comments-intro)
**6) [Document Your Work]**
<!-- Define -->
(ref:documentation-intro) Maintain documentation for your code. Code is _not_ self documenting and code without documentation won't be useful later. You need to capture higher level context such as what the code is for, why it is written a certain way and what the inputs and outputs are.
(ref:documentation-must) Produce documentation in line with [Aqua book guidance](#aqua).
(ref:documentation-should) Assemble documentation [as you code](#as_you_go).
(ref:documentation-could) Use document generation tools to produce [documentation](#doxygen).
<!-- Print -->
(ref:documentation-intro)
**7) [Be Demonstrably Correct]**
<!-- Define -->
(ref:demonstrablycorrect-intro) Have a clear and robust way to _demonstrate_ your code is correct.
We need to be confident in the outputs we provide. Just because something is done with code doesn't make it immune from answering the wrong question, using the wrong inputs, or doing the calculation incorrectly.
(ref:demonstrablycorrect-must) Hold your code to the [same standard as any other analysis](#qa_code_too) and record evidence demonstrating it produces the right output.
(ref:demonstrablycorrect-should) Use [version control](#version_control) to unambiguously link QA to code and outputs and construct [automated tests](#unit_tests) to provide confidence that changes don't break things.
(ref:demonstrablycorrect-could) Make a fully automated [reproducible analytical pipeline (RAP)](#rap_demonstrable) which incorporates checks and validation and minimises opportunity for human error.
<!-- Print -->
(ref:demonstrablycorrect-intro)
**8) [Use Sensible Defaults]**
<!-- Define -->
(ref:sensibledefaults-intro) Do common tasks in a consistent way, following guidance. If we use the same tools and approaches across the department, it makes collaboration and quality assurance easier. This is almost always more important than using the absolute best method.
(ref:sensibledefaults-must) Be aware of the [defaults](#general_defaults), understand why we have them and follow them unless you can explain how the benefits of an alternative approach outweigh those of consistency.
(ref:sensibledefaults-should) Help define what the defaults should be, and actively participate in discussion and debate to keep them up to date and relevant.
(ref:sensibledefaults-could) Proactively review and compare the defaults used with the way you work.
<!-- Print -->
(ref:sensibledefaults-intro)
**9) [Be Reproducible]**
<!-- Define -->
(ref:reproducible-intro) Work in a way which is reproducible. Within the department, analysis is used to enable evidence based decision making. A piece of evidence which you cannot rely on being able to reproduce is not much good. There are many reproducibility pitfalls and it is our responsibility to overcome them.
(ref:reproducible-must) Keep track of what you have done and document it [unambiguously](#unambiguous_docs) so that someone else can recreate it.
(ref:reproducible-should) Write [portable](#portability) code, in a standard [project structure](#projects) so that it is _easy_ for someone else to run it.
(ref:reproducible-could) Turn your code into a [package / library / module](#packages), learn and promote [RAP](#rap_section) techniques, or use [containers](#containers) to achieve reproducibility.
<!-- Print -->
(ref:reproducible-intro)
**10) [Use Appropriate and Tidy Data]**
<!-- Define -->
(ref:datastructures-intro) Use the right data structures for the job. Programming languages offer many different ways to work with the same data. Using the right one will make a task easier, and decrease your chance of getting it wrong.
(ref:datastructures-must) Know what ['Tidy Data'](#tidy_data) is, and understand why it is valuable.
(ref:datastructures-should) Be familiar with the [data types](#data_types) and structures available to you and ensure that you use the right ones.
(ref:datastructures-could) Think about relationships between datasets, design [schemas](#schema) and store data in an efficient way.
<!-- Print -->
(ref:datastructures-intro)
# Summary Table {-}
| Principle | You Must | You Should | You Could |
|------------------------------------------------------ |-------------------------------- |---------------------------------- |--------------------------------- |
| **[Use Version Control]** | (ref:versioncontrol-must) | (ref:versioncontrol-should) | (ref:versioncontrol-could) |
| **[Write Easy to Read Code]** | (ref:easytoread-must) | (ref:easytoread-should) | (ref:easytoread-could) |
| **[Correct, Clear, Fast & Concise - In That Order]** | (ref:correctclearconcise-must) | (ref:correctclearconcise-should) | (ref:correctclearconcise-could) |
| **[Write Flexible Code]** | (ref:flexiblecode-must) | (ref:flexiblecode-should) | (ref:flexiblecode-could) |
| **[Comment Effectively]** | (ref:comments-must) | (ref:comments-should) | (ref:comments-could) |
| **[Document Your Work]** | (ref:documentation-must) | (ref:documentation-should) | (ref:documentation-could) |
| **[Be Demonstrably Correct]** | (ref:demonstrablycorrect-must) | (ref:demonstrablycorrect-should) | (ref:demonstrablycorrect-could) |
| **[Use Sensible Defaults]** | (ref:sensibledefaults-must) | (ref:sensibledefaults-should) | (ref:sensibledefaults-could) |
| **[Be Reproducible]** | (ref:reproducible-must) | (ref:reproducible-should) | (ref:reproducible-could) |
| **[Use Appropriate and Tidy Data]** | (ref:datastructures-must) | (ref:datastructures-should) | (ref:datastructures-could) |