Skip to content

Commit 5846bf6

Browse files
committed
Support Python 3.7+ only
1 parent 348f699 commit 5846bf6

1 file changed

Lines changed: 115 additions & 67 deletions

File tree

README.md

Lines changed: 115 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ years of collective experience by the authors of *Clean Code*.
2626

2727
Inspired from [clean-code-javascript](https://github.com/ryanmcdermott/clean-code-javascript)
2828

29+
Targets Python3.7+
30+
2931
## **Variables**
3032
### Use meaningful and pronounceable variable names
3133

@@ -36,23 +38,44 @@ ymdstr = datetime.date.today().strftime("%y-%m-%d")
3638

3739
**Good**:
3840
```python
39-
current_date = datetime.date.today().strftime("%y-%m-%d")
41+
current_date: str = datetime.date.today().strftime("%y-%m-%d")
4042
```
4143
**[⬆ back to top](#table-of-contents)**
4244

4345
### Use the same vocabulary for the same type of variable
4446

4547
**Bad:**
48+
Here we use three different names for the same underlying entity:
4649
```python
4750
get_user_info()
4851
get_client_data()
4952
get_customer_record()
5053
```
5154

5255
**Good**:
56+
If the entity is the same, you should be consistent in referring to it in your functions:
5357
```python
54-
get_user()
58+
get_user_info()
59+
get_user_data()
60+
get_user_record()
5561
```
62+
63+
**Even better**
64+
Python is (also) an object oriented programming language. If it makes sense, package the functions together with the concrete implementation
65+
of the entity in your code, as instance attributes, property methods, or methods:
66+
67+
```python
68+
class User:
69+
info : str
70+
71+
@property
72+
def data(self) -> dict:
73+
# ...
74+
75+
def get_record(self) -> Union[Record, None]:
76+
# ...
77+
```
78+
5679
**[⬆ back to top](#table-of-contents)**
5780

5881
### Use searchable names
@@ -65,7 +88,6 @@ Make your names searchable.
6588
```python
6689
# What the heck is 86400 for?
6790
time.sleep(86400);
68-
6991
```
7092

7193
**Good**:
@@ -77,7 +99,6 @@ time.sleep(SECONDS_IN_A_DAY)
7799
```
78100
**[⬆ back to top](#table-of-contents)**
79101

80-
81102
### Use explanatory variables
82103
**Bad:**
83104
```python
@@ -149,66 +170,46 @@ variable name.
149170

150171
**Bad:**
151172

152-
```php
153-
class Car
154-
{
155-
public $carMake;
156-
public $carModel;
157-
public $carColor;
158-
159-
//...
160-
}
173+
```python
174+
class Car:
175+
car_make: str
176+
car_model: str
177+
car_color: str
161178
```
162179

163180
**Good**:
164181

165-
```php
166-
class Car
167-
{
168-
public $make;
169-
public $model;
170-
public $color;
171-
172-
//...
173-
}
182+
```python
183+
class Car:
184+
make: str
185+
model: str
186+
color: str
174187
```
175188

176189
**[⬆ back to top](#table-of-contents)**
177190

178191
### Use default arguments instead of short circuiting or conditionals
179192

180-
**Not good:**
193+
**Tricky**
181194

182-
This is not good because `$breweryName` can be `NULL`.
195+
Why write:
183196

184-
```php
185-
function createMicrobrewery($breweryName = 'Hipster Brew Co.')
186-
{
187-
   // ...
188-
}
197+
```python
198+
def create_micro_brewery(name):
199+
name = "Hipster Brew Co." if name is None else name
200+
slug = hashlib.sha1(name.encode()).hexdigest()
201+
# etc.
189202
```
190203

191-
**Not bad:**
192-
193-
This opinion is more understandable than the previous version, but it better controls the value of the variable.
194-
195-
```php
196-
function createMicrobrewery($name = null)
197-
{
198-
   $breweryName = $name ?: 'Hipster Brew Co.';
199-
// ...
200-
}
201-
```
204+
... when you can specify a default argument instead? This also makes ist clear that
205+
you are expecting a string as the argument.
202206

203207
**Good**:
204208

205-
If you support only PHP 7+, then you can use [type hinting](http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) and be sure that the `$breweryName` will not be `NULL`.
206-
207-
```php
208-
function createMicrobrewery(string $breweryName = 'Hipster Brew Co.')
209-
{
210-
   // ...
211-
}
209+
```python
210+
def create_micro_brewery(name: str="Hipster Brew Co."):
211+
slug = hashlib.sha1(name.encode()).hexdigest()
212+
# etc.
212213
```
213214

214215
**[⬆ back to top](#table-of-contents)**
@@ -224,33 +225,80 @@ arguments then your function is trying to do too much. In cases where it's not,
224225
of the time a higher-level object will suffice as an argument.
225226

226227
**Bad:**
227-
```php
228-
function createMenu($title, $body, $buttonText, $cancellable) {
229-
// ...
230-
}
228+
```python
229+
def create_menu(title, body, button_text, cancellable):
230+
# ...
231231
```
232232

233233
**Good**:
234-
```php
235-
class MenuConfig
236-
{
237-
public $title;
238-
public $body;
239-
public $buttonText;
240-
public $cancellable = false;
241-
}
234+
```python
235+
class Menu:
236+
def __init__(self, config: dict):
237+
title = config["title"]
238+
body = config["body"]
239+
# ...
242240

243-
$config = new MenuConfig();
244-
$config->title = 'Foo';
245-
$config->body = 'Bar';
246-
$config->buttonText = 'Baz';
247-
$config->cancellable = true;
241+
menu = Menu(
242+
{
243+
"title": "My Menu",
244+
"body": "Something about my menu",
245+
"button_text": "OK",
246+
"cancellable": False
247+
}
248+
)
249+
```
250+
251+
**Also good**
252+
```python
253+
class MenuConfig:
254+
title: str
255+
body: str
256+
button_text: str
257+
cancellable: bool = False
258+
259+
260+
def create_menu(config: MenuConfig):
261+
title = config.title
262+
body = config.body
263+
# ...
248264

249-
function createMenu(MenuConfig $config) {
250-
// ...
251-
}
252265

266+
config = MenuConfig
267+
config.title = "My delicious menu"
268+
config.body = "A description of the various items on the menu"
269+
config.button_text = "Order now!"
270+
# The instance attribute overrides the default class attribute.
271+
config.cancellable = True
272+
273+
create_menu(config)
253274
```
275+
276+
**Fancy**
277+
```python
278+
from typing import NamedTuple
279+
280+
281+
class MenuConfig(NamedTuple):
282+
title: str
283+
body: str
284+
button_text: str
285+
cancellable: bool = False
286+
287+
288+
def create_menu(config: MenuConfig):
289+
title, body, button_text, cancellable = config
290+
291+
292+
create_menu(
293+
MenuConfig(
294+
title="My delicious menu",
295+
body="A description of the various items on the menu",
296+
button_text="Order now!"
297+
)
298+
)
299+
```
300+
301+
254302
**[⬆ back to top](#table-of-contents)**
255303

256304

0 commit comments

Comments
 (0)