44Tutorial
55========
66
7- :Author: Robert Kirkpatrick
8-
9-
10- Intro
11- -----
12-
13- Beginner to coding standards? Pylint can be your guide to reveal what's really
14- going on behind the scenes and help you to become a more aware programmer.
15-
16- Sharing code is a rewarding endeavor. Putting your code ``out there `` can be
17- either an act of philanthropy, ``coming of age ``, or a basic extension of belief
18- in open source. Whatever the motivation, your good intentions may not have the
19- desired outcome if people find your code hard to use or understand. The Python
20- community has formalized some recommended programming styles to help everyone
21- write code in a common, agreed-upon style that makes the most sense for shared
22- code. This style is captured in `PEP 8 `_, the "Style Guide for Python Code".
23- Pylint can be a quick and easy way of
24- seeing if your code has captured the essence of `PEP 8 `_ and is therefore
25- ``friendly `` to other potential users.
26-
27- Perhaps you're not ready to share your code but you'd like to learn a bit more
28- about writing better code and don't know where to start. Pylint can tell you
29- where you may have run astray and point you in the direction to figure out what
30- you have done and how to do better.
31-
327This tutorial is all about approaching coding standards with little or no
338knowledge of in-depth programming or the code standards themselves. It's the
349equivalent of skipping the manual and jumping right in.
3510
36- My command line prompt for these examples is:
11+ The command line prompt for these examples is:
3712
3813.. sourcecode :: console
3914
40- robertk01 Desktop$
15+ tutor Desktop$
4116
4217.. _PEP 8 : https://peps.python.org/pep-0008/
4318
4419Getting Started
4520---------------
4621
47- Running Pylint with no arguments will invoke the help dialogue and give you an
48- idea of the arguments available to you. Do that now, i.e.:
22+ Running Pylint with the `` -- help`` arguments will give you an idea of the arguments
23+ available. Do that now, i.e.:
4924
5025.. sourcecode :: console
5126
52- robertk01 Desktop$ pylint
53- ...
54- a bunch of stuff
55- ...
27+ pylint --help
5628
5729
5830A couple of the options that we'll focus on here are: ::
@@ -66,17 +38,12 @@ A couple of the options that we'll focus on here are: ::
6638 --reports=<y or n>
6739 --output-format=<format>
6840
69- If you need more detail, you can also ask for an even longer help message,
70- like so: ::
41+ If you need more detail, you can also ask for an even longer help message: ::
7142
72- robertk01 Desktop$ pylint --long-help
73- ...
74- Even more stuff
75- ...
43+ pylint --long-help
7644
77- Pay attention to the last bit of this longer help output. This gives you a
78- hint of what
79- Pylint is going to ``pick on ``: ::
45+ Pay attention to the last bit of this longer help output. This gives you a
46+ hint of what Pylint is going to ``pick on ``: ::
8047
8148 Output:
8249 Using the default text output, the message format is :
@@ -90,167 +57,160 @@ Pylint is going to ``pick on``: ::
9057 further processing.
9158
9259When Pylint is first run on a fresh piece of code, a common complaint is that it
93- is too ``noisy ``. The current default configuration is set to enforce all possible
94- warnings. We'll use some of the options I noted above to make it suit your
95- preferences a bit better (and thus make it emit messages only when needed).
96-
60+ is too ``noisy ``. The default configuration enforce a lot of warnings.
61+ We'll use some of the options we noted above to make it suit your
62+ preferences a bit better.
9763
9864Your First Pylint'ing
9965---------------------
10066
101- We'll use a basic Python script as fodder for our tutorial.
102- The starting code we will use is called simplecaesar.py and is here in its
103- entirety:
67+ We'll use a basic Python script with `` black `` already applied on it,
68+ as fodder for our tutorial. The starting code we will use is called
69+ `` simplecaesar.py `` and is here in its entirety:
10470
10571.. sourcecode :: python
10672
107- #!/usr/bin/env python3
108-
109- import string;
73+ #!/usr/bin/env python3
11074
111- shift = 3
112- choice = input("would you like to encode or decode?")
113- word = input("Please enter text")
114- letters = string.ascii_letters + string.punctuation + string.digits
115- encoded = ''
116- if choice == "encode":
117- for letter in word:
118- if letter == ' ':
119- encoded = encoded + ' '
120- else:
121- x = letters.index(letter) + shift
122- encoded = encoded + letters[x]
123- if choice == "decode":
124- for letter in word:
125- if letter == ' ':
126- encoded = encoded + ' '
127- else:
128- x = letters.index(letter) - shift
129- encoded = encoded + letters[x]
75+ import string
13076
131- print(encoded)
77+ shift = 3
78+ choice = input("would you like to encode or decode?")
79+ word = input("Please enter text")
80+ letters = string.ascii_letters + string.punctuation + string.digits
81+ encoded = ""
82+ if choice == "encode":
83+ for letter in word:
84+ if letter == " ":
85+ encoded = encoded + " "
86+ else:
87+ x = letters.index(letter) + shift
88+ encoded = encoded + letters[x]
89+ if choice == "decode":
90+ for letter in word:
91+ if letter == " ":
92+ encoded = encoded + " "
93+ else:
94+ x = letters.index(letter) - shift
95+ encoded = encoded + letters[x]
13296
97+ print(encoded)
13398
134- Let's get started.
13599
136- If we run this:
100+ Let's get started. If we run this:
137101
138102.. sourcecode :: console
139103
140- robertk01 Desktop$ pylint simplecaesar.py
141- *********** ** Module simplecaesar
142- simplecaesar.py:3:0: W0301: Unnecessary semicolon (unnecessary-semicolon)
143- simplecaesar.py:1:0: C0114: Missing module docstring (missing-module-docstring)
144- simplecaesar.py:5:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
145- simplecaesar.py:9:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
146- simplecaesar.py:13:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
104+ tutor Desktop$ pylint simplecaesar.py
105+ *********** ** Module simplecaesar
106+ simplecaesar.py:1:0: C0114: Missing module docstring (missing-module-docstring)
107+ simplecaesar.py:5:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
108+ simplecaesar.py:8:0: C0103: Constant name "letters" doesn't conform to UPPER_CASE naming style (invalid-name)
109+ simplecaesar.py:9:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
110+ simplecaesar.py:13:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
111+ simplecaesar.py:15:12: C0103: Constant name "x" doesn't conform to UPPER_CASE naming style (invalid-name)
112+ simplecaesar.py:16:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
113+ simplecaesar.py:20:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
114+ simplecaesar.py:22:12: C0103: Constant name "x" doesn't conform to UPPER_CASE naming style (invalid-name)
115+ simplecaesar.py:23:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
147116
148- -----------------------------------
149- Your code has been rated at 7.37 /10
117+ -----------------------------------
118+ Your code has been rated at 4.74 /10
150119
151120
152- Previous experience taught me that the default output for the messages
153- needed a bit more info. We can see the second line is: ::
121+ We can see the second line is: ::
154122
155123 "simplecaesar.py:1:0: C0114: Missing module docstring (missing-module-docstring)"
156124
157- This basically means that line 1 violates a convention ``C0114 ``. It's telling me I really should have a docstring.
158- I agree, but what if I didn't fully understand what rule I violated. Knowing only that I violated a convention
159- isn't much help if I'm a newbie. Another piece of information there is the
160- message symbol between parens, ``missing-module-docstring `` here.
125+ This basically means that line 1 at column 0 violates the convention ``C0114 ``.
126+ Another piece of information is the message symbol between parens,
127+ ``missing-module-docstring ``.
161128
162- If I want to read up a bit more about that, I can go back to the
129+ If we want to read up a bit more about that, we can go back to the
163130command line and try this:
164131
165132.. sourcecode :: console
166133
167- robertk01 Desktop$ pylint --help-msg=missing-module-docstring
134+ tutor Desktop$ pylint --help-msg=missing-module-docstring
168135 :missing-module-docstring (C0114): *Missing module docstring *
169136 Used when a module has no docstring.Empty modules do not require a docstring.
170137 This message belongs to the basic checker.
171138
172-
173- Yeah, ok. That one was a bit of a no-brainer, but I have run into error messages
174- that left me with no clue about what went wrong, simply because I was unfamiliar
175- with the underlying mechanism of code theory. One error that puzzled my newbie
176- mind was: ::
177-
178- :too-many-instance-attributes (R0902): *Too many instance attributes (%s/%s)*
179-
180- I get it now thanks to Pylint pointing it out to me. If you don't get that one,
181- pour a fresh cup of coffee and look into it - let your programmer mind grow!
182-
139+ That one was a bit of a no-brainer, but we can also run into error messages
140+ where we are unfamiliar with the underlying code theory.
183141
184142The Next Step
185143-------------
186144
187145Now that we got some configuration stuff out of the way, let's see what we can
188- do with the remaining warnings.
189-
190- If we add a docstring to describe what the code is meant to do that will help.
191- There are 5 ``invalid-name `` messages that we will get to later. Lastly, I
192- put an unnecessary semicolon at the end of the import line so I'll
193- fix that too. To sum up, I'll add a docstring to line 2, and remove the ``; ``
194- from line 3.
195-
196- Here is the updated code:
146+ do with the remaining warnings. If we add a docstring to describe what the code
147+ is meant to do that will help. There are ``invalid-name `` messages that we will
148+ get to later. Here is the updated code:
197149
198150.. sourcecode :: python
199151
200- #!/usr/bin/env python3
201- """This script prompts a user to enter a message to encode or decode
202- using a classic Caesar shift substitution (3 letter shift)"""
203-
204- import string
205-
206- shift = 3
207- choice = input("would you like to encode or decode?")
208- word = input("Please enter text")
209- letters = string.ascii_letters + string.punctuation + string.digits
210- encoded = ''
211- if choice == "encode":
212- for letter in word:
213- if letter == ' ':
214- encoded = encoded + ' '
215- else:
216- x = letters.index(letter) + shift
217- encoded = encoded + letters[x]
218- if choice == "decode":
219- for letter in word:
220- if letter == ' ':
221- encoded = encoded + ' '
222- else:
223- x = letters.index(letter) - shift
224- encoded = encoded + letters[x]
225-
226- print(encoded)
152+ #!/usr/bin/env python3
153+
154+ """This script prompts a user to enter a message to encode or decode
155+ using a classic Caesar shift substitution (3 letter shift)"""
156+
157+ import string
158+
159+ shift = 3
160+ choice = input("would you like to encode or decode?")
161+ word = input("Please enter text")
162+ letters = string.ascii_letters + string.punctuation + string.digits
163+ encoded = ""
164+ if choice == "encode":
165+ for letter in word:
166+ if letter == " ":
167+ encoded = encoded + " "
168+ else:
169+ x = letters.index(letter) + shift
170+ encoded = encoded + letters[x]
171+ if choice == "decode":
172+ for letter in word:
173+ if letter == " ":
174+ encoded = encoded + " "
175+ else:
176+ x = letters.index(letter) - shift
177+ encoded = encoded + letters[x]
178+
179+ print(encoded)
227180
228181Here is what happens when we run it:
229182
230183.. sourcecode :: console
231184
232- robertk01 Desktop$ pylint simplecaesar.py
233- *********** ** Module simplecaesar
234- simplecaesar.py:7:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
235- simplecaesar.py:11:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
236- simplecaesar.py:15:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
185+ tutor Desktop$ pylint simplecaesar.py
186+ *********** ** Module simplecaesar
187+ simplecaesar.py:8:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
188+ simplecaesar.py:11:0: C0103: Constant name "letters" doesn't conform to UPPER_CASE naming style (invalid-name)
189+ simplecaesar.py:12:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
190+ simplecaesar.py:16:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
191+ simplecaesar.py:18:12: C0103: Constant name "x" doesn't conform to UPPER_CASE naming style (invalid-name)
192+ simplecaesar.py:19:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
193+ simplecaesar.py:23:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
194+ simplecaesar.py:25:12: C0103: Constant name "x" doesn't conform to UPPER_CASE naming style (invalid-name)
195+ simplecaesar.py:26:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
237196
238- ------------------------------------------------------------------
239- Your code has been rated at 8.42 /10 (previous run: 7.37 /10, +1.05 )
197+ ------------------------------------------------------------------
198+ Your code has been rated at 5.26 /10 (previous run: 4.74 /10, +0.53 )
240199
241- Nice! Pylint told us how much our code rating has improved since our last run, and we're down to just the ``invalid-name `` messages.
200+ Nice! Pylint told us how much our code rating has improved since our last run,
201+ and we're down to just the ``invalid-name `` messages.
242202
243203There are fairly well defined conventions around naming things like instance
244204variables, functions, classes, etc. The conventions focus on the use of
245205UPPERCASE and lowercase as well as the characters that separate multiple words
246206in the name. This lends itself well to checking via a regular expression, thus
247207the **should match (([A-Z\_ ][A-Z1-9\_ ]*)|(__.*__))$ **.
248208
249- In this case Pylint is telling me that those variables appear to be constants
209+ In this case Pylint is telling us that those variables appear to be constants
250210and should be all UPPERCASE. This is an in-house convention that has lived with Pylint
251211since its inception. You too can create your own in-house naming
252212conventions but for the purpose of this tutorial, we want to stick to the `PEP 8 `_
253- standard. In this case, the variables I declared should follow the convention
213+ standard. In this case, the variables we declared should follow the convention
254214of all lowercase. The appropriate rule would be something like:
255215"should match [a-z\_ ][a-z0-9\_ ]{2,30}$". Notice the lowercase letters in the
256216regular expression (a-z versus A-Z).
@@ -260,14 +220,15 @@ will now be quite quiet:
260220
261221.. sourcecode :: console
262222
263- robertk01 Desktop$ pylint --const-rgx='[a-z _][a-z0-9 _]{2,30}$' simplecaesar.py
223+ tutor Desktop$ pylint simplecaesar.py --const-rgx='[a-z\_ ][a-z0-9\_ ]{2,30}$'
224+ *********** ** Module simplecaesar
225+ simplecaesar.py:18:12: C0103: Constant name "x" doesn't conform to '[a-z\\ _][a-z0-9\\ _]{2,30}$' pattern (invalid-name)
226+ simplecaesar.py:25:12: C0103: Constant name "x" doesn't conform to '[a-z\\ _][a-z0-9\\ _]{2,30}$' pattern (invalid-name)
264227
265- - ------------------------------------------------------------------
266- Your code has been rated at 10.00 /10 (previous run: 8.42 /10, +1.58 )
228+ ------------------------------------------------------------------
229+ Your code has been rated at 8.95 /10 (previous run: 5.26 /10, +3.68 )
267230
268-
269- Regular expressions can be quite a beast so take my word on this particular
270- example but go ahead and `read up `_ on them if you want.
231+ You can `read up `_ on regular expressions or use `a website to help you `_.
271232
272233.. tip ::
273234 It would really be a pain to specify that regex on the command line all the time, particularly if we're using many other options.
@@ -276,6 +237,5 @@ example but go ahead and `read up`_ on them if you want.
276237 quickly sharing them with others. Invoking ``pylint --generate-toml-config `` will create a sample ``.toml `` section with all the options set and explained in comments.
277238 This can then be added to your ``pyproject.toml `` file or any other ``.toml `` file pointed to with the ``--rcfile `` option.
278239
279- That's it for the basic intro. More tutorials will follow.
280-
281240.. _`read up` : https://docs.python.org/library/re.html
241+ .. _`a website to help you` : https://regex101.com/
0 commit comments