Skip to content

Commit 1ff665a

Browse files
committed
Minor fixes, add another two rough lesson ports
1 parent 79ce079 commit 1ff665a

13 files changed

+910
-0
lines changed

config.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ episodes:
7474
- 12-running-vscode.md
7575
- 13-code-editor.md
7676
- 14-running-debugging.md
77+
- 20-introduction.md
78+
- 21-setup.md
79+
- 22-example-code.md
80+
- 23-analysing-code.md
81+
- 24-linter-advanced.md
82+
- 30-introduction.md
83+
- 31-setup.md
84+
- 32-example-code.md
85+
- 33-feature-branch.md
86+
- 34-pull-request.md
87+
- 35-merge-pr.md
88+
- 36-merge-conflicts.md
7789

7890
# Information for Learners
7991
learners:

episodes/20-introduction.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: "Lesson 2: Code Style & Linting"
3+
teaching: 15
4+
exercises: 0
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
9+
- FIXME
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- FIXME
16+
17+
::::::::::::::::::::::::::::::::::::::::::::::::
18+
19+
##
20+
21+
##

episodes/21-setup.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: "2.1 Setup"
3+
teaching: 10
4+
exercises: 2
5+
---
6+
7+
## Setup
8+
9+
:::::::::::::::::::::::::::::::::::::: questions
10+
11+
- FIXME
12+
13+
::::::::::::::::::::::::::::::::::::::::::::::::
14+
15+
::::::::::::::::::::::::::::::::::::: objectives
16+
17+
- FIXME
18+
19+
::::::::::::::::::::::::::::::::::::::::::::::::
20+
21+

episodes/22-example-code.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
title: "2.2 Some Example Code"
3+
teaching: 10
4+
exercises: 0
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
9+
- FIXME
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- FIXME
16+
17+
::::::::::::::::::::::::::::::::::::::::::::::::
18+
19+
## Obtaining Some Example Code
20+
21+
Open a shell
22+
On own machine: open terminal with a bash shell
23+
Using the shell, we’re going to use Git to clone our example GitHub code repository
24+
The URL is bit long - see the session notes for a copy and pastable link - it’s the second link at the top
25+
git clone https://github.com/UNIVERSE-HPC/code-style-example
26+
27+
28+
## Examining the Code
29+
30+
Next, let’s take a look at the code, which is in the root directory of the repository
31+
So the example code here is designed to process temperature data from a separate data file (which is also in the repository in the data directory)
32+
The idea is that is reads in fahrenheit data from a data file, and prints out fahrenheit temperatures in both celsius and kelvin
33+
The data file is a CSV file (see sc_climate_data_10.csv) which is held in the data directory
34+
It contains a number of lines, each containing a number of values, each separated by a comma
35+
There’s also a comment line at the top, to tell us what each column represents
36+
Now let’s take a look at the Python code
37+
Use any editor you like to open the file, I’ll use a command line one called nano
38+
If you’re on a Mac or Linux, you should be able to use this too
39+
cd code-style-example
40+
nano climate-analysis.py
41+
The code opens the data file, defines some functions to do some conversions
42+
I should point out that the code is deliberately written to be bad
43+
In so many ways we’ll look into
44+
Developers sometimes talk about “code smells”
45+
Code smells are cursory indications from looking at the source code that a piece of code may have some deeper issues
46+
And looking at this code, it smells pretty terrible
47+
We can see that there is inconsistent spacing, bunching in some places, very spread out in others, for example
48+
This doesn’t engender a great deal of confidence that the code will work as we expect
49+
It raises the question that if the style of the code appears rushed, what else has been rushed?
50+
It’s design? Testing?
51+
Something to bear in mind when writing code!
52+
53+
QUESTION: who has seen or used code that looks like this? Yes/No?
54+
QUESTION: who has written code like this? Yes/No
55+
56+
No one writes great code that’s readable, well formatted, and well designed all the time
57+
Sometimes you often need to explore ideas with code to understand how the code should be designed
58+
May involve trying things out first
59+
But … the key is that once you understand how to do something,
60+
it’s a good idea to make sure it’s readable and understandable by others
61+
And this includes a future version of yourself, 6 months down the line
62+
So it’s really helpful to have good clean code so your colleagues or development team can understand it
63+
So it can be extended and otherwise modified in the future
64+
But it’s also a really good idea if you write readable code for just yourself.
65+
You never know. The code may be useful elsewhere!
66+
An all too familiar example is
67+
You stop developing a piece of code, and put it to one side. Maybe it’s not needed any more, perhaps a project has finished. You forget about it
68+
BUT… suddenly, there’s a need to use the code again
69+
Maybe all of it in another project, or maybe to just part of it
70+
You come back to your code, and it’s a mess you can’t understand
71+
By spending a little time now to write good code while you understand it,
72+
you can save yourself (and possibly others) a lot of time later
73+
74+
## Running the Example Code
75+
76+
Now despite the issues with the code, does it work? Let’s find out
77+
So in the shell
78+
In the root directory of the repository, we can type
79+
python climate_analysis.py
80+
And we can see that the code does indeed appear to work, with celsius and kelvin values being printed to the terminal
81+
But how can we improve its code formatting?
82+
Let’s use Pylint, a static Python code analysis tool to help us
83+
84+
::::::::::::::::::::::::::::::::::::: keypoints
85+
86+
- FIXME
87+
88+
::::::::::::::::::::::::::::::::::::::::::::::::

episodes/23-analysing-code.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
title: "2.3 Analysing Code using a Linter"
3+
teaching: 10
4+
exercises: 0
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
9+
- FIXME
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- FIXME
16+
17+
::::::::::::::::::::::::::::::::::::::::::::::::
18+
19+
## Installing a Code Linter
20+
21+
The first thing we need to do is Install pylint
22+
Now fortunately, pylint can be installed as a Python package
23+
QUESTION: who has installed a Python package before, using the program pip? Yes/No
24+
QUESTION: who has created and used a Python virtual environment before? Yes/No
25+
Ok, so we’re going to create what’s known as a virtual environment
26+
This is a genuinely very useful technique - I cannot recommend this strongly enough!
27+
There isn’t a developer I know that doesn’t use virtual environments to install their packages whenever they can
28+
And to be honest, this could be a topic all on its own
29+
The idea is that
30+
Instead of installing Python packages at the level of our machine’s Python installation, which we could do
31+
We’re going to install them within their own container, which is separate to the machine’s Python installation
32+
And then we’ll run our Python code only using packages within that virtual environment
33+
The benefit of this is that it creates a clear separation between the packages we use for this project, and the packages we use for another
34+
The other benefit is that we don’t end up with a machine’s Python installation with a clutter of a thousand different packages
35+
Can become very difficult to tell which packages are used for which project
36+
If someone else needs to run your code for example, by using a virtual environment, you can be sure what your code actually needs as dependencies
37+
38+
## Setting up a Development Environment
39+
40+
So let’s create a Python virtual environment now, and activate it
41+
So, make sure you’re in the root directory of the repository, then type
42+
python -m venv venv
43+
Here, we’re using the built-on Python venv module - short for virtual environment - to create a virtual environment directory called venv
44+
We could have called the directory anything, but naming it venv is a common convention
45+
We create the venv within the repository root directory, which is also an established convention
46+
This makes sure the venv is closely associated with this project, and not easily confused with another
47+
Once created, we can activate the venv so it’s the one in use
48+
We do that by:
49+
(if on Linux or Mac) source venv/bin/activate
50+
(if on Windows) source venv/Scripts/activate
51+
QUESTION: who has successfully created and activated their virtual environment? Yes/No?
52+
Ok, so what’s in this virtual environment?
53+
we can do: pip list
54+
We can see this is essentially empty, aside from some default packages that are always installed
55+
So, the next thing we can do is install any packages needed for this codebase
56+
It turns out, there isn’t any needed for the code itself
57+
But - we wish to use pylint, and that’s a python package
58+
So we can install pylint into our virtual environment using
59+
pip install pylint
60+
You’ll notice the prompt changes to reflect that the virtual environment is active - a handy reminder
61+
And with that, we’re ready to go
62+
Important thing with virtual environments
63+
Don’t add the venv directory to a GitHub repository
64+
65+
## Analysing our Code using a Linter
66+
67+
Now the magic can happen - let’s run pylint
68+
If you run it without any arguments, we can see it’s got a daunting array of options
69+
But fortunately the basic use is very simple
70+
Let’s point it at our code and see what it thinks
71+
pylint climate_analysis.py
72+
We run this, and it gives us a report
73+
essentially, a list of issues, and a score
74+
for each issue, it tells us the filename, the line number and text column the problem occurred, an issue identifier (what type of issue it is), and some text describing this type of error (as well as a shortened form of the error type)
75+
You’ll notice there’s also a score at the bottom, out of 10
76+
Essentially, for every infraction, it deducts from the ideal score of 10
77+
It is perfectly possible to get a negative score! It just keeps deducting from 10!
78+
But we can see here that our score appears very low - 0.59/10
79+
If we were to resolve each of these issues in turn, we should get a perfect score
80+
We can also ask for more information on an error type
81+
for example, we can see at line 9, near column 35, there is a trailing whitespace
82+
pylint —help-msg C0303
83+
Which is helpful if we need clarification
84+
if we edit the file, e.g. nano climate-analysis.py
85+
and go to line 9, column 35,
86+
(we can use nano’s cursor locator function to help us find column 35),
87+
we can see that there is an unnecessary space
88+
I’ve made this visible in nano so you can see it (although usually you wouldn’t)
89+
QUESTION: who’s managed to run pylint on the example code? Yes/No
90+
Let’s fix this issue now. Let’s remove the space and re-run pylint on it
91+
Delete space, save
92+
pylint climate_analysis.py
93+
And we see that the error has disappeared and our score has gone up!
94+
Note that it also gives us a comparison against our last score
95+
Warning - it can get quite addictive to keep increasing your score
96+
which might well be the point!
97+
So looking at the issue types, what do the C, W, R symbols mean?
98+
Show pylint —long-help
99+
At the end, we can see a breakdown of what they mean
100+
I is for informational messages
101+
C for a programming standards violation - it’s not conforming to the normally accepted conventions of writing good code, things like variable or function naming
102+
R for a need to refactor, due to a “bad code smell”
103+
W for warning - something that
104+
E for error - so pylint think’s it’s spotted a bug (useful, but I wouldn’t depend on this!)
105+
and F for a fatal pylint error
106+
So if we run it again on our code
107+
pylint climate_analysis.py
108+
We can see that most of our issues are do to with conventions
109+
110+
111+
::::::::::::::::::::::::::::::::::::: keypoints
112+
113+
- FIXME
114+
115+
::::::::::::::::::::::::::::::::::::::::::::::::

episodes/24-linter-advanced.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: "2.4 Advanced Linting Features"
3+
teaching: 10
4+
exercises: 0
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
9+
- FIXME
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- FIXME
16+
17+
::::::::::::::::::::::::::::::::::::::::::::::::
18+
19+
## More Verbose Reporting
20+
21+
We can also obtain a more verbose report, which gives us a lot more detail
22+
pylint —reports y file
23+
QUESTION: for those doing activity, who’s managed to run this command? YES/NO
24+
It gives you some overall statistics, plus comparisons with the last time you ran it
25+
such as how many modules, classes, methods and functions were looked at
26+
some raw metrics - we’ll come back to that
27+
the extent of code duplication (none, which is good)
28+
the number of messages by category (again, we can see that it’s mainly convention issues)
29+
and a sorted count of the messages we received
30+
now coming back to the raw metrics
31+
We can see that is breaks down our program into how many lines are
32+
code lines,
33+
python docstrings
34+
standalone comments
35+
and empty lines
36+
this is very useful, since it gives us an idea of how well commented our code is
37+
in this case - not very well commented at all!
38+
what’s a good % of comments to aim for? well it depends
39+
for normal comments, the usually accepted wisdom is to add them to explain why you are doing something, or perhaps to explain how necessarily complex code works
40+
41+
## Increasing our Pylint Score - Adding a Docstring
42+
43+
QUESTION: Who’s familiar with Python docstrings? Yes/No
44+
for those that don’t know, docstrings are a special kind of comment for a function, that explain what the function does, the parameters it expects, and what is returned
45+
you can also write docstrings for classes, methods, and modules
46+
but you should usually aim to add docstring comments to your code wherever you can, particularly for critical or complex functions
47+
let’s add one to our code now, to the fahr_to_celsius function
48+
49+
"""Convert fahrenheit to Celsius.
50+
51+
:param fahr: temperature in Fahrenheit
52+
:returns: temperature in Celsius
53+
"""
54+
55+
Re-run pylint - can see we have one less docstring error, and a slightly higher score
56+
If you’d like to know more about docstrings and commenting, we’ve included a link to a RealPython tutorial on comments and docstrings, and the different ways you can format them. that’s really good
57+
58+
## Configuring Pylint Rules
59+
60+
Specifying a pylint rcfile - e.g. to ignore/specify rules
61+
Write a module docstring that exceeds 100 characters
62+
Show pylint complaining about long line length
63+
pylint --generate-rcfile
64+
Specify long line length
65+
Edit .pylintrc file, add C0301 to disable=
66+
Re-run pylint
67+
When to use? Agree as a team
68+
69+
## Summary
70+
71+
What doesn’t pylint - and other code analysis tools - give us?
72+
What are their limitations?
73+
They don’t tell us that the code works - this first and foremost
74+
And they don’t tell us if the results our code produces are actually correct
75+
So we still need to test our code
76+
They don’t give us any Idea of whether it’s a good implementation
77+
And that the technical choices are good ones
78+
For example, this code does its own temperature conversions
79+
It turns out there’s a number of well-maintained Python packages that do this, e.g. pytemperature
80+
so we should be using a tried and tested package instead of reinventing the wheel
81+
They also don’t tell us if the implementation is actually fit for purpose
82+
Ok, so the code is a good implementation, and it works as expected
83+
But is it actually solving the intended problem?
84+
They also don’t tell us anything about the data the program may use
85+
Which may have its own problems
86+
So we have to be a bit careful
87+
These are all valid, high-level questions to ask while you’re writing code
88+
I’ve added them to the google doc
89+
As a team, and also individually
90+
In the fog of development, it can be surprisingly easy to lose track of what’s actually being implemented
91+
92+
A good idea is to revisit these questions regularly, to be sure you can answer them!
93+
A high score or zero warnings may give us false confidence
94+
Just because we have reached a 10.00 score, doesn’t mean the code is actually GOOD
95+
Just that it’s likely well formatted and hopefully easier to read and understand
96+
But nevertheless, it’s a low effort way to check our code
97+
And such tools are still very useful, as far as they go
98+
99+
::::::::::::::::::::::::::::::::::::: keypoints
100+
101+
- FIXME
102+
103+
::::::::::::::::::::::::::::::::::::::::::::::::

episodes/30-introduction.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: "Lesson 3: Intermediate Git"
3+
teaching: 15
4+
exercises: 0
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
9+
- FIXME
10+
11+
::::::::::::::::::::::::::::::::::::::::::::::::
12+
13+
::::::::::::::::::::::::::::::::::::: objectives
14+
15+
- FIXME
16+
17+
::::::::::::::::::::::::::::::::::::::::::::::::
18+
19+
##
20+
21+
##

0 commit comments

Comments
 (0)