Python Coding Standards » History » Version 7
Neil Voss, 03/19/2010 02:29 PM
1 | 1 | Neil Voss | h1. Python Coding Standards |
---|---|---|---|
2 | |||
3 | This document is a list of python coding standards. To add a new standard copy the template below and modify it. |
||
4 | |||
5 | 2 | Neil Voss | see also http://emg.nysbc.org/wiki/index.php/Appionscripts_formatting_rules |
6 | |||
7 | 1 | Neil Voss | ---- |
8 | |||
9 | h2. +Name of Coding Standard+ |
||
10 | |||
11 | h3. Definition |
||
12 | |||
13 | What is the coding standard |
||
14 | |||
15 | h3. Justification |
||
16 | |||
17 | Why is the coding standard important |
||
18 | |||
19 | h3. Example |
||
20 | |||
21 | GOOD:<pre> |
||
22 | this is a good example code |
||
23 | </pre> |
||
24 | |||
25 | BAD:<pre> |
||
26 | this is a bad example code |
||
27 | </pre> |
||
28 | |||
29 | ---- |
||
30 | |||
31 | h1. Python Coding Standards for AMI |
||
32 | |||
33 | ---- |
||
34 | |||
35 | 2 | Neil Voss | h2. +Use tabs instead of spaces+ |
36 | |||
37 | h3. Definition |
||
38 | |||
39 | Use tabs instead of spaces for inline code |
||
40 | |||
41 | h3. Justification |
||
42 | |||
43 | 3 | Neil Voss | It is important to be consistent. People like different sizes of columns, some like 8 spaces, others 4, 3, or 2. With tabs each individual can customize their viewer. |
44 | 2 | Neil Voss | |
45 | h3. Example |
||
46 | |||
47 | GOOD:<pre> |
||
48 | if True: |
||
49 | <tab>while True: |
||
50 | <tab><tab>print "tab" |
||
51 | <tab>break |
||
52 | </pre> |
||
53 | |||
54 | BAD:<pre> |
||
55 | if True: |
||
56 | while True: |
||
57 | print "tab" |
||
58 | break |
||
59 | </pre> |
||
60 | |||
61 | ---- |
||
62 | |||
63 | 1 | Neil Voss | h2. +Checking beginning or ending of strings+ |
64 | |||
65 | h3. Definition |
||
66 | |||
67 | Use ''.startswith() and ''.endswith() instead of string slicing to check for prefixes or suffixes. |
||
68 | |||
69 | h3. Justification |
||
70 | |||
71 | startswith() and endswith() are cleaner and less error prone. |
||
72 | |||
73 | h3. Example |
||
74 | |||
75 | GOOD:<pre> |
||
76 | if foo.startswith('bar'): |
||
77 | </pre> |
||
78 | |||
79 | BAD:<pre> |
||
80 | if foo[:3] == 'bar': |
||
81 | </pre> |
||
82 | |||
83 | ---- |
||
84 | |||
85 | h2. +Never use @from module import *@+ |
||
86 | |||
87 | h3. Definition |
||
88 | |||
89 | Never use @from module import *@, use @import module@ instead |
||
90 | |||
91 | h3. Justification |
||
92 | |||
93 | It is hard to track where functions come from when @import *@ is used |
||
94 | |||
95 | h3. Example |
||
96 | |||
97 | GOOD:<pre> |
||
98 | import numpy |
||
99 | a = numpy.ones((3,3)) |
||
100 | </pre> |
||
101 | |||
102 | BAD:<pre> |
||
103 | from numpy import * |
||
104 | a = ones((3,3)) |
||
105 | 2 | Neil Voss | </pre> |
106 | |||
107 | ---- |
||
108 | |||
109 | h2. +Appion image data naming conventions+ |
||
110 | |||
111 | h3. Definition |
||
112 | |||
113 | # never use 'image' or 'img' |
||
114 | # use 'imgdict' for image dictionaries |
||
115 | # use 'imgarray' for image numarrays |
||
116 | # use 'imgname' for image filenames |
||
117 | # use 'imgtree' for the main list of image dictionaries |
||
118 | # use 'imglist' for a list of image data |
||
119 | |||
120 | h3. Justification |
||
121 | |||
122 | If you are consistent with your names people can read your code. |
||
123 | |||
124 | h3. Example |
||
125 | |||
126 | GOOD:<pre> |
||
127 | for imgdict in imgtree: |
||
128 | imgarray = imgdict['image'] |
||
129 | imgname = imgdict['filename'] |
||
130 | </pre> |
||
131 | |||
132 | BAD:<pre> |
||
133 | for image in imgs: |
||
134 | array = image['image'] |
||
135 | name = image['filename'] |
||
136 | 1 | Neil Voss | </pre> |
137 | 4 | Neil Voss | |
138 | ---- |
||
139 | |||
140 | h2. +Use descriptive variables+ |
||
141 | |||
142 | h3. Definition |
||
143 | |||
144 | Use descriptive variables, @asdf@ is not a variable. |
||
145 | |||
146 | h3. Justification |
||
147 | |||
148 | No one understands shorthand variables. |
||
149 | |||
150 | h3. Example |
||
151 | |||
152 | GOOD:<pre> |
||
153 | imgarray = mrc.read('leginon_image.mrc') |
||
154 | particle1 = imgarray[47, 21] |
||
155 | particle1 = imgarray[10, 15] |
||
156 | 5 | Neil Voss | stack = [particle1, particle2] |
157 | 4 | Neil Voss | </pre> |
158 | |||
159 | BAD:<pre> |
||
160 | i = mrc.read('x.mrc') |
||
161 | prtl1 = i[47, 21] |
||
162 | prtl2 = i[10, 15] |
||
163 | 5 | Neil Voss | s = [prtl1, prtl2] |
164 | 4 | Neil Voss | </pre> |
165 | 6 | Neil Voss | |
166 | ---- |
||
167 | |||
168 | 7 | Neil Voss | h2. +Location of functions+ |
169 | 6 | Neil Voss | |
170 | h3. Definition |
||
171 | |||
172 | Functions that have a global use, should go in appionlib folder. |
||
173 | Functions that will only be used by a single program go into that program's file. |
||
174 | Upload to the database function are typically only used by a single program and should be within that program not in appionlib |
||
175 | |||
176 | h3. Justification |
||
177 | |||
178 | Keep the code clean an organized. |
||
179 | |||
180 | h3. Example |
||
181 | |||
182 | 1 | Neil Voss | GOOD:<pre> |
183 | 7 | Neil Voss | from appionlib import commonFunctions |
184 | |||
185 | 6 | Neil Voss | class AppionScript(): |
186 | def customUploadToDB(self): |
||
187 | """stuff""" |
||
188 | 1 | Neil Voss | def run(self): |
189 | 7 | Neil Voss | commonFunctions.commonFunction() |
190 | 6 | Neil Voss | self.customUploadToDB() |
191 | </pre> |
||
192 | |||
193 | BAD:<pre> |
||
194 | from appionlib import apUploadCustom |
||
195 | |||
196 | 1 | Neil Voss | class AppionScript(): |
197 | 7 | Neil Voss | def commonFunction(self): |
198 | """stuff""" |
||
199 | 1 | Neil Voss | def run(self): |
200 | 7 | Neil Voss | self.commonFunction() |
201 | 6 | Neil Voss | apUploadCustom.customUploadToDB() |
202 | </pre> |