Skip to content

Commit 8a5d7da

Browse files
committed
fixes #249
1 parent 39a78c3 commit 8a5d7da

File tree

4 files changed

+68
-10
lines changed

4 files changed

+68
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ For more details, including a link to the full documentation and source code, us
5151
doc(coll_repr)
5252
```
5353

54-
<img width="499" src="nbs/images/att_00000.png" align="left">
54+
<img width="499" src="nbs/images/att_00000.png" style="max-width: 499px">
5555

5656
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.
5757

fastcore/_nbdev.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
"Path.mk_write": "03_xtras.ipynb",
159159
"Path.ls": "03_xtras.ipynb",
160160
"Path.__repr__": "03_xtras.ipynb",
161+
"autostart": "03_xtras.ipynb",
161162
"time_events": "03_xtras.ipynb",
162163
"stringfmt_names": "03_xtras.ipynb",
163164
"PartialFormatter": "03_xtras.ipynb",

fastcore/xtras.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
__all__ = ['dict2obj', 'obj2dict', 'repr_dict', 'is_listy', 'shufflish', 'mapped', 'IterLen', 'ReindexCollection',
44
'maybe_open', 'image_size', 'bunzip', 'join_path_file', 'loads', 'untar_dir', 'repo_details', 'run',
5-
'open_file', 'save_pickle', 'load_pickle', 'time_events', 'stringfmt_names', 'PartialFormatter',
5+
'open_file', 'save_pickle', 'load_pickle', 'autostart', 'time_events', 'stringfmt_names', 'PartialFormatter',
66
'partial_format', 'utc2local', 'local2utc', 'trace', 'round_multiple', 'modified_env', 'ContextManagers',
77
'str2bool', 'sort_by_run']
88

@@ -222,8 +222,19 @@ def __repr__(self:Path):
222222
return f"Path({self.as_posix()!r})"
223223

224224
# Cell
225+
def autostart(g):
226+
"Decorator that automatically starts a generator"
227+
@functools.wraps(g)
228+
def f():
229+
r = g()
230+
next(r)
231+
return r
232+
return f
233+
234+
# Cell
235+
@autostart
225236
def time_events():
226-
"A simple event timer implemented as a coroutine"
237+
"An event timer implemented as a coroutine"
227238
start,events = default_timer(),0
228239
while True: events += (yield events,events/(default_timer()-start)) or 0
229240

@@ -237,6 +248,7 @@ def stringfmt_names(s:str)->list:
237248

238249
# Cell
239250
class PartialFormatter(string.Formatter):
251+
"A `string.Formatter` that doesn't error on missing fields, and tracks missing fields and unused args"
240252
def __init__(self):
241253
self.missing = set()
242254
super().__init__()

nbs/03_xtras.ipynb

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@
618618
{
619619
"data": {
620620
"text/plain": [
621-
"['d', 'h', 'g', 'a', 'c', 'f', 'e', 'b']"
621+
"['g', 'a', 'b', 'c', 'e', 'f', 'd', 'h']"
622622
]
623623
},
624624
"execution_count": null,
@@ -1326,8 +1326,26 @@
13261326
"outputs": [],
13271327
"source": [
13281328
"#export\n",
1329+
"def autostart(g):\n",
1330+
" \"Decorator that automatically starts a generator\"\n",
1331+
" @functools.wraps(g)\n",
1332+
" def f():\n",
1333+
" r = g()\n",
1334+
" next(r)\n",
1335+
" return r\n",
1336+
" return f"
1337+
]
1338+
},
1339+
{
1340+
"cell_type": "code",
1341+
"execution_count": null,
1342+
"metadata": {},
1343+
"outputs": [],
1344+
"source": [
1345+
"#export\n",
1346+
"@autostart\n",
13291347
"def time_events():\n",
1330-
" \"A simple event timer implemented as a coroutine\"\n",
1348+
" \"An event timer implemented as a coroutine\"\n",
13311349
" start,events = default_timer(),0\n",
13321350
" while True: events += (yield events,events/(default_timer()-start)) or 0"
13331351
]
@@ -1336,7 +1354,7 @@
13361354
"cell_type": "markdown",
13371355
"metadata": {},
13381356
"source": [
1339-
"This is convenient for tracking the frequency of events. Call `send(None)` to start the timer, and then call `send(n)` any time you want to add `n` events to the counter. Pass the object to `next()` to get a tuple of the number of events and the frequency/second."
1357+
"This is convenient for tracking the frequency of events. Call `send(n)` any time you want to add `n` events to the counter. Pass the object to `next()` to get a tuple of the number of events and the frequency/second."
13401358
]
13411359
},
13421360
{
@@ -1348,18 +1366,18 @@
13481366
"name": "stdout",
13491367
"output_type": "stream",
13501368
"text": [
1351-
"# Events: 10, Freq/sec: 64.50\n"
1369+
"# Events: 10, Freq/sec: 80.30\n"
13521370
]
13531371
}
13541372
],
13551373
"source": [
13561374
"# Random wait function for testing `time_events`\n",
13571375
"def _randwait(): yield from (sleep(random.random()/30) for _ in range(10))\n",
13581376
"\n",
1359-
"c = time_events()\n",
1360-
"c.send(None) # Start timer by sending `None`\n",
1377+
"c = time_events() # Start timer\n",
13611378
"for o in _randwait(): c.send(1) # Send an event\n",
1362-
"events,freq = next(c) # `next` returns counter values\n",
1379+
"events,freq = next(c) # Return counter values\n",
1380+
"c.close() # Close when done\n",
13631381
"print(f'# Events: {events}, Freq/sec: {freq:.02f}')"
13641382
]
13651383
},
@@ -1403,6 +1421,7 @@
14031421
"source": [
14041422
"#export\n",
14051423
"class PartialFormatter(string.Formatter):\n",
1424+
" \"A `string.Formatter` that doesn't error on missing fields, and tracks missing fields and unused args\"\n",
14061425
" def __init__(self):\n",
14071426
" self.missing = set()\n",
14081427
" super().__init__()\n",
@@ -1417,6 +1436,32 @@
14171436
" self.xtra = filter_keys(kwargs, lambda o: o not in used)"
14181437
]
14191438
},
1439+
{
1440+
"cell_type": "code",
1441+
"execution_count": null,
1442+
"metadata": {},
1443+
"outputs": [
1444+
{
1445+
"data": {
1446+
"text/markdown": [
1447+
"<h4 id=\"PartialFormatter\" class=\"doc_header\"><code>class</code> <code>PartialFormatter</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
1448+
"\n",
1449+
"> <code>PartialFormatter</code>() :: `Formatter`\n",
1450+
"\n",
1451+
"A `string.Formatter` that doesn't error on missing fields, and tracks missing fields and unused args"
1452+
],
1453+
"text/plain": [
1454+
"<IPython.core.display.Markdown object>"
1455+
]
1456+
},
1457+
"metadata": {},
1458+
"output_type": "display_data"
1459+
}
1460+
],
1461+
"source": [
1462+
"show_doc(PartialFormatter, title_level=4)"
1463+
]
1464+
},
14201465
{
14211466
"cell_type": "code",
14221467
"execution_count": null,

0 commit comments

Comments
 (0)