~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to doc/python_api/rst/info_best_practice.rst

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
User Interface Layout
57
57
=====================
58
58
 
59
 
TODO: Thomas
 
59
Some notes to keep in mind when writing UI layouts:
 
60
 
 
61
* UI code is quite simple. Layout declarations are there to easily create a decent layout. 
 
62
 
 
63
  General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong. 
 
64
  
 
65
Example layouts:
 
66
 
 
67
* layout()
 
68
 
 
69
  The basic layout is a simple Top -> Bottom layout. 
 
70
  
 
71
  .. code-block:: python
 
72
 
 
73
         layout.prop()
 
74
         layout.prop()
 
75
 
 
76
* layout.row()
 
77
 
 
78
  Use row(), when you want more than 1 property in one line. 
 
79
  
 
80
  .. code-block:: python
 
81
         
 
82
         row = layout.row()
 
83
         row.prop()
 
84
         row.prop()
 
85
 
 
86
* layout.column()
 
87
 
 
88
  Use column(), when you want your properties in a column.
 
89
  
 
90
  .. code-block:: python
 
91
  
 
92
         col = layout.column()
 
93
         col.prop()
 
94
         col.prop()
 
95
 
 
96
* layout.split()
 
97
 
 
98
  This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other.
 
99
  Don't use split, when you simply want two properties in a row. Use row() for that.
 
100
  
 
101
  .. code-block:: python
 
102
  
 
103
         split = layout.split()
 
104
         
 
105
         col = split.column()
 
106
         col.prop()
 
107
         col.prop()
 
108
         
 
109
         col = split.column()
 
110
         col.prop()
 
111
         col.prop()
 
112
         
 
113
Declaration names:
 
114
 
 
115
Try to only use these variable names for layout declarations:
 
116
 
 
117
* row for a row() layout
 
118
* col for a column() layout
 
119
* split for a split() layout
 
120
* flow for a column_flow() layout
 
121
* sub for a sub layout (a column inside a column for example)
60
122
 
61
123
 
62
124
Script Efficiency
83
145
 
84
146
Modifying Lists
85
147
^^^^^^^^^^^^^^^
86
 
In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
 
148
In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
87
149
 
88
150
The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
89
151
 
92
154
Sometimes its faster (but more memory hungry) to just rebuild the list.
93
155
 
94
156
 
95
 
Say you want to remove all triangle faces in a list.
 
157
Say you want to remove all triangular faces in a list.
96
158
 
97
159
Rather than...
98
160
 
99
161
.. code-block:: python
100
162
 
101
 
   faces = mesh.faces[:]  # make a list copy of the meshes faces
 
163
   faces = mesh.tessfaces[:]  # make a list copy of the meshes faces
102
164
   f_idx = len(faces)     # Loop backwards
103
165
   while f_idx:           # while the value is not 0
104
166
       f_idx -= 1
111
173
 
112
174
.. code-block:: python
113
175
 
114
 
   faces = [f for f in mesh.faces if len(f.vertices) != 3]
 
176
   faces = [f for f in mesh.tessfaces if len(f.vertices) != 3]
115
177
 
116
178
 
117
179
Adding List Items
118
180
^^^^^^^^^^^^^^^^^
119
181
 
120
 
If you have a list that you want to add onto another list, rather then...
 
182
If you have a list that you want to add onto another list, rather than...
121
183
 
122
184
.. code-block:: python
123
185
 
143
205
       reverse_list.insert(0, list_item)
144
206
 
145
207
 
 
208
Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much:
 
209
 
 
210
 
 
211
.. code-block:: python
 
212
 
 
213
  some_reversed_list = some_list[::-1]
 
214
 
 
215
 
146
216
Removing List Items
147
217
^^^^^^^^^^^^^^^^^^^
148
218
 
162
232
           my_list.pop(list_index)
163
233
 
164
234
 
165
 
This example shows a fast way of removing items, for use in cases were where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
 
235
This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
166
236
 
167
237
.. code-block:: python
168
238
 
181
251
Avoid Copying Lists
182
252
^^^^^^^^^^^^^^^^^^^
183
253
 
184
 
When passing a list/dictionary to a function, it is faster to have the function modify the list rather then returning a new list so python doesn't have to duplicate the list in memory.
 
254
When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn't have to duplicate the list in memory.
185
255
 
186
 
Functions that modify a list in-place are more efficient then functions that create new lists.
 
256
Functions that modify a list in-place are more efficient than functions that create new lists.
187
257
 
188
258
 
189
259
This is generally slower so only use for functions when it makes sense not to modify the list in place.
211
281
This really applies to any area of your code that involves a lot of string joining.
212
282
 
213
283
 
214
 
Pythons string addition, *don't use if you can help it, especially when writing data in a loop.*
 
284
Python’s string addition, *don't use if you can help it, especially when writing data in a loop.*
215
285
 
216
286
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
217
287
 
218
288
 
219
 
String formatting. Use this when you're writing string data from floats and int's
 
289
String formatting. Use this when you're writing string data from floats and ints
220
290
 
221
291
>>> file.write("%s %s %s\n" % (str1, str2, str3))
222
292
 
223
293
 
224
 
Pythons string joining function. To join a list of strings
 
294
Python’s string joining function. To join a list of strings
225
295
 
226
296
>>> file.write(" ".join([str1, str2, str3, "\n"]))
227
297
 
228
298
 
229
 
join is fastest on many strings, string formatting is quite fast too (better for converting data types). String arithmetic is slowest.
 
299
join is fastest on many strings, `string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`_ is quite fast too (better for converting data types). String arithmetic is slowest.
230
300
 
231
301
 
232
302
Parsing Strings (Import/Exporting)
234
304
 
235
305
Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs.
236
306
 
237
 
When importing strings to make into blender there are a few ways to parse the string.
 
307
There are a few ways to parse strings when importing them into Blender.
238
308
 
239
309
Parsing Numbers
240
310
^^^^^^^^^^^^^^^
241
311
 
242
 
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``,  float() will work for an int too but its faster to read ints with int().
 
312
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``,  float() will work for an int too but it's faster to read ints with int().
243
313
 
244
314
Checking String Start/End
245
315
^^^^^^^^^^^^^^^^^^^^^^^^^
256
326
 
257
327
my_string.endswith("foo_bar") can be used for line endings too.
258
328
 
259
 
if your unsure whether the text is upper or lower case use lower or upper string function.
 
329
If you are unsure whether the text is upper or lower case use ``lower()`` or ``upper()`` string function.
260
330
 
261
331
>>> if line.lower().startswith("vert ")
262
332
 
266
336
 
267
337
The **try** statement is useful to save time writing error checking code.
268
338
 
269
 
However **try** is significantly slower then an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
 
339
However **try** is significantly slower than an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
270
340
 
271
341
There are cases where using **try** is faster than checking whether the condition will raise an error, so it is worth experimenting.
272
342
 
274
344
Value Comparison
275
345
----------------
276
346
 
277
 
Python has two ways to compare values ``a == b`` and ``a is b``, The difference is that ``==`` may run the objects comparison function ``__cmp__()`` where as ``is`` compares identity, that both variables reference the same item in memory. 
 
347
Python has two ways to compare values ``a == b`` and ``a is b``, the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, that both variables reference the same item in memory. 
278
348
 
279
349
In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
280
350
 
282
352
Time Your Code
283
353
--------------
284
354
 
285
 
While developing a script its good to time it to be aware of any changes in performance, this can be done simply.
 
355
While developing a script it's good to time it to be aware of any changes in performance, this can be done simply.
286
356
 
287
357
.. code-block:: python
288
358