└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Raspberry Pi Foundation Python Style Guide 2 | 3 | Guidelines for writing Python code in learning resources 4 | 5 | Largely based on guidelines in [PEP8](https://www.python.org/dev/peps/pep-0008) 6 | 7 | ## Why? 8 | 9 | Good Python code should be easy to read, explicit not implicit, and things should be well named. 10 | 11 | ## But ... pedagogy 12 | 13 | Sometimes it's appropriate to neglect better coding practices to accommodate for younger or less experienced programmers. This is ok. Some exercises start with simpler code and build up explaining new concepts, other exercises only use the simpler code, as they are aimed at young people or beginners and only basic concepts are used. 14 | 15 | However, much of this guide is regarding presentation rather than actual use of code. Following the presentation guidelines should be encouraged. 16 | 17 | ## Good and Bad examples 18 | 19 | Good Python code: 20 | 21 | ```python 22 | import random 23 | from time import sleep 24 | 25 | def number_is_over_ten(n): 26 | return n > 10 27 | 28 | numbers = [1, 5, 7, 11, 21] 29 | number = random.choice(numbers) 30 | 31 | for n in range(number): 32 | if number_is_over_ten(n): 33 | print("%s is over ten" % n) 34 | else: 35 | print("%s is not over ten" % n) 36 | ``` 37 | 38 | Bad Python code: 39 | 40 | ```python 41 | import os, time, random, RPi.GPIO as GPIO, numpy as n, sys, picamera as dave 42 | from pygame import * 43 | def Bob(): print "Hello" 44 | def checkIt(thing): 45 | if thing>0: 46 | if thing+1: 47 | return 1 48 | myVAR=1 49 | while myVAR<10: 50 | print myVar 51 | if checkIt(myVAR):print("ok") 52 | else:print("not ok") 53 | i=i+1 54 | ``` 55 | 56 | ## Python 2 or 3 57 | 58 | Python 3 should be the target version. 59 | 60 | If a library is unavailable with Python 3, it should be reported to be investigated for porting. If Python 2 is used then code should be Python 3 styled where possible (e.g. `print("Hello world")` rather than `print "Hello world"`) as this still works in both. 61 | 62 | ## Imports 63 | 64 | - Each import should be on a new line 65 | 66 | ```python 67 | import time 68 | import random 69 | ``` 70 | 71 | not: 72 | 73 | ```python 74 | import time, random 75 | ``` 76 | 77 | - Line space between groups of imports if many imports are used 78 | 79 | ```python 80 | import time 81 | import random 82 | 83 | import picamera 84 | import RPi.GPIO 85 | 86 | import pygame.mixer 87 | import pygame.locals 88 | ``` 89 | 90 | - `from module import *` should be avoided 91 | 92 | Imports should be explicit, not implicit. Consider the example: 93 | 94 | ```python 95 | from module_a import * 96 | from module_b import * 97 | 98 | some_function() 99 | ``` 100 | 101 | It is unclear whether `some_function` was defined in `module_a` or `module_b`. 102 | 103 | ```python 104 | from module_a import some_function, some_other_function 105 | from module_b import another_function 106 | 107 | some_function() 108 | ``` 109 | 110 | Now it is clear `some_function` belongs to `module_a`. 111 | 112 | Alternatively, import the whole module so all functions are namespaced: 113 | 114 | ```python 115 | import module_a 116 | import module_b 117 | 118 | module_a.some_function() 119 | ``` 120 | 121 | This example also makes it clear where the function comes from. 122 | 123 | - Specific imports are preferred 124 | 125 | Consider the example: 126 | 127 | ```python 128 | from picamera import PiCamera 129 | ``` 130 | 131 | While this is longer than simply `import picamera`, it allows following references to `PiCamera` to be shorter and less repetitive. 132 | 133 | ```python 134 | from picamera import PiCamera 135 | 136 | with PiCamera() as camera: 137 | ... 138 | ``` 139 | 140 | is better than: 141 | 142 | ```python 143 | import picamera 144 | 145 | with picamera.PiCamera() as camera: 146 | ... 147 | ``` 148 | 149 | But sometimes even if only one function is used, it's better left namespaced. 150 | 151 | ```python 152 | from time import sleep 153 | 154 | sleep(1) 155 | ``` 156 | 157 | is ok, and preferable. 158 | 159 | ```python 160 | import time 161 | 162 | time.sleep(1) 163 | ``` 164 | 165 | is ok, but less preferable. 166 | 167 | Whereas 168 | 169 | ```python 170 | import random 171 | 172 | numbers = [1, 5, 7] 173 | 174 | number = random.choice(numbers) 175 | ``` 176 | 177 | is fine, but 178 | 179 | ```python 180 | from random import choice 181 | 182 | numbers = [1, 5, 7] 183 | 184 | number = choice(numbers) 185 | ``` 186 | 187 | is less clear. 188 | 189 | - Renaming an import is ok, but keep it sensibly named. 190 | 191 | ```python 192 | import numpy as np 193 | ``` 194 | 195 | is ok. 196 | 197 | ```python 198 | import time as sleep 199 | ``` 200 | 201 | is confusing. 202 | 203 | - Avoid unnecessary renaming 204 | 205 | ```python 206 | import RPi.GPIO as GPIO 207 | import mcpi.minecraft as minecraft 208 | ``` 209 | 210 | These are unnecessary renames as the module reference is being renamed to what it is already named. The (easier) preferred method is: 211 | 212 | ```python 213 | from RPi import GPIO 214 | from mcpi import minecraft 215 | ``` 216 | 217 | ## Case 218 | 219 | Case should adhere to the following style: 220 | 221 | | **Type** | **Case** | **Examples** | 222 | |---------------------------|------------|--------------| 223 | | Variables and all objects | Snake case | `led`, `elec_hi_snare`| 224 | | Functions | Snake case | `setup_gpio` | 225 | | Class names | Title case | `Dog`, `GameWindow`, `GameOfLife` | 226 | | Constants (variables intended not to be changed) | All caps | `BLACK`, `WHITE`, `HEIGHT`, `WIDTH` | 227 | 228 | ## Magic numbers 229 | 230 | Magic numbers are those used with no explanation. Variables should be used instead. 231 | 232 | Bad: 233 | 234 | ```python 235 | GPIO.setup(17, GPIO.IN, GPIO.PUD_UP) 236 | GPIO.wait_for_edge(17, GPIO.FALLING) 237 | ``` 238 | 239 | Good: 240 | 241 | ```python 242 | button = 17 243 | GPIO.setup(button, GPIO.IN, GPIO.PUD_UP) 244 | GPIO.wait_for_edge(button, GPIO.FALLING) 245 | ``` 246 | 247 | This means if the button pin is changed, it only needs changing in one place. 248 | 249 | ## Unused variables 250 | 251 | Unused variables should be removed or corrected. They make code hard to read, and sometimes misleading. For example: 252 | 253 | ```python 254 | def setup_button(pin): 255 | GPIO.setup(17, GPIO.IN) 256 | 257 | setup_button(13) 258 | ``` 259 | 260 | The last line here claims to set up pin 13. The function takes `pin` as an argument but ignores it and sets up pin 17 regardless of what was passed in. 261 | 262 | The code should read: 263 | 264 | ```python 265 | def setup_button(pin): 266 | GPIO.setup(pin, GPIO.IN) 267 | 268 | setup_button(13) 269 | ``` 270 | 271 | ## Indentation 272 | 273 | - Spaces not tabs 274 | 275 | - Four spaces per tab. 276 | 277 | You don't have to hit space four times - you should configure your editor to insert four spaces when you hit the tab key. 278 | 279 | Example: 280 | 281 | ```python 282 | for i in range(10): 283 | if n < 2: 284 | return False 285 | if n == 2: 286 | return True 287 | if n % 2 == 0: 288 | return False 289 | for i in range(3, int(n**0.5) + 1, 2): 290 | if n % i == 0: 291 | return False 292 | return True 293 | ``` 294 | 295 | ## Spaces around operators 296 | 297 | - A single space should be used on each side of an operator for readability. 298 | 299 | Good: 300 | 301 | ```python 302 | a = 1 303 | b = 2 304 | c = a + b 305 | print(c % 3 == 0) 306 | ``` 307 | 308 | Bad: 309 | 310 | ```python 311 | a=1 312 | b=2 313 | c=a+b 314 | print(c%3==0) 315 | ``` 316 | 317 | - Sometimes spaces can be left out to aid readability, for example in this case spaces would usually be around the `*` multiplication operator but can be left out for clarity of priority: 318 | 319 | ```python 320 | x*x + y*y 321 | ``` 322 | 323 | is better than: 324 | 325 | ```python 326 | x * x + y * y 327 | ``` 328 | 329 | - Avoid extra spaces immediately inside parentheses, brackets or braces: 330 | 331 | Bad: 332 | 333 | ```python 334 | call (1) 335 | dct [1] 336 | dct[ 1 ] 337 | ``` 338 | 339 | Good: 340 | 341 | ```python 342 | call(1) 343 | dct[1] 344 | dct[1] 345 | ``` 346 | 347 | - Also before a comma or colon: 348 | 349 | Bad: 350 | 351 | ```python 352 | if x == 4 : 353 | print(x , y) 354 | ``` 355 | 356 | Good: 357 | 358 | ```python 359 | if x == 4 : 360 | print(x, y) 361 | ``` 362 | 363 | - Multiple spaces around operators should not be used unless necessary for alignment aiding readability. 364 | 365 | ```python 366 | a = 10 367 | b = 16 368 | angle = 2.51 369 | ``` 370 | 371 | is fine 372 | 373 | ```python 374 | a = 10 375 | b = 16 376 | angle = 2.51 377 | ``` 378 | 379 | is unnecessary. 380 | 381 | However, in this case 382 | 383 | ```python 384 | on = '10101010' 385 | off = '01010101' 386 | ``` 387 | 388 | The misalignment makes comparison difficult and 389 | 390 | ```python 391 | on = '10101010' 392 | off = '01010101' 393 | ``` 394 | 395 | is better. 396 | 397 | - The same applies to nested lists and such: 398 | 399 | ```python 400 | pixels = [[r, g, r], [g, g, g], [r, g, r]] 401 | ``` 402 | 403 | is ok, but 404 | 405 | ```python 406 | pixels = [ 407 | [r, g, r], 408 | [g, g, g], 409 | [r, g, r], 410 | ] 411 | ``` 412 | 413 | is more readable as it's presented practically. 414 | 415 | ## Line length 416 | 417 | Line length should not exceed 79 characters and usually should be shortened or rearranged to fit this limit to aid readability and avoid horizontal scrolling or line wrapping. 418 | 419 | Bad: 420 | 421 | ```python 422 | result = some_function_that_takes_arguments('foo', 'bar', 'spam', 'eggs', 'alice', 'bob') 423 | ``` 424 | 425 | Good: 426 | 427 | ```python 428 | result = some_function_that_takes_arguments( 429 | 'foo', 'bar', 'spam', 'eggs', 'alice', 'bob' 430 | ) 431 | ``` 432 | 433 | or: 434 | 435 | ```python 436 | result = some_function_that_takes_arguments( 437 | 'foo', 438 | 'bar', 439 | 'spam', 440 | 'eggs', 441 | 'alice', 442 | 'bob' 443 | ) 444 | ``` 445 | 446 | ## `with` keyword 447 | 448 | The `with` keyword should be used where possible, for example when opening files. This ensures cleanup is completed. 449 | 450 | Bad: 451 | 452 | ```python 453 | f = open('file.txt', 'r') 454 | text = f.read() 455 | print(text) 456 | f.close() 457 | ``` 458 | 459 | Good: 460 | 461 | ```python 462 | with open('file.txt', 'r') as f: 463 | text = f.read() 464 | print(text) 465 | ``` 466 | 467 | ## Booleans 468 | 469 | xxx 470 | 471 | ## Exceptions 472 | 473 | When catching exceptions, mention specific exceptions whenever possible instead of using a bare `except` clause. 474 | 475 | Bad: 476 | 477 | ```python 478 | try: 479 | a = dct['a'] 480 | except: 481 | a = lookup('a') 482 | ``` 483 | 484 | Good: 485 | 486 | ```python 487 | try: 488 | a = dct['a'] 489 | except KeyError: 490 | a = lookup('a') 491 | ``` 492 | 493 | A bare `except` clause will catch `SystemExit` and `KeyboardInterrupt` exceptions, making it harder to interrupt a program with `Ctrl-C`, and can disguise other problems. 494 | 495 | ## Comments - and naming things 496 | 497 | Use comments to explain code, but consider the following: 498 | 499 | - Are you only using the comment to repeat what the code says? Don't do that. Example: 500 | 501 | ```python 502 | import time # import the time module 503 | 504 | a = 1 # assign the value 1 to a 505 | ``` 506 | 507 | - Would a well named variable help? 508 | 509 | Bad: 510 | 511 | ```python 512 | GPIO.setup(17, GPIO.IN) # pin 17 is the button 513 | ``` 514 | 515 | Good: 516 | 517 | ```python 518 | button = 17 519 | GPIO.setup(button, GPIO.IN) 520 | ``` 521 | 522 | This also means if you change the button pin you only change it once in the whole program 523 | 524 | - Would a function be better? 525 | 526 | Bad: 527 | 528 | ```python 529 | # check if the number is prime 530 | for i in range(3, int(101**0.5) + 1, 2): 531 | if n % i == 0: 532 | print("no") 533 | break 534 | print("yes") 535 | ``` 536 | 537 | Good: 538 | 539 | ```python 540 | def is_prime(n): 541 | ... 542 | 543 | n = 101 544 | if is_prime(n): 545 | print("yes") 546 | else: 547 | print("no") 548 | ``` 549 | 550 | - If a function is used, would a better function name help? Examples: 551 | 552 | Bad: 553 | 554 | ```python 555 | # check if n is prime 556 | if my_function(n): 557 | print("yes") 558 | ``` 559 | 560 | Good: 561 | 562 | ```python 563 | if is_prime(n): 564 | print("yes") 565 | ``` 566 | 567 | ## If/Else 568 | 569 | Dictionaries should be used in place of large if/else blocks 570 | 571 | ## Duplication 572 | 573 | Don't repeat yourself. 574 | --------------------------------------------------------------------------------