Skip to content

Commit 42799b2

Browse files
committed
docs
1 parent e23c9ef commit 42799b2

File tree

7 files changed

+922
-92
lines changed

7 files changed

+922
-92
lines changed

README.md

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ For more details, including a link to the full documentation and source code, us
4141
doc(coll_repr)
4242
```
4343

44-
<img width="499" src="nbs/images/att_00000.png">
44+
<img width="499" src="nbs/images/att_00000.png" align="left">
4545

4646
The documentation also contains links to any related functions or classes, which appear like this: `coll_repr` (in the notebook itself you will just see a word with back-ticks around it; the links are auto-generated in the documentation site). The documentation will generally show one or more examples of use, along with any background context necessary to understand them. As you'll see, the examples for each function and method are shown as tests, rather than example outputs, so let's start by explaining that.
4747

@@ -111,7 +111,7 @@ p.ls()
111111

112112

113113

114-
(#2) [Path('images/puppy.jpg'),Path('images/mnist3.png')]
114+
(#3) [Path('images/att_00000.png'),Path('images/puppy.jpg'),Path('images/mnist3.png')]
115115

116116

117117

@@ -127,7 +127,7 @@ p.num_items()
127127

128128

129129

130-
2
130+
3
131131

132132

133133

@@ -189,8 +189,163 @@ p.some_method("hello")
189189

190190
The `assert not kwargs` above is used to ensure that the user doesn't pass an unknown parameter (i.e one that's not in `_methods`). `fastai` uses `funcs_kwargs` in many places, for instance, you can customize any part of a `DataLoader` by passing your own methods.
191191

192+
`fastcore` also provides many utility functions that make a Python programmer's life easier, in `fastcore.utils`. We won't look at many here, since you can easily look at the docs yourself. To get you started, have a look at the docs for `chunked` (remember, if you're in a notebook, type `doc(chunked)`), which is a handy function for creating lazily generated batches from a collection.
193+
192194
## L
193195

196+
List most languages, Python allows for very concise syntax for some very common types, such as `list`, which can be constructed with `[1,2,3]`. Perl's designer Larry Wall explained the reasoning for this kind of syntax:
197+
> In metaphorical honor of Huffman’s compression code that assigns smaller numbers of bits to more common bytes. In terms of syntax, it simply means that commonly used things should be shorter, but you shouldn’t waste short sequences on less common constructs.
198+
199+
On this basis, `fastcore` has just one type that has a single letter name:`L`. The reason for this is that it is designed to be a replacement for `list`, so we want it to be just as easy to use as `[1,2,3]`. Here's how to create that as an `L`:
200+
201+
```python
202+
L(1,2,3)
203+
```
204+
205+
206+
207+
208+
(#3) [1,2,3]
209+
210+
211+
212+
The first thing to notice is that an `L` object includes in its representation its number of elements; that's the `(#3)` in the output above. If there's more than 10 elements, it will automatically truncate the list:
213+
214+
```python
215+
p = L.range(20).shuffle()
216+
p
217+
```
218+
219+
220+
221+
222+
(#20) [3,7,14,16,1,17,19,0,4,8...]
223+
224+
225+
226+
`L` contains many of the same indexing ideas that NumPy's `array` does, including indexing with a list of indexes, or a boolean mask list:
227+
228+
```python
229+
p[2,4,6]
230+
```
231+
232+
233+
234+
235+
(#3) [14,1,19]
236+
237+
238+
239+
It also contains other methods used in `array`, such as `L.argwhere`:
240+
241+
```python
242+
p.argwhere(ge(15))
243+
```
244+
245+
246+
247+
248+
(#5) [3,5,6,12,16]
249+
250+
251+
252+
As you can see from this example, `fastcore` also includes a number of features that make a functional style of programming easier, such as a full range of boolean functions (e.g `ge`, `gt`, etc) which give the same answer as the functions from Python's `operator` module if given two parameters, but return a [curried function](https://en.wikipedia.org/wiki/Currying) if given one parameter.
253+
254+
There's too much functionality to show it all here, so be sure to check the docs. Many little things are added that we thought should have been in `list` in the first place, such as making this do what you'd expect (which is an error with `list`, but works fine with `L`):
255+
256+
```python
257+
1 + L(2,3,4)
258+
```
259+
260+
261+
262+
263+
(#4) [1,2,3,4]
264+
265+
266+
267+
## Function dispatch and Transforms
268+
269+
Most Python programmers use object oriented methods and inheritance to allow different objects to behave in different ways even when called with the same method name. Some languages use a very different approach, such as Julia, which uses [multiple dispatch generic functions](https://docs.julialang.org/en/v1/manual/methods/). Python provides [single dispatch generic functions](https://www.python.org/dev/peps/pep-0443/) as part of the standard library. `fastcore` provides multiple dispatch, with the `typedispatch` decorator (which is actually an instance of `DispatchReg`):
270+
271+
```python
272+
@typedispatch
273+
def f_td_test(x:numbers.Integral, y): return x+1
274+
@typedispatch
275+
def f_td_test(x:int, y:float): return x+y
276+
277+
f_td_test(3,2.0), f_td_test(3,2)
278+
```
279+
280+
281+
282+
283+
(5.0, 4)
284+
285+
286+
287+
This approach to dispatch is particularly useful for adding implementations of functionality in extension modules or user code. It is heavily used in the `Transform` class. A `Transform` is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the `Transform` class provides several mechanisms that make the process of building them easy and flexible (see the docs for information about each of these):
288+
289+
- Type dispatch
290+
- Dispatch over tuples
291+
- Reversability
292+
- Type propagation
293+
- Preprocessing
294+
- Filtering based on the dataset type
295+
- Ordering
296+
- Appending new behavior with decorators
297+
298+
`Transform` looks for three special methods, `encodes`, `decodes`, and `setups`, which provide the implementation for [`__call__`](https://www.python-course.eu/python3_magic_methods.php), `decode`, and `setup` respectively. For instance:
299+
300+
```python
301+
class A(Transform):
302+
def encodes(self, x): return x+1
303+
304+
A()(1)
305+
```
306+
307+
308+
309+
310+
2
311+
312+
313+
314+
For simple transforms like this, you can also use `Transform` as a decorator:
315+
316+
```python
317+
@Transform
318+
def f(x): return x+1
319+
320+
f(1)
321+
```
322+
323+
324+
325+
326+
2
327+
328+
329+
330+
Transforms can be composed into a `Pipeline`:
331+
332+
```python
333+
@Transform
334+
def g(x): return x/2
335+
336+
pipe = Pipeline([f,g])
337+
pipe(3)
338+
```
339+
340+
341+
342+
343+
2.0
344+
345+
346+
347+
The power of `Transform` and `Pipeline` is best understood by seeing how they're used to create a complete data processing pipeline. This is explained in [chapter 11](https://github.com/fastai/fastbook/blob/master/11_midlevel_data.ipynb) of the [fastai book](https://www.amazon.com/Deep-Learning-Coders-fastai-PyTorch/dp/1492045527), which is [available for free](https://github.com/fastai/fastbook) in Jupyter Notebook format.
348+
194349
## Contributing
195350

196351
After you clone this repository, please run `nbdev_install_git_hooks` in your terminal. This sets up git hooks, which clean up the notebooks to remove the extraneous stuff stored in the notebooks (e.g. which cells you ran) which causes unnecessary merge conflicts.

0 commit comments

Comments
 (0)